Browse Source

Vulkan: Update volk and Vulkan SDK components to 1.2.190

Rémi Verschelde 3 years ago
parent
commit
fd641ac85c
63 changed files with 9129 additions and 3884 deletions
  1. 27 26
      modules/glslang/SCsub
  2. 17 9
      thirdparty/README.md
  3. 2 0
      thirdparty/glslang/SPIRV/GLSL.ext.EXT.h
  4. 2 0
      thirdparty/glslang/SPIRV/GLSL.ext.KHR.h
  5. 3 0
      thirdparty/glslang/SPIRV/GLSL.ext.NV.h
  6. 492 56
      thirdparty/glslang/SPIRV/GlslangToSpv.cpp
  7. 3 0
      thirdparty/glslang/SPIRV/SPVRemapper.cpp
  8. 97 27
      thirdparty/glslang/SPIRV/SpvBuilder.cpp
  9. 4 0
      thirdparty/glslang/SPIRV/SpvBuilder.h
  10. 32 0
      thirdparty/glslang/SPIRV/SpvPostProcess.cpp
  11. 3 0
      thirdparty/glslang/SPIRV/SpvTools.cpp
  12. 40 1
      thirdparty/glslang/SPIRV/doc.cpp
  13. 113 2
      thirdparty/glslang/SPIRV/spirv.hpp
  14. 8 0
      thirdparty/glslang/StandAlone/DirStackFileIncluder.h
  15. 12 0
      thirdparty/glslang/glslang/Include/BaseTypes.h
  16. 16 0
      thirdparty/glslang/glslang/Include/Common.h
  17. 136 0
      thirdparty/glslang/glslang/Include/SpirvIntrinsics.h
  18. 215 15
      thirdparty/glslang/glslang/Include/Types.h
  19. 3 2
      thirdparty/glslang/glslang/Include/glslang_c_shader_types.h
  20. 29 5
      thirdparty/glslang/glslang/Include/intermediate.h
  21. 10 11
      thirdparty/glslang/glslang/MachineIndependent/Constant.cpp
  22. 429 25
      thirdparty/glslang/glslang/MachineIndependent/Initialize.cpp
  23. 20 9
      thirdparty/glslang/glslang/MachineIndependent/Intermediate.cpp
  24. 61 2
      thirdparty/glslang/glslang/MachineIndependent/ParseContextBase.cpp
  25. 601 42
      thirdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp
  26. 60 6
      thirdparty/glslang/glslang/MachineIndependent/ParseHelper.h
  27. 27 0
      thirdparty/glslang/glslang/MachineIndependent/Scan.cpp
  28. 99 7
      thirdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp
  29. 355 0
      thirdparty/glslang/glslang/MachineIndependent/SpirvIntrinsics.cpp
  30. 5 1
      thirdparty/glslang/glslang/MachineIndependent/SymbolTable.cpp
  31. 41 10
      thirdparty/glslang/glslang/MachineIndependent/SymbolTable.h
  32. 49 5
      thirdparty/glslang/glslang/MachineIndependent/Versions.cpp
  33. 9 1
      thirdparty/glslang/glslang/MachineIndependent/Versions.h
  34. 25 0
      thirdparty/glslang/glslang/MachineIndependent/attribute.cpp
  35. 2 1
      thirdparty/glslang/glslang/MachineIndependent/attribute.h
  36. 3 3
      thirdparty/glslang/glslang/MachineIndependent/gl_types.h
  37. 355 1
      thirdparty/glslang/glslang/MachineIndependent/glslang.y
  38. 592 503
      thirdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp
  39. 142 129
      thirdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp.h
  40. 13 0
      thirdparty/glslang/glslang/MachineIndependent/intermOut.cpp
  41. 123 61
      thirdparty/glslang/glslang/MachineIndependent/iomapper.cpp
  42. 38 5
      thirdparty/glslang/glslang/MachineIndependent/iomapper.h
  43. 3 3
      thirdparty/glslang/glslang/MachineIndependent/limits.cpp
  44. 396 32
      thirdparty/glslang/glslang/MachineIndependent/linkValidate.cpp
  45. 110 10
      thirdparty/glslang/glslang/MachineIndependent/localintermediate.h
  46. 18 19
      thirdparty/glslang/glslang/MachineIndependent/parseConst.cpp
  47. 5 3
      thirdparty/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp
  48. 4 2
      thirdparty/glslang/glslang/MachineIndependent/reflection.cpp
  49. 27 5
      thirdparty/glslang/glslang/Public/ShaderLang.h
  50. 1 1
      thirdparty/glslang/glslang/build_info.h
  51. 30 3
      thirdparty/volk/volk.c
  52. 25 4
      thirdparty/volk/volk.h
  53. 232 118
      thirdparty/vulkan/include/vulkan/vulkan.hpp
  54. 48 48
      thirdparty/vulkan/include/vulkan/vulkan_beta.h
  55. 223 30
      thirdparty/vulkan/include/vulkan/vulkan_core.h
  56. 342 316
      thirdparty/vulkan/include/vulkan/vulkan_enums.hpp
  57. 126 0
      thirdparty/vulkan/include/vulkan/vulkan_funcs.hpp
  58. 1150 902
      thirdparty/vulkan/include/vulkan/vulkan_handles.hpp
  59. 1855 1359
      thirdparty/vulkan/include/vulkan/vulkan_raii.hpp
  60. 134 15
      thirdparty/vulkan/include/vulkan/vulkan_structs.hpp
  61. 1 1
      thirdparty/vulkan/patches/VKEnumStringHelper-use-volk.patch
  62. 4 4
      thirdparty/vulkan/patches/VMA-use-volk.patch
  63. 82 44
      thirdparty/vulkan/vk_enum_string_helper.h

+ 27 - 26
modules/glslang/SCsub

@@ -13,46 +13,47 @@ if env["builtin_glslang"]:
     thirdparty_dir = "#thirdparty/glslang/"
     thirdparty_sources = [
         "glslang/CInterface/glslang_c_interface.cpp",
-        "glslang/MachineIndependent/RemoveTree.cpp",
-        "glslang/MachineIndependent/ParseHelper.cpp",
-        "glslang/MachineIndependent/iomapper.cpp",
-        "glslang/MachineIndependent/propagateNoContraction.cpp",
-        "glslang/MachineIndependent/Intermediate.cpp",
-        "glslang/MachineIndependent/linkValidate.cpp",
         "glslang/MachineIndependent/attribute.cpp",
-        "glslang/MachineIndependent/Scan.cpp",
-        "glslang/MachineIndependent/Initialize.cpp",
         "glslang/MachineIndependent/Constant.cpp",
-        "glslang/MachineIndependent/reflection.cpp",
+        "glslang/MachineIndependent/glslang_tab.cpp",
+        "glslang/MachineIndependent/InfoSink.cpp",
+        "glslang/MachineIndependent/Initialize.cpp",
+        "glslang/MachineIndependent/Intermediate.cpp",
+        "glslang/MachineIndependent/intermOut.cpp",
+        "glslang/MachineIndependent/IntermTraverse.cpp",
+        "glslang/MachineIndependent/iomapper.cpp",
         "glslang/MachineIndependent/limits.cpp",
-        "glslang/MachineIndependent/preprocessor/PpScanner.cpp",
-        "glslang/MachineIndependent/preprocessor/PpTokens.cpp",
+        "glslang/MachineIndependent/linkValidate.cpp",
+        "glslang/MachineIndependent/parseConst.cpp",
+        "glslang/MachineIndependent/ParseContextBase.cpp",
+        "glslang/MachineIndependent/ParseHelper.cpp",
+        "glslang/MachineIndependent/PoolAlloc.cpp",
         "glslang/MachineIndependent/preprocessor/PpAtom.cpp",
         "glslang/MachineIndependent/preprocessor/PpContext.cpp",
         "glslang/MachineIndependent/preprocessor/Pp.cpp",
-        "glslang/MachineIndependent/InfoSink.cpp",
-        "glslang/MachineIndependent/intermOut.cpp",
+        "glslang/MachineIndependent/preprocessor/PpScanner.cpp",
+        "glslang/MachineIndependent/preprocessor/PpTokens.cpp",
+        "glslang/MachineIndependent/propagateNoContraction.cpp",
+        "glslang/MachineIndependent/reflection.cpp",
+        "glslang/MachineIndependent/RemoveTree.cpp",
+        "glslang/MachineIndependent/Scan.cpp",
+        "glslang/MachineIndependent/ShaderLang.cpp",
+        "glslang/MachineIndependent/SpirvIntrinsics.cpp",
         "glslang/MachineIndependent/SymbolTable.cpp",
-        "glslang/MachineIndependent/glslang_tab.cpp",
         "glslang/MachineIndependent/Versions.cpp",
-        "glslang/MachineIndependent/ShaderLang.cpp",
-        "glslang/MachineIndependent/parseConst.cpp",
-        "glslang/MachineIndependent/PoolAlloc.cpp",
-        "glslang/MachineIndependent/ParseContextBase.cpp",
-        "glslang/MachineIndependent/IntermTraverse.cpp",
-        "glslang/GenericCodeGen/Link.cpp",
         "glslang/GenericCodeGen/CodeGen.cpp",
+        "glslang/GenericCodeGen/Link.cpp",
         "OGLCompilersDLL/InitializeDll.cpp",
         "SPIRV/CInterface/spirv_c_interface.cpp",
-        "SPIRV/InReadableOrder.cpp",
-        "SPIRV/GlslangToSpv.cpp",
-        "SPIRV/SpvBuilder.cpp",
-        "SPIRV/SpvTools.cpp",
         "SPIRV/disassemble.cpp",
         "SPIRV/doc.cpp",
-        "SPIRV/SPVRemapper.cpp",
-        "SPIRV/SpvPostProcess.cpp",
+        "SPIRV/GlslangToSpv.cpp",
+        "SPIRV/InReadableOrder.cpp",
         "SPIRV/Logger.cpp",
+        "SPIRV/SpvBuilder.cpp",
+        "SPIRV/SpvPostProcess.cpp",
+        "SPIRV/SPVRemapper.cpp",
+        "SPIRV/SpvTools.cpp",
         "StandAlone/ResourceLimits.cpp",
     ]
 

+ 17 - 9
thirdparty/README.md

@@ -159,7 +159,7 @@ Files extracted from upstream source:
 ## glslang
 
 - Upstream: https://github.com/KhronosGroup/glslang
-- Version: git (dd69df7f3dac26362e10b0f38efb9e47990f7537, 2020)
+- Version: 11.6.0 (2fb89a0072ae7316af1c856f22663fde4928128a, 2021)
 - License: glslang
 
 Version should be kept in sync with the one of the used Vulkan SDK (see `vulkan`
@@ -173,7 +173,7 @@ Files extracted from upstream source:
 - Run `cmake . && make` and copy generated `include/glslang/build_info.h`
   to `glslang/build_info.h`
 - `LICENSE.txt`
-- Unnecessary files like `CMakeLists.txt` and `updateGrammar` removed.
+- Unnecessary files like `CMakeLists.txt`, `*.m4` and `updateGrammar` removed.
 
 
 ## graphite
@@ -611,9 +611,12 @@ Godot. Please check the file to know what's new.
 ## spirv-reflect
 
 - Upstream: https://github.com/KhronosGroup/SPIRV-Reflect
-- Version: git (272e050728de8d4a4ce9e7101c1244e6ff56e5b0, 2021)
+- Version: git (cc937caab141d889c9c9dff572c5a6854d5cf9b4, 2021)
 - License: Apache 2.0
 
+Does not track Vulkan SDK releases closely, but try to package a commit newer
+than the matching glslang and Vulkan headers, just in case.
+
 Files extracted from upstream source:
 
 - `spirv_reflect.{c,h}`
@@ -672,10 +675,16 @@ folder.
 ## volk
 
 - Upstream: https://github.com/zeux/volk
-- Version: git (d75c007f375f35612dba3de512ac73f10bf9aa0e, 2021)
+- Version: 1.2.190 (760a782f295a66de7391d6ed573d65e3fb1c8450, 2021)
 - License: MIT
 
-The volk commit should match the version of the Vulkan headers defined below.
+Unless there is a specific reason to package a more recent version, please stick
+to tagged releases. All Vulkan libraries and headers should be kept in sync so:
+
+- Update Vulkan SDK components to the matching tag (see "vulkan").
+- Update glslang (see "glslang").
+- Update spirv-reflect (see "spirv-reflect").
+
 
 Files extracted from upstream source:
 
@@ -686,11 +695,10 @@ Files extracted from upstream source:
 ## vulkan
 
 - Upstream: https://github.com/KhronosGroup/Vulkan-Headers
-- Version: sdk-1.2.182.0 (37164a5726f7e6113810f9557903a117498421cf, 2021)
+- Version: 1.2.190 (9e62d027636cd7210f60d934f56107ed6e1579b8, 2021)
 - License: Apache 2.0
 
-Unless there is a specific reason to package a more recent version, please stick
-to Vulkan SDK releases (prefixed by `sdk-`) for all components.
+The vendored version should be kept in sync with volk, see above.
 
 Files extracted from upstream source:
 
@@ -701,7 +709,7 @@ Files extracted from upstream source:
 SDK release: https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/master/layers/generated/vk_enum_string_helper.h
 
 `vk_mem_alloc.h` is taken from https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
-Version: 3.0.0-development (2021-06-21), branch `feature-small-buffers`, commit `cfea2f72851f9ee4a399769f18865047b83711f1`
+Version: 3.0.0-development (2021-07-07), branch `feature-small-buffers`, commit `cfea2f72851f9ee4a399769f18865047b83711f1`
 `vk_mem_alloc.cpp` is a Godot file and should be preserved on updates.
 
 Patches in the `patches` directory should be re-applied after updates.

+ 2 - 0
thirdparty/glslang/SPIRV/GLSL.ext.EXT.h

@@ -36,6 +36,8 @@ static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fu
 static const char* const E_SPV_EXT_fragment_invocation_density = "SPV_EXT_fragment_invocation_density";
 static const char* const E_SPV_EXT_demote_to_helper_invocation = "SPV_EXT_demote_to_helper_invocation";
 static const char* const E_SPV_EXT_shader_atomic_float_add = "SPV_EXT_shader_atomic_float_add";
+static const char* const E_SPV_EXT_shader_atomic_float16_add = "SPV_EXT_shader_atomic_float16_add";
+static const char* const E_SPV_EXT_shader_atomic_float_min_max = "SPV_EXT_shader_atomic_float_min_max";
 static const char* const E_SPV_EXT_shader_image_int64 = "SPV_EXT_shader_image_int64";
 
 #endif  // #ifndef GLSLextEXT_H

+ 2 - 0
thirdparty/glslang/SPIRV/GLSL.ext.KHR.h

@@ -50,5 +50,7 @@ static const char* const E_SPV_KHR_ray_tracing                  = "SPV_KHR_ray_t
 static const char* const E_SPV_KHR_ray_query                    = "SPV_KHR_ray_query";
 static const char* const E_SPV_KHR_fragment_shading_rate        = "SPV_KHR_fragment_shading_rate";
 static const char* const E_SPV_KHR_terminate_invocation         = "SPV_KHR_terminate_invocation";
+static const char* const E_SPV_KHR_workgroup_memory_explicit_layout = "SPV_KHR_workgroup_memory_explicit_layout";
+static const char* const E_SPV_KHR_subgroup_uniform_control_flow = "SPV_KHR_subgroup_uniform_control_flow";
 
 #endif  // #ifndef GLSLextKHR_H

+ 3 - 0
thirdparty/glslang/SPIRV/GLSL.ext.NV.h

@@ -69,6 +69,9 @@ const char* const E_SPV_NV_mesh_shader = "SPV_NV_mesh_shader";
 //SPV_NV_raytracing
 const char* const E_SPV_NV_ray_tracing = "SPV_NV_ray_tracing";
 
+//SPV_NV_ray_tracing_motion_blur
+const char* const E_SPV_NV_ray_tracing_motion_blur = "SPV_NV_ray_tracing_motion_blur";
+
 //SPV_NV_shading_rate
 const char* const E_SPV_NV_shading_rate = "SPV_NV_shading_rate";
 

+ 492 - 56
thirdparty/glslang/SPIRV/GlslangToSpv.cpp

@@ -160,6 +160,7 @@ protected:
     spv::SelectionControlMask TranslateSwitchControl(const glslang::TIntermSwitch&) const;
     spv::LoopControlMask TranslateLoopControl(const glslang::TIntermLoop&, std::vector<unsigned int>& operands) const;
     spv::StorageClass TranslateStorageClass(const glslang::TType&);
+    void TranslateLiterals(const glslang::TVector<const glslang::TIntermConstantUnion*>&, std::vector<unsigned>&) const;
     void addIndirectionIndexCapabilities(const glslang::TType& baseType, const glslang::TType& indexType);
     spv::Id createSpvVariable(const glslang::TIntermSymbol*, spv::Id forcedType);
     spv::Id getSampledType(const glslang::TSampler&);
@@ -178,6 +179,7 @@ protected:
     spv::Id accessChainLoad(const glslang::TType& type);
     void    accessChainStore(const glslang::TType& type, spv::Id rvalue);
     void multiTypeStore(const glslang::TType&, spv::Id rValue);
+    spv::Id convertLoadedBoolInUniformToUint(const glslang::TType& type, spv::Id nominalTypeId, spv::Id loadedId);
     glslang::TLayoutPacking getExplicitLayout(const glslang::TType& type) const;
     int getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
     int getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
@@ -255,17 +257,17 @@ protected:
     bool nanMinMaxClamp;               // true if use NMin/NMax/NClamp instead of FMin/FMax/FClamp
     spv::Id stdBuiltins;
     spv::Id nonSemanticDebugPrintf;
-    std::unordered_map<const char*, spv::Id> extBuiltinMap;
+    std::unordered_map<std::string, spv::Id> extBuiltinMap;
 
-    std::unordered_map<int, spv::Id> symbolValues;
-    std::unordered_set<int> rValueParameters;  // set of formal function parameters passed as rValues,
+    std::unordered_map<long long, spv::Id> symbolValues;
+    std::unordered_set<long long> rValueParameters;  // set of formal function parameters passed as rValues,
                                                // rather than a pointer
     std::unordered_map<std::string, spv::Function*> functionMap;
     std::unordered_map<const glslang::TTypeList*, spv::Id> structMap[glslang::ElpCount][glslang::ElmCount];
     // for mapping glslang block indices to spv indices (e.g., due to hidden members):
-    std::unordered_map<int, std::vector<int>> memberRemapper;
+    std::unordered_map<long long, std::vector<int>> memberRemapper;
     // for mapping glslang symbol struct to symbol Id
-    std::unordered_map<const glslang::TTypeList*, int> glslangTypeToIdMap;
+    std::unordered_map<const glslang::TTypeList*, long long> glslangTypeToIdMap;
     std::stack<bool> breakForLoop;  // false means break for switch
     std::unordered_map<std::string, const glslang::TIntermSymbol*> counterOriginator;
     // Map pointee types for EbtReference to their forward pointers
@@ -380,6 +382,7 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto
         case glslang::EvqBuffer:       return useStorageBuffer ? spv::DecorationBlock : spv::DecorationBufferBlock;
         case glslang::EvqVaryingIn:    return spv::DecorationBlock;
         case glslang::EvqVaryingOut:   return spv::DecorationBlock;
+        case glslang::EvqShared:       return spv::DecorationBlock;
 #ifndef GLSLANG_WEB
         case glslang::EvqPayload:      return spv::DecorationBlock;
         case glslang::EvqPayloadIn:    return spv::DecorationBlock;
@@ -436,6 +439,7 @@ spv::Decoration TranslateLayoutDecoration(const glslang::TType& type, glslang::T
             break;
         case glslang::EbtBlock:
             switch (type.getQualifier().storage) {
+            case glslang::EvqShared:
             case glslang::EvqUniform:
             case glslang::EvqBuffer:
                 switch (type.getQualifier().layoutPacking) {
@@ -1029,6 +1033,10 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
         return spv::BuiltInIncomingRayFlagsKHR;
     case glslang::EbvGeometryIndex:
         return spv::BuiltInRayGeometryIndexKHR;
+    case glslang::EbvCurrentRayTimeNV:
+        builder.addExtension(spv::E_SPV_NV_ray_tracing_motion_blur);
+        builder.addCapability(spv::CapabilityRayTracingMotionBlurNV);
+        return spv::BuiltInCurrentRayTimeNV;
 
     // barycentrics
     case glslang::EbvBaryCoordNV:
@@ -1247,6 +1255,10 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
 {
     if (type.getBasicType() == glslang::EbtRayQuery)
         return spv::StorageClassPrivate;
+#ifndef GLSLANG_WEB
+    if (type.getQualifier().isSpirvByReference())
+        return spv::StorageClassFunction;
+#endif
     if (type.getQualifier().isPipeInput())
         return spv::StorageClassInput;
     if (type.getQualifier().isPipeOutput())
@@ -1278,6 +1290,12 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
         return spv::StorageClassUniformConstant;
     }
 
+    if (type.getQualifier().storage == glslang::EvqShared && type.getBasicType() == glslang::EbtBlock) {
+        builder.addExtension(spv::E_SPV_KHR_workgroup_memory_explicit_layout);
+        builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayoutKHR);
+        return spv::StorageClassWorkgroup;
+    }
+
     switch (type.getQualifier().storage) {
     case glslang::EvqGlobal:        return spv::StorageClassPrivate;
     case glslang::EvqConstReadOnly: return spv::StorageClassFunction;
@@ -1289,6 +1307,7 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
     case glslang::EvqHitAttr:        return spv::StorageClassHitAttributeKHR;
     case glslang::EvqCallableData:   return spv::StorageClassCallableDataKHR;
     case glslang::EvqCallableDataIn: return spv::StorageClassIncomingCallableDataKHR;
+    case glslang::EvqSpirvStorageClass: return static_cast<spv::StorageClass>(type.getQualifier().spirvStorageClass);
 #endif
     default:
         assert(0);
@@ -1298,6 +1317,52 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
     return spv::StorageClassFunction;
 }
 
+// Translate glslang constants to SPIR-V literals
+void TGlslangToSpvTraverser::TranslateLiterals(const glslang::TVector<const glslang::TIntermConstantUnion*>& constants,
+                                               std::vector<unsigned>& literals) const
+{
+    for (auto constant : constants) {
+        if (constant->getBasicType() == glslang::EbtFloat) {
+            float floatValue = static_cast<float>(constant->getConstArray()[0].getDConst());
+            unsigned literal = *reinterpret_cast<unsigned*>(&floatValue);
+            literals.push_back(literal);
+        } else if (constant->getBasicType() == glslang::EbtInt) {
+            unsigned literal = constant->getConstArray()[0].getIConst();
+            literals.push_back(literal);
+        } else if (constant->getBasicType() == glslang::EbtUint) {
+            unsigned literal = constant->getConstArray()[0].getUConst();
+            literals.push_back(literal);
+        } else if (constant->getBasicType() == glslang::EbtBool) {
+            unsigned literal = constant->getConstArray()[0].getBConst();
+            literals.push_back(literal);
+        } else if (constant->getBasicType() == glslang::EbtString) {
+            auto str = constant->getConstArray()[0].getSConst()->c_str();
+            unsigned literal = 0;
+            char* literalPtr = reinterpret_cast<char*>(&literal);
+            unsigned charCount = 0;
+            char ch = 0;
+            do {
+                ch = *(str++);
+                *(literalPtr++) = ch;
+                ++charCount;
+                if (charCount == 4) {
+                    literals.push_back(literal);
+                    literalPtr = reinterpret_cast<char*>(&literal);
+                    charCount = 0;
+                }
+            } while (ch != 0);
+
+            // Partial literal is padded with 0
+            if (charCount > 0) {
+                for (; charCount < 4; ++charCount)
+                    *(literalPtr++) = 0;
+                literals.push_back(literal);
+            }
+        } else
+            assert(0); // Unexpected type
+    }
+}
+
 // Add capabilities pertaining to how an array is indexed.
 void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TType& baseType,
                                                              const glslang::TType& indexType)
@@ -1485,7 +1550,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
 
     if (glslangIntermediate->usingPhysicalStorageBuffer()) {
         addressingModel = spv::AddressingModelPhysicalStorageBuffer64EXT;
-        builder.addIncorporatedExtension(spv::E_SPV_EXT_physical_storage_buffer, spv::Spv_1_5);
+        builder.addIncorporatedExtension(spv::E_SPV_KHR_physical_storage_buffer, spv::Spv_1_5);
         builder.addCapability(spv::CapabilityPhysicalStorageBufferAddressesEXT);
     }
     if (glslangIntermediate->usingVulkanMemoryModel()) {
@@ -1518,6 +1583,13 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
         builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingKHR);
     }
 
+#ifndef GLSLANG_WEB
+    if (glslangIntermediate->getSubgroupUniformControlFlow()) {
+        builder.addExtension(spv::E_SPV_KHR_subgroup_uniform_control_flow);
+        builder.addExecutionMode(shaderEntry, spv::ExecutionModeSubgroupUniformControlFlowKHR);
+    }
+#endif
+
     unsigned int mode;
     switch (glslangIntermediate->getStage()) {
     case EShLangVertex:
@@ -1543,15 +1615,16 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
             builder.addExtension(spv::E_SPV_KHR_post_depth_coverage);
         }
 
-        if (glslangIntermediate->getDepth() != glslang::EldUnchanged && glslangIntermediate->isDepthReplacing())
+        if (glslangIntermediate->isDepthReplacing())
             builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing);
 
 #ifndef GLSLANG_WEB
 
         switch(glslangIntermediate->getDepth()) {
-        case glslang::EldGreater:  mode = spv::ExecutionModeDepthGreater; break;
-        case glslang::EldLess:     mode = spv::ExecutionModeDepthLess;    break;
-        default:                   mode = spv::ExecutionModeMax;          break;
+        case glslang::EldGreater:   mode = spv::ExecutionModeDepthGreater;   break;
+        case glslang::EldLess:      mode = spv::ExecutionModeDepthLess;      break;
+        case glslang::EldUnchanged: mode = spv::ExecutionModeDepthUnchanged; break;
+        default:                    mode = spv::ExecutionModeMax;            break;
         }
         if (mode != spv::ExecutionModeMax)
             builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode);
@@ -1719,6 +1792,53 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
     default:
         break;
     }
+
+#ifndef GLSLANG_WEB
+    //
+    // Add SPIR-V requirements (GL_EXT_spirv_intrinsics)
+    //
+    if (glslangIntermediate->hasSpirvRequirement()) {
+        const glslang::TSpirvRequirement& spirvRequirement = glslangIntermediate->getSpirvRequirement();
+
+        // Add SPIR-V extension requirement
+        for (auto& extension : spirvRequirement.extensions)
+            builder.addExtension(extension.c_str());
+
+        // Add SPIR-V capability requirement
+        for (auto capability : spirvRequirement.capabilities)
+            builder.addCapability(static_cast<spv::Capability>(capability));
+    }
+
+    //
+    // Add SPIR-V execution mode qualifiers (GL_EXT_spirv_intrinsics)
+    //
+    if (glslangIntermediate->hasSpirvExecutionMode()) {
+        const glslang::TSpirvExecutionMode spirvExecutionMode = glslangIntermediate->getSpirvExecutionMode();
+
+        // Add spirv_execution_mode
+        for (auto& mode : spirvExecutionMode.modes) {
+            if (!mode.second.empty()) {
+                std::vector<unsigned> literals;
+                TranslateLiterals(mode.second, literals);
+                builder.addExecutionMode(shaderEntry, static_cast<spv::ExecutionMode>(mode.first), literals);
+            } else
+                builder.addExecutionMode(shaderEntry, static_cast<spv::ExecutionMode>(mode.first));
+        }
+
+        // Add spirv_execution_mode_id
+        for (auto& modeId : spirvExecutionMode.modeIds) {
+            std::vector<spv::Id> operandIds;
+            assert(!modeId.second.empty());
+            for (auto extraOperand : modeId.second) {
+                int nextConst = 0;
+                spv::Id operandId = createSpvConstantFromConstUnionArray(
+                    extraOperand->getType(), extraOperand->getConstArray(), nextConst, false);
+                operandIds.push_back(operandId);
+            }
+            builder.addExecutionModeId(shaderEntry, static_cast<spv::ExecutionMode>(modeId.first), operandIds);
+        }
+    }
+#endif
 }
 
 // Finish creating SPV, after the traversal is complete.
@@ -1986,7 +2106,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
                 {
                     // This may be, e.g., an anonymous block-member selection, which generally need
                     // index remapping due to hidden members in anonymous blocks.
-                    int glslangId = glslangTypeToIdMap[node->getLeft()->getType().getStruct()];
+                    long long glslangId = glslangTypeToIdMap[node->getLeft()->getType().getStruct()];
                     if (memberRemapper.find(glslangId) != memberRemapper.end()) {
                         std::vector<int>& remapper = memberRemapper[glslangId];
                         assert(remapper.size() > 0);
@@ -2116,6 +2236,49 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
     }
 }
 
+spv::Id TGlslangToSpvTraverser::convertLoadedBoolInUniformToUint(const glslang::TType& type,
+                                                                 spv::Id nominalTypeId,
+                                                                 spv::Id loadedId)
+{
+    if (builder.isScalarType(nominalTypeId)) {
+        // Conversion for bool
+        spv::Id boolType = builder.makeBoolType();
+        if (nominalTypeId != boolType)
+            return builder.createBinOp(spv::OpINotEqual, boolType, loadedId, builder.makeUintConstant(0));
+    } else if (builder.isVectorType(nominalTypeId)) {
+        // Conversion for bvec
+        int vecSize = builder.getNumTypeComponents(nominalTypeId);
+        spv::Id bvecType = builder.makeVectorType(builder.makeBoolType(), vecSize);
+        if (nominalTypeId != bvecType)
+            loadedId = builder.createBinOp(spv::OpINotEqual, bvecType, loadedId,
+                makeSmearedConstant(builder.makeUintConstant(0), vecSize));
+    } else if (builder.isArrayType(nominalTypeId)) {
+        // Conversion for bool array
+        spv::Id boolArrayTypeId = convertGlslangToSpvType(type);
+        if (nominalTypeId != boolArrayTypeId)
+        {
+            // Use OpCopyLogical from SPIR-V 1.4 if available.
+            if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4)
+                return builder.createUnaryOp(spv::OpCopyLogical, boolArrayTypeId, loadedId);
+
+            glslang::TType glslangElementType(type, 0);
+            spv::Id elementNominalTypeId = builder.getContainedTypeId(nominalTypeId);
+            std::vector<spv::Id> constituents;
+            for (int index = 0; index < type.getOuterArraySize(); ++index) {
+                // get the element
+                spv::Id elementValue = builder.createCompositeExtract(loadedId, elementNominalTypeId, index);
+
+                // recursively convert it
+                spv::Id elementConvertedValue = convertLoadedBoolInUniformToUint(glslangElementType, elementNominalTypeId, elementValue);
+                constituents.push_back(elementConvertedValue);
+            }
+            return builder.createCompositeConstruct(boolArrayTypeId, constituents);
+        }
+    }
+
+    return loadedId;
+}
+
 // Figure out what, if any, type changes are needed when accessing a specific built-in.
 // Returns <the type SPIR-V requires for declarion, the type to translate to on use>.
 // Also see comment for 'forceType', regarding tracking SPIR-V-required types.
@@ -2292,7 +2455,8 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
     if (node->getOp() == glslang::EOpAtomicCounterIncrement ||
         node->getOp() == glslang::EOpAtomicCounterDecrement ||
         node->getOp() == glslang::EOpAtomicCounter          ||
-        node->getOp() == glslang::EOpInterpolateAtCentroid  ||
+        (node->getOp() == glslang::EOpInterpolateAtCentroid &&
+          glslangIntermediate->getSource() != glslang::EShSourceHlsl)  ||
         node->getOp() == glslang::EOpRayQueryProceed        ||
         node->getOp() == glslang::EOpRayQueryGetRayTMin     ||
         node->getOp() == glslang::EOpRayQueryGetRayFlags    ||
@@ -2300,10 +2464,14 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
         node->getOp() == glslang::EOpRayQueryGetWorldRayDirection ||
         node->getOp() == glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque ||
         node->getOp() == glslang::EOpRayQueryTerminate ||
-        node->getOp() == glslang::EOpRayQueryConfirmIntersection) {
+        node->getOp() == glslang::EOpRayQueryConfirmIntersection ||
+        (node->getOp() == glslang::EOpSpirvInst && operandNode->getAsTyped()->getQualifier().isSpirvByReference())) {
         operand = builder.accessChainGetLValue(); // Special case l-value operands
         lvalueCoherentFlags = builder.getAccessChain().coherentFlags;
         lvalueCoherentFlags |= TranslateCoherent(operandNode->getAsTyped()->getType());
+    } else if (operandNode->getAsTyped()->getQualifier().isSpirvLiteral()) {
+        // Will be translated to a literal value, make a placeholder here
+        operand = spv::NoResult;
     } else
 #endif
     {
@@ -2324,6 +2492,38 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
         result = createUnaryOperation(node->getOp(), decorations, resultType(), operand,
             node->getOperand()->getBasicType(), lvalueCoherentFlags);
 
+#ifndef GLSLANG_WEB
+    // it could be attached to a SPIR-V intruction
+    if (!result) {
+        if (node->getOp() == glslang::EOpSpirvInst) {
+            const auto& spirvInst = node->getSpirvInstruction();
+            if (spirvInst.set == "") {
+                spv::IdImmediate idImmOp = {true, operand};
+                if (operandNode->getAsTyped()->getQualifier().isSpirvLiteral()) {
+                    // Translate the constant to a literal value
+                    std::vector<unsigned> literals;
+                    glslang::TVector<const glslang::TIntermConstantUnion*> constants;
+                    constants.push_back(operandNode->getAsConstantUnion());
+                    TranslateLiterals(constants, literals);
+                    idImmOp = {false, literals[0]};
+                }
+
+                if (node->getBasicType() == glslang::EbtVoid)
+                    builder.createNoResultOp(static_cast<spv::Op>(spirvInst.id), {idImmOp});
+                else
+                    result = builder.createOp(static_cast<spv::Op>(spirvInst.id), resultType(), {idImmOp});
+            } else {
+                result = builder.createBuiltinCall(
+                    resultType(), spirvInst.set == "GLSL.std.450" ? stdBuiltins : getExtBuiltins(spirvInst.set.c_str()),
+                    spirvInst.id, {operand});
+            }
+
+            if (node->getBasicType() == glslang::EbtVoid)
+                return false; // done with this node
+        }
+    }
+#endif
+
     if (result) {
         if (invertedType) {
             result = createInvertedSwizzle(decorations.precision, *node->getOperand(), result);
@@ -2775,6 +2975,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
         break;
 
     case glslang::EOpAtomicAdd:
+    case glslang::EOpAtomicSubtract:
     case glslang::EOpAtomicMin:
     case glslang::EOpAtomicMax:
     case glslang::EOpAtomicAnd:
@@ -2821,6 +3022,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
     case glslang::EOpIgnoreIntersectionNV:
     case glslang::EOpTerminateRayNV:
     case glslang::EOpTraceNV:
+    case glslang::EOpTraceRayMotionNV:
     case glslang::EOpTraceKHR:
     case glslang::EOpExecuteCallableNV:
     case glslang::EOpExecuteCallableKHR:
@@ -2946,6 +3148,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
             break;
 
         case glslang::EOpAtomicAdd:
+        case glslang::EOpAtomicSubtract:
         case glslang::EOpAtomicMin:
         case glslang::EOpAtomicMax:
         case glslang::EOpAtomicAnd:
@@ -2966,7 +3169,13 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
         case glslang::EOpInterpolateAtOffset:
         case glslang::EOpInterpolateAtVertex:
             if (arg == 0) {
-                lvalue = true;
+                // If GLSL, use the address of the interpolant argument.
+                // If HLSL, use an internal version of OpInterolates that takes
+                // the rvalue of the interpolant. A fixup pass in spirv-opt
+                // legalization will remove the OpLoad and convert to an lvalue.
+                // Had to do this because legalization will only propagate a
+                // builtin into an rvalue.
+                lvalue = glslangIntermediate->getSource() != glslang::EShSourceHlsl;
 
                 // Does it need a swizzle inversion?  If so, evaluation is inverted;
                 // operate first on the swizzle base, then apply the swizzle.
@@ -3012,6 +3221,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
             if (arg == 1)
                 lvalue = true;
             break;
+        case glslang::EOpSpirvInst:
+            if (glslangOperands[arg]->getAsTyped()->getQualifier().isSpirvByReference())
+                lvalue = true;
+            break;
 #endif
         default:
             break;
@@ -3109,15 +3322,22 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
                 bool cond = glslangOperands[arg]->getAsConstantUnion()->getConstArray()[0].getBConst();
                 operands.push_back(builder.makeIntConstant(cond ? 1 : 0));
              } else if ((arg == 10 && glslangOp == glslang::EOpTraceKHR) ||
+                        (arg == 11 && glslangOp == glslang::EOpTraceRayMotionNV) ||
                         (arg == 1  && glslangOp == glslang::EOpExecuteCallableKHR)) {
-                 const int opdNum = glslangOp == glslang::EOpTraceKHR ? 10 : 1;
-                 const int set = glslangOp == glslang::EOpTraceKHR ? 0 : 1;
+                 const int opdNum = glslangOp == glslang::EOpTraceKHR ? 10 : (glslangOp == glslang::EOpTraceRayMotionNV ? 11 : 1);
+                 const int set = glslangOp == glslang::EOpExecuteCallableKHR ? 1 : 0;
+
                  const int location = glslangOperands[opdNum]->getAsConstantUnion()->getConstArray()[0].getUConst();
                  auto itNode = locationToSymbol[set].find(location);
                  visitSymbol(itNode->second);
                  spv::Id symId = getSymbolId(itNode->second);
                  operands.push_back(symId);
-             } else {
+#ifndef GLSLANG_WEB
+             } else if (glslangOperands[arg]->getAsTyped()->getQualifier().isSpirvLiteral()) {
+                 // Will be translated to a literal value, make a placeholder here
+                 operands.push_back(spv::NoResult);
+#endif
+             } else  {
                 operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType()));
              }
         }
@@ -3155,8 +3375,38 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
 #endif
     if (atomic) {
         // Handle all atomics
-        result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(),
+        glslang::TBasicType typeProxy = (node->getOp() == glslang::EOpAtomicStore)
+            ? node->getSequence()[0]->getAsTyped()->getBasicType() : node->getBasicType();
+        result = createAtomicOperation(node->getOp(), precision, resultType(), operands, typeProxy,
             lvalueCoherentFlags);
+#ifndef GLSLANG_WEB
+    } else if (node->getOp() == glslang::EOpSpirvInst) {
+        const auto& spirvInst = node->getSpirvInstruction();
+        if (spirvInst.set == "") {
+            std::vector<spv::IdImmediate> idImmOps;
+            for (int i = 0; i < glslangOperands.size(); ++i) {
+                if (glslangOperands[i]->getAsTyped()->getQualifier().isSpirvLiteral()) {
+                    // Translate the constant to a literal value
+                    std::vector<unsigned> literals;
+                    glslang::TVector<const glslang::TIntermConstantUnion*> constants;
+                    constants.push_back(glslangOperands[i]->getAsConstantUnion());
+                    TranslateLiterals(constants, literals);
+                    idImmOps.push_back({false, literals[0]});
+                } else
+                    idImmOps.push_back({true, operands[i]});
+            }
+
+            if (node->getBasicType() == glslang::EbtVoid)
+                builder.createNoResultOp(static_cast<spv::Op>(spirvInst.id), idImmOps);
+            else
+                result = builder.createOp(static_cast<spv::Op>(spirvInst.id), resultType(), idImmOps);
+        } else {
+            result = builder.createBuiltinCall(
+                resultType(), spirvInst.set == "GLSL.std.450" ? stdBuiltins : getExtBuiltins(spirvInst.set.c_str()),
+                spirvInst.id, operands);
+        }
+        noReturnValue = node->getBasicType() == glslang::EbtVoid;
+#endif
     } else if (node->getOp() == glslang::EOpDebugPrintf) {
         if (!nonSemanticDebugPrintf) {
             nonSemanticDebugPrintf = builder.import("NonSemantic.DebugPrintf");
@@ -3437,6 +3687,11 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T
 
 void TGlslangToSpvTraverser::visitConstantUnion(glslang::TIntermConstantUnion* node)
 {
+#ifndef GLSLANG_WEB
+    if (node->getQualifier().isSpirvLiteral())
+        return; // Translated to a literal value, skip further processing
+#endif
+
     int nextConst = 0;
     spv::Id constant = createSpvConstantFromConstUnionArray(node->getType(), node->getConstArray(), nextConst, false);
 
@@ -3623,6 +3878,11 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
             break;
 #endif
         default:
+            if (storageClass == spv::StorageClassWorkgroup &&
+                node->getType().getBasicType() == glslang::EbtBlock) {
+                builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR);
+                break;
+            }
             if (node->getType().contains16BitFloat())
                 builder.addCapability(spv::CapabilityFloat16);
             if (node->getType().contains16BitInt())
@@ -3641,6 +3901,9 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
         } else if (storageClass == spv::StorageClassStorageBuffer) {
             builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
             builder.addCapability(spv::CapabilityStorageBuffer8BitAccess);
+        } else if (storageClass == spv::StorageClassWorkgroup &&
+                   node->getType().getBasicType() == glslang::EbtBlock) {
+            builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR);
         } else {
             builder.addCapability(spv::CapabilityInt8);
         }
@@ -3652,13 +3915,14 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
 
     spv::Id initializer = spv::NoResult;
 
-    if (node->getType().getQualifier().storage == glslang::EvqUniform &&
-        !node->getConstArray().empty()) {
-            int nextConst = 0;
-            initializer = createSpvConstantFromConstUnionArray(node->getType(),
-                                                               node->getConstArray(),
-                                                               nextConst,
-                                                               false /* specConst */);
+    if (node->getType().getQualifier().storage == glslang::EvqUniform && !node->getConstArray().empty()) {
+        int nextConst = 0;
+        initializer = createSpvConstantFromConstUnionArray(node->getType(),
+                                                           node->getConstArray(),
+                                                           nextConst,
+                                                           false /* specConst */);
+    } else if (node->getType().getQualifier().isNullInit()) {
+        initializer = builder.makeNullConstant(spvType);
     }
 
     return builder.createVariable(spv::NoPrecision, storageClass, spvType, name, initializer);
@@ -3876,6 +4140,77 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
     case glslang::EbtString:
         // no type used for OpString
         return 0;
+#ifndef GLSLANG_WEB
+    case glslang::EbtSpirvType: {
+        // GL_EXT_spirv_intrinsics
+        const auto& spirvType = type.getSpirvType();
+        const auto& spirvInst = spirvType.spirvInst;
+
+        std::vector<spv::Id> operands;
+        for (const auto& typeParam : spirvType.typeParams) {
+            if (typeParam.isConstant) {
+                // Constant expression
+                if (typeParam.constant->isLiteral()) {
+                    if (typeParam.constant->getBasicType() == glslang::EbtFloat) {
+                        float floatValue = static_cast<float>(typeParam.constant->getConstArray()[0].getDConst());
+                        unsigned literal = *reinterpret_cast<unsigned*>(&floatValue);
+                        operands.push_back(literal);
+                    } else if (typeParam.constant->getBasicType() == glslang::EbtInt) {
+                        unsigned literal = typeParam.constant->getConstArray()[0].getIConst();
+                        operands.push_back(literal);
+                    } else if (typeParam.constant->getBasicType() == glslang::EbtUint) {
+                        unsigned literal = typeParam.constant->getConstArray()[0].getUConst();
+                        operands.push_back(literal);
+                    } else if (typeParam.constant->getBasicType() == glslang::EbtBool) {
+                        unsigned literal = typeParam.constant->getConstArray()[0].getBConst();
+                        operands.push_back(literal);
+                    } else if (typeParam.constant->getBasicType() == glslang::EbtString) {
+                        auto str = typeParam.constant->getConstArray()[0].getSConst()->c_str();
+                        unsigned literal = 0;
+                        char* literalPtr = reinterpret_cast<char*>(&literal);
+                        unsigned charCount = 0;
+                        char ch = 0;
+                        do {
+                            ch = *(str++);
+                            *(literalPtr++) = ch;
+                            ++charCount;
+                            if (charCount == 4) {
+                                operands.push_back(literal);
+                                literalPtr = reinterpret_cast<char*>(&literal);
+                                charCount = 0;
+                            }
+                        } while (ch != 0);
+
+                        // Partial literal is padded with 0
+                        if (charCount > 0) {
+                            for (; charCount < 4; ++charCount)
+                                *(literalPtr++) = 0;
+                            operands.push_back(literal);
+                        }
+                    } else
+                        assert(0); // Unexpected type
+                } else {
+                    int nextConst = 0;
+                    spv::Id constant = createSpvConstantFromConstUnionArray(
+                        typeParam.constant->getType(), typeParam.constant->getConstArray(), nextConst, false);
+                    operands.push_back(constant);
+                }
+            } else {
+                // Type specifier
+                spv::Id typeId = convertGlslangToSpvType(*typeParam.type);
+                operands.push_back(typeId);
+            }
+        }
+
+        if (spirvInst.set == "")
+            spvType = builder.createOp(static_cast<spv::Op>(spirvInst.id), spv::NoType, operands);
+        else {
+            spvType = builder.createBuiltinCall(
+                spv::NoType, getExtBuiltins(spirvInst.set.c_str()), spirvInst.id, operands);
+        }
+        break;
+    }
+#endif
     default:
         assert(0);
         break;
@@ -4072,7 +4407,6 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
 {
     // Name and decorate the non-hidden members
     int offset = -1;
-    int locationOffset = 0;  // for use within the members of this struct
     bool memberLocationInvalid = type.isArrayOfArrays() ||
         (type.isArray() && (type.getQualifier().isArrayedIo(glslangIntermediate->getStage()) == false));
     for (int i = 0; i < (int)glslangMembers->size(); i++) {
@@ -4130,10 +4464,6 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
         if (!memberLocationInvalid && memberQualifier.hasLocation())
             builder.addMemberDecoration(spvType, member, spv::DecorationLocation, memberQualifier.layoutLocation);
 
-        if (qualifier.hasLocation())      // track for upcoming inheritance
-            locationOffset += glslangIntermediate->computeTypeLocationSize(
-                                            glslangMember, glslangIntermediate->getStage());
-
         // component, XFB, others
         if (glslangMember.getQualifier().hasComponent())
             builder.addMemberDecoration(spvType, member, spv::DecorationComponent,
@@ -4189,6 +4519,38 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
             builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV);
             builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
         }
+
+        //
+        // Add SPIR-V decorations for members (GL_EXT_spirv_intrinsics)
+        //
+        if (glslangMember.getQualifier().hasSprivDecorate()) {
+            const glslang::TSpirvDecorate& spirvDecorate = glslangMember.getQualifier().getSpirvDecorate();
+
+            // Add spirv_decorate
+            for (auto& decorate : spirvDecorate.decorates) {
+                if (!decorate.second.empty()) {
+                    std::vector<unsigned> literals;
+                    TranslateLiterals(decorate.second, literals);
+                    builder.addMemberDecoration(spvType, member, static_cast<spv::Decoration>(decorate.first), literals);
+                }
+                else
+                    builder.addMemberDecoration(spvType, member, static_cast<spv::Decoration>(decorate.first));
+            }
+
+            // spirv_decorate_id not applied to members
+            assert(spirvDecorate.decorateIds.empty());
+
+            // Add spirv_decorate_string
+            for (auto& decorateString : spirvDecorate.decorateStrings) {
+                std::vector<const char*> strings;
+                assert(!decorateString.second.empty());
+                for (auto extraOperand : decorateString.second) {
+                    const char* string = extraOperand->getConstArray()[0].getSConst()->c_str();
+                    strings.push_back(string);
+                }
+                builder.addDecoration(spvType, static_cast<spv::Decoration>(decorateString.first), strings);
+            }
+        }
 #endif
     }
 
@@ -4207,6 +4569,8 @@ spv::Id TGlslangToSpvTraverser::makeArraySizeId(const glslang::TArraySizes& arra
     glslang::TIntermTyped* specNode = arraySizes.getDimNode(dim);
     if (specNode != nullptr) {
         builder.clearAccessChain();
+        SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
+        spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
         specNode->traverse(this);
         return accessChainLoad(specNode->getAsTyped()->getType());
     }
@@ -4242,19 +4606,7 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
 
     // Need to convert to abstract types when necessary
     if (type.getBasicType() == glslang::EbtBool) {
-        if (builder.isScalarType(nominalTypeId)) {
-            // Conversion for bool
-            spv::Id boolType = builder.makeBoolType();
-            if (nominalTypeId != boolType)
-                loadedId = builder.createBinOp(spv::OpINotEqual, boolType, loadedId, builder.makeUintConstant(0));
-        } else if (builder.isVectorType(nominalTypeId)) {
-            // Conversion for bvec
-            int vecSize = builder.getNumTypeComponents(nominalTypeId);
-            spv::Id bvecType = builder.makeVectorType(builder.makeBoolType(), vecSize);
-            if (nominalTypeId != bvecType)
-                loadedId = builder.createBinOp(spv::OpINotEqual, bvecType, loadedId,
-                    makeSmearedConstant(builder.makeUintConstant(0), vecSize));
-        }
+        loadedId = convertLoadedBoolInUniformToUint(type, nominalTypeId, loadedId);
     }
 
     return loadedId;
@@ -4406,6 +4758,7 @@ glslang::TLayoutPacking TGlslangToSpvTraverser::getExplicitLayout(const glslang:
     // has to be a uniform or buffer block or task in/out blocks
     if (type.getQualifier().storage != glslang::EvqUniform &&
         type.getQualifier().storage != glslang::EvqBuffer &&
+        type.getQualifier().storage != glslang::EvqShared &&
         !type.getQualifier().isTaskMemory())
         return glslang::ElpNone;
 
@@ -4575,6 +4928,9 @@ bool TGlslangToSpvTraverser::originalParam(glslang::TStorageQualifier qualifier,
     if (glslangIntermediate->getSource() == glslang::EShSourceHlsl)
         return paramType.getBasicType() == glslang::EbtBlock;
     return paramType.containsOpaque() ||                                                       // sampler, etc.
+#ifndef GLSLANG_WEB
+           paramType.getQualifier().isSpirvByReference() ||                                    // spirv_by_reference
+#endif
            (paramType.getBasicType() == glslang::EbtBlock && qualifier == glslang::EvqBuffer); // SSBO
 }
 
@@ -4968,7 +5324,10 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
 
     int components = node->getType().getVectorSize();
 
-    if (node->getOp() == glslang::EOpTextureFetch) {
+    if (node->getOp() == glslang::EOpImageLoad ||
+        node->getOp() == glslang::EOpImageLoadLod ||
+        node->getOp() == glslang::EOpTextureFetch ||
+        node->getOp() == glslang::EOpTextureFetchOffset) {
         // These must produce 4 components, per SPIR-V spec.  We'll add a conversion constructor if needed.
         // This will only happen through the HLSL path for operator[], so we do not have to handle e.g.
         // the EOpTexture/Proj/Lod/etc family.  It would be harmless to do so, but would need more logic
@@ -5530,7 +5889,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg
             ++lValueCount;
         } else {
             // process r-value, which involves a copy for a type mismatch
-            if (function->getParamType(a) != convertGlslangToSpvType(*argTypes[a]) ||
+            if (function->getParamType(a) != builder.getTypeId(rValues[rValueCount]) ||
                 TranslatePrecisionDecoration(*argTypes[a]) != function->getParamPrecision(a))
             {
                 spv::Id argCopy = builder.createVariable(function->getParamPrecision(a), spv::StorageClassFunction, function->getParamType(a), "arg");
@@ -6813,9 +7172,6 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora
         break;
     case glslang::EOpConvPtrToUvec2:
     case glslang::EOpConvUvec2ToPtr:
-        if (builder.isVector(operand))
-            builder.promoteIncorporatedExtension(spv::E_SPV_EXT_physical_storage_buffer,
-                                                 spv::E_SPV_KHR_physical_storage_buffer, spv::Spv_1_5);
         convOp = spv::OpBitcast;
         break;
 #endif
@@ -6864,29 +7220,58 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
     case glslang::EOpImageAtomicAdd:
     case glslang::EOpAtomicCounterAdd:
         opCode = spv::OpAtomicIAdd;
-        if (typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
+        if (typeProxy == glslang::EbtFloat16 || typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
             opCode = spv::OpAtomicFAddEXT;
             builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_add);
-            if (typeProxy == glslang::EbtFloat)
+            if (typeProxy == glslang::EbtFloat16) {
+                builder.addExtension(spv::E_SPV_EXT_shader_atomic_float16_add);
+                builder.addCapability(spv::CapabilityAtomicFloat16AddEXT);
+            } else if (typeProxy == glslang::EbtFloat) {
                 builder.addCapability(spv::CapabilityAtomicFloat32AddEXT);
-            else
+            } else {
                 builder.addCapability(spv::CapabilityAtomicFloat64AddEXT);
+            }
         }
         break;
+    case glslang::EOpAtomicSubtract:
     case glslang::EOpAtomicCounterSubtract:
         opCode = spv::OpAtomicISub;
         break;
     case glslang::EOpAtomicMin:
     case glslang::EOpImageAtomicMin:
     case glslang::EOpAtomicCounterMin:
-        opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ?
-            spv::OpAtomicUMin : spv::OpAtomicSMin;
+        if (typeProxy == glslang::EbtFloat16 || typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
+            opCode = spv::OpAtomicFMinEXT;
+            builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_min_max);
+            if (typeProxy == glslang::EbtFloat16)
+                builder.addCapability(spv::CapabilityAtomicFloat16MinMaxEXT);
+            else if (typeProxy == glslang::EbtFloat)
+                builder.addCapability(spv::CapabilityAtomicFloat32MinMaxEXT);
+            else
+                builder.addCapability(spv::CapabilityAtomicFloat64MinMaxEXT);
+        } else if (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) {
+            opCode = spv::OpAtomicUMin;
+        } else {
+            opCode = spv::OpAtomicSMin;
+        }
         break;
     case glslang::EOpAtomicMax:
     case glslang::EOpImageAtomicMax:
     case glslang::EOpAtomicCounterMax:
-        opCode = (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) ?
-            spv::OpAtomicUMax : spv::OpAtomicSMax;
+        if (typeProxy == glslang::EbtFloat16 || typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
+            opCode = spv::OpAtomicFMaxEXT;
+            builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_min_max);
+            if (typeProxy == glslang::EbtFloat16)
+                builder.addCapability(spv::CapabilityAtomicFloat16MinMaxEXT);
+            else if (typeProxy == glslang::EbtFloat)
+                builder.addCapability(spv::CapabilityAtomicFloat32MinMaxEXT);
+            else
+                builder.addCapability(spv::CapabilityAtomicFloat64MinMaxEXT);
+        } else if (typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64) {
+            opCode = spv::OpAtomicUMax;
+        } else {
+            opCode = spv::OpAtomicSMax;
+        }
         break;
     case glslang::EOpAtomicAnd:
     case glslang::EOpImageAtomicAnd:
@@ -6995,6 +7380,10 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
         builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
     }
 
+    if (builder.getConstantScalar(scopeId) == spv::ScopeQueueFamily) {
+        builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
+    }
+
     if (glslangIntermediate->usingVulkanMemoryModel() && builder.getConstantScalar(scopeId) == spv::ScopeDevice) {
         builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
     }
@@ -7940,6 +8329,11 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
     case glslang::EOpTraceNV:
         builder.createNoResultOp(spv::OpTraceNV, operands);
         return 0;
+    case glslang::EOpTraceRayMotionNV:
+        builder.addExtension(spv::E_SPV_NV_ray_tracing_motion_blur);
+        builder.addCapability(spv::CapabilityRayTracingMotionBlurNV);
+        builder.createNoResultOp(spv::OpTraceRayMotionNV, operands);
+        return 0;
     case glslang::EOpTraceKHR:
         builder.createNoResultOp(spv::OpTraceRayKHR, operands);
         return 0;
@@ -7991,7 +8385,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
         opCode = spv::OpRayQueryGetIntersectionInstanceIdKHR;
         break;
     case glslang::EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset:
-        typeId = builder.makeIntType(32);
+        typeId = builder.makeUintType(32);
         opCode = spv::OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR;
         break;
     case glslang::EOpRayQueryGetIntersectionGeometryIndex:
@@ -8424,6 +8818,48 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
         builder.addDecoration(id, symbol->getType().getQualifier().restrict ?
             spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
     }
+
+    //
+    // Add SPIR-V decorations for structure (GL_EXT_spirv_intrinsics)
+    //
+    if (symbol->getType().getQualifier().hasSprivDecorate()) {
+        const glslang::TSpirvDecorate& spirvDecorate = symbol->getType().getQualifier().getSpirvDecorate();
+
+        // Add spirv_decorate
+        for (auto& decorate : spirvDecorate.decorates) {
+            if (!decorate.second.empty()) {
+                std::vector<unsigned> literals;
+                TranslateLiterals(decorate.second, literals);
+                builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first), literals);
+            }
+            else
+                builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first));
+        }
+
+        // Add spirv_decorate_id
+        for (auto& decorateId : spirvDecorate.decorateIds) {
+            std::vector<spv::Id> operandIds;
+            assert(!decorateId.second.empty());
+            for (auto extraOperand : decorateId.second) {
+                int nextConst = 0;
+                spv::Id operandId = createSpvConstantFromConstUnionArray(
+                    extraOperand->getType(), extraOperand->getConstArray(), nextConst, false);
+                operandIds.push_back(operandId);
+            }
+            builder.addDecoration(id, static_cast<spv::Decoration>(decorateId.first), operandIds);
+        }
+
+        // Add spirv_decorate_string
+        for (auto& decorateString : spirvDecorate.decorateStrings) {
+            std::vector<const char*> strings;
+            assert(!decorateString.second.empty());
+            for (auto extraOperand : decorateString.second) {
+                const char* string = extraOperand->getConstArray()[0].getSConst()->c_str();
+                strings.push_back(string);
+            }
+            builder.addDecoration(id, static_cast<spv::Decoration>(decorateString.first), strings);
+        }
+    }
 #endif
 
     return id;

+ 3 - 0
thirdparty/glslang/SPIRV/SPVRemapper.cpp

@@ -544,6 +544,9 @@ namespace spv {
         // Extended instructions: currently, assume everything is an ID.
         // TODO: add whatever data we need for exceptions to that
         if (opCode == spv::OpExtInst) {
+
+            idFn(asId(word)); // Instruction set is an ID that also needs to be mapped
+
             word        += 2; // instruction set, and instruction from set
             numOperands -= 2;
 

+ 97 - 27
thirdparty/glslang/SPIRV/SpvBuilder.cpp

@@ -743,6 +743,26 @@ Id Builder::getContainedTypeId(Id typeId, int member) const
     }
 }
 
+// Figure out the final resulting type of the access chain.
+Id Builder::getResultingAccessChainType() const
+{
+    assert(accessChain.base != NoResult);
+    Id typeId = getTypeId(accessChain.base);
+
+    assert(isPointerType(typeId));
+    typeId = getContainedTypeId(typeId);
+
+    for (int i = 0; i < (int)accessChain.indexChain.size(); ++i) {
+        if (isStructType(typeId)) {
+            assert(isConstantScalar(accessChain.indexChain[i]));
+            typeId = getContainedTypeId(typeId, getConstantScalar(accessChain.indexChain[i]));
+        } else
+            typeId = getContainedTypeId(typeId, accessChain.indexChain[i]);
+    }
+
+    return typeId;
+}
+
 // Return the immediately contained type of a given composite type.
 Id Builder::getContainedTypeId(Id typeId) const
 {
@@ -869,6 +889,30 @@ bool Builder::isSpecConstantOpCode(Op opcode) const
     }
 }
 
+Id Builder::makeNullConstant(Id typeId)
+{
+    Instruction* constant;
+
+    // See if we already made it.
+    Id existing = NoResult;
+    for (int i = 0; i < (int)nullConstants.size(); ++i) {
+        constant = nullConstants[i];
+        if (constant->getTypeId() == typeId)
+            existing = constant->getResultId();
+    }
+
+    if (existing != NoResult)
+        return existing;
+
+    // Make it
+    Instruction* c = new Instruction(getUniqueId(), typeId, OpConstantNull);
+    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
+    nullConstants.push_back(c);
+    module.mapInstruction(c);
+
+    return c->getResultId();
+}
+
 Id Builder::makeBoolConstant(bool b, bool specConstant)
 {
     Id typeId = makeBoolType();
@@ -1561,16 +1605,7 @@ Id Builder::createLoad(Id lValue, spv::Decoration precision, spv::MemoryAccessMa
 Id Builder::createAccessChain(StorageClass storageClass, Id base, const std::vector<Id>& offsets)
 {
     // Figure out the final resulting type.
-    spv::Id typeId = getTypeId(base);
-    assert(isPointerType(typeId) && offsets.size() > 0);
-    typeId = getContainedTypeId(typeId);
-    for (int i = 0; i < (int)offsets.size(); ++i) {
-        if (isStructType(typeId)) {
-            assert(isConstantScalar(offsets[i]));
-            typeId = getContainedTypeId(typeId, getConstantScalar(offsets[i]));
-        } else
-            typeId = getContainedTypeId(typeId, offsets[i]);
-    }
+    Id typeId = getResultingAccessChainType();
     typeId = makePointer(storageClass, typeId);
 
     // Make the instruction
@@ -2519,7 +2554,7 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
         int row = 0;
         int col = 0;
 
-        for (int arg = 0; arg < (int)sources.size(); ++arg) {
+        for (int arg = 0; arg < (int)sources.size() && col < numCols; ++arg) {
             Id argComp = sources[arg];
             for (int comp = 0; comp < getNumComponents(sources[arg]); ++comp) {
                 if (getNumComponents(sources[arg]) > 1) {
@@ -2531,6 +2566,10 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
                     row = 0;
                     col++;
                 }
+                if (col == numCols) {
+                    // If more components are provided than fit the matrix, discard the rest.
+                    break;
+                }
             }
         }
     }
@@ -2766,28 +2805,59 @@ void Builder::accessChainStore(Id rvalue, Decoration nonUniform, spv::MemoryAcce
     assert(accessChain.isRValue == false);
 
     transferAccessChainSwizzle(true);
-    Id base = collapseAccessChain();
-    addDecoration(base, nonUniform);
 
-    Id source = rvalue;
+    // If a swizzle exists and is not full and is not dynamic, then the swizzle will be broken into individual stores.
+    if (accessChain.swizzle.size() > 0 &&
+        getNumTypeComponents(getResultingAccessChainType()) != (int)accessChain.swizzle.size() &&
+        accessChain.component == NoResult) {
+        for (unsigned int i = 0; i < accessChain.swizzle.size(); ++i) {
+            accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle[i]));
+            accessChain.instr = NoResult;
 
-    // dynamic component should be gone
-    assert(accessChain.component == NoResult);
+            Id base = collapseAccessChain();
+            addDecoration(base, nonUniform);
 
-    // If swizzle still exists, it is out-of-order or not full, we must load the target vector,
-    // extract and insert elements to perform writeMask and/or swizzle.
-    if (accessChain.swizzle.size() > 0) {
-        Id tempBaseId = createLoad(base, spv::NoPrecision);
-        source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
-    }
+            accessChain.indexChain.pop_back();
+            accessChain.instr = NoResult;
+
+            // dynamic component should be gone
+            assert(accessChain.component == NoResult);
+
+            Id source = createCompositeExtract(rvalue, getContainedTypeId(getTypeId(rvalue)), i);
+
+            // take LSB of alignment
+            alignment = alignment & ~(alignment & (alignment-1));
+            if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) {
+                memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
+            }
 
-    // take LSB of alignment
-    alignment = alignment & ~(alignment & (alignment-1));
-    if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) {
-        memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
+            createStore(source, base, memoryAccess, scope, alignment);
+        }
     }
+    else {
+        Id base = collapseAccessChain();
+        addDecoration(base, nonUniform);
+
+        Id source = rvalue;
+
+        // dynamic component should be gone
+        assert(accessChain.component == NoResult);
+
+        // If swizzle still exists, it may be out-of-order, we must load the target vector,
+        // extract and insert elements to perform writeMask and/or swizzle.
+        if (accessChain.swizzle.size() > 0) {
+            Id tempBaseId = createLoad(base, spv::NoPrecision);
+            source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
+        }
 
-    createStore(source, base, memoryAccess, scope, alignment);
+        // take LSB of alignment
+        alignment = alignment & ~(alignment & (alignment-1));
+        if (getStorageClass(base) == StorageClassPhysicalStorageBufferEXT) {
+            memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
+        }
+
+        createStore(source, base, memoryAccess, scope, alignment);
+    }
 }
 
 // Comments in header

+ 4 - 0
thirdparty/glslang/SPIRV/SpvBuilder.h

@@ -202,6 +202,7 @@ public:
     StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); }
     ImageFormat getImageTypeFormat(Id typeId) const
         { return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); }
+    Id getResultingAccessChainType() const;
 
     bool isPointer(Id resultId)      const { return isPointerType(getTypeId(resultId)); }
     bool isScalar(Id resultId)       const { return isScalarType(getTypeId(resultId)); }
@@ -293,6 +294,7 @@ public:
     }
 
     // For making new constants (will return old constant if the requested one was already made).
+    Id makeNullConstant(Id typeId);
     Id makeBoolConstant(bool b, bool specConstant = false);
     Id makeInt8Constant(int i, bool specConstant = false)
         { return makeIntConstant(makeIntType(8),  (unsigned)i, specConstant); }
@@ -838,6 +840,8 @@ public:
     std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants;
     // map type opcodes to type instructions
     std::unordered_map<unsigned int, std::vector<Instruction*>> groupedTypes;
+    // list of OpConstantNull instructions
+    std::vector<Instruction*> nullConstants;
 
     // stack of switches
     std::stack<Block*> switchMerges;

+ 32 - 0
thirdparty/glslang/SPIRV/SpvPostProcess.cpp

@@ -436,6 +436,38 @@ void Builder::postProcessFeatures() {
             }
         }
     }
+
+    // If any Vulkan memory model-specific functionality is used, update the
+    // OpMemoryModel to match.
+    if (capabilities.find(spv::CapabilityVulkanMemoryModelKHR) != capabilities.end()) {
+        memoryModel = spv::MemoryModelVulkanKHR;
+        addIncorporatedExtension(spv::E_SPV_KHR_vulkan_memory_model, spv::Spv_1_5);
+    }
+
+    // Add Aliased decoration if there's more than one Workgroup Block variable.
+    if (capabilities.find(spv::CapabilityWorkgroupMemoryExplicitLayoutKHR) != capabilities.end()) {
+        assert(entryPoints.size() == 1);
+        auto &ep = entryPoints[0];
+
+        std::vector<Id> workgroup_variables;
+        for (int i = 0; i < (int)ep->getNumOperands(); i++) {
+            if (!ep->isIdOperand(i))
+                continue;
+
+            const Id id = ep->getIdOperand(i);
+            const Instruction *instr = module.getInstruction(id);
+            if (instr->getOpCode() != spv::OpVariable)
+                continue;
+
+            if (instr->getImmediateOperand(0) == spv::StorageClassWorkgroup)
+                workgroup_variables.push_back(id);
+        }
+
+        if (workgroup_variables.size() > 1) {
+            for (size_t i = 0; i < workgroup_variables.size(); i++)
+                addDecoration(workgroup_variables[i], spv::DecorationAliased);
+        }
+    }
 }
 #endif
 

+ 3 - 0
thirdparty/glslang/SPIRV/SpvTools.cpp

@@ -153,6 +153,8 @@ void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<
     spv_validator_options options = spvValidatorOptionsCreate();
     spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets());
     spvValidatorOptionsSetBeforeHlslLegalization(options, prelegalization);
+    spvValidatorOptionsSetScalarBlockLayout(options, intermediate.usingScalarBlockLayout());
+    spvValidatorOptionsSetWorkgroupScalarBlockLayout(options, intermediate.usingScalarBlockLayout());
     spvValidateWithOptions(context, options, &binary, &diagnostic);
 
     // report
@@ -205,6 +207,7 @@ void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector
     optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
     optimizer.RegisterPass(spvtools::CreateVectorDCEPass());
     optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass());
+    optimizer.RegisterPass(spvtools::CreateInterpolateFixupPass());
     if (options->optimizeSize) {
         optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass());
     }

+ 40 - 1
thirdparty/glslang/SPIRV/doc.cpp

@@ -188,6 +188,7 @@ const char* ExecutionModeString(int mode)
     case ExecutionModeRoundingModeRTE:          return "RoundingModeRTE";
     case ExecutionModeRoundingModeRTZ:          return "RoundingModeRTZ";
     case ExecutionModeStencilRefReplacingEXT:   return "StencilRefReplacingEXT";
+    case ExecutionModeSubgroupUniformControlFlowKHR: return "SubgroupUniformControlFlow";
 
     case ExecutionModeOutputLinesNV:            return "OutputLinesNV";
     case ExecutionModeOutputPrimitivesNV:       return "OutputPrimitivesNV";
@@ -425,6 +426,7 @@ const char* BuiltInString(int builtIn)
     case BuiltInSMCountNV:              return "SMCountNV";
     case BuiltInWarpIDNV:               return "WarpIDNV";
     case BuiltInSMIDNV:                 return "SMIDNV";
+    case BuiltInCurrentRayTimeNV:       return "CurrentRayTimeNV";
 
     default: return "Bad";
     }
@@ -915,8 +917,10 @@ const char* CapabilityString(int info)
     case CapabilityPerViewAttributesNV:             return "PerViewAttributesNV";
     case CapabilityGroupNonUniformPartitionedNV:    return "GroupNonUniformPartitionedNV";
     case CapabilityRayTracingNV:                    return "RayTracingNV";
+    case CapabilityRayTracingMotionBlurNV:          return "RayTracingMotionBlurNV";
     case CapabilityRayTracingKHR:                   return "RayTracingKHR";
     case CapabilityRayQueryKHR:                     return "RayQueryKHR";
+    case CapabilityRayTracingProvisionalKHR:        return "RayTracingProvisionalKHR";
     case CapabilityRayTraversalPrimitiveCullingKHR: return "RayTraversalPrimitiveCullingKHR";
     case CapabilityComputeDerivativeGroupQuadsNV:   return "ComputeDerivativeGroupQuadsNV";
     case CapabilityComputeDerivativeGroupLinearNV:  return "ComputeDerivativeGroupLinearNV";
@@ -964,8 +968,16 @@ const char* CapabilityString(int info)
 
     case CapabilityIntegerFunctions2INTEL:              return "CapabilityIntegerFunctions2INTEL";
 
+    case CapabilityAtomicFloat16AddEXT:                     return "AtomicFloat16AddEXT";
     case CapabilityAtomicFloat32AddEXT:                     return "AtomicFloat32AddEXT";
     case CapabilityAtomicFloat64AddEXT:                     return "AtomicFloat64AddEXT";
+    case CapabilityAtomicFloat16MinMaxEXT:                  return "AtomicFloat16MinMaxEXT";
+    case CapabilityAtomicFloat32MinMaxEXT:                  return "AtomicFloat32MinMaxEXT";
+    case CapabilityAtomicFloat64MinMaxEXT:                  return "AtomicFloat64MinMaxEXT";
+
+    case CapabilityWorkgroupMemoryExplicitLayoutKHR:            return "CapabilityWorkgroupMemoryExplicitLayoutKHR";
+    case CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR:  return "CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR";
+    case CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR: return "CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR";
 
     default: return "Bad";
     }
@@ -1346,6 +1358,8 @@ const char* OpcodeString(int op)
     case 4432: return "OpSubgroupReadInvocationKHR";
 
     case OpAtomicFAddEXT: return "OpAtomicFAddEXT";
+    case OpAtomicFMinEXT: return "OpAtomicFMinEXT";
+    case OpAtomicFMaxEXT: return "OpAtomicFMaxEXT";
 
     case 5000: return "OpGroupIAddNonUniformAMD";
     case 5001: return "OpGroupFAddNonUniformAMD";
@@ -1370,6 +1384,7 @@ const char* OpcodeString(int op)
     case OpTerminateRayNV:                    return "OpTerminateRayNV";
     case OpTerminateRayKHR:                   return "OpTerminateRayKHR";
     case OpTraceNV:                           return "OpTraceNV";
+    case OpTraceRayMotionNV:                  return "OpTraceRayMotionNV";
     case OpTraceRayKHR:                       return "OpTraceRayKHR";
     case OpTypeAccelerationStructureKHR:      return "OpTypeAccelerationStructureKHR";
     case OpExecuteCallableNV:                 return "OpExecuteCallableNV";
@@ -2336,6 +2351,16 @@ void Parameterize()
     InstructionDesc[OpAtomicSMax].operands.push(OperandMemorySemantics, "'Semantics'");
     InstructionDesc[OpAtomicSMax].operands.push(OperandId, "'Value'");
 
+    InstructionDesc[OpAtomicFMinEXT].operands.push(OperandId, "'Pointer'");
+    InstructionDesc[OpAtomicFMinEXT].operands.push(OperandScope, "'Scope'");
+    InstructionDesc[OpAtomicFMinEXT].operands.push(OperandMemorySemantics, "'Semantics'");
+    InstructionDesc[OpAtomicFMinEXT].operands.push(OperandId, "'Value'");
+
+    InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandId, "'Pointer'");
+    InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandScope, "'Scope'");
+    InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandMemorySemantics, "'Semantics'");
+    InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandId, "'Value'");
+
     InstructionDesc[OpAtomicAnd].operands.push(OperandId, "'Pointer'");
     InstructionDesc[OpAtomicAnd].operands.push(OperandScope, "'Scope'");
     InstructionDesc[OpAtomicAnd].operands.push(OperandMemorySemantics, "'Semantics'");
@@ -2714,7 +2739,7 @@ void Parameterize()
 
     InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandScope, "'Execution'");
     InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandId, "X");
-    InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandLiteralNumber, "'Direction'");
+    InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandId, "'Direction'");
 
     InstructionDesc[OpSubgroupBallotKHR].operands.push(OperandId, "'Predicate'");
 
@@ -2790,6 +2815,20 @@ void Parameterize()
     InstructionDesc[OpTraceNV].operands.push(OperandId, "'Payload'");
     InstructionDesc[OpTraceNV].setResultAndType(false, false);
 
+    InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Acceleration Structure'");
+    InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Flags'");
+    InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Cull Mask'");
+    InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'SBT Record Offset'");
+    InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'SBT Record Stride'");
+    InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Miss Index'");
+    InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Origin'");
+    InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'TMin'");
+    InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Direction'");
+    InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'TMax'");
+    InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Time'");
+    InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Payload'");
+    InstructionDesc[OpTraceRayMotionNV].setResultAndType(false, false);
+
     InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Acceleration Structure'");
     InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Flags'");
     InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Cull Mask'");

+ 113 - 2
thirdparty/glslang/SPIRV/spirv.hpp

@@ -150,6 +150,7 @@ enum ExecutionMode {
     ExecutionModeSubgroupsPerWorkgroupId = 37,
     ExecutionModeLocalSizeId = 38,
     ExecutionModeLocalSizeHintId = 39,
+    ExecutionModeSubgroupUniformControlFlowKHR = 4421,
     ExecutionModePostDepthCoverage = 4446,
     ExecutionModeDenormPreserve = 4459,
     ExecutionModeDenormFlushToZero = 4460,
@@ -168,10 +169,16 @@ enum ExecutionMode {
     ExecutionModeSampleInterlockUnorderedEXT = 5369,
     ExecutionModeShadingRateInterlockOrderedEXT = 5370,
     ExecutionModeShadingRateInterlockUnorderedEXT = 5371,
+    ExecutionModeSharedLocalMemorySizeINTEL = 5618,
+    ExecutionModeRoundingModeRTPINTEL = 5620,
+    ExecutionModeRoundingModeRTNINTEL = 5621,
+    ExecutionModeFloatingPointModeALTINTEL = 5622,
+    ExecutionModeFloatingPointModeIEEEINTEL = 5623,
     ExecutionModeMaxWorkgroupSizeINTEL = 5893,
     ExecutionModeMaxWorkDimINTEL = 5894,
     ExecutionModeNoGlobalOffsetINTEL = 5895,
     ExecutionModeNumSIMDWorkitemsINTEL = 5896,
+    ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903,
     ExecutionModeMax = 0x7fffffff,
 };
 
@@ -204,6 +211,8 @@ enum StorageClass {
     StorageClassPhysicalStorageBuffer = 5349,
     StorageClassPhysicalStorageBufferEXT = 5349,
     StorageClassCodeSectionINTEL = 5605,
+    StorageClassDeviceOnlyINTEL = 5936,
+    StorageClassHostOnlyINTEL = 5937,
     StorageClassMax = 0x7fffffff,
 };
 
@@ -374,6 +383,8 @@ enum FPFastMathModeShift {
     FPFastMathModeNSZShift = 2,
     FPFastMathModeAllowRecipShift = 3,
     FPFastMathModeFastShift = 4,
+    FPFastMathModeAllowContractFastINTELShift = 16,
+    FPFastMathModeAllowReassocINTELShift = 17,
     FPFastMathModeMax = 0x7fffffff,
 };
 
@@ -384,6 +395,8 @@ enum FPFastMathModeMask {
     FPFastMathModeNSZMask = 0x00000004,
     FPFastMathModeAllowRecipMask = 0x00000008,
     FPFastMathModeFastMask = 0x00000010,
+    FPFastMathModeAllowContractFastINTELMask = 0x00010000,
+    FPFastMathModeAllowReassocINTELMask = 0x00020000,
 };
 
 enum FPRoundingMode {
@@ -397,6 +410,7 @@ enum FPRoundingMode {
 enum LinkageType {
     LinkageTypeExport = 0,
     LinkageTypeImport = 1,
+    LinkageTypeLinkOnceODR = 2,
     LinkageTypeMax = 0x7fffffff,
 };
 
@@ -484,12 +498,22 @@ enum Decoration {
     DecorationRestrictPointerEXT = 5355,
     DecorationAliasedPointer = 5356,
     DecorationAliasedPointerEXT = 5356,
+    DecorationSIMTCallINTEL = 5599,
     DecorationReferencedIndirectlyINTEL = 5602,
+    DecorationClobberINTEL = 5607,
+    DecorationSideEffectsINTEL = 5608,
+    DecorationVectorComputeVariableINTEL = 5624,
+    DecorationFuncParamIOKindINTEL = 5625,
+    DecorationVectorComputeFunctionINTEL = 5626,
+    DecorationStackCallINTEL = 5627,
+    DecorationGlobalVariableOffsetINTEL = 5628,
     DecorationCounterBuffer = 5634,
     DecorationHlslCounterBufferGOOGLE = 5634,
     DecorationHlslSemanticGOOGLE = 5635,
     DecorationUserSemantic = 5635,
     DecorationUserTypeGOOGLE = 5636,
+    DecorationFunctionRoundingModeINTEL = 5822,
+    DecorationFunctionDenormModeINTEL = 5823,
     DecorationRegisterINTEL = 5825,
     DecorationMemoryINTEL = 5826,
     DecorationNumbanksINTEL = 5827,
@@ -502,6 +526,17 @@ enum Decoration {
     DecorationMergeINTEL = 5834,
     DecorationBankBitsINTEL = 5835,
     DecorationForcePow2DepthINTEL = 5836,
+    DecorationBurstCoalesceINTEL = 5899,
+    DecorationCacheSizeINTEL = 5900,
+    DecorationDontStaticallyCoalesceINTEL = 5901,
+    DecorationPrefetchINTEL = 5902,
+    DecorationStallEnableINTEL = 5905,
+    DecorationFuseLoopsInFunctionINTEL = 5907,
+    DecorationBufferLocationINTEL = 5921,
+    DecorationIOPipeStorageINTEL = 5944,
+    DecorationFunctionFloatingPointModeINTEL = 6080,
+    DecorationSingleElementVectorINTEL = 6085,
+    DecorationVectorComputeCallableFunctionINTEL = 6087,
     DecorationMax = 0x7fffffff,
 };
 
@@ -617,6 +652,7 @@ enum BuiltIn {
     BuiltInHitTNV = 5332,
     BuiltInHitKindKHR = 5333,
     BuiltInHitKindNV = 5333,
+    BuiltInCurrentRayTimeNV = 5334,
     BuiltInIncomingRayFlagsKHR = 5351,
     BuiltInIncomingRayFlagsNV = 5351,
     BuiltInRayGeometryIndexKHR = 5352,
@@ -656,6 +692,7 @@ enum LoopControlShift {
     LoopControlLoopCoalesceINTELShift = 20,
     LoopControlMaxInterleavingINTELShift = 21,
     LoopControlSpeculatedIterationsINTELShift = 22,
+    LoopControlNoFusionINTELShift = 23,
     LoopControlMax = 0x7fffffff,
 };
 
@@ -677,6 +714,7 @@ enum LoopControlMask {
     LoopControlLoopCoalesceINTELMask = 0x00100000,
     LoopControlMaxInterleavingINTELMask = 0x00200000,
     LoopControlSpeculatedIterationsINTELMask = 0x00400000,
+    LoopControlNoFusionINTELMask = 0x00800000,
 };
 
 enum FunctionControlShift {
@@ -876,6 +914,9 @@ enum Capability {
     CapabilityFragmentShadingRateKHR = 4422,
     CapabilitySubgroupBallotKHR = 4423,
     CapabilityDrawParameters = 4427,
+    CapabilityWorkgroupMemoryExplicitLayoutKHR = 4428,
+    CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429,
+    CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430,
     CapabilitySubgroupVoteKHR = 4431,
     CapabilityStorageBuffer16BitAccess = 4433,
     CapabilityStorageUniformBufferBlock16 = 4433,
@@ -948,6 +989,7 @@ enum Capability {
     CapabilityStorageTexelBufferArrayNonUniformIndexing = 5312,
     CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
     CapabilityRayTracingNV = 5340,
+    CapabilityRayTracingMotionBlurNV = 5341,
     CapabilityVulkanMemoryModel = 5345,
     CapabilityVulkanMemoryModelKHR = 5345,
     CapabilityVulkanMemoryModelDeviceScope = 5346,
@@ -966,21 +1008,42 @@ enum Capability {
     CapabilitySubgroupBufferBlockIOINTEL = 5569,
     CapabilitySubgroupImageBlockIOINTEL = 5570,
     CapabilitySubgroupImageMediaBlockIOINTEL = 5579,
+    CapabilityRoundToInfinityINTEL = 5582,
+    CapabilityFloatingPointModeINTEL = 5583,
     CapabilityIntegerFunctions2INTEL = 5584,
     CapabilityFunctionPointersINTEL = 5603,
     CapabilityIndirectReferencesINTEL = 5604,
+    CapabilityAsmINTEL = 5606,
+    CapabilityAtomicFloat32MinMaxEXT = 5612,
+    CapabilityAtomicFloat64MinMaxEXT = 5613,
+    CapabilityAtomicFloat16MinMaxEXT = 5616,
+    CapabilityVectorComputeINTEL = 5617,
+    CapabilityVectorAnyINTEL = 5619,
+    CapabilityExpectAssumeKHR = 5629,
     CapabilitySubgroupAvcMotionEstimationINTEL = 5696,
     CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697,
     CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698,
+    CapabilityVariableLengthArrayINTEL = 5817,
+    CapabilityFunctionFloatControlINTEL = 5821,
     CapabilityFPGAMemoryAttributesINTEL = 5824,
+    CapabilityFPFastMathModeINTEL = 5837,
+    CapabilityArbitraryPrecisionIntegersINTEL = 5844,
     CapabilityUnstructuredLoopControlsINTEL = 5886,
     CapabilityFPGALoopControlsINTEL = 5888,
     CapabilityKernelAttributesINTEL = 5892,
     CapabilityFPGAKernelAttributesINTEL = 5897,
+    CapabilityFPGAMemoryAccessesINTEL = 5898,
+    CapabilityFPGAClusterAttributesINTEL = 5904,
+    CapabilityLoopFuseINTEL = 5906,
+    CapabilityFPGABufferLocationINTEL = 5920,
+    CapabilityUSMStorageClassesINTEL = 5935,
+    CapabilityIOPipesINTEL = 5943,
     CapabilityBlockingPipesINTEL = 5945,
     CapabilityFPGARegINTEL = 5948,
     CapabilityAtomicFloat32AddEXT = 6033,
     CapabilityAtomicFloat64AddEXT = 6034,
+    CapabilityLongConstantCompositeINTEL = 6089,
+    CapabilityAtomicFloat16AddEXT = 6095,
     CapabilityMax = 0x7fffffff,
 };
 
@@ -1047,6 +1110,18 @@ enum FragmentShadingRateMask {
     FragmentShadingRateHorizontal4PixelsMask = 0x00000008,
 };
 
+enum FPDenormMode {
+    FPDenormModePreserve = 0,
+    FPDenormModeFlushToZero = 1,
+    FPDenormModeMax = 0x7fffffff,
+};
+
+enum FPOperationMode {
+    FPOperationModeIEEE = 0,
+    FPOperationModeALT = 1,
+    FPOperationModeMax = 0x7fffffff,
+};
+
 enum Op {
     OpNop = 0,
     OpUndef = 1,
@@ -1430,6 +1505,8 @@ enum Op {
     OpIgnoreIntersectionNV = 5335,
     OpTerminateRayNV = 5336,
     OpTraceNV = 5337,
+    OpTraceMotionNV = 5338,
+    OpTraceRayMotionNV = 5339,
     OpTypeAccelerationStructureKHR = 5341,
     OpTypeAccelerationStructureNV = 5341,
     OpExecuteCallableNV = 5344,
@@ -1466,8 +1543,15 @@ enum Op {
     OpUSubSatINTEL = 5596,
     OpIMul32x16INTEL = 5597,
     OpUMul32x16INTEL = 5598,
-    OpFunctionPointerINTEL = 5600,
+    OpConstFunctionPointerINTEL = 5600,
     OpFunctionPointerCallINTEL = 5601,
+    OpAsmTargetINTEL = 5609,
+    OpAsmINTEL = 5610,
+    OpAsmCallINTEL = 5611,
+    OpAtomicFMinEXT = 5614,
+    OpAtomicFMaxEXT = 5615,
+    OpAssumeTrueKHR = 5630,
+    OpExpectKHR = 5631,
     OpDecorateString = 5632,
     OpDecorateStringGOOGLE = 5632,
     OpMemberDecorateString = 5633,
@@ -1590,7 +1674,12 @@ enum Op {
     OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814,
     OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815,
     OpSubgroupAvcSicGetInterRawSadsINTEL = 5816,
+    OpVariableLengthArrayINTEL = 5818,
+    OpSaveMemoryINTEL = 5819,
+    OpRestoreMemoryINTEL = 5820,
     OpLoopControlINTEL = 5887,
+    OpPtrCastToCrossWorkgroupINTEL = 5934,
+    OpCrossWorkgroupCastToPtrINTEL = 5938,
     OpReadPipeBlockingINTEL = 5946,
     OpWritePipeBlockingINTEL = 5947,
     OpFPGARegINTEL = 5949,
@@ -1612,6 +1701,10 @@ enum Op {
     OpRayQueryGetIntersectionObjectToWorldKHR = 6031,
     OpRayQueryGetIntersectionWorldToObjectKHR = 6032,
     OpAtomicFAddEXT = 6035,
+    OpTypeBufferSurfaceINTEL = 6086,
+    OpTypeStructContinuedINTEL = 6090,
+    OpConstantCompositeContinuedINTEL = 6091,
+    OpSpecConstantCompositeContinuedINTEL = 6092,
     OpMax = 0x7fffffff,
 };
 
@@ -2001,6 +2094,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
     case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break;
     case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break;
     case OpTraceNV: *hasResult = false; *hasResultType = false; break;
+    case OpTraceMotionNV: *hasResult = false; *hasResultType = false; break;
+    case OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break;
     case OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break;
     case OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break;
     case OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break;
@@ -2036,8 +2131,15 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
     case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break;
     case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
     case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break;
-    case OpFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpConstFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break;
     case OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpAsmINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpAsmCallINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break;
+    case OpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break;
+    case OpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break;
+    case OpExpectKHR: *hasResult = true; *hasResultType = true; break;
     case OpDecorateString: *hasResult = false; *hasResultType = false; break;
     case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break;
     case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break;
@@ -2158,7 +2260,12 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
     case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break;
     case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break;
     case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break;
     case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break;
+    case OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break;
+    case OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break;
     case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
     case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break;
     case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break;
@@ -2180,6 +2287,10 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
     case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break;
     case OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break;
     case OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break;
+    case OpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break;
+    case OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break;
+    case OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
+    case OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
     }
 }
 #endif /* SPV_ENABLE_UTILITY_CODE */

+ 8 - 0
thirdparty/glslang/StandAlone/DirStackFileIncluder.h

@@ -40,6 +40,7 @@
 #include <string>
 #include <fstream>
 #include <algorithm>
+#include <set>
 
 #include "./../glslang/Public/ShaderLang.h"
 
@@ -84,12 +85,18 @@ public:
         }
     }
 
+    virtual std::set<std::string> getIncludedFiles()
+    {
+        return includedFiles;
+    }
+
     virtual ~DirStackFileIncluder() override { }
 
 protected:
     typedef char tUserDataElement;
     std::vector<std::string> directoryStack;
     int externalLocalDirectoryCount;
+    std::set<std::string> includedFiles;
 
     // Search for a valid "local" path based on combining the stack of include
     // directories and the nominal name of the header.
@@ -108,6 +115,7 @@ protected:
             std::ifstream file(path, std::ios_base::binary | std::ios_base::ate);
             if (file) {
                 directoryStack.push_back(getDirectory(path));
+                includedFiles.insert(path);
                 return newIncludeResult(path, file, (int)file.tellg());
             }
         }

+ 12 - 0
thirdparty/glslang/glslang/Include/BaseTypes.h

@@ -65,6 +65,10 @@ enum TBasicType {
     EbtAccStruct,
     EbtReference,
     EbtRayQuery,
+#ifndef GLSLANG_WEB
+    // SPIR-V type defined by spirv_type
+    EbtSpirvType,
+#endif
 
     // HLSL types that live only temporarily.
     EbtString,
@@ -91,6 +95,9 @@ enum TStorageQualifier {
     EvqUniform,       // read only, shared with app
     EvqBuffer,        // read/write, shared with app
     EvqShared,        // compute shader's read/write 'shared' qualifier
+#ifndef GLSLANG_WEB
+    EvqSpirvStorageClass, // spirv_storage_class
+#endif
 
     EvqPayload,
     EvqPayloadIn,
@@ -263,6 +270,7 @@ enum TBuiltInVariable {
     EbvWorldToObject,
     EbvWorldToObject3x4,
     EbvIncomingRayFlags,
+    EbvCurrentRayTimeNV,
     // barycentrics
     EbvBaryCoordNV,
     EbvBaryCoordNoPerspNV,
@@ -321,6 +329,9 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q)
     case EvqGlobal:         return "global";         break;
     case EvqConst:          return "const";          break;
     case EvqConstReadOnly:  return "const (read only)"; break;
+#ifndef GLSLANG_WEB
+    case EvqSpirvStorageClass: return "spirv_storage_class"; break;
+#endif
     case EvqVaryingIn:      return "in";             break;
     case EvqVaryingOut:     return "out";            break;
     case EvqUniform:        return "uniform";        break;
@@ -465,6 +476,7 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
     case EbvIncomingRayFlags:           return "IncomingRayFlagsNV";
     case EbvObjectToWorld:              return "ObjectToWorldNV";
     case EbvWorldToObject:              return "WorldToObjectNV";
+    case EbvCurrentRayTimeNV:           return "CurrentRayTimeNV";
 
     case EbvBaryCoordNV:                return "BaryCoordNV";
     case EbvBaryCoordNoPerspNV:         return "BaryCoordNoPerspNV";

+ 16 - 0
thirdparty/glslang/glslang/Include/Common.h

@@ -194,6 +194,10 @@ template <class K, class D, class HASH = std::hash<K>, class PRED = std::equal_t
 class TUnorderedMap : public std::unordered_map<K, D, HASH, PRED, pool_allocator<std::pair<K const, D> > > {
 };
 
+template <class K, class CMP = std::less<K> >
+class TSet : public std::set<K, CMP, pool_allocator<K> > {
+};
+
 //
 // Persistent string memory.  Should only be used for strings that survive
 // across compiles/links.
@@ -286,6 +290,18 @@ template <class T> bool IsMultipleOfPow2(T number, int powerOf2)
     return ! (number & (powerOf2 - 1));
 }
 
+// Returns log2 of an integer power of 2.
+// T should be integral.
+template <class T> int IntLog2(T n)
+{
+    assert(IsPow2(n));
+    int result = 0;
+    while ((T(1) << result) != n) {
+      result++;
+    }
+    return result;
+}
+
 } // end namespace glslang
 
 #endif // _COMMON_INCLUDED_

+ 136 - 0
thirdparty/glslang/glslang/Include/SpirvIntrinsics.h

@@ -0,0 +1,136 @@
+//
+// Copyright(C) 2021 Advanced Micro Devices, Inc.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//    Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//
+//    Redistributions in binary form must reproduce the above
+//    copyright notice, this list of conditions and the following
+//    disclaimer in the documentation and/or other materials provided
+//    with the distribution.
+//
+//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+
+#pragma once
+
+#ifndef GLSLANG_WEB
+
+//
+// GL_EXT_spirv_intrinsics
+//
+#include "Common.h"
+
+namespace glslang {
+
+class TIntermTyped;
+class TIntermConstantUnion;
+class TType;
+
+// SPIR-V requirements
+struct TSpirvRequirement {
+    POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
+
+    // capability = [..]
+    TSet<TString> extensions;
+    // extension = [..]
+    TSet<int> capabilities;
+};
+
+// SPIR-V execution modes
+struct TSpirvExecutionMode {
+    POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
+
+    // spirv_execution_mode
+    TMap<int, TVector<const TIntermConstantUnion*>> modes;
+    // spirv_execution_mode_id
+    TMap<int, TVector<const TIntermConstantUnion*> > modeIds;
+};
+
+// SPIR-V decorations
+struct TSpirvDecorate {
+    POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
+
+    // spirv_decorate
+    TMap<int, TVector<const TIntermConstantUnion*> > decorates;
+    // spirv_decorate_id
+    TMap<int, TVector<const TIntermConstantUnion*> > decorateIds;
+    // spirv_decorate_string
+    TMap<int, TVector<const TIntermConstantUnion*> > decorateStrings;
+};
+
+// SPIR-V instruction
+struct TSpirvInstruction {
+    POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
+
+    TSpirvInstruction() { set = ""; id = -1; }
+
+    bool operator==(const TSpirvInstruction& rhs) const { return set == rhs.set && id == rhs.id; }
+    bool operator!=(const TSpirvInstruction& rhs) const { return !operator==(rhs); }
+
+    // spirv_instruction
+    TString set;
+    int     id;
+};
+
+// SPIR-V type parameter
+struct TSpirvTypeParameter {
+    POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
+
+    TSpirvTypeParameter(const TIntermConstantUnion* arg) { isConstant = true; constant = arg; }
+    TSpirvTypeParameter(const TType* arg) { isConstant = false; type = arg; }
+
+    bool operator==(const TSpirvTypeParameter& rhs) const
+    {
+        return isConstant == rhs.isConstant && ((isConstant && constant == rhs.constant) || (!isConstant && type == rhs.type));
+    }
+    bool operator!=(const TSpirvTypeParameter& rhs) const { return !operator==(rhs); }
+
+    bool isConstant;
+    union {
+        const TIntermConstantUnion* constant;
+        const TType* type;
+    };
+};
+
+typedef TVector<TSpirvTypeParameter> TSpirvTypeParameters;
+
+// SPIR-V type
+struct TSpirvType {
+    POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
+
+    bool operator==(const TSpirvType& rhs) const
+    {
+        return spirvInst == rhs.spirvInst && typeParams == rhs.typeParams;
+    }
+    bool operator!=(const TSpirvType& rhs) const { return !operator==(rhs); }
+
+    // spirv_type
+    TSpirvInstruction spirvInst;
+    TSpirvTypeParameters typeParams;
+};
+
+} // end namespace glslang
+
+#endif // GLSLANG_WEB

+ 215 - 15
thirdparty/glslang/glslang/Include/Types.h

@@ -44,11 +44,14 @@
 #include "../Include/BaseTypes.h"
 #include "../Public/ShaderLang.h"
 #include "arrays.h"
+#include "SpirvIntrinsics.h"
 
 #include <algorithm>
 
 namespace glslang {
 
+class TIntermAggregate;
+
 const int GlslangMaxTypeLength = 200;  // TODO: need to print block/struct one member per line, so this can stay bounded
 
 const char* const AnonymousPrefix = "anon@"; // for something like a block whose members can be directly accessed
@@ -115,6 +118,7 @@ struct TSampler {   // misnomer now; includes images, textures without sampler,
 #endif
 
     bool is1D()          const { return dim == Esd1D; }
+    bool is2D()          const { return dim == Esd2D; }
     bool isBuffer()      const { return dim == EsdBuffer; }
     bool isRect()        const { return dim == EsdRect; }
     bool isSubpass()     const { return dim == EsdSubpass; }
@@ -486,7 +490,6 @@ enum TShaderInterface
     EsiCount
 };
 
-
 class TQualifier {
 public:
     static const int layoutNotSet = -1;
@@ -499,7 +502,11 @@ public:
         declaredBuiltIn = EbvNone;
 #ifndef GLSLANG_WEB
         noContraction = false;
+        nullInit = false;
+        spirvByReference = false;
+        spirvLiteral = false;
 #endif
+        defaultBlock = false;
     }
 
     // drop qualifiers that don't belong in a temporary variable
@@ -512,7 +519,15 @@ public:
         clearMemory();
         specConstant = false;
         nonUniform = false;
+        nullInit = false;
+        defaultBlock = false;
         clearLayout();
+#ifndef GLSLANG_WEB
+        spirvStorageClass = -1;
+        spirvDecorate = nullptr;
+        spirvByReference = false;
+        spirvLiteral = false;
+#endif
     }
 
     void clearInterstage()
@@ -570,6 +585,7 @@ public:
     bool specConstant : 1;
     bool nonUniform   : 1;
     bool explicitOffset   : 1;
+    bool defaultBlock : 1; // default blocks with matching names have structures merged when linking
 
 #ifdef GLSLANG_WEB
     bool isWriteOnly() const { return false; }
@@ -588,6 +604,12 @@ public:
     bool isNoContraction() const { return false; }
     void setNoContraction() { }
     bool isPervertexNV() const { return false; }
+    void setNullInit() { }
+    bool isNullInit() const { return false; }
+    void setSpirvByReference() { }
+    bool isSpirvByReference() { return false; }
+    void setSpirvLiteral() { }
+    bool isSpirvLiteral() { return false; }
 #else
     bool noContraction: 1; // prevent contraction and reassociation, e.g., for 'precise' keyword, and expressions it affects
     bool nopersp      : 1;
@@ -609,6 +631,9 @@ public:
     bool subgroupcoherent  : 1;
     bool shadercallcoherent : 1;
     bool nonprivate   : 1;
+    bool nullInit : 1;
+    bool spirvByReference : 1;
+    bool spirvLiteral : 1;
     bool isWriteOnly() const { return writeonly; }
     bool isReadOnly() const { return readonly; }
     bool isRestrict() const { return restrict; }
@@ -644,6 +669,12 @@ public:
     bool isNoContraction() const { return noContraction; }
     void setNoContraction() { noContraction = true; }
     bool isPervertexNV() const { return pervertexNV; }
+    void setNullInit() { nullInit = true; }
+    bool isNullInit() const { return nullInit; }
+    void setSpirvByReference() { spirvByReference = true; }
+    bool isSpirvByReference() const { return spirvByReference; }
+    void setSpirvLiteral() { spirvLiteral = true; }
+    bool isSpirvLiteral() const { return spirvLiteral; }
 #endif
 
     bool isPipeInput() const
@@ -749,6 +780,46 @@ public:
         }
     }
 
+    TBlockStorageClass getBlockStorage() const {
+        if (storage == EvqUniform && !isPushConstant()) {
+            return EbsUniform;
+        }
+        else if (storage == EvqUniform) {
+            return EbsPushConstant;
+        }
+        else if (storage == EvqBuffer) {
+            return EbsStorageBuffer;
+        }
+        return EbsNone;
+    }
+
+    void setBlockStorage(TBlockStorageClass newBacking) {
+#ifndef GLSLANG_WEB
+        layoutPushConstant = (newBacking == EbsPushConstant);
+#endif
+        switch (newBacking) {
+        case EbsUniform :
+            if (layoutPacking == ElpStd430) {
+                // std430 would not be valid
+                layoutPacking = ElpStd140;
+            }
+            storage = EvqUniform;
+            break;
+        case EbsStorageBuffer : 
+            storage = EvqBuffer;
+            break;
+#ifndef GLSLANG_WEB
+        case EbsPushConstant :
+            storage = EvqUniform;
+            layoutSet = TQualifier::layoutSetEnd;
+            layoutBinding = TQualifier::layoutBindingEnd;
+            break;
+#endif
+        default:
+            break;
+        }
+    }
+
 #ifdef GLSLANG_WEB
     bool isPerView() const { return false; }
     bool isTaskMemory() const { return false; }
@@ -845,6 +916,7 @@ public:
         return hasNonXfbLayout() ||
                hasXfb();
     }
+
     TLayoutMatrix  layoutMatrix  : 3;
     TLayoutPacking layoutPacking : 4;
     int layoutOffset;
@@ -896,6 +968,10 @@ public:
     bool layoutViewportRelative;
     int layoutSecondaryViewportRelativeOffset;
     bool layoutShaderRecord;
+
+    // GL_EXT_spirv_intrinsics
+    int spirvStorageClass;
+    TSpirvDecorate* spirvDecorate;
 #endif
 
     bool hasUniformLayout() const
@@ -1027,6 +1103,15 @@ public:
     {
         return nonUniform;
     }
+
+    // GL_EXT_spirv_intrinsics
+    bool hasSprivDecorate() const { return spirvDecorate != nullptr; }
+    void setSpirvDecorate(int decoration, const TIntermAggregate* args = nullptr);
+    void setSpirvDecorateId(int decoration, const TIntermAggregate* args);
+    void setSpirvDecorateString(int decoration, const TIntermAggregate* args);
+    const TSpirvDecorate& getSpirvDecorate() const { assert(spirvDecorate); return *spirvDecorate; }
+    TSpirvDecorate& getSpirvDecorate() { assert(spirvDecorate); return *spirvDecorate; }
+    TString getSpirvDecorateQualifierString() const;
 #endif
     bool hasSpecConstantId() const
     {
@@ -1371,6 +1456,10 @@ public:
     const TType* userDef;
     TSourceLoc loc;
     TArraySizes* typeParameters;
+#ifndef GLSLANG_WEB
+    // SPIR-V type defined by spirv_type directive
+    TSpirvType* spirvType;
+#endif
 
 #ifdef GLSLANG_WEB
     bool isCoopmat() const { return false; }
@@ -1389,6 +1478,9 @@ public:
         loc = l;
         typeParameters = nullptr;
         coopmat = false;
+#ifndef GLSLANG_WEB
+        spirvType = nullptr;
+#endif
     }
 
     void initQualifiers(bool global = false)
@@ -1425,6 +1517,11 @@ public:
         return matrixCols == 0 && vectorSize == 1 && arraySizes == nullptr && userDef == nullptr;
     }
 
+#ifndef GLSLANG_WEB
+    // GL_EXT_spirv_intrinsics
+    void setSpirvType(const TSpirvInstruction& spirvInst, const TSpirvTypeParameters* typeParams = nullptr);
+#endif
+
     // "Image" is a superset of "Subpass"
     bool isImage()   const { return basicType == EbtSampler && sampler.isImage(); }
     bool isSubpass() const { return basicType == EbtSampler && sampler.isSubpass(); }
@@ -1442,6 +1539,9 @@ public:
                    bool isVector = false) :
                             basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmat(false),
                             arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr)
+#ifndef GLSLANG_WEB
+                            , spirvType(nullptr)
+#endif
                             {
                                 sampler.clear();
                                 qualifier.clear();
@@ -1453,6 +1553,9 @@ public:
           bool isVector = false) :
                             basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmat(false),
                             arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr)
+#ifndef GLSLANG_WEB
+                            , spirvType(nullptr)
+#endif
                             {
                                 sampler.clear();
                                 qualifier.clear();
@@ -1466,6 +1569,9 @@ public:
                             basicType(p.basicType),
                             vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmat(p.coopmat),
                             arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(p.typeParameters)
+#ifndef GLSLANG_WEB
+                            , spirvType(p.spirvType)
+#endif
                             {
                                 if (basicType == EbtSampler)
                                     sampler = p.sampler;
@@ -1500,6 +1606,9 @@ public:
         basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false),
         arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr),
         sampler(sampler), typeParameters(nullptr)
+#ifndef GLSLANG_WEB
+        , spirvType(nullptr)
+#endif
     {
         qualifier.clear();
         qualifier.storage = q;
@@ -1550,6 +1659,9 @@ public:
     TType(TTypeList* userDef, const TString& n) :
                             basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false),
                             arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr)
+#ifndef GLSLANG_WEB
+                            , spirvType(nullptr)
+#endif
                             {
                                 sampler.clear();
                                 qualifier.clear();
@@ -1559,6 +1671,9 @@ public:
     TType(TTypeList* userDef, const TString& n, const TQualifier& q) :
                             basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false),
                             qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr)
+#ifndef GLSLANG_WEB
+                            , spirvType(nullptr)
+#endif
                             {
                                 sampler.clear();
                                 typeName = NewPoolTString(n.c_str());
@@ -1567,6 +1682,9 @@ public:
     explicit TType(TBasicType t, const TType &p, const TString& n) :
                             basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false),
                             arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr)
+#ifndef GLSLANG_WEB
+                            , spirvType(nullptr)
+#endif
                             {
                                 assert(t == EbtReference);
                                 typeName = NewPoolTString(n.c_str());
@@ -1597,6 +1715,9 @@ public:
             referentType = copyOf.referentType;
         }
         typeParameters = copyOf.typeParameters;
+#ifndef GLSLANG_WEB
+        spirvType = copyOf.spirvType;
+#endif
         coopmat = copyOf.isCoopMat();
     }
 
@@ -1687,6 +1808,7 @@ public:
 
     virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); }
     virtual bool isScalarOrVec1() const { return isScalar() || vector1; }
+    virtual bool isScalarOrVector() const { return !isMatrix() && !isStruct() && !isArray(); }
     virtual bool isVector() const { return vectorSize > 1 || vector1; }
     virtual bool isMatrix() const { return matrixCols ? true : false; }
     virtual bool isArray()  const { return arraySizes != nullptr; }
@@ -1717,7 +1839,7 @@ public:
     }
     virtual bool isOpaque() const { return basicType == EbtSampler
 #ifndef GLSLANG_WEB
-         || basicType == EbtAtomicUint || basicType == EbtAccStruct || basicType == EbtRayQuery
+            || basicType == EbtAtomicUint || basicType == EbtAccStruct || basicType == EbtRayQuery
 #endif
         ; }
     virtual bool isBuiltIn() const { return getQualifier().builtIn != EbvNone; }
@@ -1965,8 +2087,6 @@ public:
         }
     }
 
-
-
     const char* getBasicString() const
     {
         return TType::getBasicString(basicType);
@@ -1997,6 +2117,7 @@ public:
         case EbtRayQuery:          return "rayQueryEXT";
         case EbtReference:         return "reference";
         case EbtString:            return "string";
+        case EbtSpirvType:         return "spirv_type";
 #endif
         default:                   return "unknown type";
         }
@@ -2017,6 +2138,9 @@ public:
         const auto appendUint = [&](unsigned int u) { typeString.append(std::to_string(u).c_str()); };
         const auto appendInt  = [&](int i)          { typeString.append(std::to_string(i).c_str()); };
 
+        if (qualifier.hasSprivDecorate())
+            appendStr(qualifier.getSpirvDecorateQualifierString().c_str());
+
         if (qualifier.hasLayout()) {
             // To reduce noise, skip this if the only layout is an xfb_buffer
             // with no triggering xfb_offset.
@@ -2164,6 +2288,12 @@ public:
             appendStr(" specialization-constant");
         if (qualifier.nonUniform)
             appendStr(" nonuniform");
+        if (qualifier.isNullInit())
+            appendStr(" null-init");
+        if (qualifier.isSpirvByReference())
+            appendStr(" spirv_by_reference");
+        if (qualifier.isSpirvLiteral())
+            appendStr(" spirv_literal");
         appendStr(" ");
         appendStr(getStorageQualifierString());
         if (isArray()) {
@@ -2283,6 +2413,17 @@ public:
         name += ';' ;
     }
 
+    // These variables are inconsistently declared inside and outside of gl_PerVertex in glslang right now.
+    // They are declared inside of 'in gl_PerVertex', but sitting as standalone when they are 'out'puts.
+    bool isInconsistentGLPerVertexMember(const TString& name) const
+    {
+        if (name == "gl_SecondaryPositionNV" ||
+            name == "gl_PositionPerViewNV")
+            return true;
+        return false;
+    }
+
+
     // Do two structure types match?  They could be declared independently,
     // in different places, but still might satisfy the definition of matching.
     // From the spec:
@@ -2298,22 +2439,48 @@ public:
             (isStruct() && right.isStruct() && structure == right.structure))
             return true;
 
-        // Both being nullptr was caught above, now they both have to be structures of the same number of elements
-        if (!isStruct() || !right.isStruct() ||
-            structure->size() != right.structure->size())
-            return false;
-
         // Structure names have to match
         if (*typeName != *right.typeName)
             return false;
 
-        // Compare the names and types of all the members, which have to match
-        for (unsigned int i = 0; i < structure->size(); ++i) {
-            if ((*structure)[i].type->getFieldName() != (*right.structure)[i].type->getFieldName())
-                return false;
+        // There are inconsistencies with how gl_PerVertex is setup. For now ignore those as errors if they
+        // are known inconsistencies.
+        bool isGLPerVertex = *typeName == "gl_PerVertex";
 
-            if (*(*structure)[i].type != *(*right.structure)[i].type)
-                return false;
+        // Both being nullptr was caught above, now they both have to be structures of the same number of elements
+        if (!isStruct() || !right.isStruct() ||
+            (structure->size() != right.structure->size() && !isGLPerVertex))
+            return false;
+
+        // Compare the names and types of all the members, which have to match
+        for (size_t li = 0, ri = 0; li < structure->size() || ri < right.structure->size(); ++li, ++ri) {
+            if (li < structure->size() && ri < right.structure->size()) {
+                if ((*structure)[li].type->getFieldName() == (*right.structure)[ri].type->getFieldName()) {
+                    if (*(*structure)[li].type != *(*right.structure)[ri].type)
+                        return false;
+                } else {
+                    // If one of the members is something that's inconsistently declared, skip over it
+                    // for now.
+                    if (isGLPerVertex) {
+                        if (isInconsistentGLPerVertexMember((*structure)[li].type->getFieldName())) {
+                            ri--;
+                            continue;
+                        } else if (isInconsistentGLPerVertexMember((*right.structure)[ri].type->getFieldName())) {
+                            li--;
+                            continue;
+                        }
+                    } else {
+                        return false;
+                    }
+                }
+            // If we get here, then there should only be inconsistently declared members left
+            } else if (li < structure->size()) {
+                if (!isInconsistentGLPerVertexMember((*structure)[li].type->getFieldName()))
+                    return false;
+            } else {
+                if (!isInconsistentGLPerVertexMember((*right.structure)[ri].type->getFieldName()))
+                    return false;
+            }
         }
 
         return true;
@@ -2363,6 +2530,15 @@ public:
                 (typeParameters != nullptr && right.typeParameters != nullptr && *typeParameters == *right.typeParameters));
     }
 
+#ifndef GLSLANG_WEB
+    // See if two type's SPIR-V type contents match
+    bool sameSpirvType(const TType& right) const
+    {
+        return ((spirvType == nullptr && right.spirvType == nullptr) ||
+                (spirvType != nullptr && right.spirvType != nullptr && *spirvType == *right.spirvType));
+    }
+#endif
+
     // See if two type's elements match in all ways except basic type
     bool sameElementShape(const TType& right) const
     {
@@ -2401,7 +2577,11 @@ public:
     // See if two types match in all ways (just the actual type, not qualification)
     bool operator==(const TType& right) const
     {
+#ifndef GLSLANG_WEB
+        return sameElementType(right) && sameArrayness(right) && sameTypeParameters(right) && sameSpirvType(right);
+#else
         return sameElementType(right) && sameArrayness(right) && sameTypeParameters(right);
+#endif
     }
 
     bool operator!=(const TType& right) const
@@ -2420,6 +2600,10 @@ public:
         return 0;
     }
 
+#ifndef GLSLANG_WEB
+    const TSpirvType& getSpirvType() const { assert(spirvType); return *spirvType; }
+#endif
+
 protected:
     // Require consumer to pick between deep copy and shallow copy.
     TType(const TType& type);
@@ -2432,6 +2616,19 @@ protected:
     {
         shallowCopy(copyOf);
 
+#ifndef GLSLANG_WEB
+        // GL_EXT_spirv_intrinsics
+        if (copyOf.qualifier.spirvDecorate) {
+            qualifier.spirvDecorate = new TSpirvDecorate;
+            *qualifier.spirvDecorate = *copyOf.qualifier.spirvDecorate;
+        }
+
+        if (copyOf.spirvType) {
+            spirvType = new TSpirvType;
+            *spirvType = *copyOf.spirvType;
+        }
+#endif
+
         if (copyOf.arraySizes) {
             arraySizes = new TArraySizes;
             *arraySizes = *copyOf.arraySizes;
@@ -2491,6 +2688,9 @@ protected:
     TString *typeName;          // for structure type name
     TSampler sampler;
     TArraySizes* typeParameters;// nullptr unless a parameterized type; can be shared across types
+#ifndef GLSLANG_WEB
+    TSpirvType* spirvType;  // SPIR-V type defined by spirv_type directive
+#endif
 };
 
 } // end namespace glslang

+ 3 - 2
thirdparty/glslang/glslang/Include/glslang_c_shader_types.h

@@ -100,8 +100,9 @@ typedef enum {
 typedef enum {
     GLSLANG_TARGET_VULKAN_1_0 = (1 << 22),
     GLSLANG_TARGET_VULKAN_1_1 = (1 << 22) | (1 << 12),
+    GLSLANG_TARGET_VULKAN_1_2 = (1 << 22) | (2 << 12),
     GLSLANG_TARGET_OPENGL_450 = 450,
-    LAST_ELEMENT_MARKER(GLSLANG_TARGET_CLIENT_VERSION_COUNT),
+    LAST_ELEMENT_MARKER(GLSLANG_TARGET_CLIENT_VERSION_COUNT = 4),
 } glslang_target_client_version_t;
 
 /* SH_TARGET_LanguageVersion counterpart */
@@ -112,7 +113,7 @@ typedef enum {
     GLSLANG_TARGET_SPV_1_3 = (1 << 16) | (3 << 8),
     GLSLANG_TARGET_SPV_1_4 = (1 << 16) | (4 << 8),
     GLSLANG_TARGET_SPV_1_5 = (1 << 16) | (5 << 8),
-    LAST_ELEMENT_MARKER(GLSLANG_TARGET_LANGUAGE_VERSION_COUNT),
+    LAST_ELEMENT_MARKER(GLSLANG_TARGET_LANGUAGE_VERSION_COUNT = 6),
 } glslang_target_language_version_t;
 
 /* EShExecutable counterpart */

+ 29 - 5
thirdparty/glslang/glslang/Include/intermediate.h

@@ -71,6 +71,9 @@ enum TOperator {
     EOpFunctionCall,
     EOpFunction,        // For function definition
     EOpParameters,      // an aggregate listing the parameters to a function
+#ifndef GLSLANG_WEB
+    EOpSpirvInst,
+#endif
 
     //
     // Unary operators
@@ -593,6 +596,7 @@ enum TOperator {
     EOpTime,
 
     EOpAtomicAdd,
+    EOpAtomicSubtract,
     EOpAtomicMin,
     EOpAtomicMax,
     EOpAtomicAnd,
@@ -922,6 +926,7 @@ enum TOperator {
     EOpMul32x16,
 
     EOpTraceNV,
+    EOpTraceRayMotionNV,
     EOpTraceKHR,
     EOpReportIntersection,
     EOpIgnoreIntersectionNV,
@@ -1135,6 +1140,8 @@ public:
     virtual TBasicType getBasicType() const { return type.getBasicType(); }
     virtual TQualifier& getQualifier() { return type.getQualifier(); }
     virtual const TQualifier& getQualifier() const { return type.getQualifier(); }
+    virtual TArraySizes* getArraySizes() { return type.getArraySizes(); }
+    virtual const TArraySizes* getArraySizes() const { return type.getArraySizes(); }
     virtual void propagatePrecision(TPrecisionQualifier);
     virtual int getVectorSize() const { return type.getVectorSize(); }
     virtual int getMatrixCols() const { return type.getMatrixCols(); }
@@ -1275,15 +1282,15 @@ public:
     // if symbol is initialized as symbol(sym), the memory comes from the pool allocator of sym. If sym comes from
     // per process threadPoolAllocator, then it causes increased memory usage per compile
     // it is essential to use "symbol = sym" to assign to symbol
-    TIntermSymbol(int i, const TString& n, const TType& t)
+    TIntermSymbol(long long i, const TString& n, const TType& t)
         : TIntermTyped(t), id(i),
 #ifndef GLSLANG_WEB
         flattenSubset(-1),
 #endif
         constSubtree(nullptr)
           { name = n; }
-    virtual int getId() const { return id; }
-    virtual void changeId(int i) { id = i; }
+    virtual long long getId() const { return id; }
+    virtual void changeId(long long i) { id = i; }
     virtual const TString& getName() const { return name; }
     virtual void traverse(TIntermTraverser*);
     virtual       TIntermSymbol* getAsSymbolNode()       { return this; }
@@ -1301,10 +1308,10 @@ public:
 
     // This is meant for cases where a node has already been constructed, and
     // later on, it becomes necessary to switch to a different symbol.
-    virtual void switchId(int newId) { id = newId; }
+    virtual void switchId(long long newId) { id = newId; }
 
 protected:
-    int id;                      // the unique id of the symbol this node represents
+    long long id;                // the unique id of the symbol this node represents
 #ifndef GLSLANG_WEB
     int flattenSubset;           // how deeply the flattened object rooted at id has been dereferenced
 #endif
@@ -1613,8 +1620,15 @@ public:
     virtual       TIntermUnary* getAsUnaryNode()       { return this; }
     virtual const TIntermUnary* getAsUnaryNode() const { return this; }
     virtual void updatePrecision();
+#ifndef GLSLANG_WEB
+    void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
+    const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
+#endif
 protected:
     TIntermTyped* operand;
+#ifndef GLSLANG_WEB
+    TSpirvInstruction spirvInst;
+#endif
 };
 
 typedef TVector<TIntermNode*> TIntermSequence;
@@ -1645,6 +1659,10 @@ public:
     bool getDebug() const { return debug; }
     void setPragmaTable(const TPragmaTable& pTable);
     const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
+#ifndef GLSLANG_WEB
+    void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
+    const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
+#endif
 protected:
     TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
     TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
@@ -1655,6 +1673,9 @@ protected:
     bool optimize;
     bool debug;
     TPragmaTable* pragmaTable;
+#ifndef GLSLANG_WEB
+    TSpirvInstruction spirvInst;
+#endif
 };
 
 //
@@ -1672,8 +1693,11 @@ public:
         flatten(false), dontFlatten(false) {}
     virtual void traverse(TIntermTraverser*);
     virtual TIntermTyped* getCondition() const { return condition; }
+    virtual void setCondition(TIntermTyped* c) { condition = c; }
     virtual TIntermNode* getTrueBlock() const { return trueBlock; }
+    virtual void setTrueBlock(TIntermTyped* tb) { trueBlock = tb; }
     virtual TIntermNode* getFalseBlock() const { return falseBlock; }
+    virtual void setFalseBlock(TIntermTyped* fb) { falseBlock = fb; }
     virtual       TIntermSelection* getAsSelectionNode()       { return this; }
     virtual const TIntermSelection* getAsSelectionNode() const { return this; }
 

+ 10 - 11
thirdparty/glslang/glslang/MachineIndependent/Constant.cpp

@@ -529,7 +529,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
             case EbtDouble:
             case EbtFloat16:
             case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
-            case EbtInt:   newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
+            // Note: avoid UBSAN error regarding negating 0x80000000
+            case EbtInt:   newConstArray[i].setIConst(
+                                unionArray[i].getIConst() == 0x80000000
+                                    ? -0x7FFFFFFF - 1
+                                    : -unionArray[i].getIConst());
+                           break;
             case EbtUint:  newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst())));  break;
 #ifndef GLSLANG_WEB
             case EbtInt8:  newConstArray[i].setI8Const(-unionArray[i].getI8Const()); break;
@@ -599,17 +604,11 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
             newConstArray[i].setDConst(log(unionArray[i].getDConst()));
             break;
         case EOpExp2:
-            {
-                const double inv_log2_e = 0.69314718055994530941723212145818;
-                newConstArray[i].setDConst(exp(unionArray[i].getDConst() * inv_log2_e));
-                break;
-            }
+            newConstArray[i].setDConst(exp2(unionArray[i].getDConst()));
+            break;
         case EOpLog2:
-            {
-                const double log2_e = 1.4426950408889634073599246810019;
-                newConstArray[i].setDConst(log2_e * log(unionArray[i].getDConst()));
-                break;
-            }
+            newConstArray[i].setDConst(log2(unionArray[i].getDConst()));
+            break;
         case EOpSqrt:
             newConstArray[i].setDConst(sqrt(unionArray[i].getDConst()));
             break;

+ 429 - 25
thirdparty/glslang/glslang/MachineIndependent/Initialize.cpp

@@ -483,7 +483,8 @@ void TBuiltIns::relateTabledBuiltins(int /* version */, EProfile /* profile */,
 
 inline bool IncludeLegacy(int version, EProfile profile, const SpvVersion& spvVersion)
 {
-    return profile != EEsProfile && (version <= 130 || (spvVersion.spv == 0 && ARBCompatibility) || profile == ECompatibilityProfile);
+    return profile != EEsProfile && (version <= 130 || (spvVersion.spv == 0 && version == 140 && ARBCompatibility) ||
+           profile == ECompatibilityProfile);
 }
 
 // Construct TBuiltInParseables base class.  This can be used for language-common constructs.
@@ -931,7 +932,203 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             "\n");
     }
 
-    if (profile != EEsProfile && version >= 450) {
+    if (profile == EEsProfile && version >= 310) {  // Explicit Types
+      commonBuiltins.append(
+
+        "float64_t sqrt(float64_t);"
+        "f64vec2  sqrt(f64vec2);"
+        "f64vec3  sqrt(f64vec3);"
+        "f64vec4  sqrt(f64vec4);"
+
+        "float64_t inversesqrt(float64_t);"
+        "f64vec2  inversesqrt(f64vec2);"
+        "f64vec3  inversesqrt(f64vec3);"
+        "f64vec4  inversesqrt(f64vec4);"
+
+        "float64_t abs(float64_t);"
+        "f64vec2  abs(f64vec2);"
+        "f64vec3  abs(f64vec3);"
+        "f64vec4  abs(f64vec4);"
+
+        "float64_t sign(float64_t);"
+        "f64vec2  sign(f64vec2);"
+        "f64vec3  sign(f64vec3);"
+        "f64vec4  sign(f64vec4);"
+
+        "float64_t floor(float64_t);"
+        "f64vec2  floor(f64vec2);"
+        "f64vec3  floor(f64vec3);"
+        "f64vec4  floor(f64vec4);"
+
+        "float64_t trunc(float64_t);"
+        "f64vec2  trunc(f64vec2);"
+        "f64vec3  trunc(f64vec3);"
+        "f64vec4  trunc(f64vec4);"
+
+        "float64_t round(float64_t);"
+        "f64vec2  round(f64vec2);"
+        "f64vec3  round(f64vec3);"
+        "f64vec4  round(f64vec4);"
+
+        "float64_t roundEven(float64_t);"
+        "f64vec2  roundEven(f64vec2);"
+        "f64vec3  roundEven(f64vec3);"
+        "f64vec4  roundEven(f64vec4);"
+
+        "float64_t ceil(float64_t);"
+        "f64vec2  ceil(f64vec2);"
+        "f64vec3  ceil(f64vec3);"
+        "f64vec4  ceil(f64vec4);"
+
+        "float64_t fract(float64_t);"
+        "f64vec2  fract(f64vec2);"
+        "f64vec3  fract(f64vec3);"
+        "f64vec4  fract(f64vec4);"
+
+        "float64_t mod(float64_t, float64_t);"
+        "f64vec2  mod(f64vec2 , float64_t);"
+        "f64vec3  mod(f64vec3 , float64_t);"
+        "f64vec4  mod(f64vec4 , float64_t);"
+        "f64vec2  mod(f64vec2 , f64vec2);"
+        "f64vec3  mod(f64vec3 , f64vec3);"
+        "f64vec4  mod(f64vec4 , f64vec4);"
+
+        "float64_t modf(float64_t, out float64_t);"
+        "f64vec2  modf(f64vec2,  out f64vec2);"
+        "f64vec3  modf(f64vec3,  out f64vec3);"
+        "f64vec4  modf(f64vec4,  out f64vec4);"
+
+        "float64_t min(float64_t, float64_t);"
+        "f64vec2  min(f64vec2,  float64_t);"
+        "f64vec3  min(f64vec3,  float64_t);"
+        "f64vec4  min(f64vec4,  float64_t);"
+        "f64vec2  min(f64vec2,  f64vec2);"
+        "f64vec3  min(f64vec3,  f64vec3);"
+        "f64vec4  min(f64vec4,  f64vec4);"
+
+        "float64_t max(float64_t, float64_t);"
+        "f64vec2  max(f64vec2 , float64_t);"
+        "f64vec3  max(f64vec3 , float64_t);"
+        "f64vec4  max(f64vec4 , float64_t);"
+        "f64vec2  max(f64vec2 , f64vec2);"
+        "f64vec3  max(f64vec3 , f64vec3);"
+        "f64vec4  max(f64vec4 , f64vec4);"
+
+        "float64_t clamp(float64_t, float64_t, float64_t);"
+        "f64vec2  clamp(f64vec2 , float64_t, float64_t);"
+        "f64vec3  clamp(f64vec3 , float64_t, float64_t);"
+        "f64vec4  clamp(f64vec4 , float64_t, float64_t);"
+        "f64vec2  clamp(f64vec2 , f64vec2 , f64vec2);"
+        "f64vec3  clamp(f64vec3 , f64vec3 , f64vec3);"
+        "f64vec4  clamp(f64vec4 , f64vec4 , f64vec4);"
+
+        "float64_t mix(float64_t, float64_t, float64_t);"
+        "f64vec2  mix(f64vec2,  f64vec2,  float64_t);"
+        "f64vec3  mix(f64vec3,  f64vec3,  float64_t);"
+        "f64vec4  mix(f64vec4,  f64vec4,  float64_t);"
+        "f64vec2  mix(f64vec2,  f64vec2,  f64vec2);"
+        "f64vec3  mix(f64vec3,  f64vec3,  f64vec3);"
+        "f64vec4  mix(f64vec4,  f64vec4,  f64vec4);"
+        "float64_t mix(float64_t, float64_t, bool);"
+        "f64vec2  mix(f64vec2,  f64vec2,  bvec2);"
+        "f64vec3  mix(f64vec3,  f64vec3,  bvec3);"
+        "f64vec4  mix(f64vec4,  f64vec4,  bvec4);"
+
+        "float64_t step(float64_t, float64_t);"
+        "f64vec2  step(f64vec2 , f64vec2);"
+        "f64vec3  step(f64vec3 , f64vec3);"
+        "f64vec4  step(f64vec4 , f64vec4);"
+        "f64vec2  step(float64_t, f64vec2);"
+        "f64vec3  step(float64_t, f64vec3);"
+        "f64vec4  step(float64_t, f64vec4);"
+
+        "float64_t smoothstep(float64_t, float64_t, float64_t);"
+        "f64vec2  smoothstep(f64vec2 , f64vec2 , f64vec2);"
+        "f64vec3  smoothstep(f64vec3 , f64vec3 , f64vec3);"
+        "f64vec4  smoothstep(f64vec4 , f64vec4 , f64vec4);"
+        "f64vec2  smoothstep(float64_t, float64_t, f64vec2);"
+        "f64vec3  smoothstep(float64_t, float64_t, f64vec3);"
+        "f64vec4  smoothstep(float64_t, float64_t, f64vec4);"
+
+        "float64_t length(float64_t);"
+        "float64_t length(f64vec2);"
+        "float64_t length(f64vec3);"
+        "float64_t length(f64vec4);"
+
+        "float64_t distance(float64_t, float64_t);"
+        "float64_t distance(f64vec2 , f64vec2);"
+        "float64_t distance(f64vec3 , f64vec3);"
+        "float64_t distance(f64vec4 , f64vec4);"
+
+        "float64_t dot(float64_t, float64_t);"
+        "float64_t dot(f64vec2 , f64vec2);"
+        "float64_t dot(f64vec3 , f64vec3);"
+        "float64_t dot(f64vec4 , f64vec4);"
+
+        "f64vec3 cross(f64vec3, f64vec3);"
+
+        "float64_t normalize(float64_t);"
+        "f64vec2  normalize(f64vec2);"
+        "f64vec3  normalize(f64vec3);"
+        "f64vec4  normalize(f64vec4);"
+
+        "float64_t faceforward(float64_t, float64_t, float64_t);"
+        "f64vec2  faceforward(f64vec2,  f64vec2,  f64vec2);"
+        "f64vec3  faceforward(f64vec3,  f64vec3,  f64vec3);"
+        "f64vec4  faceforward(f64vec4,  f64vec4,  f64vec4);"
+
+        "float64_t reflect(float64_t, float64_t);"
+        "f64vec2  reflect(f64vec2 , f64vec2 );"
+        "f64vec3  reflect(f64vec3 , f64vec3 );"
+        "f64vec4  reflect(f64vec4 , f64vec4 );"
+
+        "float64_t refract(float64_t, float64_t, float64_t);"
+        "f64vec2  refract(f64vec2 , f64vec2 , float64_t);"
+        "f64vec3  refract(f64vec3 , f64vec3 , float64_t);"
+        "f64vec4  refract(f64vec4 , f64vec4 , float64_t);"
+
+        "f64mat2 matrixCompMult(f64mat2, f64mat2);"
+        "f64mat3 matrixCompMult(f64mat3, f64mat3);"
+        "f64mat4 matrixCompMult(f64mat4, f64mat4);"
+        "f64mat2x3 matrixCompMult(f64mat2x3, f64mat2x3);"
+        "f64mat2x4 matrixCompMult(f64mat2x4, f64mat2x4);"
+        "f64mat3x2 matrixCompMult(f64mat3x2, f64mat3x2);"
+        "f64mat3x4 matrixCompMult(f64mat3x4, f64mat3x4);"
+        "f64mat4x2 matrixCompMult(f64mat4x2, f64mat4x2);"
+        "f64mat4x3 matrixCompMult(f64mat4x3, f64mat4x3);"
+
+        "f64mat2   outerProduct(f64vec2, f64vec2);"
+        "f64mat3   outerProduct(f64vec3, f64vec3);"
+        "f64mat4   outerProduct(f64vec4, f64vec4);"
+        "f64mat2x3 outerProduct(f64vec3, f64vec2);"
+        "f64mat3x2 outerProduct(f64vec2, f64vec3);"
+        "f64mat2x4 outerProduct(f64vec4, f64vec2);"
+        "f64mat4x2 outerProduct(f64vec2, f64vec4);"
+        "f64mat3x4 outerProduct(f64vec4, f64vec3);"
+        "f64mat4x3 outerProduct(f64vec3, f64vec4);"
+
+        "f64mat2   transpose(f64mat2);"
+        "f64mat3   transpose(f64mat3);"
+        "f64mat4   transpose(f64mat4);"
+        "f64mat2x3 transpose(f64mat3x2);"
+        "f64mat3x2 transpose(f64mat2x3);"
+        "f64mat2x4 transpose(f64mat4x2);"
+        "f64mat4x2 transpose(f64mat2x4);"
+        "f64mat3x4 transpose(f64mat4x3);"
+        "f64mat4x3 transpose(f64mat3x4);"
+
+        "float64_t determinant(f64mat2);"
+        "float64_t determinant(f64mat3);"
+        "float64_t determinant(f64mat4);"
+
+        "f64mat2 inverse(f64mat2);"
+        "f64mat3 inverse(f64mat3);"
+        "f64mat4 inverse(f64mat4);"
+
+        "\n");
+    }
+
+    if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 310)) {
         commonBuiltins.append(
 
             "int64_t abs(int64_t);"
@@ -998,25 +1195,25 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             "u64vec3  mix(u64vec3,  u64vec3,  bvec3);"
             "u64vec4  mix(u64vec4,  u64vec4,  bvec4);"
 
-            "int64_t doubleBitsToInt64(double);"
-            "i64vec2 doubleBitsToInt64(dvec2);"
-            "i64vec3 doubleBitsToInt64(dvec3);"
-            "i64vec4 doubleBitsToInt64(dvec4);"
+            "int64_t doubleBitsToInt64(float64_t);"
+            "i64vec2 doubleBitsToInt64(f64vec2);"
+            "i64vec3 doubleBitsToInt64(f64vec3);"
+            "i64vec4 doubleBitsToInt64(f64vec4);"
 
-            "uint64_t doubleBitsToUint64(double);"
-            "u64vec2  doubleBitsToUint64(dvec2);"
-            "u64vec3  doubleBitsToUint64(dvec3);"
-            "u64vec4  doubleBitsToUint64(dvec4);"
+            "uint64_t doubleBitsToUint64(float64_t);"
+            "u64vec2  doubleBitsToUint64(f64vec2);"
+            "u64vec3  doubleBitsToUint64(f64vec3);"
+            "u64vec4  doubleBitsToUint64(f64vec4);"
 
-            "double int64BitsToDouble(int64_t);"
-            "dvec2  int64BitsToDouble(i64vec2);"
-            "dvec3  int64BitsToDouble(i64vec3);"
-            "dvec4  int64BitsToDouble(i64vec4);"
+            "float64_t int64BitsToDouble(int64_t);"
+            "f64vec2  int64BitsToDouble(i64vec2);"
+            "f64vec3  int64BitsToDouble(i64vec3);"
+            "f64vec4  int64BitsToDouble(i64vec4);"
 
-            "double uint64BitsToDouble(uint64_t);"
-            "dvec2  uint64BitsToDouble(u64vec2);"
-            "dvec3  uint64BitsToDouble(u64vec3);"
-            "dvec4  uint64BitsToDouble(u64vec4);"
+            "float64_t uint64BitsToDouble(uint64_t);"
+            "f64vec2  uint64BitsToDouble(u64vec2);"
+            "f64vec3  uint64BitsToDouble(u64vec3);"
+            "f64vec4  uint64BitsToDouble(u64vec4);"
 
             "int64_t  packInt2x32(ivec2);"
             "uint64_t packUint2x32(uvec2);"
@@ -1065,6 +1262,16 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             "bvec3 notEqual(u64vec3, u64vec3);"
             "bvec4 notEqual(u64vec4, u64vec4);"
 
+            "int64_t bitCount(int64_t);"
+            "i64vec2 bitCount(i64vec2);"
+            "i64vec3 bitCount(i64vec3);"
+            "i64vec4 bitCount(i64vec4);"
+
+            "int64_t bitCount(uint64_t);"
+            "i64vec2 bitCount(u64vec2);"
+            "i64vec3 bitCount(u64vec3);"
+            "i64vec4 bitCount(u64vec4);"
+
             "int64_t findLSB(int64_t);"
             "i64vec2 findLSB(i64vec2);"
             "i64vec3 findLSB(i64vec3);"
@@ -1230,11 +1437,23 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             " int64_t atomicMin(coherent volatile inout  int64_t,  int64_t);"
             "uint64_t atomicMin(coherent volatile inout uint64_t, uint64_t, int, int, int);"
             " int64_t atomicMin(coherent volatile inout  int64_t,  int64_t, int, int, int);"
+            "float16_t atomicMin(coherent volatile inout float16_t, float16_t);"
+            "float16_t atomicMin(coherent volatile inout float16_t, float16_t, int, int, int);"
+            "   float atomicMin(coherent volatile inout float, float);"
+            "   float atomicMin(coherent volatile inout float, float, int, int, int);"
+            "  double atomicMin(coherent volatile inout double, double);"
+            "  double atomicMin(coherent volatile inout double, double, int, int, int);"
 
             "uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t);"
             " int64_t atomicMax(coherent volatile inout  int64_t,  int64_t);"
             "uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t, int, int, int);"
             " int64_t atomicMax(coherent volatile inout  int64_t,  int64_t, int, int, int);"
+            "float16_t atomicMax(coherent volatile inout float16_t, float16_t);"
+            "float16_t atomicMax(coherent volatile inout float16_t, float16_t, int, int, int);"
+            "   float atomicMax(coherent volatile inout float, float);"
+            "   float atomicMax(coherent volatile inout float, float, int, int, int);"
+            "  double atomicMax(coherent volatile inout double, double);"
+            "  double atomicMax(coherent volatile inout double, double, int, int, int);"
 
             "uint64_t atomicAnd(coherent volatile inout uint64_t, uint64_t);"
             " int64_t atomicAnd(coherent volatile inout  int64_t,  int64_t);"
@@ -1255,6 +1474,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             " int64_t atomicAdd(coherent volatile inout  int64_t,  int64_t);"
             "uint64_t atomicAdd(coherent volatile inout uint64_t, uint64_t, int, int, int);"
             " int64_t atomicAdd(coherent volatile inout  int64_t,  int64_t, int, int, int);"
+            "float16_t atomicAdd(coherent volatile inout float16_t, float16_t);"
+            "float16_t atomicAdd(coherent volatile inout float16_t, float16_t, int, int, int);"
             "   float atomicAdd(coherent volatile inout float, float);"
             "   float atomicAdd(coherent volatile inout float, float, int, int, int);"
             "  double atomicAdd(coherent volatile inout double, double);"
@@ -1264,6 +1485,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             " int64_t atomicExchange(coherent volatile inout  int64_t,  int64_t);"
             "uint64_t atomicExchange(coherent volatile inout uint64_t, uint64_t, int, int, int);"
             " int64_t atomicExchange(coherent volatile inout  int64_t,  int64_t, int, int, int);"
+            "float16_t atomicExchange(coherent volatile inout float16_t, float16_t);"
+            "float16_t atomicExchange(coherent volatile inout float16_t, float16_t, int, int, int);"
             "   float atomicExchange(coherent volatile inout float, float);"
             "   float atomicExchange(coherent volatile inout float, float, int, int, int);"
             "  double atomicExchange(coherent volatile inout double, double);"
@@ -1276,11 +1499,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
 
             "uint64_t atomicLoad(coherent volatile in uint64_t, int, int, int);"
             " int64_t atomicLoad(coherent volatile in  int64_t, int, int, int);"
+            "float16_t atomicLoad(coherent volatile in float16_t, int, int, int);"
             "   float atomicLoad(coherent volatile in float, int, int, int);"
             "  double atomicLoad(coherent volatile in double, int, int, int);"
 
             "void atomicStore(coherent volatile out uint64_t, uint64_t, int, int, int);"
             "void atomicStore(coherent volatile out  int64_t,  int64_t, int, int, int);"
+            "void atomicStore(coherent volatile out float16_t, float16_t, int, int, int);"
             "void atomicStore(coherent volatile out float, float, int, int, int);"
             "void atomicStore(coherent volatile out double, double, int, int, int);"
             "\n");
@@ -1335,6 +1560,15 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
                 "dvec4  fma(dvec4,  dvec4,  dvec4 );"
                 "\n");
     }
+
+    if (profile == EEsProfile && version >= 310) {  // ARB_gpu_shader_fp64
+            commonBuiltins.append(
+                "float64_t fma(float64_t, float64_t, float64_t);"
+                "f64vec2  fma(f64vec2,  f64vec2,  f64vec2 );"
+                "f64vec3  fma(f64vec3,  f64vec3,  f64vec3 );"
+                "f64vec4  fma(f64vec4,  f64vec4,  f64vec4 );"
+                "\n");
+    }
 #endif
 
     if ((profile == EEsProfile && version >= 310) ||
@@ -1371,6 +1605,21 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
 
             "\n");
     }
+
+    if (profile == EEsProfile && version >= 310) { // ARB_gpu_shader_fp64
+        commonBuiltins.append(
+            "float64_t frexp(float64_t, out int);"
+            "f64vec2  frexp( f64vec2, out ivec2);"
+            "f64vec3  frexp( f64vec3, out ivec3);"
+            "f64vec4  frexp( f64vec4, out ivec4);"
+
+            "float64_t ldexp(float64_t, int);"
+            "f64vec2  ldexp( f64vec2, ivec2);"
+            "f64vec3  ldexp( f64vec3, ivec3);"
+            "f64vec4  ldexp( f64vec4, ivec4);"
+
+            "\n");
+    }
 #endif
 #endif
 
@@ -1615,6 +1864,22 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
 
                 "\n");
         }
+        if (profile != EEsProfile && version == 450) {
+            commonBuiltins.append(
+                "uint atomicCounterAddARB(atomic_uint, uint);"
+                "uint atomicCounterSubtractARB(atomic_uint, uint);"
+                "uint atomicCounterMinARB(atomic_uint, uint);"
+                "uint atomicCounterMaxARB(atomic_uint, uint);"
+                "uint atomicCounterAndARB(atomic_uint, uint);"
+                "uint atomicCounterOrARB(atomic_uint, uint);"
+                "uint atomicCounterXorARB(atomic_uint, uint);"
+                "uint atomicCounterExchangeARB(atomic_uint, uint);"
+                "uint atomicCounterCompSwapARB(atomic_uint, uint, uint);"
+
+                "\n");
+        }
+
+
         if (profile != EEsProfile && version >= 460) {
             commonBuiltins.append(
                 "uint atomicCounterAdd(atomic_uint, uint);"
@@ -1627,6 +1892,36 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
                 "uint atomicCounterExchange(atomic_uint, uint);"
                 "uint atomicCounterCompSwap(atomic_uint, uint, uint);"
 
+                "\n");
+        }
+    }
+    else if (spvVersion.vulkanRelaxed) {
+        //
+        // Atomic counter functions act as aliases to normal atomic functions.
+        // replace definitions to take 'volatile coherent uint' instead of 'atomic_uint'
+        // and map to equivalent non-counter atomic op
+        //
+        if ((profile != EEsProfile && version >= 300) ||
+            (profile == EEsProfile && version >= 310)) {
+            commonBuiltins.append(
+                "uint atomicCounterIncrement(volatile coherent uint);"
+                "uint atomicCounterDecrement(volatile coherent uint);"
+                "uint atomicCounter(volatile coherent uint);"
+
+                "\n");
+        }
+        if (profile != EEsProfile && version >= 460) {
+            commonBuiltins.append(
+                "uint atomicCounterAdd(volatile coherent uint, uint);"
+                "uint atomicCounterSubtract(volatile coherent uint, uint);"
+                "uint atomicCounterMin(volatile coherent uint, uint);"
+                "uint atomicCounterMax(volatile coherent uint, uint);"
+                "uint atomicCounterAnd(volatile coherent uint, uint);"
+                "uint atomicCounterOr(volatile coherent uint, uint);"
+                "uint atomicCounterXor(volatile coherent uint, uint);"
+                "uint atomicCounterExchange(volatile coherent uint, uint);"
+                "uint atomicCounterCompSwap(volatile coherent uint, uint, uint);"
+
                 "\n");
         }
     }
@@ -3116,7 +3411,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
 
 #ifndef GLSLANG_ANGLE
     // GL_AMD_gpu_shader_half_float/Explicit types
-    if (profile != EEsProfile && version >= 450) {
+    if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 310)) {
         commonBuiltins.append(
             "float16_t radians(float16_t);"
             "f16vec2   radians(f16vec2);"
@@ -3464,7 +3759,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
     }
 
     // Explicit types
-    if (profile != EEsProfile && version >= 450) {
+    if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 310)) {
         commonBuiltins.append(
             "int8_t abs(int8_t);"
             "i8vec2 abs(i8vec2);"
@@ -4124,7 +4419,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
     }
 #ifndef GLSLANG_WEB
     if ((profile != EEsProfile && version >= 420) || esBarrier) {
-        if (spvVersion.vulkan == 0) {
+        if (spvVersion.vulkan == 0 || spvVersion.vulkanRelaxed) {
             commonBuiltins.append("void memoryBarrierAtomicCounter();");
         }
         commonBuiltins.append("void memoryBarrierImage();");
@@ -4382,7 +4677,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             "\n");
         }
 
-    // Builtins for GL_NV_ray_tracing/GL_EXT_ray_tracing/GL_EXT_ray_query
+    // Builtins for GL_NV_ray_tracing/GL_NV_ray_tracing_motion_blur/GL_EXT_ray_tracing/GL_EXT_ray_query
     if (profile != EEsProfile && version >= 460) {
          commonBuiltins.append("void rayQueryInitializeEXT(rayQueryEXT, accelerationStructureEXT, uint, uint, vec3, float, vec3, float);"
             "void rayQueryTerminateEXT(rayQueryEXT);"
@@ -4411,6 +4706,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
 
         stageBuiltins[EShLangRayGen].append(
             "void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
+            "void traceRayMotionNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);"
             "void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
             "void executeCallableNV(uint, int);"
             "void executeCallableEXT(uint, int);"
@@ -4425,12 +4721,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             "\n");
         stageBuiltins[EShLangClosestHit].append(
             "void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
+            "void traceRayMotionNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);"
             "void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
             "void executeCallableNV(uint, int);"
             "void executeCallableEXT(uint, int);"
             "\n");
         stageBuiltins[EShLangMiss].append(
             "void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
+            "void traceRayMotionNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);"
             "void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
             "void executeCallableNV(uint, int);"
             "void executeCallableEXT(uint, int);"
@@ -4848,6 +5146,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
                 "in int gl_VertexIndex;"
                 "in int gl_InstanceIndex;"
                 );
+
+        if (spvVersion.vulkan > 0 && version >= 140 && spvVersion.vulkanRelaxed)
+            stageBuiltins[EShLangVertex].append(
+                "in int gl_VertexID;"         // declare with 'in' qualifier
+                "in int gl_InstanceID;"
+                );
+
         if (version >= 440) {
             stageBuiltins[EShLangVertex].append(
                 "in int gl_BaseVertexARB;"
@@ -4885,7 +5190,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
                 "mediump float gl_PointSize;" // needs qualifier fixed later
                 );
         } else {
-            if (spvVersion.vulkan == 0)
+            if (spvVersion.vulkan == 0 || spvVersion.vulkanRelaxed)
                 stageBuiltins[EShLangVertex].append(
                     "in highp int gl_VertexID;"      // needs qualifier fixed later
                     "in highp int gl_InstanceID;"    // needs qualifier fixed later
@@ -5632,6 +5937,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             "in    mat3x4 gl_WorldToObject3x4EXT;"
             "in    uint   gl_IncomingRayFlagsNV;"
             "in    uint   gl_IncomingRayFlagsEXT;"
+            "in    float  gl_CurrentRayTimeNV;"
             "\n";
         const char *hitDecls =
             "in    uvec3  gl_LaunchIDNV;"
@@ -5667,6 +5973,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             "in    mat3x4 gl_WorldToObject3x4EXT;"
             "in    uint   gl_IncomingRayFlagsNV;"
             "in    uint   gl_IncomingRayFlagsEXT;"
+            "in    float  gl_CurrentRayTimeNV;"
             "\n";
         const char *missDecls =
             "in    uvec3  gl_LaunchIDNV;"
@@ -5685,6 +5992,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             "in    float  gl_RayTmaxEXT;"
             "in    uint   gl_IncomingRayFlagsNV;"
             "in    uint   gl_IncomingRayFlagsEXT;"
+            "in    float  gl_CurrentRayTimeNV;"
             "\n";
 
         const char *callableDecls =
@@ -6211,6 +6519,24 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int
                 commonBuiltins.append(imageParams);
                 commonBuiltins.append(", float");
                 commonBuiltins.append(", int, int, int);\n");
+
+                commonBuiltins.append("float imageAtomicMin(volatile coherent ");
+                commonBuiltins.append(imageParams);
+                commonBuiltins.append(", float);\n");
+
+                commonBuiltins.append("float imageAtomicMin(volatile coherent ");
+                commonBuiltins.append(imageParams);
+                commonBuiltins.append(", float");
+                commonBuiltins.append(", int, int, int);\n");
+
+                commonBuiltins.append("float imageAtomicMax(volatile coherent ");
+                commonBuiltins.append(imageParams);
+                commonBuiltins.append(", float);\n");
+
+                commonBuiltins.append("float imageAtomicMax(volatile coherent ");
+                commonBuiltins.append(imageParams);
+                commonBuiltins.append(", float");
+                commonBuiltins.append(", int, int, int);\n");
             }
         }
     }
@@ -6538,7 +6864,7 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName,
                                             s.append(");\n");
 
                                             // Add to the per-language set of built-ins
-                                            if (bias || lodClamp != 0) {
+                                            if (!grad && (bias || lodClamp != 0)) {
                                                 stageBuiltins[EShLangFragment].append(s);
                                                 stageBuiltins[EShLangCompute].append(s);
                                             } else
@@ -6979,6 +7305,9 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
 
             snprintf(builtInConstant, maxSize, "const int  gl_MaxFragmentUniformVectors = %d;", resources.maxFragmentUniformVectors);
             s.append(builtInConstant);
+
+            snprintf(builtInConstant, maxSize, "const int  gl_MaxVaryingVectors = %d;", resources.maxVaryingVectors);
+            s.append(builtInConstant);
         }
 
         snprintf(builtInConstant, maxSize, "const int  gl_MaxVertexAttribs = %d;", resources.maxVertexAttribs);
@@ -7011,7 +7340,8 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
         snprintf(builtInConstant, maxSize, "const int  gl_MaxVertexUniformComponents = %d;", resources.maxVertexUniformComponents);
         s.append(builtInConstant);
 
-        if (version < 150 || ARBCompatibility) {
+        // Moved from just being deprecated into compatibility profile only as of 4.20
+        if (version < 420 || profile == ECompatibilityProfile) {
             snprintf(builtInConstant, maxSize, "const int  gl_MaxVaryingFloats = %d;", resources.maxVaryingFloats);
             s.append(builtInConstant);
         }
@@ -7436,6 +7766,12 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
             SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable);
         }
 
+        if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) {
+            // treat these built-ins as aliases of VertexIndex and InstanceIndex
+            BuiltInVariable("gl_VertexID", EbvVertexIndex, symbolTable);
+            BuiltInVariable("gl_InstanceID", EbvInstanceIndex, symbolTable);
+        }
+
         if (profile != EEsProfile) {
             if (version >= 440) {
                 symbolTable.setVariableExtensions("gl_BaseVertexARB",   1, &E_GL_ARB_shader_draw_parameters);
@@ -7947,6 +8283,19 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
             symbolTable.setFunctionExtensions("atomicCounter"         , 1, &E_GL_ARB_shader_atomic_counters);
         }
 
+        // E_GL_ARB_shader_atomic_counter_ops
+        if (profile != EEsProfile && version == 450) {
+            symbolTable.setFunctionExtensions("atomicCounterAddARB"     , 1, &E_GL_ARB_shader_atomic_counter_ops);
+            symbolTable.setFunctionExtensions("atomicCounterSubtractARB", 1, &E_GL_ARB_shader_atomic_counter_ops);
+            symbolTable.setFunctionExtensions("atomicCounterMinARB"     , 1, &E_GL_ARB_shader_atomic_counter_ops);
+            symbolTable.setFunctionExtensions("atomicCounterMaxARB"     , 1, &E_GL_ARB_shader_atomic_counter_ops);
+            symbolTable.setFunctionExtensions("atomicCounterAndARB"     , 1, &E_GL_ARB_shader_atomic_counter_ops);
+            symbolTable.setFunctionExtensions("atomicCounterOrARB"      , 1, &E_GL_ARB_shader_atomic_counter_ops);
+            symbolTable.setFunctionExtensions("atomicCounterXorARB"     , 1, &E_GL_ARB_shader_atomic_counter_ops);
+            symbolTable.setFunctionExtensions("atomicCounterExchangeARB", 1, &E_GL_ARB_shader_atomic_counter_ops);
+            symbolTable.setFunctionExtensions("atomicCounterCompSwapARB", 1, &E_GL_ARB_shader_atomic_counter_ops);
+        }
+
         // E_GL_ARB_derivative_control
         if (profile != EEsProfile && version < 450) {
             symbolTable.setFunctionExtensions("dFdxFine",     1, &E_GL_ARB_derivative_control);
@@ -8475,11 +8824,13 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
             symbolTable.setVariableExtensions("gl_WorldToObject3x4EXT", 1, &E_GL_EXT_ray_tracing);
             symbolTable.setVariableExtensions("gl_IncomingRayFlagsNV", 1, &E_GL_NV_ray_tracing);
             symbolTable.setVariableExtensions("gl_IncomingRayFlagsEXT", 1, &E_GL_EXT_ray_tracing);
+            symbolTable.setVariableExtensions("gl_CurrentRayTimeNV", 1, &E_GL_NV_ray_tracing_motion_blur);
 
             symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group);
 
 
             symbolTable.setFunctionExtensions("traceNV", 1, &E_GL_NV_ray_tracing);
+            symbolTable.setFunctionExtensions("traceRayMotionNV", 1, &E_GL_NV_ray_tracing_motion_blur);
             symbolTable.setFunctionExtensions("traceRayEXT", 1, &E_GL_EXT_ray_tracing);
             symbolTable.setFunctionExtensions("reportIntersectionNV", 1, &E_GL_NV_ray_tracing);
             symbolTable.setFunctionExtensions("reportIntersectionEXT", 1, &E_GL_EXT_ray_tracing);
@@ -8523,6 +8874,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
             BuiltInVariable("gl_IncomingRayFlagsNV",     EbvIncomingRayFlags,   symbolTable);
             BuiltInVariable("gl_IncomingRayFlagsEXT",    EbvIncomingRayFlags,   symbolTable);
             BuiltInVariable("gl_DeviceIndex",            EbvDeviceIndex,        symbolTable);
+            BuiltInVariable("gl_CurrentRayTimeNV",       EbvCurrentRayTimeNV,   symbolTable);
 
             // GL_ARB_shader_ballot
             symbolTable.setVariableExtensions("gl_SubGroupSizeARB",       1, &E_GL_ARB_shader_ballot);
@@ -8912,6 +9264,14 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
     symbolTable.relateToOperator("memoryBarrierAtomicCounter", EOpMemoryBarrierAtomicCounter);
     symbolTable.relateToOperator("memoryBarrierImage",         EOpMemoryBarrierImage);
 
+    if (spvVersion.vulkanRelaxed) {
+        //
+        // functions signature have been replaced to take uint operations on buffer variables
+        // remap atomic counter functions to atomic operations
+        //
+        symbolTable.relateToOperator("memoryBarrierAtomicCounter", EOpMemoryBarrierBuffer);
+    }
+
     symbolTable.relateToOperator("atomicLoad",     EOpAtomicLoad);
     symbolTable.relateToOperator("atomicStore",    EOpAtomicStore);
 
@@ -8919,12 +9279,38 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
     symbolTable.relateToOperator("atomicCounterDecrement", EOpAtomicCounterDecrement);
     symbolTable.relateToOperator("atomicCounter",          EOpAtomicCounter);
 
+    if (spvVersion.vulkanRelaxed) {
+        //
+        // functions signature have been replaced to take uint operations
+        // remap atomic counter functions to atomic operations
+        //
+        // these atomic counter functions do not match signatures of glsl
+        // atomic functions, so they will be remapped to semantically
+        // equivalent functions in the parser
+        //
+        symbolTable.relateToOperator("atomicCounterIncrement", EOpNull);
+        symbolTable.relateToOperator("atomicCounterDecrement", EOpNull);
+        symbolTable.relateToOperator("atomicCounter", EOpNull);
+    }
+
     symbolTable.relateToOperator("clockARB",     EOpReadClockSubgroupKHR);
     symbolTable.relateToOperator("clock2x32ARB", EOpReadClockSubgroupKHR);
 
     symbolTable.relateToOperator("clockRealtimeEXT",     EOpReadClockDeviceKHR);
     symbolTable.relateToOperator("clockRealtime2x32EXT", EOpReadClockDeviceKHR);
 
+    if (profile != EEsProfile && version == 450) {
+        symbolTable.relateToOperator("atomicCounterAddARB",      EOpAtomicCounterAdd);
+        symbolTable.relateToOperator("atomicCounterSubtractARB", EOpAtomicCounterSubtract);
+        symbolTable.relateToOperator("atomicCounterMinARB",      EOpAtomicCounterMin);
+        symbolTable.relateToOperator("atomicCounterMaxARB",      EOpAtomicCounterMax);
+        symbolTable.relateToOperator("atomicCounterAndARB",      EOpAtomicCounterAnd);
+        symbolTable.relateToOperator("atomicCounterOrARB",       EOpAtomicCounterOr);
+        symbolTable.relateToOperator("atomicCounterXorARB",      EOpAtomicCounterXor);
+        symbolTable.relateToOperator("atomicCounterExchangeARB", EOpAtomicCounterExchange);
+        symbolTable.relateToOperator("atomicCounterCompSwapARB", EOpAtomicCounterCompSwap);
+    }
+
     if (profile != EEsProfile && version >= 460) {
         symbolTable.relateToOperator("atomicCounterAdd",      EOpAtomicCounterAdd);
         symbolTable.relateToOperator("atomicCounterSubtract", EOpAtomicCounterSubtract);
@@ -8937,6 +9323,23 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
         symbolTable.relateToOperator("atomicCounterCompSwap", EOpAtomicCounterCompSwap);
     }
 
+    if (spvVersion.vulkanRelaxed) {
+        //
+        // functions signature have been replaced to take 'uint' instead of 'atomic_uint'
+        // remap atomic counter functions to non-counter atomic ops so
+        // functions act as aliases to non-counter atomic ops
+        //
+        symbolTable.relateToOperator("atomicCounterAdd", EOpAtomicAdd);
+        symbolTable.relateToOperator("atomicCounterSubtract", EOpAtomicSubtract);
+        symbolTable.relateToOperator("atomicCounterMin", EOpAtomicMin);
+        symbolTable.relateToOperator("atomicCounterMax", EOpAtomicMax);
+        symbolTable.relateToOperator("atomicCounterAnd", EOpAtomicAnd);
+        symbolTable.relateToOperator("atomicCounterOr", EOpAtomicOr);
+        symbolTable.relateToOperator("atomicCounterXor", EOpAtomicXor);
+        symbolTable.relateToOperator("atomicCounterExchange", EOpAtomicExchange);
+        symbolTable.relateToOperator("atomicCounterCompSwap", EOpAtomicCompSwap);
+    }
+
     symbolTable.relateToOperator("fma",               EOpFma);
     symbolTable.relateToOperator("frexp",             EOpFrexp);
     symbolTable.relateToOperator("ldexp",             EOpLdexp);
@@ -9315,6 +9718,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
     case EShLangMiss:
         if (profile != EEsProfile && version >= 460) {
             symbolTable.relateToOperator("traceNV", EOpTraceNV);
+            symbolTable.relateToOperator("traceRayMotionNV", EOpTraceRayMotionNV);
             symbolTable.relateToOperator("traceRayEXT", EOpTraceKHR);
             symbolTable.relateToOperator("executeCallableNV", EOpExecuteCallableNV);
             symbolTable.relateToOperator("executeCallableEXT", EOpExecuteCallableKHR);

+ 20 - 9
thirdparty/glslang/glslang/MachineIndependent/Intermediate.cpp

@@ -65,7 +65,7 @@ namespace glslang {
 // Returns the added node.
 //
 
-TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, const TConstUnionArray& constArray,
+TIntermSymbol* TIntermediate::addSymbol(long long id, const TString& name, const TType& type, const TConstUnionArray& constArray,
                                         TIntermTyped* constSubtree, const TSourceLoc& loc)
 {
     TIntermSymbol* node = new TIntermSymbol(id, name, type);
@@ -1739,7 +1739,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
         case EbtUint:
             switch (from) {
             case EbtInt:
-                return version >= 400 || getSource() == EShSourceHlsl;
+                return version >= 400 || getSource() == EShSourceHlsl || IsRequestedExtension(E_GL_ARB_gpu_shader5);
             case EbtBool:
                 return getSource() == EShSourceHlsl;
             case EbtInt16:
@@ -2676,7 +2676,11 @@ TIntermTyped* TIntermediate::addSwizzle(TSwizzleSelectors<selectorType>& selecto
 // 'swizzleOkay' says whether or not it is okay to consider a swizzle
 // a valid part of the dereference chain.
 //
-const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay)
+// 'BufferReferenceOk' says if type is buffer_reference, the routine stop to find the most left node.
+//
+//
+
+const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay , bool bufferReferenceOk)
 {
     do {
         const TIntermBinary* binary = node->getAsBinaryNode();
@@ -2694,6 +2698,8 @@ const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool
                 return nullptr;
         }
         node = node->getAsBinaryNode()->getLeft();
+        if (bufferReferenceOk && node->isReference())
+            return node;
     } while (true);
 }
 
@@ -2870,7 +2876,7 @@ void TIntermediate::addToCallGraph(TInfoSink& /*infoSink*/, const TString& calle
             return;
     }
 
-    callGraph.push_front(TCall(caller, callee));
+    callGraph.emplace_front(caller, callee);
 }
 
 //
@@ -3776,11 +3782,16 @@ void TIntermBinary::updatePrecision()
 {
      if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
          getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
-        getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision);
-        if (getQualifier().precision != EpqNone) {
-            left->propagatePrecision(getQualifier().precision);
-            right->propagatePrecision(getQualifier().precision);
-        }
+       if (op == EOpRightShift || op == EOpLeftShift) {
+         // For shifts get precision from left side only and thus no need to propagate
+         getQualifier().precision = left->getQualifier().precision;
+       } else {
+         getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision);
+         if (getQualifier().precision != EpqNone) {
+           left->propagatePrecision(getQualifier().precision);
+           right->propagatePrecision(getQualifier().precision);
+         }
+       }
     }
 }
 

+ 61 - 2
thirdparty/glslang/glslang/MachineIndependent/ParseContextBase.cpp

@@ -601,7 +601,6 @@ void TParseContextBase::parseSwizzleSelector(const TSourceLoc& loc, const TStrin
         selector.push_back(0);
 }
 
-#ifdef ENABLE_HLSL
 //
 // Make the passed-in variable information become a member of the
 // global uniform block.  If this doesn't exist yet, make it.
@@ -646,7 +645,67 @@ void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& mem
 
     ++firstNewMember;
 }
-#endif
+
+void TParseContextBase::growAtomicCounterBlock(int binding, const TSourceLoc& loc, TType& memberType, const TString& memberName, TTypeList* typeList) {
+    // Make the atomic counter block, if not yet made.
+    const auto &at  = atomicCounterBuffers.find(binding);
+    if (at == atomicCounterBuffers.end()) {
+        atomicCounterBuffers.insert({binding, (TVariable*)nullptr });
+        atomicCounterBlockFirstNewMember.insert({binding, 0});
+    }
+
+    TVariable*& atomicCounterBuffer = atomicCounterBuffers[binding];
+    int& bufferNewMember = atomicCounterBlockFirstNewMember[binding];
+
+    if (atomicCounterBuffer == nullptr) {
+        TQualifier blockQualifier;
+        blockQualifier.clear();
+        blockQualifier.storage = EvqBuffer;
+        
+        char charBuffer[512];
+        if (binding != TQualifier::layoutBindingEnd) {
+            snprintf(charBuffer, 512, "%s_%d", getAtomicCounterBlockName(), binding);
+        } else {
+            snprintf(charBuffer, 512, "%s_0", getAtomicCounterBlockName());
+        }
+        
+        TType blockType(new TTypeList, *NewPoolTString(charBuffer), blockQualifier);
+        setUniformBlockDefaults(blockType);
+        blockType.getQualifier().layoutPacking = ElpStd430;
+        atomicCounterBuffer = new TVariable(NewPoolTString(""), blockType, true);
+        // If we arn't auto mapping bindings then set the block to use the same
+        // binding as what the atomic was set to use
+        if (!intermediate.getAutoMapBindings()) {
+            atomicCounterBuffer->getWritableType().getQualifier().layoutBinding = binding;
+        }
+        bufferNewMember = 0;
+
+        atomicCounterBuffer->getWritableType().getQualifier().layoutSet = atomicCounterBlockSet;
+    }
+
+    // Add the requested member as a member to the global block.
+    TType* type = new TType;
+    type->shallowCopy(memberType);
+    type->setFieldName(memberName);
+    if (typeList)
+        type->setStruct(typeList);
+    TTypeLoc typeLoc = {type, loc};
+    atomicCounterBuffer->getType().getWritableStruct()->push_back(typeLoc);
+
+    // Insert into the symbol table.
+    if (bufferNewMember == 0) {
+        // This is the first request; we need a normal symbol table insert
+        if (symbolTable.insert(*atomicCounterBuffer))
+            trackLinkage(*atomicCounterBuffer);
+        else
+            error(loc, "failed to insert the global constant buffer", "buffer", "");
+    } else {
+        // This is a follow-on request; we need to amend the first insert
+        symbolTable.amend(*atomicCounterBuffer, bufferNewMember);
+    }
+
+    ++bufferNewMember;
+}
 
 void TParseContextBase::finish()
 {

File diff suppressed because it is too large
+ 601 - 42
thirdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp


+ 60 - 6
thirdparty/glslang/glslang/MachineIndependent/ParseHelper.h

@@ -67,7 +67,7 @@ struct TPragma {
 class TScanContext;
 class TPpContext;
 
-typedef std::set<int> TIdSetType;
+typedef std::set<long long> TIdSetType;
 typedef std::map<const TTypeList*, std::map<size_t, const TTypeList*>> TStructRecord;
 
 //
@@ -92,7 +92,8 @@ public:
             limits(resources.limits),
             globalUniformBlock(nullptr),
             globalUniformBinding(TQualifier::layoutBindingEnd),
-            globalUniformSet(TQualifier::layoutSetEnd)
+            globalUniformSet(TQualifier::layoutSetEnd),
+            atomicCounterBlockSet(TQualifier::layoutSetEnd)
     {
         if (entryPoint != nullptr)
             sourceEntryPointName = *entryPoint;
@@ -154,10 +155,11 @@ public:
             extensionCallback(line, extension, behavior);
     }
 
-#ifdef ENABLE_HLSL
     // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
     virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
-#endif
+
+    // Manage global buffer (used for backing atomic counters in GLSL when using relaxed Vulkan semantics)
+    virtual void growAtomicCounterBlock(int binding, const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
 
     // Potentially rename shader entry point function
     void renameShaderFunction(TString*& name) const
@@ -230,7 +232,25 @@ protected:
     // override this to set the language-specific name
     virtual const char* getGlobalUniformBlockName() const { return ""; }
     virtual void setUniformBlockDefaults(TType&) const { }
-    virtual void finalizeGlobalUniformBlockLayout(TVariable&) { }
+    virtual void finalizeGlobalUniformBlockLayout(TVariable&) {}
+
+    // Manage the atomic counter block (used for atomic_uints with Vulkan-Relaxed)
+    TMap<int, TVariable*> atomicCounterBuffers;
+    unsigned int atomicCounterBlockSet;
+    TMap<int, int> atomicCounterBlockFirstNewMember;
+    // override this to set the language-specific name
+    virtual const char* getAtomicCounterBlockName() const { return ""; }
+    virtual void setAtomicCounterBlockDefaults(TType&) const {}
+    virtual void setInvariant(const TSourceLoc& loc, const char* builtin) {}
+    virtual void finalizeAtomicCounterBlockLayout(TVariable&) {}
+    bool isAtomicCounterBlock(const TSymbol& symbol) {
+        const TVariable* var = symbol.getAsVariable();
+        if (!var)
+            return false;
+        const auto& at = atomicCounterBuffers.find(var->getType().getQualifier().layoutBinding);
+        return (at != atomicCounterBuffers.end() && (*at).second->getType() == var->getType());
+    }
+
     virtual void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken,
                                const char* szExtraInfoFormat, TPrefixType prefix,
                                va_list args);
@@ -293,6 +313,9 @@ public:
     bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) override;
     void parserError(const char* s);     // for bison's yyerror
 
+    virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr) override;
+    virtual void growAtomicCounterBlock(int binding, const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr) override;
+
     void reservedErrorCheck(const TSourceLoc&, const TString&);
     void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) override;
     bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) override;
@@ -340,6 +363,10 @@ public:
     void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier);
     void memorySemanticsCheck(const TSourceLoc&, const TFunction&, const TIntermOperator& callNode);
 
+    TIntermTyped* vkRelaxedRemapFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
+    // returns true if the variable was remapped to something else
+    bool vkRelaxedRemapUniformVariable(const TSourceLoc&, TString&, const TPublicType&, TArraySizes*, TIntermTyped*, TType&);
+
     void assignError(const TSourceLoc&, const char* op, TString left, TString right);
     void unaryOpError(const TSourceLoc&, const char* op, TString operand);
     void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right);
@@ -392,7 +419,7 @@ public:
     void arrayLimitCheck(const TSourceLoc&, const TString&, int size);
     void limitCheck(const TSourceLoc&, int value, const char* limit, const char* feature);
 
-    void inductiveLoopBodyCheck(TIntermNode*, int loopIndexId, TSymbolTable&);
+    void inductiveLoopBodyCheck(TIntermNode*, long long loopIndexId, TSymbolTable&);
     void constantIndexExpressionCheck(TIntermNode*);
 
     void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&);
@@ -417,6 +444,7 @@ public:
     TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
     void inheritMemoryQualifiers(const TQualifier& from, TQualifier& to);
     void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
+    void blockStorageRemap(const TSourceLoc&, const TString*, TQualifier&);
     void blockStageIoCheck(const TSourceLoc&, const TQualifier&);
     void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName);
     void fixBlockLocations(const TSourceLoc&, TQualifier&, TTypeList&, bool memberWithLocation, bool memberWithoutLocation);
@@ -443,6 +471,22 @@ public:
     void handleSwitchAttributes(const TAttributes& attributes, TIntermNode*);
     // Determine loop control from attributes
     void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
+    // Function attributes
+    void handleFunctionAttributes(const TSourceLoc&, const TAttributes&, TFunction*);
+
+    // GL_EXT_spirv_intrinsics
+    TSpirvRequirement* makeSpirvRequirement(const TSourceLoc& loc, const TString& name,
+                                            const TIntermAggregate* extensions, const TIntermAggregate* capabilities);
+    TSpirvRequirement* mergeSpirvRequirements(const TSourceLoc& loc, TSpirvRequirement* spirvReq1,
+                                                TSpirvRequirement* spirvReq2);
+    TSpirvTypeParameters* makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant);
+    TSpirvTypeParameters* makeSpirvTypeParameters(const TPublicType& type);
+    TSpirvTypeParameters* mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1,
+                                                   TSpirvTypeParameters* spirvTypeParams2);
+    TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, const TString& value);
+    TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, int value);
+    TSpirvInstruction* mergeSpirvInstruction(const TSourceLoc& loc, TSpirvInstruction* spirvInst1,
+                                             TSpirvInstruction* spirvInst2);
 #endif
 
     void checkAndResizeMeshViewDim(const TSourceLoc&, TType&, bool isBlockMember);
@@ -461,6 +505,15 @@ protected:
     void finish() override;
 #endif
 
+    virtual const char* getGlobalUniformBlockName() const override;
+    virtual void finalizeGlobalUniformBlockLayout(TVariable&) override;
+    virtual void setUniformBlockDefaults(TType& block) const override;
+
+    virtual const char* getAtomicCounterBlockName() const override;
+    virtual void finalizeAtomicCounterBlockLayout(TVariable&) override;
+    virtual void setAtomicCounterBlockDefaults(TType& block) const override;
+    virtual void setInvariant(const TSourceLoc& loc, const char* builtin) override;
+
 public:
     //
     // Generally, bison productions, the scanner, and the PP need read/write access to these; just give them direct access
@@ -485,6 +538,7 @@ protected:
     TQualifier globalUniformDefaults;
     TQualifier globalInputDefaults;
     TQualifier globalOutputDefaults;
+    TQualifier globalSharedDefaults;
     TString currentCaller;        // name of last function body entered (not valid when at global scope)
 #ifndef GLSLANG_WEB
     int* atomicUintOffsets;       // to become an array of the right size to hold an offset per binding point

+ 27 - 0
thirdparty/glslang/glslang/MachineIndependent/Scan.cpp

@@ -586,6 +586,18 @@ void TScanContext::fillInKeywordMap()
     (*KeywordMap)["f64mat4x2"] =               F64MAT4X2;
     (*KeywordMap)["f64mat4x3"] =               F64MAT4X3;
     (*KeywordMap)["f64mat4x4"] =               F64MAT4X4;
+
+    // GL_EXT_spirv_intrinsics
+    (*KeywordMap)["spirv_instruction"] =       SPIRV_INSTRUCTION;
+    (*KeywordMap)["spirv_execution_mode"] =    SPIRV_EXECUTION_MODE;
+    (*KeywordMap)["spirv_execution_mode_id"] = SPIRV_EXECUTION_MODE_ID;
+    (*KeywordMap)["spirv_decorate"] =          SPIRV_DECORATE;
+    (*KeywordMap)["spirv_decorate_id"] =       SPIRV_DECORATE_ID;
+    (*KeywordMap)["spirv_decorate_string"] =   SPIRV_DECORATE_STRING;
+    (*KeywordMap)["spirv_type"] =              SPIRV_TYPE;
+    (*KeywordMap)["spirv_storage_class"] =     SPIRV_STORAGE_CLASS;
+    (*KeywordMap)["spirv_by_reference"] =      SPIRV_BY_REFERENCE;
+    (*KeywordMap)["spirv_literal"] =           SPIRV_LITERAL;
 #endif
 
     (*KeywordMap)["sampler2D"] =               SAMPLER2D;
@@ -1747,6 +1759,21 @@ int TScanContext::tokenizeIdentifier()
             return keyword;
         else
             return identifierOrType();
+
+    case SPIRV_INSTRUCTION:
+    case SPIRV_EXECUTION_MODE:
+    case SPIRV_EXECUTION_MODE_ID:
+    case SPIRV_DECORATE:
+    case SPIRV_DECORATE_ID:
+    case SPIRV_DECORATE_STRING:
+    case SPIRV_TYPE:
+    case SPIRV_STORAGE_CLASS:
+    case SPIRV_BY_REFERENCE:
+    case SPIRV_LITERAL:
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            parseContext.extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
+            return keyword;
+        return identifierOrType();
 #endif
 
     default:

+ 99 - 7
thirdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp

@@ -159,7 +159,7 @@ int MapVersionToIndex(int version)
     return index;
 }
 
-const int SpvVersionCount = 3;  // index range in MapSpvVersionToIndex
+const int SpvVersionCount = 4;  // index range in MapSpvVersionToIndex
 
 int MapSpvVersionToIndex(const SpvVersion& spvVersion)
 {
@@ -167,8 +167,12 @@ int MapSpvVersionToIndex(const SpvVersion& spvVersion)
 
     if (spvVersion.openGl > 0)
         index = 1;
-    else if (spvVersion.vulkan > 0)
-        index = 2;
+    else if (spvVersion.vulkan > 0) {
+        if (!spvVersion.vulkanRelaxed)
+            index = 2;
+        else
+            index = 3;
+    }
 
     assert(index < SpvVersionCount);
 
@@ -723,6 +727,7 @@ void TranslateEnvironment(const TEnvironment* environment, EShMessages& messages
                 break;
             case EShClientVulkan:
                 spvVersion.vulkanGlsl = environment->input.dialectVersion;
+                spvVersion.vulkanRelaxed = environment->input.vulkanRulesRelaxed;
                 break;
             case EShClientOpenGL:
                 spvVersion.openGl = environment->input.dialectVersion;
@@ -949,6 +954,9 @@ bool ProcessDeferred(
     if (cachedTable)
         symbolTable->adoptLevels(*cachedTable);
 
+    if (intermediate.getUniqueId() != 0)
+        symbolTable->overwriteUniqueId(intermediate.getUniqueId());
+
     // Add built-in symbols that are potentially context dependent;
     // they get popped again further down.
     if (! AddContextSpecificSymbols(resources, compiler->infoSink, *symbolTable, version, profile, spvVersion,
@@ -1011,6 +1019,7 @@ bool ProcessDeferred(
     bool success = processingContext(*parseContext, ppContext, fullInput,
                                      versionWillBeError, *symbolTable,
                                      intermediate, optLevel, messages);
+    intermediate.setUniqueId(symbolTable->getMaxSymbolId());
     return success;
 }
 
@@ -1270,14 +1279,15 @@ bool PreprocessDeferred(
     EShMessages messages,       // warnings/errors/AST; things to print out
     TShader::Includer& includer,
     TIntermediate& intermediate, // returned tree, etc.
-    std::string* outputString)
+    std::string* outputString,
+    TEnvironment* environment = nullptr)
 {
     DoPreprocessing parser(outputString);
     return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
                            preamble, optLevel, resources, defaultVersion,
                            defaultProfile, forceDefaultVersionAndProfile,
                            forwardCompatible, messages, intermediate, parser,
-                           false, includer);
+                           false, includer, "", environment);
 }
 #endif
 
@@ -1757,6 +1767,7 @@ TShader::TShader(EShLanguage s)
     // clear environment (avoid constructors in them for use in a C interface)
     environment.input.languageFamily = EShSourceNone;
     environment.input.dialect = EShClientNone;
+    environment.input.vulkanRulesRelaxed = false;
     environment.client.client = EShClientNone;
     environment.target.language = EShTargetNone;
     environment.target.hlslFunctionality1 = false;
@@ -1810,6 +1821,11 @@ void TShader::addProcesses(const std::vector<std::string>& p)
     intermediate->addProcesses(p);
 }
 
+void  TShader::setUniqueId(unsigned long long id)
+{
+    intermediate->setUniqueId(id);
+}
+
 void TShader::setInvertY(bool invert)                   { intermediate->setInvertY(invert); }
 void TShader::setNanMinMaxClamp(bool useNonNan)         { intermediate->setNanMinMaxClamp(useNonNan); }
 
@@ -1858,6 +1874,15 @@ void TShader::setResourceSetBinding(const std::vector<std::string>& base)   { in
 void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); }
 #endif
 
+void TShader::addBlockStorageOverride(const char* nameStr, TBlockStorageClass backing) { intermediate->addBlockStorageOverride(nameStr, backing); }
+
+void TShader::setGlobalUniformBlockName(const char* name) { intermediate->setGlobalUniformBlockName(name); }
+void TShader::setGlobalUniformSet(unsigned int set) { intermediate->setGlobalUniformSet(set); }
+void TShader::setGlobalUniformBinding(unsigned int binding) { intermediate->setGlobalUniformBinding(binding); }
+
+void TShader::setAtomicCounterBlockName(const char* name) { intermediate->setAtomicCounterBlockName(name); }
+void TShader::setAtomicCounterBlockSet(unsigned int set) { intermediate->setAtomicCounterBlockSet(set); }
+
 #ifdef ENABLE_HLSL
 // See comment above TDefaultHlslIoMapper in iomapper.cpp:
 void TShader::setHlslIoMapping(bool hlslIoMap)          { intermediate->setHlslIoMapping(hlslIoMap); }
@@ -1909,7 +1934,8 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources,
     return PreprocessDeferred(compiler, strings, numStrings, lengths, stringNames, preamble,
                               EShOptNone, builtInResources, defaultVersion,
                               defaultProfile, forceDefaultVersionAndProfile,
-                              forwardCompatible, message, includer, *intermediate, output_string);
+                              forwardCompatible, message, includer, *intermediate, output_string,
+                              &environment);
 }
 #endif
 
@@ -1972,7 +1998,10 @@ bool TProgram::link(EShMessages messages)
             error = true;
     }
 
-    // TODO: Link: cross-stage error checking
+    if (!error) {
+        if (! crossStageCheck(messages))
+            error = true;
+    }
 
     return ! error;
 }
@@ -2049,6 +2078,69 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
     return intermediate[stage]->getNumErrors() == 0;
 }
 
+//
+// Check that there are no errors in linker objects accross stages
+//
+// Return true if no errors.
+//
+bool TProgram::crossStageCheck(EShMessages) {
+
+    // make temporary intermediates to hold the linkage symbols for each linking interface
+    // while we do the checks
+    // Independent interfaces are:
+    //                  all uniform variables and blocks
+    //                  all buffer blocks
+    //                  all in/out on a stage boundary
+
+    TVector<TIntermediate*> activeStages;
+    for (int s = 0; s < EShLangCount; ++s) {
+        if (intermediate[s])
+            activeStages.push_back(intermediate[s]);
+    }
+
+    // no extra linking if there is only one stage
+    if (! (activeStages.size() > 1))
+        return true;
+
+    // setup temporary tree to hold unfirom objects from different stages
+    TIntermediate* firstIntermediate = activeStages.front();
+    TIntermediate uniforms(EShLangCount,
+                           firstIntermediate->getVersion(),
+                           firstIntermediate->getProfile());
+    uniforms.setSpv(firstIntermediate->getSpv());
+
+    TIntermAggregate uniformObjects(EOpLinkerObjects);
+    TIntermAggregate root(EOpSequence);
+    root.getSequence().push_back(&uniformObjects);
+    uniforms.setTreeRoot(&root);
+
+    bool error = false;
+
+    // merge uniforms from all stages into a single intermediate
+    for (unsigned int i = 0; i < activeStages.size(); ++i) {
+        uniforms.mergeUniformObjects(*infoSink, *activeStages[i]);
+    }
+    error |= uniforms.getNumErrors() != 0;
+
+    // copy final definition of global block back into each stage
+    for (unsigned int i = 0; i < activeStages.size(); ++i) {
+        // We only want to merge into already existing global uniform blocks.
+        // A stage that doesn't already know about the global doesn't care about it's content.
+        // Otherwise we end up pointing to the same object between different stages
+        // and that will break binding/set remappings
+        bool mergeExistingOnly = true;
+        activeStages[i]->mergeGlobalUniformBlocks(*infoSink, uniforms, mergeExistingOnly);
+    }
+
+    // compare cross stage symbols for each stage boundary
+    for (unsigned int i = 1; i < activeStages.size(); ++i) {
+        activeStages[i - 1]->checkStageIO(*infoSink, *activeStages[i]);
+        error |= (activeStages[i - 1]->getNumErrors() != 0);
+    }
+
+    return !error;
+}
+
 const char* TProgram::getInfoLog()
 {
     return infoSink->info.c_str();

+ 355 - 0
thirdparty/glslang/glslang/MachineIndependent/SpirvIntrinsics.cpp

@@ -0,0 +1,355 @@
+//
+// Copyright(C) 2021 Advanced Micro Devices, Inc.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//    Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//
+//    Redistributions in binary form must reproduce the above
+//    copyright notice, this list of conditions and the following
+//    disclaimer in the documentation and/or other materials provided
+//    with the distribution.
+//
+//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+
+#ifndef GLSLANG_WEB
+
+//
+// GL_EXT_spirv_intrinsics
+//
+#include "../Include/intermediate.h"
+#include "../Include/SpirvIntrinsics.h"
+#include "../Include/Types.h"
+#include "ParseHelper.h"
+
+namespace glslang {
+
+//
+// Handle SPIR-V requirements
+//
+TSpirvRequirement* TParseContext::makeSpirvRequirement(const TSourceLoc& loc, const TString& name,
+                                                       const TIntermAggregate* extensions,
+                                                       const TIntermAggregate* capabilities)
+{
+    TSpirvRequirement* spirvReq = new TSpirvRequirement;
+
+    if (name == "extensions") {
+        assert(extensions);
+        for (auto extension : extensions->getSequence()) {
+            assert(extension->getAsConstantUnion());
+            spirvReq->extensions.insert(*extension->getAsConstantUnion()->getConstArray()[0].getSConst());
+        }
+    } else if (name == "capabilities") {
+        assert(capabilities);
+        for (auto capability : capabilities->getSequence()) {
+            assert(capability->getAsConstantUnion());
+            spirvReq->capabilities.insert(capability->getAsConstantUnion()->getConstArray()[0].getIConst());
+        }
+    } else
+        error(loc, "unknow SPIR-V requirement", name.c_str(), "");
+
+    return spirvReq;
+}
+
+TSpirvRequirement* TParseContext::mergeSpirvRequirements(const TSourceLoc& loc, TSpirvRequirement* spirvReq1,
+                                                         TSpirvRequirement* spirvReq2)
+{
+    // Merge the second SPIR-V requirement to the first one
+    if (!spirvReq2->extensions.empty()) {
+        if (spirvReq1->extensions.empty())
+            spirvReq1->extensions = spirvReq2->extensions;
+        else
+            error(loc, "too many SPIR-V requirements", "extensions", "");
+    }
+
+    if (!spirvReq2->capabilities.empty()) {
+        if (spirvReq1->capabilities.empty())
+            spirvReq1->capabilities = spirvReq2->capabilities;
+        else
+            error(loc, "too many SPIR-V requirements", "capabilities", "");
+    }
+
+    return spirvReq1;
+}
+
+void TIntermediate::insertSpirvRequirement(const TSpirvRequirement* spirvReq)
+{
+    if (!spirvRequirement)
+        spirvRequirement = new TSpirvRequirement;
+
+    for (auto extension : spirvReq->extensions)
+        spirvRequirement->extensions.insert(extension);
+
+    for (auto capability : spirvReq->capabilities)
+        spirvRequirement->capabilities.insert(capability);
+}
+
+//
+// Handle SPIR-V execution modes
+//
+void TIntermediate::insertSpirvExecutionMode(int executionMode, const TIntermAggregate* args)
+{
+    if (!spirvExecutionMode)
+        spirvExecutionMode = new TSpirvExecutionMode;
+
+    TVector<const TIntermConstantUnion*> extraOperands;
+    if (args) {
+        for (auto arg : args->getSequence()) {
+            auto extraOperand = arg->getAsConstantUnion();
+            assert(extraOperand != nullptr);
+            extraOperands.push_back(extraOperand);
+        }
+    }
+    spirvExecutionMode->modes[executionMode] = extraOperands;
+}
+
+void TIntermediate::insertSpirvExecutionModeId(int executionMode, const TIntermAggregate* args)
+{
+    if (!spirvExecutionMode)
+        spirvExecutionMode = new TSpirvExecutionMode;
+
+    assert(args);
+    TVector<const TIntermConstantUnion*> extraOperands;
+
+    for (auto arg : args->getSequence()) {
+        auto extraOperand = arg->getAsConstantUnion();
+        assert(extraOperand != nullptr);
+        extraOperands.push_back(extraOperand);
+    }
+    spirvExecutionMode->modeIds[executionMode] = extraOperands;
+}
+
+//
+// Handle SPIR-V decorate qualifiers
+//
+void TQualifier::setSpirvDecorate(int decoration, const TIntermAggregate* args)
+{
+    if (!spirvDecorate)
+        spirvDecorate = new TSpirvDecorate;
+
+    TVector<const TIntermConstantUnion*> extraOperands;
+    if (args) {
+        for (auto arg : args->getSequence()) {
+            auto extraOperand = arg->getAsConstantUnion();
+            assert(extraOperand != nullptr);
+            extraOperands.push_back(extraOperand);
+        }
+    }
+    spirvDecorate->decorates[decoration] = extraOperands;
+}
+
+void TQualifier::setSpirvDecorateId(int decoration, const TIntermAggregate* args)
+{
+    if (!spirvDecorate)
+        spirvDecorate = new TSpirvDecorate;
+
+    assert(args);
+    TVector<const TIntermConstantUnion*> extraOperands;
+    for (auto arg : args->getSequence()) {
+        auto extraOperand = arg->getAsConstantUnion();
+        assert(extraOperand != nullptr);
+        extraOperands.push_back(extraOperand);
+    }
+    spirvDecorate->decorateIds[decoration] = extraOperands;
+}
+
+void TQualifier::setSpirvDecorateString(int decoration, const TIntermAggregate* args)
+{
+    if (!spirvDecorate)
+        spirvDecorate = new TSpirvDecorate;
+
+    assert(args);
+    TVector<const TIntermConstantUnion*> extraOperands;
+    for (auto arg : args->getSequence()) {
+        auto extraOperand = arg->getAsConstantUnion();
+        assert(extraOperand != nullptr);
+        extraOperands.push_back(extraOperand);
+    }
+    spirvDecorate->decorateStrings[decoration] = extraOperands;
+}
+
+TString TQualifier::getSpirvDecorateQualifierString() const
+{
+    assert(spirvDecorate);
+
+    TString qualifierString;
+
+    const auto appendFloat = [&](float f) { qualifierString.append(std::to_string(f).c_str()); };
+    const auto appendInt = [&](int i) { qualifierString.append(std::to_string(i).c_str()); };
+    const auto appendUint = [&](unsigned int u) { qualifierString.append(std::to_string(u).c_str()); };
+    const auto appendBool = [&](bool b) { qualifierString.append(std::to_string(b).c_str()); };
+    const auto appendStr = [&](const char* s) { qualifierString.append(s); };
+
+    const auto appendDecorate = [&](const TIntermConstantUnion* constant) {
+        if (constant->getBasicType() == EbtFloat) {
+            float value = static_cast<float>(constant->getConstArray()[0].getDConst());
+            appendFloat(value);
+        }
+        else if (constant->getBasicType() == EbtInt) {
+            int value = constant->getConstArray()[0].getIConst();
+            appendInt(value);
+        }
+        else if (constant->getBasicType() == EbtUint) {
+            unsigned value = constant->getConstArray()[0].getUConst();
+            appendUint(value);
+        }
+        else if (constant->getBasicType() == EbtBool) {
+            bool value = constant->getConstArray()[0].getBConst();
+            appendBool(value);
+        }
+        else if (constant->getBasicType() == EbtString) {
+            const TString* value = constant->getConstArray()[0].getSConst();
+            appendStr(value->c_str());
+        }
+        else
+            assert(0);
+    };
+
+    for (auto& decorate : spirvDecorate->decorates) {
+        appendStr("spirv_decorate(");
+        appendInt(decorate.first);
+        for (auto extraOperand : decorate.second) {
+            appendStr(", ");
+            appendDecorate(extraOperand);
+        }
+        appendStr(") ");
+    }
+
+    for (auto& decorateId : spirvDecorate->decorateIds) {
+        appendStr("spirv_decorate_id(");
+        appendInt(decorateId.first);
+        for (auto extraOperand : decorateId.second) {
+            appendStr(", ");
+            appendDecorate(extraOperand);
+        }
+        appendStr(") ");
+    }
+
+    for (auto& decorateString : spirvDecorate->decorateStrings) {
+        appendStr("spirv_decorate_string(");
+        appendInt(decorateString.first);
+        for (auto extraOperand : decorateString.second) {
+            appendStr(", ");
+            appendDecorate(extraOperand);
+        }
+        appendStr(") ");
+    }
+
+    return qualifierString;
+}
+
+//
+// Handle SPIR-V type specifiers
+//
+void TPublicType::setSpirvType(const TSpirvInstruction& spirvInst, const TSpirvTypeParameters* typeParams)
+{
+    if (!spirvType)
+        spirvType = new TSpirvType;
+
+    basicType = EbtSpirvType;
+    spirvType->spirvInst = spirvInst;
+    if (typeParams)
+        spirvType->typeParams = *typeParams;
+}
+
+TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant)
+{
+    TSpirvTypeParameters* spirvTypeParams = new TSpirvTypeParameters;
+    if (constant->getBasicType() != EbtFloat &&
+        constant->getBasicType() != EbtInt &&
+        constant->getBasicType() != EbtUint &&
+        constant->getBasicType() != EbtBool &&
+        constant->getBasicType() != EbtString)
+        error(loc, "this type not allowed", constant->getType().getBasicString(), "");
+    else {
+        assert(constant);
+        spirvTypeParams->push_back(TSpirvTypeParameter(constant));
+    }
+
+    return spirvTypeParams;
+}
+
+TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TPublicType& type)
+{
+    TSpirvTypeParameters* spirvTypeParams = new TSpirvTypeParameters;
+    spirvTypeParams->push_back(TSpirvTypeParameter(new TType(type)));
+    return spirvTypeParams;
+}
+
+TSpirvTypeParameters* TParseContext::mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1, TSpirvTypeParameters* spirvTypeParams2)
+{
+    // Merge SPIR-V type parameters of the second one to the first one
+    for (const auto& spirvTypeParam : *spirvTypeParams2)
+        spirvTypeParams1->push_back(spirvTypeParam);
+    return spirvTypeParams1;
+}
+
+//
+// Handle SPIR-V instruction qualifiers
+//
+TSpirvInstruction* TParseContext::makeSpirvInstruction(const TSourceLoc& loc, const TString& name, const TString& value)
+{
+    TSpirvInstruction* spirvInst = new TSpirvInstruction;
+    if (name == "set")
+        spirvInst->set = value;
+    else
+        error(loc, "unknown SPIR-V instruction qualifier", name.c_str(), "");
+
+    return spirvInst;
+}
+
+TSpirvInstruction* TParseContext::makeSpirvInstruction(const TSourceLoc& loc, const TString& name, int value)
+{
+    TSpirvInstruction* spirvInstuction = new TSpirvInstruction;
+    if (name == "id")
+        spirvInstuction->id = value;
+    else
+        error(loc, "unknown SPIR-V instruction qualifier", name.c_str(), "");
+
+    return spirvInstuction;
+}
+
+TSpirvInstruction* TParseContext::mergeSpirvInstruction(const TSourceLoc& loc, TSpirvInstruction* spirvInst1, TSpirvInstruction* spirvInst2)
+{
+    // Merge qualifiers of the second SPIR-V instruction to those of the first one
+    if (!spirvInst2->set.empty()) {
+        if (spirvInst1->set.empty())
+            spirvInst1->set = spirvInst2->set;
+        else
+            error(loc, "too many SPIR-V instruction qualifiers", "spirv_instruction", "(set)");
+    }
+
+    if (spirvInst2->id != -1) {
+        if (spirvInst1->id == -1)
+            spirvInst1->id = spirvInst2->id;
+        else
+            error(loc, "too many SPIR-V instruction qualifiers", "spirv_instruction", "(id)");
+    }
+
+    return spirvInst1;
+}
+
+} // end namespace glslang
+
+#endif // GLSLANG_WEB

+ 5 - 1
thirdparty/glslang/glslang/MachineIndependent/SymbolTable.cpp

@@ -77,6 +77,7 @@ void TType::buildMangledName(TString& mangledName) const
     case EbtAtomicUint:         mangledName += "au";     break;
     case EbtAccStruct:          mangledName += "as";     break;
     case EbtRayQuery:           mangledName += "rq";     break;
+    case EbtSpirvType:          mangledName += "spv-t";  break;
 #endif
     case EbtSampler:
         switch (sampler.type) {
@@ -170,7 +171,7 @@ void TType::buildMangledName(TString& mangledName) const
         for (int i = 0; i < arraySizes->getNumDims(); ++i) {
             if (arraySizes->getDimNode(i)) {
                 if (arraySizes->getDimNode(i)->getAsSymbolNode())
-                    snprintf(buf, maxSize, "s%d", arraySizes->getDimNode(i)->getAsSymbolNode()->getId());
+                    snprintf(buf, maxSize, "s%lld", arraySizes->getDimNode(i)->getAsSymbolNode()->getId());
                 else
                     snprintf(buf, maxSize, "s%p", arraySizes->getDimNode(i));
             } else
@@ -390,6 +391,9 @@ TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf)
     implicitThis = copyOf.implicitThis;
     illegalImplicitThis = copyOf.illegalImplicitThis;
     defaultParamCount = copyOf.defaultParamCount;
+#ifndef GLSLANG_WEB
+    spirvInst = copyOf.spirvInst;
+#endif
 }
 
 TFunction* TFunction::clone() const

+ 41 - 10
thirdparty/glslang/glslang/MachineIndependent/SymbolTable.h

@@ -104,8 +104,8 @@ public:
     virtual const TAnonMember* getAsAnonMember() const { return 0; }
     virtual const TType& getType() const = 0;
     virtual TType& getWritableType() = 0;
-    virtual void setUniqueId(int id) { uniqueId = id; }
-    virtual int getUniqueId() const { return uniqueId; }
+    virtual void setUniqueId(long long id) { uniqueId = id; }
+    virtual long long getUniqueId() const { return uniqueId; }
     virtual void setExtensions(int numExts, const char* const exts[])
     {
         assert(extensions == 0);
@@ -130,7 +130,7 @@ protected:
     TSymbol& operator=(const TSymbol&);
 
     const TString *name;
-    unsigned int uniqueId;      // For cross-scope comparing during code generation
+    unsigned long long uniqueId;      // For cross-scope comparing during code generation
 
     // For tracking what extensions must be present
     // (don't use if correct version/profile is present).
@@ -319,6 +319,15 @@ public:
     virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
     virtual const TParameter& operator[](int i) const { return parameters[i]; }
 
+#ifndef GLSLANG_WEB
+    virtual void setSpirvInstruction(const TSpirvInstruction& inst)
+    {
+        relateToOperator(EOpSpirvInst);
+        spirvInst = inst;
+    }
+    virtual const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
+#endif
+
 #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
     virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
 #endif
@@ -342,6 +351,10 @@ protected:
                                // This is important for a static member function that has member variables in scope,
                                // but is not allowed to use them, or see hidden symbols instead.
     int  defaultParamCount;
+
+#ifndef GLSLANG_WEB
+    TSpirvInstruction spirvInst; // SPIR-V instruction qualifiers
+#endif
 };
 
 //
@@ -612,6 +625,7 @@ public:
     //   3: user-shader globals
     //
 protected:
+    static const uint32_t LevelFlagBitOffset = 56;
     static const int globalLevel = 3;
     static bool isSharedLevel(int level)  { return level <= 1; }            // exclude all per-compile levels
     static bool isBuiltInLevel(int level) { return level <= 2; }            // exclude user globals
@@ -620,10 +634,12 @@ public:
     bool isEmpty() { return table.size() == 0; }
     bool atBuiltInLevel() { return isBuiltInLevel(currentLevel()); }
     bool atGlobalLevel()  { return isGlobalLevel(currentLevel()); }
-    static bool isBuiltInSymbol(int uniqueId) {
-        int level = uniqueId >> LevelFlagBitOffset;
+    static bool isBuiltInSymbol(long long uniqueId) {
+        int level = static_cast<int>(uniqueId >> LevelFlagBitOffset);
         return isBuiltInLevel(level);
     }
+    static constexpr uint64_t uniqueIdMask = (1LL << LevelFlagBitOffset) - 1;
+    static const uint32_t MaxLevelInUniqueID = 127;
     void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; }
     void setSeparateNameSpaces() { separateNameSpaces = true; }
 
@@ -691,6 +707,16 @@ public:
         return table[currentLevel()]->amend(symbol, firstNewMember);
     }
 
+    // Update the level info in symbol's unique ID to current level
+    void amendSymbolIdLevel(TSymbol& symbol)
+    {
+        // clamp level to avoid overflow
+        uint64_t level = (uint32_t)currentLevel() > MaxLevelInUniqueID ? MaxLevelInUniqueID : currentLevel();
+        uint64_t symbolId = symbol.getUniqueId();
+        symbolId &= uniqueIdMask;
+        symbolId |= (level << LevelFlagBitOffset);
+        symbol.setUniqueId(symbolId);
+    }
     //
     // To allocate an internal temporary, which will need to be uniquely
     // identified by the consumer of the AST, but never need to
@@ -859,7 +885,7 @@ public:
         }
     }
 
-    int getMaxSymbolId() { return uniqueId; }
+    long long getMaxSymbolId() { return uniqueId; }
 #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
     void dump(TInfoSink& infoSink, bool complete = false) const;
 #endif
@@ -876,19 +902,24 @@ public:
     // Add current level in the high-bits of unique id
     void updateUniqueIdLevelFlag() {
         // clamp level to avoid overflow
-        uint32_t level = currentLevel() > 7 ? 7 : currentLevel();
-        uniqueId &= ((1 << LevelFlagBitOffset) - 1);
+        uint64_t level = (uint32_t)currentLevel() > MaxLevelInUniqueID ? MaxLevelInUniqueID : currentLevel();
+        uniqueId &= uniqueIdMask;
         uniqueId |= (level << LevelFlagBitOffset);
     }
 
+    void overwriteUniqueId(long long id)
+    {
+        uniqueId = id;
+        updateUniqueIdLevelFlag();
+    }
+
 protected:
     TSymbolTable(TSymbolTable&);
     TSymbolTable& operator=(TSymbolTableLevel&);
 
     int currentLevel() const { return static_cast<int>(table.size()) - 1; }
-    static const uint32_t LevelFlagBitOffset = 28;
     std::vector<TSymbolTableLevel*> table;
-    int uniqueId;     // for unique identification in code generation
+    long long uniqueId;     // for unique identification in code generation
     bool noBuiltInRedeclarations;
     bool separateNameSpaces;
     unsigned int adoptedLevels;

+ 49 - 5
thirdparty/glslang/glslang/MachineIndependent/Versions.cpp

@@ -165,12 +165,14 @@ void TParseVersions::initializeExtensionBehavior()
         EShTargetLanguageVersion minSpvVersion;
     } extensionData;
 
-    const extensionData exts[] = { {E_GL_EXT_ray_tracing, EShTargetSpv_1_4} };
+    const extensionData exts[] = { {E_GL_EXT_ray_tracing, EShTargetSpv_1_4},
+                                   {E_GL_NV_ray_tracing_motion_blur, EShTargetSpv_1_4}
+                                 };
 
     for (size_t ii = 0; ii < sizeof(exts) / sizeof(exts[0]); ii++) {
         // Add only extensions which require > spv1.0 to save space in map
         if (exts[ii].minSpvVersion > EShTargetSpv_1_0) {
-            extensionMinSpv[E_GL_EXT_ray_tracing] = exts[ii].minSpvVersion;
+            extensionMinSpv[exts[ii].extensionName] = exts[ii].minSpvVersion;
         }
     }
 
@@ -198,6 +200,7 @@ void TParseVersions::initializeExtensionBehavior()
     extensionBehavior[E_GL_ARB_explicit_uniform_location]    = EBhDisable;
     extensionBehavior[E_GL_ARB_shader_image_load_store]      = EBhDisable;
     extensionBehavior[E_GL_ARB_shader_atomic_counters]       = EBhDisable;
+    extensionBehavior[E_GL_ARB_shader_atomic_counter_ops]    = EBhDisable;
     extensionBehavior[E_GL_ARB_shader_draw_parameters]       = EBhDisable;
     extensionBehavior[E_GL_ARB_shader_group_vote]            = EBhDisable;
     extensionBehavior[E_GL_ARB_derivative_control]           = EBhDisable;
@@ -251,6 +254,7 @@ void TParseVersions::initializeExtensionBehavior()
 
     extensionBehavior[E_GL_EXT_shader_16bit_storage]                    = EBhDisable;
     extensionBehavior[E_GL_EXT_shader_8bit_storage]                     = EBhDisable;
+    extensionBehavior[E_GL_EXT_subgroup_uniform_control_flow]           = EBhDisable;
 
     // #line and #include
     extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive]          = EBhDisable;
@@ -280,6 +284,7 @@ void TParseVersions::initializeExtensionBehavior()
     extensionBehavior[E_GL_NV_shader_subgroup_partitioned]           = EBhDisable;
     extensionBehavior[E_GL_NV_shading_rate_image]                    = EBhDisable;
     extensionBehavior[E_GL_NV_ray_tracing]                           = EBhDisable;
+    extensionBehavior[E_GL_NV_ray_tracing_motion_blur]               = EBhDisable;
     extensionBehavior[E_GL_NV_fragment_shader_barycentric]           = EBhDisable;
     extensionBehavior[E_GL_NV_compute_shader_derivatives]            = EBhDisable;
     extensionBehavior[E_GL_NV_shader_texture_footprint]              = EBhDisable;
@@ -305,6 +310,7 @@ void TParseVersions::initializeExtensionBehavior()
     extensionBehavior[E_GL_EXT_tessellation_point_size]              = EBhDisable;
     extensionBehavior[E_GL_EXT_texture_buffer]                       = EBhDisable;
     extensionBehavior[E_GL_EXT_texture_cube_map_array]               = EBhDisable;
+    extensionBehavior[E_GL_EXT_null_initializer]                     = EBhDisable;
 
     // OES matching AEP
     extensionBehavior[E_GL_OES_geometry_shader]          = EBhDisable;
@@ -330,6 +336,8 @@ void TParseVersions::initializeExtensionBehavior()
     extensionBehavior[E_GL_EXT_fragment_shading_rate]       = EBhDisable;
     extensionBehavior[E_GL_EXT_shader_image_int64]   = EBhDisable;
     extensionBehavior[E_GL_EXT_terminate_invocation]        = EBhDisable;
+    extensionBehavior[E_GL_EXT_shared_memory_block]         = EBhDisable;
+    extensionBehavior[E_GL_EXT_spirv_intrinsics]            = EBhDisable;
 
     // OVR extensions
     extensionBehavior[E_GL_OVR_multiview]                = EBhDisable;
@@ -351,6 +359,7 @@ void TParseVersions::initializeExtensionBehavior()
     extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int64]   = EBhDisable;
     extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_float16] = EBhDisable;
     extensionBehavior[E_GL_EXT_shader_atomic_float]                    = EBhDisable;
+    extensionBehavior[E_GL_EXT_shader_atomic_float2]                   = EBhDisable;
 }
 
 #endif // GLSLANG_WEB
@@ -408,9 +417,13 @@ void TParseVersions::getPreamble(std::string& preamble)
             "#define GL_EXT_shader_non_constant_global_initializers 1\n"
             ;
 
-            if (isEsProfile() && version >= 300) {
+            if (version >= 300) {
                 preamble += "#define GL_NV_shader_noperspective_interpolation 1\n";
             }
+            if (version >= 310) {
+                preamble += "#define GL_EXT_null_initializer 1\n";
+                preamble += "#define GL_EXT_subgroup_uniform_control_flow 1\n";
+            }
 
     } else { // !isEsProfile()
         preamble =
@@ -468,6 +481,7 @@ void TParseVersions::getPreamble(std::string& preamble)
             "#define GL_EXT_demote_to_helper_invocation 1\n"
             "#define GL_EXT_debug_printf 1\n"
             "#define GL_EXT_fragment_shading_rate 1\n"
+            "#define GL_EXT_shared_memory_block 1\n"
 
             // GL_KHR_shader_subgroup
             "#define GL_KHR_shader_subgroup_basic 1\n"
@@ -485,6 +499,7 @@ void TParseVersions::getPreamble(std::string& preamble)
             "#define GL_EXT_ray_tracing 1\n"
             "#define GL_EXT_ray_query 1\n"
             "#define GL_EXT_ray_flags_primitive_culling 1\n"
+            "#define GL_EXT_spirv_intrinsics 1\n"
 
             "#define GL_AMD_shader_ballot 1\n"
             "#define GL_AMD_shader_trinary_minmax 1\n"
@@ -507,6 +522,7 @@ void TParseVersions::getPreamble(std::string& preamble)
             "#define GL_NV_shader_subgroup_partitioned 1\n"
             "#define GL_NV_shading_rate_image 1\n"
             "#define GL_NV_ray_tracing 1\n"
+            "#define GL_NV_ray_tracing_motion_blur 1\n"
             "#define GL_NV_fragment_shader_barycentric 1\n"
             "#define GL_NV_compute_shader_derivatives 1\n"
             "#define GL_NV_shader_texture_footprint 1\n"
@@ -529,6 +545,7 @@ void TParseVersions::getPreamble(std::string& preamble)
             "#define GL_EXT_shader_subgroup_extended_types_float16 1\n"
 
             "#define GL_EXT_shader_atomic_float 1\n"
+            "#define GL_EXT_shader_atomic_float2 1\n"
             ;
 
         if (version >= 150) {
@@ -538,6 +555,10 @@ void TParseVersions::getPreamble(std::string& preamble)
             if (profile == ECompatibilityProfile)
                 preamble += "#define GL_compatibility_profile 1\n";
         }
+        if (version >= 140) {
+            preamble += "#define GL_EXT_null_initializer 1\n";
+            preamble += "#define GL_EXT_subgroup_uniform_control_flow 1\n";
+        }
 #endif // GLSLANG_WEB
     }
 
@@ -590,6 +611,29 @@ void TParseVersions::getPreamble(std::string& preamble)
         preamble += "\n";
     }
 #endif
+
+#ifndef GLSLANG_WEB
+    // GL_EXT_spirv_intrinsics
+    if (!isEsProfile()) {
+        switch (language) {
+        case EShLangVertex:         preamble += "#define GL_VERTEX_SHADER 1 \n";                    break;
+        case EShLangTessControl:    preamble += "#define GL_TESSELLATION_CONTROL_SHADER 1 \n";      break;
+        case EShLangTessEvaluation: preamble += "#define GL_TESSELLATION_EVALUATION_SHADER 1 \n";   break;
+        case EShLangGeometry:       preamble += "#define GL_GEOMETRY_SHADER 1 \n";                  break;
+        case EShLangFragment:       preamble += "#define GL_FRAGMENT_SHADER 1 \n";                  break;
+        case EShLangCompute:        preamble += "#define GL_COMPUTE_SHADER 1 \n";                   break;
+        case EShLangRayGen:         preamble += "#define GL_RAY_GENERATION_SHADER_EXT 1 \n";        break;
+        case EShLangIntersect:      preamble += "#define GL_INTERSECTION_SHADER_EXT 1 \n";          break;
+        case EShLangAnyHit:         preamble += "#define GL_ANY_HIT_SHADER_EXT 1 \n";               break;
+        case EShLangClosestHit:     preamble += "#define GL_CLOSEST_HIT_SHADER_EXT 1 \n";           break;
+        case EShLangMiss:           preamble += "#define GL_MISS_SHADER_EXT 1 \n";                  break;
+        case EShLangCallable:       preamble += "#define GL_CALLABLE_SHADER_EXT 1 \n";              break;
+        case EShLangTaskNV:         preamble += "#define GL_TASK_SHADER_NV 1 \n";                   break;
+        case EShLangMeshNV:         preamble += "#define GL_MESH_SHADER_NV 1 \n";                   break;
+        default:                                                                                    break;
+        }
+    }
+#endif
 }
 
 //
@@ -866,7 +910,7 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co
     checkExtensionStage(getCurrentLoc(), extension);
 
     // check if extension has additional requirements
-    extensionRequires(getCurrentLoc(), extension ,behaviorString);
+    extensionRequires(getCurrentLoc(), extension, behaviorString);
 
     // update the requested extension
     updateExtensionBehavior(extension, behavior);
@@ -1264,7 +1308,7 @@ void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op)
 // Call for any operation removed because Vulkan SPIR-V is being generated.
 void TParseVersions::vulkanRemoved(const TSourceLoc& loc, const char* op)
 {
-    if (spvVersion.vulkan > 0)
+    if (spvVersion.vulkan > 0 && !spvVersion.vulkanRelaxed)
         error(loc, "not allowed when using GLSL for Vulkan", op, "");
 }
 

+ 9 - 1
thirdparty/glslang/glslang/MachineIndependent/Versions.h

@@ -87,11 +87,12 @@ inline const char* ProfileName(EProfile profile)
 // The union of all requested rule sets will be applied.
 //
 struct SpvVersion {
-    SpvVersion() : spv(0), vulkanGlsl(0), vulkan(0), openGl(0) {}
+    SpvVersion() : spv(0), vulkanGlsl(0), vulkan(0), openGl(0), vulkanRelaxed(false) {}
     unsigned int spv; // the version of SPIR-V to target, as defined by "word 1" of the SPIR-V binary header
     int vulkanGlsl;   // the version of GLSL semantics for Vulkan, from GL_KHR_vulkan_glsl, for "#define VULKAN XXX"
     int vulkan;       // the version of Vulkan, for which SPIR-V execution environment rules to use
     int openGl;       // the version of GLSL semantics for OpenGL, from GL_ARB_gl_spirv, for "#define GL_SPIRV XXX"
+    bool vulkanRelaxed; // relax changes to GLSL for Vulkan, allowing some GL-specific to be compiled to Vulkan SPIR-V target
 };
 
 //
@@ -135,6 +136,7 @@ const char* const E_GL_ARB_explicit_attrib_location     = "GL_ARB_explicit_attri
 const char* const E_GL_ARB_explicit_uniform_location    = "GL_ARB_explicit_uniform_location";
 const char* const E_GL_ARB_shader_image_load_store      = "GL_ARB_shader_image_load_store";
 const char* const E_GL_ARB_shader_atomic_counters       = "GL_ARB_shader_atomic_counters";
+const char* const E_GL_ARB_shader_atomic_counter_ops    = "GL_ARB_shader_atomic_counter_ops";
 const char* const E_GL_ARB_shader_draw_parameters       = "GL_ARB_shader_draw_parameters";
 const char* const E_GL_ARB_shader_group_vote            = "GL_ARB_shader_group_vote";
 const char* const E_GL_ARB_derivative_control           = "GL_ARB_derivative_control";
@@ -201,6 +203,10 @@ const char* const E_GL_EXT_blend_func_extended              = "GL_EXT_blend_func
 const char* const E_GL_EXT_shader_implicit_conversions      = "GL_EXT_shader_implicit_conversions";
 const char* const E_GL_EXT_fragment_shading_rate            = "GL_EXT_fragment_shading_rate";
 const char* const E_GL_EXT_shader_image_int64               = "GL_EXT_shader_image_int64";
+const char* const E_GL_EXT_null_initializer                 = "GL_EXT_null_initializer";
+const char* const E_GL_EXT_shared_memory_block              = "GL_EXT_shared_memory_block";
+const char* const E_GL_EXT_subgroup_uniform_control_flow    = "GL_EXT_subgroup_uniform_control_flow";
+const char* const E_GL_EXT_spirv_intrinsics                 = "GL_EXT_spirv_intrinsics";
 
 // Arrays of extensions for the above viewportEXTs duplications
 
@@ -242,6 +248,7 @@ const char* const E_GL_NV_shader_noperspective_interpolation    = "GL_NV_shader_
 const char* const E_GL_NV_shader_subgroup_partitioned           = "GL_NV_shader_subgroup_partitioned";
 const char* const E_GL_NV_shading_rate_image                    = "GL_NV_shading_rate_image";
 const char* const E_GL_NV_ray_tracing                           = "GL_NV_ray_tracing";
+const char* const E_GL_NV_ray_tracing_motion_blur               = "GL_NV_ray_tracing_motion_blur";
 const char* const E_GL_NV_fragment_shader_barycentric           = "GL_NV_fragment_shader_barycentric";
 const char* const E_GL_NV_compute_shader_derivatives            = "GL_NV_compute_shader_derivatives";
 const char* const E_GL_NV_shader_texture_footprint              = "GL_NV_shader_texture_footprint";
@@ -302,6 +309,7 @@ const char* const E_GL_EXT_shader_subgroup_extended_types_float16 = "GL_EXT_shad
 const char* const E_GL_EXT_terminate_invocation = "GL_EXT_terminate_invocation";
 
 const char* const E_GL_EXT_shader_atomic_float = "GL_EXT_shader_atomic_float";
+const char* const E_GL_EXT_shader_atomic_float2 = "GL_EXT_shader_atomic_float2";
 
 // Arrays of extensions for the above AEP duplications
 

+ 25 - 0
thirdparty/glslang/glslang/MachineIndependent/attribute.cpp

@@ -123,6 +123,8 @@ TAttributeType TParseContext::attributeFromName(const TString& name) const
         return EatPeelCount;
     else if (name == "partial_count")
         return EatPartialCount;
+    else if (name == "subgroup_uniform_control_flow")
+        return EatSubgroupUniformControlFlow;
     else
         return EatNone;
 }
@@ -341,6 +343,29 @@ void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermN
     }
 }
 
+
+//
+// Function attributes
+//
+void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttributes& attributes, TFunction* function)
+{
+    for (auto it = attributes.begin(); it != attributes.end(); ++it) {
+        if (it->size() > 0) {
+            warn(loc, "attribute with arguments not recognized, skipping", "", "");
+            continue;
+        }
+
+        switch (it->name) {
+        case EatSubgroupUniformControlFlow:
+            intermediate.setSubgroupUniformControlFlow();
+            break;
+        default:
+            warn(loc, "attribute does not apply to a function", "", "");
+            break;
+        }
+    }
+}
+
 } // end namespace glslang
 
 #endif // GLSLANG_WEB

+ 2 - 1
thirdparty/glslang/glslang/MachineIndependent/attribute.h

@@ -118,7 +118,8 @@ namespace glslang {
         EatFormatR8ui,
         EatFormatUnknown,
         EatNonWritable,
-        EatNonReadable
+        EatNonReadable,
+        EatSubgroupUniformControlFlow,
     };
 
     class TIntermAggregate;

+ 3 - 3
thirdparty/glslang/glslang/MachineIndependent/gl_types.h

@@ -49,9 +49,9 @@
 #define GL_INT64_VEC4_ARB                 0x8FEB
 
 #define GL_UNSIGNED_INT64_ARB             0x140F
-#define GL_UNSIGNED_INT64_VEC2_ARB        0x8FE5
-#define GL_UNSIGNED_INT64_VEC3_ARB        0x8FE6
-#define GL_UNSIGNED_INT64_VEC4_ARB        0x8FE7
+#define GL_UNSIGNED_INT64_VEC2_ARB        0x8FF5
+#define GL_UNSIGNED_INT64_VEC3_ARB        0x8FF6
+#define GL_UNSIGNED_INT64_VEC4_ARB        0x8FF7
 #define GL_UNSIGNED_INT16_VEC2_NV         0x8FF1
 #define GL_UNSIGNED_INT16_VEC3_NV         0x8FF2
 #define GL_UNSIGNED_INT16_VEC4_NV         0x8FF3

+ 355 - 1
thirdparty/glslang/glslang/MachineIndependent/glslang.y

@@ -116,6 +116,9 @@ using namespace glslang;
             glslang::TIntermNodePair nodePair;
             glslang::TIntermTyped* intermTypedNode;
             glslang::TAttributes* attributes;
+            glslang::TSpirvRequirement* spirvReq;
+            glslang::TSpirvInstruction* spirvInst;
+            glslang::TSpirvTypeParameters* spirvTypeParams;
         };
         union {
             glslang::TPublicType type;
@@ -271,6 +274,11 @@ extern int yylex(YYSTYPE*, TParseContext&);
 %token <lex> SUBPASSINPUT SUBPASSINPUTMS ISUBPASSINPUT ISUBPASSINPUTMS USUBPASSINPUT USUBPASSINPUTMS
 %token <lex> F16SUBPASSINPUT F16SUBPASSINPUTMS
 
+// spirv intrinsics
+%token <lex> SPIRV_INSTRUCTION SPIRV_EXECUTION_MODE SPIRV_EXECUTION_MODE_ID
+%token <lex> SPIRV_DECORATE SPIRV_DECORATE_ID SPIRV_DECORATE_STRING
+%token <lex> SPIRV_TYPE SPIRV_STORAGE_CLASS SPIRV_BY_REFERENCE SPIRV_LITERAL
+
 
 
 %token <lex> LEFT_OP RIGHT_OP
@@ -362,6 +370,19 @@ extern int yylex(YYSTYPE*, TParseContext&);
 %type <interm.attributes> attribute attribute_list single_attribute
 %type <interm.intermNode> demote_statement
 %type <interm.intermTypedNode> initializer_list
+%type <interm.spirvReq> spirv_requirements_list spirv_requirements_parameter
+%type <interm.intermNode> spirv_extension_list spirv_capability_list
+%type <interm.intermNode> spirv_execution_mode_qualifier
+%type <interm.intermNode> spirv_execution_mode_parameter_list spirv_execution_mode_parameter spirv_execution_mode_id_parameter_list
+%type <interm.type> spirv_storage_class_qualifier
+%type <interm.type> spirv_decorate_qualifier
+%type <interm.intermNode> spirv_decorate_parameter_list spirv_decorate_parameter
+%type <interm.intermNode> spirv_decorate_id_parameter_list
+%type <interm.intermNode> spirv_decorate_string_parameter_list
+%type <interm.type> spirv_type_specifier
+%type <interm.spirvTypeParams> spirv_type_parameter_list spirv_type_parameter
+%type <interm.spirvInst> spirv_instruction_qualifier
+%type <interm.spirvInst> spirv_instruction_qualifier_list spirv_instruction_qualifier_id
 
 
 %start translation_unit
@@ -875,6 +896,20 @@ declaration
         $$ = 0;
         // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature
     }
+
+    | spirv_instruction_qualifier function_prototype SEMICOLON {
+        parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V instruction qualifier");
+        $2.function->setSpirvInstruction(*$1); // Attach SPIR-V intruction qualifier
+        parseContext.handleFunctionDeclarator($2.loc, *$2.function, true /* prototype */);
+        $$ = 0;
+        // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature
+    }
+    | spirv_execution_mode_qualifier SEMICOLON {
+        parseContext.globalCheck($2.loc, "SPIR-V execution mode qualifier");
+        parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V execution mode qualifier");
+        $$ = 0;
+    }
+
     | init_declarator_list SEMICOLON {
         if ($1.intermNode && $1.intermNode->getAsAggregate())
             $1.intermNode->getAsAggregate()->setOperator(EOpSequence);
@@ -944,6 +979,25 @@ function_prototype
         $$.function = $1;
         $$.loc = $2.loc;
     }
+    | function_declarator RIGHT_PAREN attribute {
+        $$.function = $1;
+        $$.loc = $2.loc;
+        parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
+        parseContext.handleFunctionAttributes($2.loc, *$3, $$.function);
+    }
+    | attribute function_declarator RIGHT_PAREN {
+        $$.function = $2;
+        $$.loc = $3.loc;
+        parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
+        parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
+    }
+    | attribute function_declarator RIGHT_PAREN attribute {
+        $$.function = $2;
+        $$.loc = $3.loc;
+        parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
+        parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
+        parseContext.handleFunctionAttributes($3.loc, *$4, $$.function);
+    }
     ;
 
 function_declarator
@@ -1347,6 +1401,25 @@ single_type_qualifier
     | non_uniform_qualifier {
         $$ = $1;
     }
+    | spirv_storage_class_qualifier {
+        parseContext.globalCheck($1.loc, "spirv_storage_class");
+        parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V storage class qualifier");
+        $$ = $1;
+    }
+    | spirv_decorate_qualifier {
+        parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V decorate qualifier");
+        $$ = $1;
+    }
+    | SPIRV_BY_REFERENCE {
+        parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_reference");
+        $$.init($1.loc);
+        $$.qualifier.setSpirvByReference();
+    }
+    | SPIRV_LITERAL {
+        parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_literal");
+        $$.init($1.loc);
+        $$.qualifier.setSpirvLiteral();
+    }
 
     ;
 
@@ -3407,6 +3480,10 @@ type_specifier_nonarray
         $$.basicType = EbtUint;
         $$.coopmat = true;
     }
+    | spirv_type_specifier {
+        parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V type specifier");
+        $$ = $1;
+    }
 
     | struct_specifier {
         $$ = $1;
@@ -3575,6 +3652,12 @@ initializer
         parseContext.profileRequires($1.loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature);
         $$ = $2;
     }
+    | LEFT_BRACE RIGHT_BRACE {
+        const char* initFeature = "empty { } initializer";
+        parseContext.profileRequires($1.loc, EEsProfile, 0, E_GL_EXT_null_initializer, initFeature);
+        parseContext.profileRequires($1.loc, ~EEsProfile, 0, E_GL_EXT_null_initializer, initFeature);
+        $$ = parseContext.intermediate.makeAggregate($1.loc);
+    }
 
     ;
 
@@ -3707,6 +3790,7 @@ selection_statement
     }
 
     | attribute selection_statement_nonattributed {
+        parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
         parseContext.handleSelectionAttributes(*$1, $2);
         $$ = $2;
     }
@@ -3754,6 +3838,7 @@ switch_statement
     }
 
     | attribute switch_statement_nonattributed {
+        parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
         parseContext.handleSwitchAttributes(*$1, $2);
         $$ = $2;
     }
@@ -3818,6 +3903,7 @@ iteration_statement
     }
 
     | attribute iteration_statement_nonattributed {
+        parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
         parseContext.handleLoopAttributes(*$1, $2);
         $$ = $2;
     }
@@ -4021,7 +4107,6 @@ function_definition
 attribute
     : LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET {
         $$ = $3;
-        parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_control_flow_attributes, "attribute");
     }
 
 attribute_list
@@ -4041,4 +4126,273 @@ single_attribute
     }
 
 
+
+spirv_requirements_list
+    : spirv_requirements_parameter {
+        $$ = $1;
+    }
+    | spirv_requirements_list COMMA spirv_requirements_parameter {
+        $$ = parseContext.mergeSpirvRequirements($2.loc, $1, $3);
+    }
+
+spirv_requirements_parameter
+    : IDENTIFIER EQUAL LEFT_BRACKET spirv_extension_list RIGHT_BRACKET {
+        $$ = parseContext.makeSpirvRequirement($2.loc, *$1.string, $4->getAsAggregate(), nullptr);
+    }
+    | IDENTIFIER EQUAL LEFT_BRACKET spirv_capability_list RIGHT_BRACKET {
+        $$ = parseContext.makeSpirvRequirement($2.loc, *$1.string, nullptr, $4->getAsAggregate());
+    }
+
+spirv_extension_list
+    : STRING_LITERAL {
+        $$ = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion($1.string, $1.loc, true));
+    }
+    | spirv_extension_list COMMA STRING_LITERAL {
+        $$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.string, $3.loc, true));
+    }
+
+spirv_capability_list
+    : INTCONSTANT {
+        $$ = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion($1.i, $1.loc, true));
+    }
+    | spirv_capability_list COMMA INTCONSTANT {
+        $$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.i, $3.loc, true));
+    }
+
+spirv_execution_mode_qualifier
+    : SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT RIGHT_PAREN {
+        parseContext.intermediate.insertSpirvExecutionMode($3.i);
+        $$ = 0;
+    }
+    | SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN {
+        parseContext.intermediate.insertSpirvRequirement($3);
+        parseContext.intermediate.insertSpirvExecutionMode($5.i);
+        $$ = 0;
+    }
+    | SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN {
+        parseContext.intermediate.insertSpirvExecutionMode($3.i, $5->getAsAggregate());
+        $$ = 0;
+    }
+    | SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN {
+        parseContext.intermediate.insertSpirvRequirement($3);
+        parseContext.intermediate.insertSpirvExecutionMode($5.i, $7->getAsAggregate());
+        $$ = 0;
+    }
+    | SPIRV_EXECUTION_MODE_ID LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN {
+        parseContext.intermediate.insertSpirvExecutionModeId($3.i, $5->getAsAggregate());
+        $$ = 0;
+    }
+    | SPIRV_EXECUTION_MODE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN {
+        parseContext.intermediate.insertSpirvRequirement($3);
+        parseContext.intermediate.insertSpirvExecutionModeId($5.i, $7->getAsAggregate());
+        $$ = 0;
+    }
+
+spirv_execution_mode_parameter_list
+    : spirv_execution_mode_parameter {
+        $$ = parseContext.intermediate.makeAggregate($1);
+    }
+    | spirv_execution_mode_parameter_list COMMA spirv_execution_mode_parameter {
+        $$ = parseContext.intermediate.growAggregate($1, $3);
+    }
+
+spirv_execution_mode_parameter
+    : FLOATCONSTANT {
+        $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true);
+    }
+    | INTCONSTANT {
+        $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true);
+    }
+    | UINTCONSTANT {
+        $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true);
+    }
+    | BOOLCONSTANT {
+        $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
+    }
+    | STRING_LITERAL {
+        $$ = parseContext.intermediate.addConstantUnion($1.string, $1.loc, true);
+    }
+
+spirv_execution_mode_id_parameter_list
+    : constant_expression {
+        if ($1->getBasicType() != EbtFloat &&
+            $1->getBasicType() != EbtInt &&
+            $1->getBasicType() != EbtUint &&
+            $1->getBasicType() != EbtBool &&
+            $1->getBasicType() != EbtString)
+            parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), "");
+        $$ = parseContext.intermediate.makeAggregate($1);
+    }
+    | spirv_execution_mode_id_parameter_list COMMA constant_expression {
+        if ($3->getBasicType() != EbtFloat &&
+            $3->getBasicType() != EbtInt &&
+            $3->getBasicType() != EbtUint &&
+            $3->getBasicType() != EbtBool &&
+            $3->getBasicType() != EbtString)
+            parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), "");
+        $$ = parseContext.intermediate.growAggregate($1, $3);
+    }
+
+spirv_storage_class_qualifier
+    : SPIRV_STORAGE_CLASS LEFT_PAREN INTCONSTANT RIGHT_PAREN {
+        $$.init($1.loc);
+        $$.qualifier.storage = EvqSpirvStorageClass;
+        $$.qualifier.spirvStorageClass = $3.i;
+    }
+    | SPIRV_STORAGE_CLASS LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN {
+        $$.init($1.loc);
+        parseContext.intermediate.insertSpirvRequirement($3);
+        $$.qualifier.storage = EvqSpirvStorageClass;
+        $$.qualifier.spirvStorageClass = $5.i;
+    }
+
+spirv_decorate_qualifier
+    : SPIRV_DECORATE LEFT_PAREN INTCONSTANT RIGHT_PAREN{
+        $$.init($1.loc);
+        $$.qualifier.setSpirvDecorate($3.i);
+    }
+    | SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN{
+        $$.init($1.loc);
+        parseContext.intermediate.insertSpirvRequirement($3);
+        $$.qualifier.setSpirvDecorate($5.i);
+    }
+    | SPIRV_DECORATE LEFT_PAREN INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN {
+        $$.init($1.loc);
+        $$.qualifier.setSpirvDecorate($3.i, $5->getAsAggregate());
+    }
+    | SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN {
+        $$.init($1.loc);
+        parseContext.intermediate.insertSpirvRequirement($3);
+        $$.qualifier.setSpirvDecorate($5.i, $7->getAsAggregate());
+    }
+    | SPIRV_DECORATE_ID LEFT_PAREN INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN {
+        $$.init($1.loc);
+        $$.qualifier.setSpirvDecorateId($3.i, $5->getAsAggregate());
+    }
+    | SPIRV_DECORATE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN {
+        $$.init($1.loc);
+        parseContext.intermediate.insertSpirvRequirement($3);
+        $$.qualifier.setSpirvDecorateId($5.i, $7->getAsAggregate());
+    }
+    | SPIRV_DECORATE_STRING LEFT_PAREN INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN {
+        $$.init($1.loc);
+        $$.qualifier.setSpirvDecorateString($3.i, $5->getAsAggregate());
+    }
+    | SPIRV_DECORATE_STRING LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN {
+        $$.init($1.loc);
+        parseContext.intermediate.insertSpirvRequirement($3);
+        $$.qualifier.setSpirvDecorateString($5.i, $7->getAsAggregate());
+    }
+
+spirv_decorate_parameter_list
+    : spirv_decorate_parameter {
+        $$ = parseContext.intermediate.makeAggregate($1);
+    }
+    | spirv_decorate_parameter_list COMMA spirv_decorate_parameter {
+        $$ = parseContext.intermediate.growAggregate($1, $3);
+    }
+
+spirv_decorate_parameter
+    : FLOATCONSTANT {
+        $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true);
+    }
+    | INTCONSTANT {
+        $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true);
+    }
+    | UINTCONSTANT {
+        $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true);
+    }
+    | BOOLCONSTANT {
+        $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
+    }
+
+spirv_decorate_id_parameter_list
+    : constant_expression {
+        if ($1->getBasicType() != EbtFloat &&
+            $1->getBasicType() != EbtInt &&
+            $1->getBasicType() != EbtUint &&
+            $1->getBasicType() != EbtBool)
+            parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), "");
+        $$ = parseContext.intermediate.makeAggregate($1);
+    }
+    | spirv_decorate_id_parameter_list COMMA constant_expression {
+        if ($3->getBasicType() != EbtFloat &&
+            $3->getBasicType() != EbtInt &&
+            $3->getBasicType() != EbtUint &&
+            $3->getBasicType() != EbtBool)
+            parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), "");
+        $$ = parseContext.intermediate.growAggregate($1, $3);
+    }
+
+spirv_decorate_string_parameter_list
+    : STRING_LITERAL {
+        $$ = parseContext.intermediate.makeAggregate(
+            parseContext.intermediate.addConstantUnion($1.string, $1.loc, true));
+    }
+    | spirv_decorate_string_parameter_list COMMA STRING_LITERAL {
+        $$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.string, $3.loc, true));
+    }
+
+spirv_type_specifier
+    : SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN {
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
+        $$.setSpirvType(*$3, $5);
+    }
+    | SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN {
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
+        parseContext.intermediate.insertSpirvRequirement($3);
+        $$.setSpirvType(*$5, $7);
+    }
+    | SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
+        $$.setSpirvType(*$3);
+    }
+    | SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN {
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
+        parseContext.intermediate.insertSpirvRequirement($3);
+        $$.setSpirvType(*$5);
+    }
+
+spirv_type_parameter_list
+    : spirv_type_parameter {
+        $$ = $1;
+    }
+    | spirv_type_parameter_list COMMA spirv_type_parameter {
+        $$ = parseContext.mergeSpirvTypeParameters($1, $3);
+    }
+
+spirv_type_parameter
+    : constant_expression {
+        $$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1->getAsConstantUnion());
+    }
+    | type_specifier {
+        $$ = parseContext.makeSpirvTypeParameters($1);
+    }
+
+spirv_instruction_qualifier
+    : SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {
+        $$ = $3;
+    }
+    | SPIRV_INSTRUCTION LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN {
+        parseContext.intermediate.insertSpirvRequirement($3);
+        $$ = $5;
+    }
+
+spirv_instruction_qualifier_list
+    : spirv_instruction_qualifier_id {
+        $$ = $1;
+    }
+    | spirv_instruction_qualifier_list COMMA spirv_instruction_qualifier_id {
+        $$ = parseContext.mergeSpirvInstruction($2.loc, $1, $3);
+    }
+
+spirv_instruction_qualifier_id
+    : IDENTIFIER EQUAL STRING_LITERAL {
+        $$ = parseContext.makeSpirvInstruction($2.loc, *$1.string, *$3.string);
+    }
+    | IDENTIFIER EQUAL INTCONSTANT {
+        $$ = parseContext.makeSpirvInstruction($2.loc, *$1.string, $3.i);
+    }
+
+
 %%

File diff suppressed because it is too large
+ 592 - 503
thirdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp


+ 142 - 129
thirdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp.h

@@ -368,134 +368,144 @@ extern int yydebug;
     USUBPASSINPUTMS = 569,         /* USUBPASSINPUTMS  */
     F16SUBPASSINPUT = 570,         /* F16SUBPASSINPUT  */
     F16SUBPASSINPUTMS = 571,       /* F16SUBPASSINPUTMS  */
-    LEFT_OP = 572,                 /* LEFT_OP  */
-    RIGHT_OP = 573,                /* RIGHT_OP  */
-    INC_OP = 574,                  /* INC_OP  */
-    DEC_OP = 575,                  /* DEC_OP  */
-    LE_OP = 576,                   /* LE_OP  */
-    GE_OP = 577,                   /* GE_OP  */
-    EQ_OP = 578,                   /* EQ_OP  */
-    NE_OP = 579,                   /* NE_OP  */
-    AND_OP = 580,                  /* AND_OP  */
-    OR_OP = 581,                   /* OR_OP  */
-    XOR_OP = 582,                  /* XOR_OP  */
-    MUL_ASSIGN = 583,              /* MUL_ASSIGN  */
-    DIV_ASSIGN = 584,              /* DIV_ASSIGN  */
-    ADD_ASSIGN = 585,              /* ADD_ASSIGN  */
-    MOD_ASSIGN = 586,              /* MOD_ASSIGN  */
-    LEFT_ASSIGN = 587,             /* LEFT_ASSIGN  */
-    RIGHT_ASSIGN = 588,            /* RIGHT_ASSIGN  */
-    AND_ASSIGN = 589,              /* AND_ASSIGN  */
-    XOR_ASSIGN = 590,              /* XOR_ASSIGN  */
-    OR_ASSIGN = 591,               /* OR_ASSIGN  */
-    SUB_ASSIGN = 592,              /* SUB_ASSIGN  */
-    STRING_LITERAL = 593,          /* STRING_LITERAL  */
-    LEFT_PAREN = 594,              /* LEFT_PAREN  */
-    RIGHT_PAREN = 595,             /* RIGHT_PAREN  */
-    LEFT_BRACKET = 596,            /* LEFT_BRACKET  */
-    RIGHT_BRACKET = 597,           /* RIGHT_BRACKET  */
-    LEFT_BRACE = 598,              /* LEFT_BRACE  */
-    RIGHT_BRACE = 599,             /* RIGHT_BRACE  */
-    DOT = 600,                     /* DOT  */
-    COMMA = 601,                   /* COMMA  */
-    COLON = 602,                   /* COLON  */
-    EQUAL = 603,                   /* EQUAL  */
-    SEMICOLON = 604,               /* SEMICOLON  */
-    BANG = 605,                    /* BANG  */
-    DASH = 606,                    /* DASH  */
-    TILDE = 607,                   /* TILDE  */
-    PLUS = 608,                    /* PLUS  */
-    STAR = 609,                    /* STAR  */
-    SLASH = 610,                   /* SLASH  */
-    PERCENT = 611,                 /* PERCENT  */
-    LEFT_ANGLE = 612,              /* LEFT_ANGLE  */
-    RIGHT_ANGLE = 613,             /* RIGHT_ANGLE  */
-    VERTICAL_BAR = 614,            /* VERTICAL_BAR  */
-    CARET = 615,                   /* CARET  */
-    AMPERSAND = 616,               /* AMPERSAND  */
-    QUESTION = 617,                /* QUESTION  */
-    INVARIANT = 618,               /* INVARIANT  */
-    HIGH_PRECISION = 619,          /* HIGH_PRECISION  */
-    MEDIUM_PRECISION = 620,        /* MEDIUM_PRECISION  */
-    LOW_PRECISION = 621,           /* LOW_PRECISION  */
-    PRECISION = 622,               /* PRECISION  */
-    PACKED = 623,                  /* PACKED  */
-    RESOURCE = 624,                /* RESOURCE  */
-    SUPERP = 625,                  /* SUPERP  */
-    FLOATCONSTANT = 626,           /* FLOATCONSTANT  */
-    INTCONSTANT = 627,             /* INTCONSTANT  */
-    UINTCONSTANT = 628,            /* UINTCONSTANT  */
-    BOOLCONSTANT = 629,            /* BOOLCONSTANT  */
-    IDENTIFIER = 630,              /* IDENTIFIER  */
-    TYPE_NAME = 631,               /* TYPE_NAME  */
-    CENTROID = 632,                /* CENTROID  */
-    IN = 633,                      /* IN  */
-    OUT = 634,                     /* OUT  */
-    INOUT = 635,                   /* INOUT  */
-    STRUCT = 636,                  /* STRUCT  */
-    VOID = 637,                    /* VOID  */
-    WHILE = 638,                   /* WHILE  */
-    BREAK = 639,                   /* BREAK  */
-    CONTINUE = 640,                /* CONTINUE  */
-    DO = 641,                      /* DO  */
-    ELSE = 642,                    /* ELSE  */
-    FOR = 643,                     /* FOR  */
-    IF = 644,                      /* IF  */
-    DISCARD = 645,                 /* DISCARD  */
-    RETURN = 646,                  /* RETURN  */
-    SWITCH = 647,                  /* SWITCH  */
-    CASE = 648,                    /* CASE  */
-    DEFAULT = 649,                 /* DEFAULT  */
-    TERMINATE_INVOCATION = 650,    /* TERMINATE_INVOCATION  */
-    TERMINATE_RAY = 651,           /* TERMINATE_RAY  */
-    IGNORE_INTERSECTION = 652,     /* IGNORE_INTERSECTION  */
-    UNIFORM = 653,                 /* UNIFORM  */
-    SHARED = 654,                  /* SHARED  */
-    BUFFER = 655,                  /* BUFFER  */
-    FLAT = 656,                    /* FLAT  */
-    SMOOTH = 657,                  /* SMOOTH  */
-    LAYOUT = 658,                  /* LAYOUT  */
-    DOUBLECONSTANT = 659,          /* DOUBLECONSTANT  */
-    INT16CONSTANT = 660,           /* INT16CONSTANT  */
-    UINT16CONSTANT = 661,          /* UINT16CONSTANT  */
-    FLOAT16CONSTANT = 662,         /* FLOAT16CONSTANT  */
-    INT32CONSTANT = 663,           /* INT32CONSTANT  */
-    UINT32CONSTANT = 664,          /* UINT32CONSTANT  */
-    INT64CONSTANT = 665,           /* INT64CONSTANT  */
-    UINT64CONSTANT = 666,          /* UINT64CONSTANT  */
-    SUBROUTINE = 667,              /* SUBROUTINE  */
-    DEMOTE = 668,                  /* DEMOTE  */
-    PAYLOADNV = 669,               /* PAYLOADNV  */
-    PAYLOADINNV = 670,             /* PAYLOADINNV  */
-    HITATTRNV = 671,               /* HITATTRNV  */
-    CALLDATANV = 672,              /* CALLDATANV  */
-    CALLDATAINNV = 673,            /* CALLDATAINNV  */
-    PAYLOADEXT = 674,              /* PAYLOADEXT  */
-    PAYLOADINEXT = 675,            /* PAYLOADINEXT  */
-    HITATTREXT = 676,              /* HITATTREXT  */
-    CALLDATAEXT = 677,             /* CALLDATAEXT  */
-    CALLDATAINEXT = 678,           /* CALLDATAINEXT  */
-    PATCH = 679,                   /* PATCH  */
-    SAMPLE = 680,                  /* SAMPLE  */
-    NONUNIFORM = 681,              /* NONUNIFORM  */
-    COHERENT = 682,                /* COHERENT  */
-    VOLATILE = 683,                /* VOLATILE  */
-    RESTRICT = 684,                /* RESTRICT  */
-    READONLY = 685,                /* READONLY  */
-    WRITEONLY = 686,               /* WRITEONLY  */
-    DEVICECOHERENT = 687,          /* DEVICECOHERENT  */
-    QUEUEFAMILYCOHERENT = 688,     /* QUEUEFAMILYCOHERENT  */
-    WORKGROUPCOHERENT = 689,       /* WORKGROUPCOHERENT  */
-    SUBGROUPCOHERENT = 690,        /* SUBGROUPCOHERENT  */
-    NONPRIVATE = 691,              /* NONPRIVATE  */
-    SHADERCALLCOHERENT = 692,      /* SHADERCALLCOHERENT  */
-    NOPERSPECTIVE = 693,           /* NOPERSPECTIVE  */
-    EXPLICITINTERPAMD = 694,       /* EXPLICITINTERPAMD  */
-    PERVERTEXNV = 695,             /* PERVERTEXNV  */
-    PERPRIMITIVENV = 696,          /* PERPRIMITIVENV  */
-    PERVIEWNV = 697,               /* PERVIEWNV  */
-    PERTASKNV = 698,               /* PERTASKNV  */
-    PRECISE = 699                  /* PRECISE  */
+    SPIRV_INSTRUCTION = 572,       /* SPIRV_INSTRUCTION  */
+    SPIRV_EXECUTION_MODE = 573,    /* SPIRV_EXECUTION_MODE  */
+    SPIRV_EXECUTION_MODE_ID = 574, /* SPIRV_EXECUTION_MODE_ID  */
+    SPIRV_DECORATE = 575,          /* SPIRV_DECORATE  */
+    SPIRV_DECORATE_ID = 576,       /* SPIRV_DECORATE_ID  */
+    SPIRV_DECORATE_STRING = 577,   /* SPIRV_DECORATE_STRING  */
+    SPIRV_TYPE = 578,              /* SPIRV_TYPE  */
+    SPIRV_STORAGE_CLASS = 579,     /* SPIRV_STORAGE_CLASS  */
+    SPIRV_BY_REFERENCE = 580,      /* SPIRV_BY_REFERENCE  */
+    SPIRV_LITERAL = 581,           /* SPIRV_LITERAL  */
+    LEFT_OP = 582,                 /* LEFT_OP  */
+    RIGHT_OP = 583,                /* RIGHT_OP  */
+    INC_OP = 584,                  /* INC_OP  */
+    DEC_OP = 585,                  /* DEC_OP  */
+    LE_OP = 586,                   /* LE_OP  */
+    GE_OP = 587,                   /* GE_OP  */
+    EQ_OP = 588,                   /* EQ_OP  */
+    NE_OP = 589,                   /* NE_OP  */
+    AND_OP = 590,                  /* AND_OP  */
+    OR_OP = 591,                   /* OR_OP  */
+    XOR_OP = 592,                  /* XOR_OP  */
+    MUL_ASSIGN = 593,              /* MUL_ASSIGN  */
+    DIV_ASSIGN = 594,              /* DIV_ASSIGN  */
+    ADD_ASSIGN = 595,              /* ADD_ASSIGN  */
+    MOD_ASSIGN = 596,              /* MOD_ASSIGN  */
+    LEFT_ASSIGN = 597,             /* LEFT_ASSIGN  */
+    RIGHT_ASSIGN = 598,            /* RIGHT_ASSIGN  */
+    AND_ASSIGN = 599,              /* AND_ASSIGN  */
+    XOR_ASSIGN = 600,              /* XOR_ASSIGN  */
+    OR_ASSIGN = 601,               /* OR_ASSIGN  */
+    SUB_ASSIGN = 602,              /* SUB_ASSIGN  */
+    STRING_LITERAL = 603,          /* STRING_LITERAL  */
+    LEFT_PAREN = 604,              /* LEFT_PAREN  */
+    RIGHT_PAREN = 605,             /* RIGHT_PAREN  */
+    LEFT_BRACKET = 606,            /* LEFT_BRACKET  */
+    RIGHT_BRACKET = 607,           /* RIGHT_BRACKET  */
+    LEFT_BRACE = 608,              /* LEFT_BRACE  */
+    RIGHT_BRACE = 609,             /* RIGHT_BRACE  */
+    DOT = 610,                     /* DOT  */
+    COMMA = 611,                   /* COMMA  */
+    COLON = 612,                   /* COLON  */
+    EQUAL = 613,                   /* EQUAL  */
+    SEMICOLON = 614,               /* SEMICOLON  */
+    BANG = 615,                    /* BANG  */
+    DASH = 616,                    /* DASH  */
+    TILDE = 617,                   /* TILDE  */
+    PLUS = 618,                    /* PLUS  */
+    STAR = 619,                    /* STAR  */
+    SLASH = 620,                   /* SLASH  */
+    PERCENT = 621,                 /* PERCENT  */
+    LEFT_ANGLE = 622,              /* LEFT_ANGLE  */
+    RIGHT_ANGLE = 623,             /* RIGHT_ANGLE  */
+    VERTICAL_BAR = 624,            /* VERTICAL_BAR  */
+    CARET = 625,                   /* CARET  */
+    AMPERSAND = 626,               /* AMPERSAND  */
+    QUESTION = 627,                /* QUESTION  */
+    INVARIANT = 628,               /* INVARIANT  */
+    HIGH_PRECISION = 629,          /* HIGH_PRECISION  */
+    MEDIUM_PRECISION = 630,        /* MEDIUM_PRECISION  */
+    LOW_PRECISION = 631,           /* LOW_PRECISION  */
+    PRECISION = 632,               /* PRECISION  */
+    PACKED = 633,                  /* PACKED  */
+    RESOURCE = 634,                /* RESOURCE  */
+    SUPERP = 635,                  /* SUPERP  */
+    FLOATCONSTANT = 636,           /* FLOATCONSTANT  */
+    INTCONSTANT = 637,             /* INTCONSTANT  */
+    UINTCONSTANT = 638,            /* UINTCONSTANT  */
+    BOOLCONSTANT = 639,            /* BOOLCONSTANT  */
+    IDENTIFIER = 640,              /* IDENTIFIER  */
+    TYPE_NAME = 641,               /* TYPE_NAME  */
+    CENTROID = 642,                /* CENTROID  */
+    IN = 643,                      /* IN  */
+    OUT = 644,                     /* OUT  */
+    INOUT = 645,                   /* INOUT  */
+    STRUCT = 646,                  /* STRUCT  */
+    VOID = 647,                    /* VOID  */
+    WHILE = 648,                   /* WHILE  */
+    BREAK = 649,                   /* BREAK  */
+    CONTINUE = 650,                /* CONTINUE  */
+    DO = 651,                      /* DO  */
+    ELSE = 652,                    /* ELSE  */
+    FOR = 653,                     /* FOR  */
+    IF = 654,                      /* IF  */
+    DISCARD = 655,                 /* DISCARD  */
+    RETURN = 656,                  /* RETURN  */
+    SWITCH = 657,                  /* SWITCH  */
+    CASE = 658,                    /* CASE  */
+    DEFAULT = 659,                 /* DEFAULT  */
+    TERMINATE_INVOCATION = 660,    /* TERMINATE_INVOCATION  */
+    TERMINATE_RAY = 661,           /* TERMINATE_RAY  */
+    IGNORE_INTERSECTION = 662,     /* IGNORE_INTERSECTION  */
+    UNIFORM = 663,                 /* UNIFORM  */
+    SHARED = 664,                  /* SHARED  */
+    BUFFER = 665,                  /* BUFFER  */
+    FLAT = 666,                    /* FLAT  */
+    SMOOTH = 667,                  /* SMOOTH  */
+    LAYOUT = 668,                  /* LAYOUT  */
+    DOUBLECONSTANT = 669,          /* DOUBLECONSTANT  */
+    INT16CONSTANT = 670,           /* INT16CONSTANT  */
+    UINT16CONSTANT = 671,          /* UINT16CONSTANT  */
+    FLOAT16CONSTANT = 672,         /* FLOAT16CONSTANT  */
+    INT32CONSTANT = 673,           /* INT32CONSTANT  */
+    UINT32CONSTANT = 674,          /* UINT32CONSTANT  */
+    INT64CONSTANT = 675,           /* INT64CONSTANT  */
+    UINT64CONSTANT = 676,          /* UINT64CONSTANT  */
+    SUBROUTINE = 677,              /* SUBROUTINE  */
+    DEMOTE = 678,                  /* DEMOTE  */
+    PAYLOADNV = 679,               /* PAYLOADNV  */
+    PAYLOADINNV = 680,             /* PAYLOADINNV  */
+    HITATTRNV = 681,               /* HITATTRNV  */
+    CALLDATANV = 682,              /* CALLDATANV  */
+    CALLDATAINNV = 683,            /* CALLDATAINNV  */
+    PAYLOADEXT = 684,              /* PAYLOADEXT  */
+    PAYLOADINEXT = 685,            /* PAYLOADINEXT  */
+    HITATTREXT = 686,              /* HITATTREXT  */
+    CALLDATAEXT = 687,             /* CALLDATAEXT  */
+    CALLDATAINEXT = 688,           /* CALLDATAINEXT  */
+    PATCH = 689,                   /* PATCH  */
+    SAMPLE = 690,                  /* SAMPLE  */
+    NONUNIFORM = 691,              /* NONUNIFORM  */
+    COHERENT = 692,                /* COHERENT  */
+    VOLATILE = 693,                /* VOLATILE  */
+    RESTRICT = 694,                /* RESTRICT  */
+    READONLY = 695,                /* READONLY  */
+    WRITEONLY = 696,               /* WRITEONLY  */
+    DEVICECOHERENT = 697,          /* DEVICECOHERENT  */
+    QUEUEFAMILYCOHERENT = 698,     /* QUEUEFAMILYCOHERENT  */
+    WORKGROUPCOHERENT = 699,       /* WORKGROUPCOHERENT  */
+    SUBGROUPCOHERENT = 700,        /* SUBGROUPCOHERENT  */
+    NONPRIVATE = 701,              /* NONPRIVATE  */
+    SHADERCALLCOHERENT = 702,      /* SHADERCALLCOHERENT  */
+    NOPERSPECTIVE = 703,           /* NOPERSPECTIVE  */
+    EXPLICITINTERPAMD = 704,       /* EXPLICITINTERPAMD  */
+    PERVERTEXNV = 705,             /* PERVERTEXNV  */
+    PERPRIMITIVENV = 706,          /* PERPRIMITIVENV  */
+    PERVIEWNV = 707,               /* PERVIEWNV  */
+    PERTASKNV = 708,               /* PERTASKNV  */
+    PRECISE = 709                  /* PRECISE  */
   };
   typedef enum yytokentype yytoken_kind_t;
 #endif
@@ -527,6 +537,9 @@ union YYSTYPE
             glslang::TIntermNodePair nodePair;
             glslang::TIntermTyped* intermTypedNode;
             glslang::TAttributes* attributes;
+            glslang::TSpirvRequirement* spirvReq;
+            glslang::TSpirvInstruction* spirvInst;
+            glslang::TSpirvTypeParameters* spirvTypeParams;
         };
         union {
             glslang::TPublicType type;
@@ -540,7 +553,7 @@ union YYSTYPE
         glslang::TArraySizes* typeParameters;
     } interm;
 
-#line 544 "MachineIndependent/glslang_tab.cpp.h"
+#line 557 "MachineIndependent/glslang_tab.cpp.h"
 
 };
 typedef union YYSTYPE YYSTYPE;

+ 13 - 0
thirdparty/glslang/glslang/MachineIndependent/intermOut.cpp

@@ -696,6 +696,10 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
 
     case EOpConstructReference: out.debug << "Construct reference type"; break;
 
+#ifndef GLSLANG_WEB
+    case EOpSpirvInst: out.debug << "spirv_instruction"; break;
+#endif
+
     default: out.debug.message(EPrefixError, "Bad unary op");
     }
 
@@ -886,6 +890,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
     case EOpTime:                       out.debug << "time";                  break;
 
     case EOpAtomicAdd:                  out.debug << "AtomicAdd";             break;
+    case EOpAtomicSubtract:             out.debug << "AtomicSubtract";        break;
     case EOpAtomicMin:                  out.debug << "AtomicMin";             break;
     case EOpAtomicMax:                  out.debug << "AtomicMax";             break;
     case EOpAtomicAnd:                  out.debug << "AtomicAnd";             break;
@@ -1084,6 +1089,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
     case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
 
     case EOpTraceNV:                          out.debug << "traceNV"; break;
+    case EOpTraceRayMotionNV:                 out.debug << "traceRayMotionNV"; break;
     case EOpTraceKHR:                         out.debug << "traceRayKHR"; break;
     case EOpReportIntersection:               out.debug << "reportIntersectionNV"; break;
     case EOpIgnoreIntersectionNV:             out.debug << "ignoreIntersectionNV"; break;
@@ -1125,6 +1131,10 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
     case EOpIsHelperInvocation: out.debug << "IsHelperInvocation"; break;
     case EOpDebugPrintf:  out.debug << "Debug printf";  break;
 
+#ifndef GLSLANG_WEB
+    case EOpSpirvInst: out.debug << "spirv_instruction"; break;
+#endif
+
     default: out.debug.message(EPrefixError, "Bad aggregation op");
     }
 
@@ -1486,6 +1496,9 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
     if (xfbMode)
         infoSink.debug << "in xfb mode\n";
 
+    if (getSubgroupUniformControlFlow())
+        infoSink.debug << "subgroup_uniform_control_flow\n";
+
     switch (language) {
     case EShLangVertex:
         break;

+ 123 - 61
thirdparty/glslang/glslang/MachineIndependent/iomapper.cpp

@@ -210,8 +210,8 @@ struct TResolverUniformAdaptor {
         ent.newIndex = -1;
         const bool isValid = resolver.validateBinding(stage, ent);
         if (isValid) {
-            resolver.resolveBinding(ent.stage, ent);
             resolver.resolveSet(ent.stage, ent);
+            resolver.resolveBinding(ent.stage, ent);
             resolver.resolveUniformLocation(ent.stage, ent);
 
             if (ent.newBinding != -1) {
@@ -317,15 +317,13 @@ private:
 };
 
 // The class is used for reserving explicit uniform locations and ubo/ssbo/opaque bindings
+// xxTODO: maybe this logic should be moved into the resolver's "validateInOut" and "validateUniform"
 
 struct TSymbolValidater
 {
     TSymbolValidater(TIoMapResolver& r, TInfoSink& i, TVarLiveMap* in[EShLangCount], TVarLiveMap* out[EShLangCount],
                      TVarLiveMap* uniform[EShLangCount], bool& hadError, EProfile profile, int version)
-        : preStage(EShLangCount)
-        , currentStage(EShLangCount)
-        , nextStage(EShLangCount)
-        , resolver(r)
+        : resolver(r)
         , infoSink(i)
         , hadError(hadError)
         , profile(profile)
@@ -438,17 +436,23 @@ struct TSymbolValidater
         TIntermSymbol* base = ent1.symbol;
         const TType& type = ent1.symbol->getType();
         const TString& name = entKey.first;
-        EShLanguage stage = ent1.stage;
         TString mangleName1, mangleName2;
-        if (currentStage != stage) {
-            preStage = currentStage;
-            currentStage = stage;
-            nextStage = EShLangCount;
-            for (int i = currentStage + 1; i < EShLangCount; i++) {
-                if (inVarMaps[i] != nullptr) {
-                    nextStage = static_cast<EShLanguage>(i);
-                    break;
-                }
+        EShLanguage stage = ent1.stage;
+        EShLanguage preStage, currentStage, nextStage;
+
+        preStage = EShLangCount;
+        for (int i = stage - 1; i >= 0; i--) {
+            if (inVarMaps[i] != nullptr) {
+                preStage = static_cast<EShLanguage>(i);
+                break;
+            }
+        }
+        currentStage = stage;
+        nextStage = EShLangCount;
+        for (int i = stage + 1; i < EShLangCount; i++) {
+            if (inVarMaps[i] != nullptr) {
+                nextStage = static_cast<EShLanguage>(i);
+                break;
             }
         }
 
@@ -459,6 +463,9 @@ struct TSymbolValidater
             type.appendMangledName(mangleName1);
         }
 
+
+        // basic checking that symbols match
+        // more extensive checking in the link stage
         if (base->getQualifier().storage == EvqVaryingIn) {
             // validate stage in;
             if (preStage == EShLangCount)
@@ -484,8 +491,7 @@ struct TSymbolValidater
                     if (ent2->second.symbol->getType().getQualifier().isArrayedIo(preStage)) {
                         TType subType(ent2->second.symbol->getType(), 0);
                         subType.appendMangledName(mangleName2);
-                    }
-                    else {
+                    } else {
                         ent2->second.symbol->getType().appendMangledName(mangleName2);
                     }
 
@@ -536,8 +542,7 @@ struct TSymbolValidater
                     if (ent2->second.symbol->getType().getQualifier().isArrayedIo(nextStage)) {
                         TType subType(ent2->second.symbol->getType(), 0);
                         subType.appendMangledName(mangleName2);
-                    }
-                    else {
+                    } else {
                         ent2->second.symbol->getType().appendMangledName(mangleName2);
                     }
                     if (mangleName1 == mangleName2)
@@ -550,7 +555,7 @@ struct TSymbolValidater
                 }
                 return;
             }
-        } else if (base->getQualifier().isUniformOrBuffer() && ! base->getQualifier().isPushConstant()) {
+        } else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().isPushConstant()) {
             // validate uniform type;
             for (int i = 0; i < EShLangCount; i++) {
                 if (i != currentStage && outVarMaps[i] != nullptr) {
@@ -558,6 +563,7 @@ struct TSymbolValidater
                     if (ent2 != uniformVarMap[i]->end()) {
                         ent2->second.symbol->getType().appendMangledName(mangleName2);
                         if (mangleName1 != mangleName2) {
+                            ent2->second.symbol->getType().sameElementType(type);
                             TString err = "Invalid Uniform variable type : " + entKey.first;
                             infoSink.info.message(EPrefixInternalError, err.c_str());
                             hadError = true;
@@ -608,8 +614,7 @@ struct TSymbolValidater
     }
 
     TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount], *uniformVarMap[EShLangCount];
-    // Use for mark pre stage, to get more interface symbol information.
-    EShLanguage preStage, currentStage, nextStage;
+
     // Use for mark current shader stage for resolver
     TIoMapResolver& resolver;
     TInfoSink& infoSink;
@@ -749,14 +754,18 @@ TDefaultIoResolverBase::TDefaultIoResolverBase(const TIntermediate& intermediate
     , nextOutputLocation(0)
 {
     memset(stageMask, false, sizeof(bool) * (EShLangCount + 1));
+    memset(stageIntermediates, 0, sizeof(TIntermediate*) * (EShLangCount));
+    stageIntermediates[intermediate.getStage()] = &intermediate;
 }
 
-int TDefaultIoResolverBase::getBaseBinding(TResourceType res, unsigned int set) const {
-    return selectBaseBinding(intermediate.getShiftBinding(res), intermediate.getShiftBindingForSet(res, set));
+int TDefaultIoResolverBase::getBaseBinding(EShLanguage stage, TResourceType res, unsigned int set) const {
+    return stageIntermediates[stage] ? selectBaseBinding(stageIntermediates[stage]->getShiftBinding(res), stageIntermediates[stage]->getShiftBindingForSet(res, set))
+                                     : selectBaseBinding(intermediate.getShiftBinding(res), intermediate.getShiftBindingForSet(res, set));
 }
 
-const std::vector<std::string>& TDefaultIoResolverBase::getResourceSetBinding() const {
-    return intermediate.getResourceSetBinding();
+const std::vector<std::string>& TDefaultIoResolverBase::getResourceSetBinding(EShLanguage stage) const {
+    return stageIntermediates[stage] ? stageIntermediates[stage]->getResourceSetBinding()
+                                     : intermediate.getResourceSetBinding();
 }
 
 bool TDefaultIoResolverBase::doAutoBindingMapping() const { return intermediate.getAutoMapBindings(); }
@@ -797,14 +806,14 @@ int TDefaultIoResolverBase::getFreeSlot(int set, int base, int size) {
     return reserveSlot(set, base, size);
 }
 
-int TDefaultIoResolverBase::resolveSet(EShLanguage /*stage*/, TVarEntryInfo& ent) {
+int TDefaultIoResolverBase::resolveSet(EShLanguage stage, TVarEntryInfo& ent) {
     const TType& type = ent.symbol->getType();
     if (type.getQualifier().hasSet()) {
         return ent.newSet = type.getQualifier().layoutSet;
     }
     // If a command line or API option requested a single descriptor set, use that (if not overrided by spaceN)
-    if (getResourceSetBinding().size() == 1) {
-        return ent.newSet = atoi(getResourceSetBinding()[0].c_str());
+    if (getResourceSetBinding(stage).size() == 1) {
+        return ent.newSet = atoi(getResourceSetBinding(stage)[0].c_str());
     }
     return ent.newSet = 0;
 }
@@ -925,7 +934,7 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf
         preStage = currentStage;
         currentStage = stage;
     }
-    // kick out of not doing this
+    // kick out if not doing this
     if (! doAutoLocationMapping()) {
         return ent.newLocation = -1;
     }
@@ -1073,7 +1082,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
     return ent.newLocation = location;
 }
 
-int TDefaultGlslIoResolver::resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) {
+int TDefaultGlslIoResolver::resolveBinding(EShLanguage stage, TVarEntryInfo& ent) {
     const TType& type = ent.symbol->getType();
     const TString& name = ent.symbol->getAccessName();
     // On OpenGL arrays of opaque types take a separate binding for each element
@@ -1086,30 +1095,32 @@ int TDefaultGlslIoResolver::resolveBinding(EShLanguage /*stage*/, TVarEntryInfo&
     // There is no 'set' qualifier in OpenGL shading language, each resource has its own
     // binding name space, so remap the 'set' to resource type which make each resource
     // binding is valid from 0 to MAX_XXRESOURCE_BINDINGS
-    int set = resource;
+    int set = intermediate.getSpv().openGl != 0 ? resource : ent.newSet;
+    int resourceKey = set;
     if (resource < EResCount) {
         if (type.getQualifier().hasBinding()) {
-            ent.newBinding = reserveSlot(set, getBaseBinding(resource, set) + type.getQualifier().layoutBinding, numBindings);
-            return ent.newBinding;
-        } else if (ent.live && doAutoBindingMapping()) {
+            int newBinding = reserveSlot(resourceKey, getBaseBinding(stage, resource, set) + type.getQualifier().layoutBinding, numBindings);
+            return ent.newBinding = newBinding;
+
+        } else {
             // The resource in current stage is not declared with binding, but it is possible declared
             // with explicit binding in other stages, find the resourceSlotMap firstly to check whether
             // the resource has binding, don't need to allocate if it already has a binding
             bool hasBinding = false;
-            if (! resourceSlotMap[resource].empty()) {
-                TVarSlotMap::iterator iter = resourceSlotMap[resource].find(name);
-                if (iter != resourceSlotMap[resource].end()) {
+            ent.newBinding = -1; // leave as -1 if it isn't set below
+
+            if (! resourceSlotMap[resourceKey].empty()) {
+                TVarSlotMap::iterator iter = resourceSlotMap[resourceKey].find(name);
+                if (iter != resourceSlotMap[resourceKey].end()) {
                     hasBinding = true;
                     ent.newBinding = iter->second;
                 }
             }
-            if (! hasBinding) {
-                TVarSlotMap varSlotMap;
+            if (!hasBinding && (ent.live && doAutoBindingMapping())) {
                 // find free slot, the caller did make sure it passes all vars with binding
                 // first and now all are passed that do not have a binding and needs one
-                int binding = getFreeSlot(resource, getBaseBinding(resource, set), numBindings);
-                varSlotMap[name] = binding;
-                resourceSlotMap[resource] = varSlotMap;
+                int binding = getFreeSlot(resourceKey, getBaseBinding(stage, resource, set), numBindings);
+                resourceSlotMap[resourceKey][name] = binding;
                 ent.newBinding = binding;
             }
             return ent.newBinding;
@@ -1211,16 +1222,20 @@ void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink&
 void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) {
     const TType& type = ent.symbol->getType();
     const TString& name = ent.symbol->getAccessName();
-    int resource = getResourceType(type);
+    TResourceType resource = getResourceType(type);
+    int set = intermediate.getSpv().openGl != 0 ? resource : resolveSet(ent.stage, ent);
+    int resourceKey = set;
+
     if (type.getQualifier().hasBinding()) {
-        TVarSlotMap& varSlotMap = resourceSlotMap[resource];
+        TVarSlotMap& varSlotMap = resourceSlotMap[resourceKey];
         TVarSlotMap::iterator iter = varSlotMap.find(name);
-        int binding = type.getQualifier().layoutBinding;
+        int binding = type.getQualifier().layoutBinding + getBaseBinding(ent.stage, resource, set);
+
         if (iter == varSlotMap.end()) {
             // Reserve the slots for the ubo, ssbo and opaques who has explicit binding
-            int numBindings = type.isSizedArray() ? type.getCumulativeArraySize() : 1;
+            int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
             varSlotMap[name] = binding;
-            reserveSlot(resource, binding, numBindings);
+            reserveSlot(resourceKey, binding, numBindings);
         } else {
             // Allocate binding by name for OpenGL driver, so the resource in different
             // stages should be declared with the same binding
@@ -1269,7 +1284,7 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase {
         return EResCount;
     }
 
-    int resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) override {
+    int resolveBinding(EShLanguage stage, TVarEntryInfo& ent) override {
         const TType& type = ent.symbol->getType();
         const int set = getLayoutSet(type);
         // On OpenGL arrays of opaque types take a seperate binding for each element
@@ -1278,11 +1293,11 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase {
         if (resource < EResCount) {
             if (type.getQualifier().hasBinding()) {
                 return ent.newBinding = reserveSlot(
-                           set, getBaseBinding(resource, set) + type.getQualifier().layoutBinding, numBindings);
+                           set, getBaseBinding(stage, resource, set) + type.getQualifier().layoutBinding, numBindings);
             } else if (ent.live && doAutoBindingMapping()) {
                 // find free slot, the caller did make sure it passes all vars with binding
                 // first and now all are passed that do not have a binding and needs one
-                return ent.newBinding = getFreeSlot(set, getBaseBinding(resource, set), numBindings);
+                return ent.newBinding = getFreeSlot(set, getBaseBinding(stage, resource, set), numBindings);
             }
         }
         return ent.newBinding = -1;
@@ -1354,17 +1369,17 @@ struct TDefaultHlslIoResolver : public TDefaultIoResolverBase {
         return EResCount;
     }
 
-    int resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) override {
+    int resolveBinding(EShLanguage stage, TVarEntryInfo& ent) override {
         const TType& type = ent.symbol->getType();
         const int set = getLayoutSet(type);
         TResourceType resource = getResourceType(type);
         if (resource < EResCount) {
             if (type.getQualifier().hasBinding()) {
-                return ent.newBinding = reserveSlot(set, getBaseBinding(resource, set) + type.getQualifier().layoutBinding);
+                return ent.newBinding = reserveSlot(set, getBaseBinding(stage, resource, set) + type.getQualifier().layoutBinding);
             } else if (ent.live && doAutoBindingMapping()) {
                 // find free slot, the caller did make sure it passes all vars with binding
                 // first and now all are passed that do not have a binding and needs one
-                return ent.newBinding = getFreeSlot(set, getBaseBinding(resource, set));
+                return ent.newBinding = getFreeSlot(set, getBaseBinding(stage, resource, set));
             }
         }
         return ent.newBinding = -1;
@@ -1403,10 +1418,10 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TInfoSi
         else
             resolver = &defaultResolver;
     }
-    resolver->addStage(stage);
 #else
     resolver = &defaultResolver;
 #endif
+    resolver->addStage(stage, intermediate);
 
     TVarLiveMap inVarMap, outVarMap, uniformVarMap;
     TVarLiveVector inVector, outVector, uniformVector;
@@ -1502,10 +1517,21 @@ bool TGlslIoMapper::addStage(EShLanguage stage, TIntermediate& intermediate, TIn
     }
     // if no resolver is provided, use the default resolver with the given shifts and auto map settings
     TDefaultGlslIoResolver defaultResolver(intermediate);
+#ifdef ENABLE_HLSL
+    TDefaultHlslIoResolver defaultHlslResolver(intermediate);
+    if (resolver == nullptr) {
+        // TODO: use a passed in IO mapper for this
+        if (intermediate.usingHlslIoMapping())
+            resolver = &defaultHlslResolver;
+        else
+            resolver = &defaultResolver;
+    }
+#else
     if (resolver == nullptr) {
         resolver = &defaultResolver;
     }
-    resolver->addStage(stage);
+#endif
+    resolver->addStage(stage, intermediate);
     inVarMaps[stage] = new TVarLiveMap(); outVarMaps[stage] = new TVarLiveMap(); uniformVarMap[stage] = new TVarLiveMap();
     TVarGatherTraverser iter_binding_all(intermediate, true, *inVarMaps[stage], *outVarMaps[stage],
                                          *uniformVarMap[stage]);
@@ -1547,15 +1573,51 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) {
         TResolverInOutAdaptor inOutResolve(EShLangCount, *resolver, infoSink, hadError);
         TSymbolValidater symbolValidater(*resolver, infoSink, inVarMaps,
                                          outVarMaps, uniformVarMap, hadError, profile, version);
+
+        TVarLiveVector inVectors[EShLangCount];
+        TVarLiveVector outVectors[EShLangCount];
         TVarLiveVector uniformVector;
+
         resolver->beginResolve(EShLangCount);
         for (int stage = EShLangVertex; stage < EShLangCount; stage++) {
             if (inVarMaps[stage] != nullptr) {
                 inOutResolve.setStage(EShLanguage(stage));
-                for (auto& var : *(inVarMaps[stage])) { symbolValidater(var); }
-                for (auto& var : *(inVarMaps[stage])) { inOutResolve(var); }
-                for (auto& var : *(outVarMaps[stage])) { symbolValidater(var); }
-                for (auto& var : *(outVarMaps[stage])) { inOutResolve(var); }
+
+                // copy vars into a sorted list
+                std::for_each(inVarMaps[stage]->begin(), inVarMaps[stage]->end(),
+                        [&inVectors, stage](TVarLivePair p) { inVectors[stage].push_back(p); });
+                std::sort(inVectors[stage].begin(), inVectors[stage].end(),
+                        [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool {
+                            return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
+                });
+
+                std::for_each(outVarMaps[stage]->begin(), outVarMaps[stage]->end(),
+                        [&outVectors, stage](TVarLivePair p) { outVectors[stage].push_back(p); });
+                std::sort(outVectors[stage].begin(), outVectors[stage].end(),
+                        [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool {
+                            return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
+                });
+
+                for (auto& var : inVectors[stage]) { symbolValidater(var); }
+                for (auto& var : inVectors[stage]) { inOutResolve(var); }
+                for (auto& var : outVectors[stage]) { symbolValidater(var); }
+                for (auto& var : outVectors[stage]) { inOutResolve(var); }
+
+                // copy results back into maps
+                std::for_each(inVectors[stage].begin(), inVectors[stage].end(),
+                    [this, stage](TVarLivePair p) {
+                        auto at = inVarMaps[stage]->find(p.first);
+                        if (at != inVarMaps[stage]->end())
+                            at->second = p.second;
+                });
+
+                std::for_each(outVectors[stage].begin(), outVectors[stage].end(),
+                    [this, stage](TVarLivePair p) {
+                        auto at = outVarMaps[stage]->find(p.first);
+                        if (at != outVarMaps[stage]->end())
+                            at->second = p.second;
+                });
+
             }
             if (uniformVarMap[stage] != nullptr) {
                 uniformResolve.setStage(EShLanguage(stage));
@@ -1563,7 +1625,7 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) {
             }
         }
         std::sort(uniformVector.begin(), uniformVector.end(), [](const TVarLivePair& p1, const TVarLivePair& p2) -> bool {
-            return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
+            return TVarEntryInfo::TOrderByPriorityAndLive()(p1.second, p2.second);
         });
         for (auto& var : uniformVector) { symbolValidater(var); }
         for (auto& var : uniformVector) { uniformResolve(var); }

+ 38 - 5
thirdparty/glslang/glslang/MachineIndependent/iomapper.h

@@ -52,7 +52,7 @@ namespace glslang {
 
 class TIntermediate;
 struct TVarEntryInfo {
-    int id;
+    long long id;
     TIntermSymbol* symbol;
     bool live;
     int newBinding;
@@ -87,6 +87,35 @@ struct TVarEntryInfo {
             return lPoints > rPoints;
         }
     };
+
+    struct TOrderByPriorityAndLive {
+        // ordering:
+        // 1) do live variables first
+        // 2) has both binding and set
+        // 3) has binding but no set
+        // 4) has no binding but set
+        // 5) has no binding and no set
+        inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) {
+
+            const TQualifier& lq = l.symbol->getQualifier();
+            const TQualifier& rq = r.symbol->getQualifier();
+
+            // simple rules:
+            // has binding gives 2 points
+            // has set gives 1 point
+            // who has the most points is more important.
+            int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0);
+            int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0);
+
+            if (l.live != r.live)
+                return l.live > r.live;
+
+            if (lPoints != rPoints)
+                return lPoints > rPoints;
+
+            return l.id < r.id;
+        }
+    };
 };
 
 // Base class for shared TIoMapResolver services, used by several derivations.
@@ -107,8 +136,8 @@ public:
     void endCollect(EShLanguage) override {}
     void reserverResourceSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {}
     void reserverStorageSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {}
-    int getBaseBinding(TResourceType res, unsigned int set) const;
-    const std::vector<std::string>& getResourceSetBinding() const;
+    int getBaseBinding(EShLanguage stage, TResourceType res, unsigned int set) const;
+    const std::vector<std::string>& getResourceSetBinding(EShLanguage stage) const;
     virtual TResourceType getResourceType(const glslang::TType& type) = 0;
     bool doAutoBindingMapping() const;
     bool doAutoLocationMapping() const;
@@ -122,9 +151,11 @@ public:
     int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) override;
     int resolveInOutComponent(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
     int resolveInOutIndex(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
-    void addStage(EShLanguage stage) override {
-        if (stage < EShLangCount)
+    void addStage(EShLanguage stage, TIntermediate& stageIntermediate) override {
+        if (stage < EShLangCount) {
             stageMask[stage] = true;
+            stageIntermediates[stage] = &stageIntermediate;
+        }
     }
     uint32_t computeTypeLocationSize(const TType& type, EShLanguage stage);
 
@@ -139,6 +170,8 @@ protected:
     int nextInputLocation;
     int nextOutputLocation;
     bool stageMask[EShLangCount + 1];
+    const TIntermediate* stageIntermediates[EShLangCount];
+
     // Return descriptor set specific base if there is one, and the generic base otherwise.
     int selectBaseBinding(int base, int descriptorSetBase) const {
         return descriptorSetBase != -1 ? descriptorSetBase : base;

+ 3 - 3
thirdparty/glslang/glslang/MachineIndependent/limits.cpp

@@ -63,14 +63,14 @@ namespace glslang {
 
 class TInductiveTraverser : public TIntermTraverser {
 public:
-    TInductiveTraverser(int id, TSymbolTable& st)
+    TInductiveTraverser(long long id, TSymbolTable& st)
     : loopId(id), symbolTable(st), bad(false)  { }
 
     virtual bool visitBinary(TVisit, TIntermBinary* node);
     virtual bool visitUnary(TVisit, TIntermUnary* node);
     virtual bool visitAggregate(TVisit, TIntermAggregate* node);
 
-    int loopId;           // unique ID of the symbol that's the loop inductive variable
+    long long loopId;           // unique ID of the symbol that's the loop inductive variable
     TSymbolTable& symbolTable;
     bool bad;
     TSourceLoc badLoc;
@@ -129,7 +129,7 @@ bool TInductiveTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* n
 //
 // External function to call for loop check.
 //
-void TParseContext::inductiveLoopBodyCheck(TIntermNode* body, int loopId, TSymbolTable& symbolTable)
+void TParseContext::inductiveLoopBodyCheck(TIntermNode* body, long long loopId, TSymbolTable& symbolTable)
 {
     TInductiveTraverser it(loopId, symbolTable);
 

+ 396 - 32
thirdparty/glslang/glslang/MachineIndependent/linkValidate.cpp

@@ -48,6 +48,7 @@
 
 #include "localintermediate.h"
 #include "../Include/InfoSink.h"
+#include "SymbolTable.h"
 
 namespace glslang {
 
@@ -89,6 +90,56 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
 #endif
 }
 
+//
+// check that link objects between stages
+//
+void TIntermediate::mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit) {
+    if (unit.treeRoot == nullptr || treeRoot == nullptr)
+        return;
+
+    // Get the linker-object lists
+    TIntermSequence& linkerObjects = findLinkerObjects()->getSequence();
+    TIntermSequence unitLinkerObjects = unit.findLinkerObjects()->getSequence();
+
+    // filter unitLinkerObjects to only contain uniforms
+    auto end = std::remove_if(unitLinkerObjects.begin(), unitLinkerObjects.end(),
+        [](TIntermNode* node) {return node->getAsSymbolNode()->getQualifier().storage != EvqUniform &&
+                                      node->getAsSymbolNode()->getQualifier().storage != EvqBuffer; });
+    unitLinkerObjects.resize(end - unitLinkerObjects.begin());
+
+    // merge uniforms and do error checking
+    bool mergeExistingOnly = false;
+    mergeGlobalUniformBlocks(infoSink, unit, mergeExistingOnly);
+    mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage());
+}
+
+//
+// do error checking on the shader boundary in / out vars 
+//
+void TIntermediate::checkStageIO(TInfoSink& infoSink, TIntermediate& unit) {
+    if (unit.treeRoot == nullptr || treeRoot == nullptr)
+        return;
+
+    // Get copies of the linker-object lists
+    TIntermSequence linkerObjects = findLinkerObjects()->getSequence();
+    TIntermSequence unitLinkerObjects = unit.findLinkerObjects()->getSequence();
+
+    // filter linkerObjects to only contain out variables
+    auto end = std::remove_if(linkerObjects.begin(), linkerObjects.end(),
+        [](TIntermNode* node) {return node->getAsSymbolNode()->getQualifier().storage != EvqVaryingOut; });
+    linkerObjects.resize(end - linkerObjects.begin());
+
+    // filter unitLinkerObjects to only contain in variables
+    auto unitEnd = std::remove_if(unitLinkerObjects.begin(), unitLinkerObjects.end(),
+        [](TIntermNode* node) {return node->getAsSymbolNode()->getQualifier().storage != EvqVaryingIn; });
+    unitLinkerObjects.resize(unitEnd - unitLinkerObjects.begin());
+
+    // do matching and error checking
+    mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage());
+
+    // TODO: final check; make sure that any statically used `in` have matching `out` written to
+}
+
 void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit)
 {
     if (unit.getNumEntryPoints() > 0) {
@@ -136,6 +187,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
     MERGE_MAX(spvVersion.vulkanGlsl);
     MERGE_MAX(spvVersion.vulkan);
     MERGE_MAX(spvVersion.openGl);
+    MERGE_TRUE(spvVersion.vulkanRelaxed);
 
     numErrors += unit.getNumErrors();
     // Only one push_constant is allowed, mergeLinkerObjects() will ensure the push_constant
@@ -264,6 +316,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
     MERGE_TRUE(useUnknownFormat);
     MERGE_TRUE(hlslOffsets);
     MERGE_TRUE(useStorageBuffer);
+    MERGE_TRUE(invariantAll);
     MERGE_TRUE(hlslIoMapping);
 
     // TODO: sourceFile
@@ -306,12 +359,14 @@ void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit)
     // Map by global name to unique ID to rationalize the same object having
     // differing IDs in different trees.
     TIdMaps idMaps;
-    int maxId;
-    seedIdMap(idMaps, maxId);
-    remapIds(idMaps, maxId + 1, unit);
+    long long idShift;
+    seedIdMap(idMaps, idShift);
+    remapIds(idMaps, idShift + 1, unit);
 
     mergeBodies(infoSink, globals, unitGlobals);
-    mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects);
+    bool mergeExistingOnly = false;
+    mergeGlobalUniformBlocks(infoSink, unit, mergeExistingOnly);
+    mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage());
     ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end());
 }
 
@@ -329,14 +384,14 @@ static const TString& getNameForIdMap(TIntermSymbol* symbol)
 
 
 // Traverser that seeds an ID map with all built-ins, and tracks the
-// maximum ID used.
+// maximum ID used, currently using (maximum ID + 1) as new symbol id shift seed.
+// Level id will keep same after shifting.
 // (It would be nice to put this in a function, but that causes warnings
 // on having no bodies for the copy-constructor/operator=.)
 class TBuiltInIdTraverser : public TIntermTraverser {
 public:
-    TBuiltInIdTraverser(TIdMaps& idMaps) : idMaps(idMaps), maxId(0) { }
+    TBuiltInIdTraverser(TIdMaps& idMaps) : idMaps(idMaps), idShift(0) { }
     // If it's a built in, add it to the map.
-    // Track the max ID.
     virtual void visitSymbol(TIntermSymbol* symbol)
     {
         const TQualifier& qualifier = symbol->getType().getQualifier();
@@ -344,14 +399,16 @@ public:
             TShaderInterface si = symbol->getType().getShaderInterface();
             idMaps[si][getNameForIdMap(symbol)] = symbol->getId();
         }
-        maxId = std::max(maxId, symbol->getId());
+        idShift = (symbol->getId() & ~TSymbolTable::uniqueIdMask) |
+                std::max(idShift & TSymbolTable::uniqueIdMask,
+                         symbol->getId() & TSymbolTable::uniqueIdMask);
     }
-    int getMaxId() const { return maxId; }
+    long long getIdShift() const { return idShift; }
 protected:
     TBuiltInIdTraverser(TBuiltInIdTraverser&);
     TBuiltInIdTraverser& operator=(TBuiltInIdTraverser&);
     TIdMaps& idMaps;
-    int maxId;
+    long long idShift;
 };
 
 // Traverser that seeds an ID map with non-builtins.
@@ -377,12 +434,12 @@ protected:
 };
 
 // Initialize the the ID map with what we know of 'this' AST.
-void TIntermediate::seedIdMap(TIdMaps& idMaps, int& maxId)
+void TIntermediate::seedIdMap(TIdMaps& idMaps, long long& idShift)
 {
     // all built-ins everywhere need to align on IDs and contribute to the max ID
     TBuiltInIdTraverser builtInIdTraverser(idMaps);
     treeRoot->traverse(&builtInIdTraverser);
-    maxId = builtInIdTraverser.getMaxId();
+    idShift = builtInIdTraverser.getIdShift() & TSymbolTable::uniqueIdMask;
 
     // user variables in the linker object list need to align on ids
     TUserIdTraverser userIdTraverser(idMaps);
@@ -394,7 +451,7 @@ void TIntermediate::seedIdMap(TIdMaps& idMaps, int& maxId)
 // on having no bodies for the copy-constructor/operator=.)
 class TRemapIdTraverser : public TIntermTraverser {
 public:
-    TRemapIdTraverser(const TIdMaps& idMaps, int idShift) : idMaps(idMaps), idShift(idShift) { }
+    TRemapIdTraverser(const TIdMaps& idMaps, long long idShift) : idMaps(idMaps), idShift(idShift) { }
     // Do the mapping:
     //  - if the same symbol, adopt the 'this' ID
     //  - otherwise, ensure a unique ID by shifting to a new space
@@ -406,7 +463,9 @@ public:
             TShaderInterface si = symbol->getType().getShaderInterface();
             auto it = idMaps[si].find(getNameForIdMap(symbol));
             if (it != idMaps[si].end()) {
-                symbol->changeId(it->second);
+                uint64_t id = (symbol->getId() & ~TSymbolTable::uniqueIdMask) |
+                    (it->second & TSymbolTable::uniqueIdMask);
+                symbol->changeId(id);
                 remapped = true;
             }
         }
@@ -417,10 +476,10 @@ protected:
     TRemapIdTraverser(TRemapIdTraverser&);
     TRemapIdTraverser& operator=(TRemapIdTraverser&);
     const TIdMaps& idMaps;
-    int idShift;
+    long long idShift;
 };
 
-void TIntermediate::remapIds(const TIdMaps& idMaps, int idShift, TIntermediate& unit)
+void TIntermediate::remapIds(const TIdMaps& idMaps, long long idShift, TIntermediate& unit)
 {
     // Remap all IDs to either share or be unique, as dictated by the idMap and idShift.
     TRemapIdTraverser idTraverser(idMaps, idShift);
@@ -451,11 +510,193 @@ void TIntermediate::mergeBodies(TInfoSink& infoSink, TIntermSequence& globals, c
     globals.insert(globals.end() - 1, unitGlobals.begin(), unitGlobals.end() - 1);
 }
 
+static inline bool isSameInterface(TIntermSymbol* symbol, EShLanguage stage, TIntermSymbol* unitSymbol, EShLanguage unitStage) {
+    return // 1) same stage and same shader interface
+        (stage == unitStage && symbol->getType().getShaderInterface() == unitSymbol->getType().getShaderInterface()) ||
+        // 2) accross stages and both are uniform or buffer
+        (symbol->getQualifier().storage == EvqUniform  && unitSymbol->getQualifier().storage == EvqUniform) ||
+        (symbol->getQualifier().storage == EvqBuffer   && unitSymbol->getQualifier().storage == EvqBuffer) ||
+        // 3) in/out matched across stage boundary
+        (stage < unitStage && symbol->getQualifier().storage == EvqVaryingOut  && unitSymbol->getQualifier().storage == EvqVaryingIn) ||
+        (unitStage < stage && symbol->getQualifier().storage == EvqVaryingIn && unitSymbol->getQualifier().storage == EvqVaryingOut);
+}
+
+//
+// Global Unfiform block stores any default uniforms (i.e. uniforms without a block)
+// If two linked stages declare the same member, they are meant to be the same uniform
+// and need to be in the same block
+// merge the members of different stages to allow them to be linked properly
+// as a single block
+//
+void TIntermediate::mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate& unit, bool mergeExistingOnly)
+{
+    TIntermSequence& linkerObjects = findLinkerObjects()->getSequence();
+    TIntermSequence& unitLinkerObjects = unit.findLinkerObjects()->getSequence();
+
+    // build lists of default blocks from the intermediates
+    TIntermSequence defaultBlocks;
+    TIntermSequence unitDefaultBlocks;
+
+    auto filter = [](TIntermSequence& list, TIntermNode* node) {
+        if (node->getAsSymbolNode()->getQualifier().defaultBlock) {
+            list.push_back(node);
+        }
+    };
+
+    std::for_each(linkerObjects.begin(), linkerObjects.end(),
+        [&defaultBlocks, &filter](TIntermNode* node) {
+            filter(defaultBlocks, node);
+        });
+    std::for_each(unitLinkerObjects.begin(), unitLinkerObjects.end(),
+        [&unitDefaultBlocks, &filter](TIntermNode* node) {
+            filter(unitDefaultBlocks, node);
+    });
+
+    auto itUnitBlock = unitDefaultBlocks.begin();
+    for (; itUnitBlock != unitDefaultBlocks.end(); itUnitBlock++) {
+
+        bool add = !mergeExistingOnly;
+        auto itBlock = defaultBlocks.begin();
+
+        for (; itBlock != defaultBlocks.end(); itBlock++) {
+            TIntermSymbol* block = (*itBlock)->getAsSymbolNode();
+            TIntermSymbol* unitBlock = (*itUnitBlock)->getAsSymbolNode();
+
+            assert(block && unitBlock);
+
+            // if the two default blocks match, then merge their definitions
+            if (block->getType().getTypeName() == unitBlock->getType().getTypeName() &&
+                block->getQualifier().storage == unitBlock->getQualifier().storage) {
+                add = false;
+                mergeBlockDefinitions(infoSink, block, unitBlock, &unit);
+            }
+        }
+        if (add) {
+            // push back on original list; won't change the size of the list we're iterating over
+            linkerObjects.push_back(*itUnitBlock);
+        }
+    }
+}
+
+void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* block, TIntermSymbol* unitBlock, TIntermediate* unit) {
+    if (block->getType() == unitBlock->getType()) {
+        return;
+    }
+
+    if (block->getType().getTypeName() != unitBlock->getType().getTypeName() ||
+        block->getType().getBasicType() != unitBlock->getType().getBasicType() ||
+        block->getQualifier().storage != unitBlock->getQualifier().storage ||
+        block->getQualifier().layoutSet != unitBlock->getQualifier().layoutSet) {
+        // different block names likely means different blocks
+        return;
+    }
+
+    // merge the struct
+    // order of declarations doesn't matter and they matched based on member name
+    TTypeList* memberList = block->getType().getWritableStruct();
+    TTypeList* unitMemberList = unitBlock->getType().getWritableStruct();
+
+    // keep track of which members have changed position
+    // so we don't have to search the array again
+    std::map<unsigned int, unsigned int> memberIndexUpdates;
+
+    size_t memberListStartSize = memberList->size();
+    for (unsigned int i = 0; i < unitMemberList->size(); ++i) {
+        bool merge = true;
+        for (unsigned int j = 0; j < memberListStartSize; ++j) {
+            if ((*memberList)[j].type->getFieldName() == (*unitMemberList)[i].type->getFieldName()) {
+                merge = false;
+                const TType* memberType = (*memberList)[j].type;
+                const TType* unitMemberType = (*unitMemberList)[i].type;
+
+                // compare types
+                // don't need as many checks as when merging symbols, since
+                // initializers and most qualifiers are stripped when the member is moved into the block
+                if ((*memberType) != (*unitMemberType)) {
+                    error(infoSink, "Types must match:");
+                    infoSink.info << "    " << memberType->getFieldName() << ": ";
+                    infoSink.info << "\"" << memberType->getCompleteString() << "\" versus ";
+                    infoSink.info << "\"" << unitMemberType->getCompleteString() << "\"\n";
+                }
+
+                memberIndexUpdates[i] = j;
+            }
+        }
+        if (merge) {
+            memberList->push_back((*unitMemberList)[i]);
+            memberIndexUpdates[i] = (unsigned int)memberList->size() - 1;
+        }
+    }
+
+    TType unitType;
+    unitType.shallowCopy(unitBlock->getType());
+
+    // update symbol node in unit tree,
+    // and other nodes that may reference it
+    class TMergeBlockTraverser : public TIntermTraverser {
+    public:
+        TMergeBlockTraverser(const glslang::TType &type, const glslang::TType& unitType,
+                             glslang::TIntermediate& unit,
+                             const std::map<unsigned int, unsigned int>& memberIdxUpdates) :
+            newType(type), unitType(unitType), unit(unit), memberIndexUpdates(memberIdxUpdates)
+        { }
+        virtual ~TMergeBlockTraverser() { }
+
+        const glslang::TType& newType;          // type with modifications
+        const glslang::TType& unitType;         // copy of original type
+        glslang::TIntermediate& unit;           // intermediate that is being updated
+        const std::map<unsigned int, unsigned int>& memberIndexUpdates;
+
+        virtual void visitSymbol(TIntermSymbol* symbol)
+        {
+            glslang::TType& symType = symbol->getWritableType();
+
+            if (symType == unitType) {
+                // each symbol node has a local copy of the unitType
+                //  if merging involves changing properties that aren't shared objects
+                //  they should be updated in all instances
+
+                // e.g. the struct list is a ptr to an object, so it can be updated
+                // once, outside the traverser
+                //*symType.getWritableStruct() = *newType.getStruct();
+            }
+
+        }
+
+        virtual bool visitBinary(TVisit, glslang::TIntermBinary* node)
+        {
+            if (node->getOp() == EOpIndexDirectStruct && node->getLeft()->getType() == unitType) {
+                // this is a dereference to a member of the block since the
+                // member list changed, need to update this to point to the
+                // right index
+                assert(node->getRight()->getAsConstantUnion());
+
+                glslang::TIntermConstantUnion* constNode = node->getRight()->getAsConstantUnion();
+                unsigned int memberIdx = constNode->getConstArray()[0].getUConst();
+                unsigned int newIdx = memberIndexUpdates.at(memberIdx);
+                TIntermTyped* newConstNode = unit.addConstantUnion(newIdx, node->getRight()->getLoc());
+
+                node->setRight(newConstNode);
+                delete constNode;
+
+                return true;
+            }
+            return true;
+        }
+    } finalLinkTraverser(block->getType(), unitType, *unit, memberIndexUpdates);
+
+    // update the tree to use the new type
+    unit->getTreeRoot()->traverse(&finalLinkTraverser);
+
+    // update the member list
+    (*unitMemberList) = (*memberList);
+}
+
 //
 // Merge the linker objects from unitLinkerObjects into linkerObjects.
 // Duplication is expected and filtered out, but contradictions are an error.
 //
-void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects)
+void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects, EShLanguage unitStage)
 {
     // Error check and merge the linker objects (duplicates should not be created)
     std::size_t initialNumLinkerObjects = linkerObjects.size();
@@ -470,7 +711,7 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
             // If they are both blocks in the same shader interface,
             // match by the block-name, not the identifier name.
             if (symbol->getType().getBasicType() == EbtBlock && unitSymbol->getType().getBasicType() == EbtBlock) {
-                if (symbol->getType().getShaderInterface() == unitSymbol->getType().getShaderInterface()) {
+                if (isSameInterface(symbol, getStage(), unitSymbol, unitStage)) {
                     isSameSymbol = symbol->getType().getTypeName() == unitSymbol->getType().getTypeName();
                 }
             }
@@ -490,18 +731,54 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
                 if (! symbol->getQualifier().hasBinding() && unitSymbol->getQualifier().hasBinding())
                     symbol->getQualifier().layoutBinding = unitSymbol->getQualifier().layoutBinding;
 
+                // Similarly for location
+                if (!symbol->getQualifier().hasLocation() && unitSymbol->getQualifier().hasLocation()) {
+                    symbol->getQualifier().layoutLocation = unitSymbol->getQualifier().layoutLocation;
+                }
+
                 // Update implicit array sizes
                 mergeImplicitArraySizes(symbol->getWritableType(), unitSymbol->getType());
 
                 // Check for consistent types/qualification/initializers etc.
-                mergeErrorCheck(infoSink, *symbol, *unitSymbol, false);
+                mergeErrorCheck(infoSink, *symbol, *unitSymbol, unitStage);
             }
             // If different symbols, verify they arn't push_constant since there can only be one per stage
-            else if (symbol->getQualifier().isPushConstant() && unitSymbol->getQualifier().isPushConstant())
+            else if (symbol->getQualifier().isPushConstant() && unitSymbol->getQualifier().isPushConstant() && getStage() == unitStage)
                 error(infoSink, "Only one push_constant block is allowed per stage");
         }
-        if (merge)
+        if (merge) {
             linkerObjects.push_back(unitLinkerObjects[unitLinkObj]);
+
+            // for anonymous blocks, check that their members don't conflict with other names
+            if (unitLinkerObjects[unitLinkObj]->getAsSymbolNode()->getBasicType() == EbtBlock &&
+                IsAnonymous(unitLinkerObjects[unitLinkObj]->getAsSymbolNode()->getName())) {
+                for (std::size_t linkObj = 0; linkObj < initialNumLinkerObjects; ++linkObj) {
+                    TIntermSymbol* symbol = linkerObjects[linkObj]->getAsSymbolNode();
+                    TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode();
+                    assert(symbol && unitSymbol);
+
+                    auto checkName = [this, unitSymbol, &infoSink](const TString& name) {
+                        for (unsigned int i = 0; i < unitSymbol->getType().getStruct()->size(); ++i) {
+                            if (name == (*unitSymbol->getType().getStruct())[i].type->getFieldName()) {
+                                error(infoSink, "Anonymous member name used for global variable or other anonymous member: ");
+                                infoSink.info << (*unitSymbol->getType().getStruct())[i].type->getCompleteString() << "\n";
+                            }
+                        }
+                    };
+
+                    if (isSameInterface(symbol, getStage(), unitSymbol, unitStage)) {
+                        checkName(symbol->getName());
+
+                        // check members of other anonymous blocks
+                        if (symbol->getBasicType() == EbtBlock && IsAnonymous(symbol->getName())) {
+                            for (unsigned int i = 0; i < symbol->getType().getStruct()->size(); ++i) {
+                                checkName((*symbol->getType().getStruct())[i].type->getFieldName());
+                            }
+                        }
+                    }
+                }
+            }
+        }
     }
 }
 
@@ -533,26 +810,75 @@ void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType)
 //
 // This function only does one of intra- or cross-stage matching per call.
 //
-void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, bool crossStage)
+void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, EShLanguage unitStage)
 {
 #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
+    bool crossStage = getStage() != unitStage;
     bool writeTypeComparison = false;
 
     // Types have to match
-    if (symbol.getType() != unitSymbol.getType()) {
+    {
         // but, we make an exception if one is an implicit array and the other is sized
-        if (! (symbol.getType().isArray() && unitSymbol.getType().isArray() &&
-                symbol.getType().sameElementType(unitSymbol.getType()) &&
-                (symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray()))) {
-            error(infoSink, "Types must match:");
+        // or if the array sizes differ because of the extra array dimension on some in/out boundaries
+        bool arraysMatch = false;
+        if (isIoResizeArray(symbol.getType(), getStage()) || isIoResizeArray(unitSymbol.getType(), unitStage)) {
+            // if the arrays have an extra dimension because of the stage.
+            // compare dimensions while ignoring the outer dimension
+            unsigned int firstDim = isIoResizeArray(symbol.getType(), getStage()) ? 1 : 0;
+            unsigned int numDim = symbol.getArraySizes()
+                ? symbol.getArraySizes()->getNumDims() : 0;
+            unsigned int unitFirstDim = isIoResizeArray(unitSymbol.getType(), unitStage) ? 1 : 0;
+            unsigned int unitNumDim = unitSymbol.getArraySizes()
+                ? unitSymbol.getArraySizes()->getNumDims() : 0;
+            arraysMatch = (numDim - firstDim) == (unitNumDim - unitFirstDim);
+            // check that array sizes match as well
+            for (unsigned int i = 0; i < (numDim - firstDim) && arraysMatch; i++) {
+                if (symbol.getArraySizes()->getDimSize(firstDim + i) !=
+                    unitSymbol.getArraySizes()->getDimSize(unitFirstDim + i)) {
+                    arraysMatch = false;
+                    break;
+                }
+            }
+        }
+        else {
+            arraysMatch = symbol.getType().sameArrayness(unitSymbol.getType()) ||
+                (symbol.getType().isArray() && unitSymbol.getType().isArray() &&
+                (symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray()));
+        }
+
+        if (!symbol.getType().sameElementType(unitSymbol.getType()) ||
+            !symbol.getType().sameTypeParameters(unitSymbol.getType()) ||
+            !arraysMatch ) {
             writeTypeComparison = true;
+            error(infoSink, "Types must match:");
         }
     }
 
-    // Qualifiers have to (almost) match
+    // Interface block  member-wise layout qualifiers have to match
+    if (symbol.getType().getBasicType() == EbtBlock && unitSymbol.getType().getBasicType() == EbtBlock &&
+        symbol.getType().getStruct() && unitSymbol.getType().getStruct() &&
+        symbol.getType().sameStructType(unitSymbol.getType())) {
+        for (unsigned int i = 0; i < symbol.getType().getStruct()->size(); ++i) {
+            const TQualifier& qualifier = (*symbol.getType().getStruct())[i].type->getQualifier();
+            const TQualifier& unitQualifier = (*unitSymbol.getType().getStruct())[i].type->getQualifier();
+            if (qualifier.layoutMatrix     != unitQualifier.layoutMatrix ||
+                qualifier.layoutOffset     != unitQualifier.layoutOffset ||
+                qualifier.layoutAlign      != unitQualifier.layoutAlign ||
+                qualifier.layoutLocation   != unitQualifier.layoutLocation ||
+                qualifier.layoutComponent  != unitQualifier.layoutComponent) {
+                error(infoSink, "Interface block member layout qualifiers must match:");
+                writeTypeComparison = true;
+            }
+        }
+    }
+
+    bool isInOut = crossStage &&
+                   ((symbol.getQualifier().storage == EvqVaryingIn && unitSymbol.getQualifier().storage == EvqVaryingOut) ||
+                   (symbol.getQualifier().storage == EvqVaryingOut && unitSymbol.getQualifier().storage == EvqVaryingIn));
 
+    // Qualifiers have to (almost) match
     // Storage...
-    if (symbol.getQualifier().storage != unitSymbol.getQualifier().storage) {
+    if (!isInOut && symbol.getQualifier().storage != unitSymbol.getQualifier().storage) {
         error(infoSink, "Storage qualifiers must match:");
         writeTypeComparison = true;
     }
@@ -574,7 +900,7 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
     }
 
     // Precision...
-    if (symbol.getQualifier().precision != unitSymbol.getQualifier().precision) {
+    if (!isInOut && symbol.getQualifier().precision != unitSymbol.getQualifier().precision) {
         error(infoSink, "Precision qualifiers must match:");
         writeTypeComparison = true;
     }
@@ -592,12 +918,16 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
     }
 
     // Auxiliary and interpolation...
-    if (symbol.getQualifier().centroid  != unitSymbol.getQualifier().centroid ||
+    // "interpolation qualification (e.g., flat) and auxiliary qualification (e.g. centroid) may differ.  
+    //  These mismatches are allowed between any pair of stages ...
+    //  those provided in the fragment shader supersede those provided in previous stages."
+    if (!crossStage &&
+        (symbol.getQualifier().centroid  != unitSymbol.getQualifier().centroid ||
         symbol.getQualifier().smooth    != unitSymbol.getQualifier().smooth ||
         symbol.getQualifier().flat      != unitSymbol.getQualifier().flat ||
         symbol.getQualifier().isSample()!= unitSymbol.getQualifier().isSample() ||
         symbol.getQualifier().isPatch() != unitSymbol.getQualifier().isPatch() ||
-        symbol.getQualifier().isNonPerspective() != unitSymbol.getQualifier().isNonPerspective()) {
+        symbol.getQualifier().isNonPerspective() != unitSymbol.getQualifier().isNonPerspective())) {
         error(infoSink, "Interpolation and auxiliary storage qualifiers must match:");
         writeTypeComparison = true;
     }
@@ -653,6 +983,25 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
 #endif
 }
 
+void TIntermediate::sharedBlockCheck(TInfoSink& infoSink)
+{
+    bool has_shared_block = false;
+    bool has_shared_non_block = false;
+    TIntermSequence& linkObjects = findLinkerObjects()->getSequence();
+    for (size_t i = 0; i < linkObjects.size(); ++i) {
+        const TType& type = linkObjects[i]->getAsTyped()->getType();
+        const TQualifier& qualifier = type.getQualifier();
+        if (qualifier.storage == glslang::EvqShared) {
+            if (type.getBasicType() == glslang::EbtBlock)
+                has_shared_block = true;
+            else
+                has_shared_non_block = true;
+        }
+    }
+    if (has_shared_block && has_shared_non_block)
+        error(infoSink, "cannot mix use of shared variables inside and outside blocks");
+}
+
 //
 // Do final link-time error checking of a complete (merged) intermediate representation.
 // (Much error checking was done during merging).
@@ -778,6 +1127,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
             error(infoSink, "post_depth_coverage requires early_fragment_tests");
         break;
     case EShLangCompute:
+        sharedBlockCheck(infoSink);
         break;
     case EShLangRayGen:
     case EShLangIntersect:
@@ -810,6 +1160,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
     case EShLangTaskNV:
         if (numTaskNVBlocks > 1)
             error(infoSink, "Only one taskNV interface block is allowed per shader");
+        sharedBlockCheck(infoSink);
         break;
     default:
         error(infoSink, "Unknown Stage.");
@@ -1804,4 +2155,17 @@ int TIntermediate::computeBufferReferenceTypeSize(const TType& type)
     return size;
 }
 
+#ifndef GLSLANG_WEB
+bool TIntermediate::isIoResizeArray(const TType& type, EShLanguage language) {
+    return type.isArray() &&
+            ((language == EShLangGeometry    && type.getQualifier().storage == EvqVaryingIn) ||
+            (language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut &&
+                ! type.getQualifier().patch) ||
+            (language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn &&
+                type.getQualifier().pervertexNV) ||
+            (language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut &&
+                !type.getQualifier().perTaskNV));
+}
+#endif // not GLSLANG_WEB
+
 } // end namespace glslang

+ 110 - 10
thirdparty/glslang/glslang/MachineIndependent/localintermediate.h

@@ -227,10 +227,10 @@ enum ComputeDerivativeMode {
 
 class TIdMaps {
 public:
-    TMap<TString, int>& operator[](int i) { return maps[i]; }
-    const TMap<TString, int>& operator[](int i) const { return maps[i]; }
+    TMap<TString, long long>& operator[](long long i) { return maps[i]; }
+    const TMap<TString, long long>& operator[](long long i) const { return maps[i]; }
 private:
-    TMap<TString, int> maps[EsiCount];
+    TMap<TString, long long> maps[EsiCount];
 };
 
 class TNumericFeatures {
@@ -291,8 +291,15 @@ public:
         numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
         invertY(false),
         useStorageBuffer(false),
+        invariantAll(false),
         nanMinMaxClamp(false),
-        depthReplacing(false)
+        depthReplacing(false),
+        uniqueId(0),
+        globalUniformBlockName(""),
+        atomicCounterBlockName(""),
+        globalUniformBlockSet(TQualifier::layoutSetEnd),
+        globalUniformBlockBinding(TQualifier::layoutBindingEnd),
+        atomicCounterBlockSet(TQualifier::layoutSetEnd)
 #ifndef GLSLANG_WEB
         ,
         implicitThisName("@this"), implicitCounterName("@count"),
@@ -322,7 +329,10 @@ public:
         textureSamplerTransformMode(EShTexSampTransKeep),
         needToLegalize(false),
         binaryDoubleOutput(false),
+        subgroupUniformControlFlow(false),
         usePhysicalStorageBuffer(false),
+        spirvRequirement(nullptr),
+        spirvExecutionMode(nullptr),
         uniformLocationBase(0)
 #endif
     {
@@ -529,15 +539,30 @@ public:
     TIntermTyped* foldSwizzle(TIntermTyped* node, TSwizzleSelectors<TVectorSelector>& fields, const TSourceLoc&);
 
     // Tree ops
-    static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay);
+    static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay , bool BufferReferenceOk = false);
 
     // Linkage related
     void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
     void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&);
     TIntermAggregate* findLinkerObjects() const;
 
+    void setGlobalUniformBlockName(const char* name) { globalUniformBlockName = std::string(name); }
+    const char* getGlobalUniformBlockName() const { return globalUniformBlockName.c_str(); }
+    void setGlobalUniformSet(unsigned int set) { globalUniformBlockSet = set; }
+    unsigned int getGlobalUniformSet() const { return globalUniformBlockSet; }
+    void setGlobalUniformBinding(unsigned int binding) { globalUniformBlockBinding = binding; }
+    unsigned int getGlobalUniformBinding() const { return globalUniformBlockBinding; }
+
+    void setAtomicCounterBlockName(const char* name) { atomicCounterBlockName = std::string(name); }
+    const char* getAtomicCounterBlockName() const { return atomicCounterBlockName.c_str(); }
+    void setAtomicCounterBlockSet(unsigned int set) { atomicCounterBlockSet = set; }
+    unsigned int getAtomicCounterBlockSet() const { return atomicCounterBlockSet; }
+
+
     void setUseStorageBuffer() { useStorageBuffer = true; }
     bool usingStorageBuffer() const { return useStorageBuffer; }
+    void setInvariantAll() { invariantAll = true; }
+    bool isInvariantAll() const { return invariantAll; }
     void setDepthReplacing() { depthReplacing = true; }
     bool isDepthReplacing() const { return depthReplacing; }
     bool setLocalSize(int dim, int size)
@@ -549,6 +574,11 @@ public:
         return true;
     }
     unsigned int getLocalSize(int dim) const { return localSize[dim]; }
+    bool isLocalSizeSet() const
+    {
+        // Return true if any component has been set (i.e. any component is not default).
+        return localSizeNotDefault[0] || localSizeNotDefault[1] || localSizeNotDefault[2];
+    }
     bool setLocalSizeSpecId(int dim, int id)
     {
         if (localSizeSpecId[dim] != TQualifier::layoutNotSet)
@@ -557,6 +587,13 @@ public:
         return true;
     }
     int getLocalSizeSpecId(int dim) const { return localSizeSpecId[dim]; }
+    bool isLocalSizeSpecialized() const
+    {
+        // Return true if any component has been specialized.
+        return localSizeSpecId[0] != TQualifier::layoutNotSet ||
+               localSizeSpecId[1] != TQualifier::layoutNotSet ||
+               localSizeSpecId[2] != TQualifier::layoutNotSet;
+    }
 #ifdef GLSLANG_WEB
     void output(TInfoSink&, bool tree) { }
 
@@ -833,8 +870,34 @@ public:
 
     void setBinaryDoubleOutput() { binaryDoubleOutput = true; }
     bool getBinaryDoubleOutput() { return binaryDoubleOutput; }
+
+    void setSubgroupUniformControlFlow() { subgroupUniformControlFlow = true; }
+    bool getSubgroupUniformControlFlow() const { return subgroupUniformControlFlow; }
+
+    // GL_EXT_spirv_intrinsics
+    void insertSpirvRequirement(const TSpirvRequirement* spirvReq);
+    bool hasSpirvRequirement() const { return spirvRequirement != nullptr; }
+    const TSpirvRequirement& getSpirvRequirement() const { return *spirvRequirement; }
+    void insertSpirvExecutionMode(int executionMode, const TIntermAggregate* args = nullptr);
+    void insertSpirvExecutionModeId(int executionMode, const TIntermAggregate* args);
+    bool hasSpirvExecutionMode() const { return spirvExecutionMode != nullptr; }
+    const TSpirvExecutionMode& getSpirvExecutionMode() const { return *spirvExecutionMode; }
 #endif // GLSLANG_WEB
 
+    void addBlockStorageOverride(const char* nameStr, TBlockStorageClass backing)
+    {
+        std::string name(nameStr);
+        blockBackingOverrides[name] = backing;
+    }
+    TBlockStorageClass getBlockStorageOverride(const char* nameStr) const
+    {
+        std::string name = nameStr;
+        auto pos = blockBackingOverrides.find(name);
+        if (pos == blockBackingOverrides.end())
+            return EbsNone;
+        else
+            return pos->second;
+    }
 #ifdef ENABLE_HLSL
     void setHlslFunctionality1() { hlslFunctionality1 = true; }
     bool getHlslFunctionality1() const { return hlslFunctionality1; }
@@ -858,10 +921,27 @@ public:
     bool usingHlslIoMapping() { return false; }
 #endif
 
+    bool usingScalarBlockLayout() const {
+        for (auto extIt = requestedExtensions.begin(); extIt != requestedExtensions.end(); ++extIt) {
+            if (*extIt == E_GL_EXT_scalar_block_layout)
+                return true;
+        }
+        return false;
+    }
+
+    bool IsRequestedExtension(const char* extension) const
+    {
+        return (requestedExtensions.find(extension) != requestedExtensions.end());
+    }
+
     void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee);
     void merge(TInfoSink&, TIntermediate&);
     void finalCheck(TInfoSink&, bool keepUncalled);
 
+    void mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate& unit, bool mergeExistingOnly);
+    void mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit);
+    void checkStageIO(TInfoSink&, TIntermediate&);
+
     bool buildConvertOp(TBasicType dst, TBasicType src, TOperator& convertOp) const;
     TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const;
 
@@ -885,6 +965,8 @@ public:
     static int getOffset(const TType& type, int index);
     static int getBlockSize(const TType& blockType);
     static int computeBufferReferenceTypeSize(const TType&);
+    static bool isIoResizeArray(const TType& type, EShLanguage language);
+
     bool promote(TIntermOperator*);
     void setNanMinMaxClamp(bool setting) { nanMinMaxClamp = setting; }
     bool getNanMinMaxClamp() const { return nanMinMaxClamp; }
@@ -903,6 +985,8 @@ public:
     void addProcess(const std::string& process) { processes.addProcess(process); }
     void addProcessArgument(const std::string& arg) { processes.addArgument(arg); }
     const std::vector<std::string>& getProcesses() const { return processes.getProcesses(); }
+    unsigned long long getUniqueId() const { return uniqueId; }
+    void setUniqueId(unsigned long long id) { uniqueId = id; }
 
     // Certain explicit conversions are allowed conditionally
 #ifdef GLSLANG_WEB
@@ -931,21 +1015,23 @@ public:
 #endif
 
 protected:
-    TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
+    TIntermSymbol* addSymbol(long long Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
     void error(TInfoSink& infoSink, const char*);
     void warn(TInfoSink& infoSink, const char*);
     void mergeCallGraphs(TInfoSink&, TIntermediate&);
     void mergeModes(TInfoSink&, TIntermediate&);
     void mergeTrees(TInfoSink&, TIntermediate&);
-    void seedIdMap(TIdMaps& idMaps, int& maxId);
-    void remapIds(const TIdMaps& idMaps, int idShift, TIntermediate&);
+    void seedIdMap(TIdMaps& idMaps, long long& IdShift);
+    void remapIds(const TIdMaps& idMaps, long long idShift, TIntermediate&);
     void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals);
-    void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects);
+    void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects, EShLanguage);
+    void mergeBlockDefinitions(TInfoSink&, TIntermSymbol* block, TIntermSymbol* unitBlock, TIntermediate* unitRoot);
     void mergeImplicitArraySizes(TType&, const TType&);
-    void mergeErrorCheck(TInfoSink&, const TIntermSymbol&, const TIntermSymbol&, bool crossStage);
+    void mergeErrorCheck(TInfoSink&, const TIntermSymbol&, const TIntermSymbol&, EShLanguage);
     void checkCallGraphCycles(TInfoSink&);
     void checkCallGraphBodies(TInfoSink&, bool keepUncalled);
     void inOutLocationCheck(TInfoSink&);
+    void sharedBlockCheck(TInfoSink&);
     bool userOutputUsed() const;
     bool isSpecializationOperation(const TIntermOperator&) const;
     bool isNonuniformPropagating(TOperator) const;
@@ -985,11 +1071,20 @@ protected:
     bool recursive;
     bool invertY;
     bool useStorageBuffer;
+    bool invariantAll;
     bool nanMinMaxClamp;            // true if desiring min/max/clamp to favor non-NaN over NaN
     bool depthReplacing;
     int localSize[3];
     bool localSizeNotDefault[3];
     int localSizeSpecId[3];
+    unsigned long long uniqueId;
+
+    std::string globalUniformBlockName;
+    std::string atomicCounterBlockName;
+    unsigned int globalUniformBlockSet;
+    unsigned int globalUniformBlockBinding;
+    unsigned int atomicCounterBlockSet;
+
 #ifndef GLSLANG_WEB
 public:
     const char* const implicitThisName;
@@ -1044,12 +1139,17 @@ protected:
 
     bool needToLegalize;
     bool binaryDoubleOutput;
+    bool subgroupUniformControlFlow;
     bool usePhysicalStorageBuffer;
 
+    TSpirvRequirement* spirvRequirement;
+    TSpirvExecutionMode* spirvExecutionMode;
+
     std::unordered_map<std::string, int> uniformLocationOverrides;
     int uniformLocationBase;
     TNumericFeatures numericFeatures;
 #endif
+    std::unordered_map<std::string, TBlockStorageClass> blockBackingOverrides;
 
     std::unordered_set<int> usedConstantId; // specialization constant ids used
     std::vector<TOffsetRange> usedAtomics;  // sets of bindings used by atomic counters

+ 18 - 19
thirdparty/glslang/glslang/MachineIndependent/parseConst.cpp

@@ -166,31 +166,30 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
                 }
             } else {
                 // matrix from vector or scalar
-                int count = 0;
-                const int startIndex = index;
                 int nodeComps = node->getType().computeNumComponents();
-                for (int i = startIndex; i < endIndex; i++) {
-                    if (i >= instanceSize)
-                        return;
-                    if (nodeComps == 1) {
-                        // If there is a single scalar parameter to a matrix
-                        // constructor, it is used to initialize all the
-                        // components on the matrix's diagonal, with the
-                        // remaining components initialized to 0.0.
-                        if (i == startIndex || (i - startIndex) % (matrixRows + 1) == 0 )
-                            leftUnionArray[i] = rightUnionArray[count];
-                        else
-                            leftUnionArray[i].setDConst(0.0);
-                    } else {
+                if (nodeComps == 1) {
+                    for (int c = 0; c < matrixCols; ++c) {
+                        for (int r = 0; r < matrixRows; ++r) {
+                            if (r == c)
+                                leftUnionArray[index] = rightUnionArray[0];
+                            else
+                                leftUnionArray[index].setDConst(0.0);
+                            index++;
+                        }
+                    }
+                } else {
+                    int count = 0;
+                    for (int i = index; i < endIndex; i++) {
+                        if (i >= instanceSize)
+                            return;
+
                         // construct the matrix in column-major order, from
                         // the components provided, in order
                         leftUnionArray[i] = rightUnionArray[count];
-                    }
-
-                    index++;
 
-                    if (nodeComps > 1)
+                        index++;
                         count++;
+                    }
                 }
             }
         }

+ 5 - 3
thirdparty/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp

@@ -1191,9 +1191,11 @@ int TPpContext::tokenize(TPpToken& ppToken)
             // HLSL allows string literals.
             // GLSL allows string literals with GL_EXT_debug_printf.
             if (ifdepth == 0 && parseContext.intermediate.getSource() != EShSourceHlsl) {
-                parseContext.requireExtensions(ppToken.loc, 1, &E_GL_EXT_debug_printf, "string literal");
-                if (!parseContext.extensionTurnedOn(E_GL_EXT_debug_printf))
-                    continue;
+              const char* const string_literal_EXTs[] = { E_GL_EXT_debug_printf, E_GL_EXT_spirv_intrinsics };
+              parseContext.requireExtensions(ppToken.loc, 2, string_literal_EXTs, "string literal");
+              if (!parseContext.extensionTurnedOn(E_GL_EXT_debug_printf) &&
+                  !parseContext.extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
+                  continue;
             }
             break;
         case '\'':

+ 4 - 2
thirdparty/glslang/glslang/MachineIndependent/reflection.cpp

@@ -907,8 +907,8 @@ public:
             case EbtFloat16:    return GL_FLOAT16_VEC2_NV             + offset;
             case EbtInt:        return GL_INT_VEC2                    + offset;
             case EbtUint:       return GL_UNSIGNED_INT_VEC2           + offset;
-            case EbtInt64:      return GL_INT64_ARB                   + offset;
-            case EbtUint64:     return GL_UNSIGNED_INT64_ARB          + offset;
+            case EbtInt64:      return GL_INT64_VEC2_ARB              + offset;
+            case EbtUint64:     return GL_UNSIGNED_INT64_VEC2_ARB     + offset;
             case EbtBool:       return GL_BOOL_VEC2                   + offset;
             case EbtAtomicUint: return GL_UNSIGNED_INT_ATOMIC_COUNTER + offset;
             default:            return 0;
@@ -1138,6 +1138,8 @@ void TReflection::buildCounterIndices(const TIntermediate& intermediate)
         if (index >= 0)
             indexToUniformBlock[i].counterIndex = index;
     }
+#else
+    (void)intermediate;
 #endif
 }
 

+ 27 - 5
thirdparty/glslang/glslang/Public/ShaderLang.h

@@ -167,7 +167,7 @@ typedef enum {
     EShTargetVulkan_1_1 = (1 << 22) | (1 << 12),      // Vulkan 1.1
     EShTargetVulkan_1_2 = (1 << 22) | (2 << 12),      // Vulkan 1.2
     EShTargetOpenGL_450 = 450,                        // OpenGL
-    LAST_ELEMENT_MARKER(EShTargetClientVersionCount),
+    LAST_ELEMENT_MARKER(EShTargetClientVersionCount = 4),
 } EShTargetClientVersion;
 
 typedef EShTargetClientVersion EshTargetClientVersion;
@@ -179,7 +179,7 @@ typedef enum {
     EShTargetSpv_1_3 = (1 << 16) | (3 << 8),          // SPIR-V 1.3
     EShTargetSpv_1_4 = (1 << 16) | (4 << 8),          // SPIR-V 1.4
     EShTargetSpv_1_5 = (1 << 16) | (5 << 8),          // SPIR-V 1.5
-    LAST_ELEMENT_MARKER(EShTargetLanguageVersionCount),
+    LAST_ELEMENT_MARKER(EShTargetLanguageVersionCount = 6),
 } EShTargetLanguageVersion;
 
 struct TInputLanguage {
@@ -187,6 +187,7 @@ struct TInputLanguage {
     EShLanguage stage;        // redundant information with other input, this one overrides when not EShSourceNone
     EShClient dialect;
     int dialectVersion;       // version of client's language definition, not the client (when not EShClientNone)
+    bool vulkanRulesRelaxed;
 };
 
 struct TClient {
@@ -427,6 +428,14 @@ enum TResourceType {
     EResCount
 };
 
+enum TBlockStorageClass
+{
+    EbsUniform = 0,
+    EbsStorageBuffer,
+    EbsPushConstant,
+    EbsNone,    // not a uniform or buffer variable
+    EbsCount,
+};
 
 // Make one TShader per shader that you will link into a program. Then
 //  - provide the shader through setStrings() or setStringsWithLengths()
@@ -458,6 +467,7 @@ public:
     GLSLANG_EXPORT void setEntryPoint(const char* entryPoint);
     GLSLANG_EXPORT void setSourceEntryPoint(const char* sourceEntryPointName);
     GLSLANG_EXPORT void addProcesses(const std::vector<std::string>&);
+    GLSLANG_EXPORT void setUniqueId(unsigned long long id);
 
     // IO resolver binding data: see comments in ShaderLang.cpp
     GLSLANG_EXPORT void setShiftBinding(TResourceType res, unsigned int base);
@@ -482,6 +492,14 @@ public:
     GLSLANG_EXPORT void setNoStorageFormat(bool useUnknownFormat);
     GLSLANG_EXPORT void setNanMinMaxClamp(bool nanMinMaxClamp);
     GLSLANG_EXPORT void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
+    GLSLANG_EXPORT void addBlockStorageOverride(const char* nameStr, glslang::TBlockStorageClass backing);
+
+    GLSLANG_EXPORT void setGlobalUniformBlockName(const char* name);
+    GLSLANG_EXPORT void setAtomicCounterBlockName(const char* name);
+    GLSLANG_EXPORT void setGlobalUniformSet(unsigned int set);
+    GLSLANG_EXPORT void setGlobalUniformBinding(unsigned int binding);
+    GLSLANG_EXPORT void setAtomicCounterBlockSet(unsigned int set);
+    GLSLANG_EXPORT void setAtomicCounterBlockBinding(unsigned int binding);
 
     // For setting up the environment (cleared to nothingness in the constructor).
     // These must be called so that parsing is done for the right source language and
@@ -490,7 +508,7 @@ public:
     //
     // setEnvInput:    The input source language and stage. If generating code for a
     //                 specific client, the input client semantics to use and the
-    //                 version of the that client's input semantics to use, otherwise
+    //                 version of that client's input semantics to use, otherwise
     //                 use EShClientNone and version of 0, e.g. for validation mode.
     //                 Note 'version' does not describe the target environment,
     //                 just the version of the source dialect to compile under.
@@ -538,6 +556,9 @@ public:
     bool getEnvTargetHlslFunctionality1() const { return false; }
 #endif
 
+    void setEnvInputVulkanRulesRelaxed() { environment.input.vulkanRulesRelaxed = true; }
+    bool getEnvInputVulkanRulesRelaxed() const { return environment.input.vulkanRulesRelaxed; }
+
     // Interface to #include handlers.
     //
     // To support #include, a client of Glslang does the following:
@@ -701,7 +722,7 @@ class TObjectReflection {
 public:
     GLSLANG_EXPORT TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex);
 
-    GLSLANG_EXPORT const TType* getType() const { return type; }
+    const TType* getType() const { return type; }
     GLSLANG_EXPORT int getBinding() const;
     GLSLANG_EXPORT void dump() const;
     static TObjectReflection badReflection() { return TObjectReflection(); }
@@ -805,7 +826,7 @@ public:
     // Called by TSlotCollector to resolve resource locations or bindings
     virtual void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) = 0;
     // Called by mapIO.addStage to set shader stage mask to mark a stage be added to this pipeline
-    virtual void addStage(EShLanguage stage) = 0;
+    virtual void addStage(EShLanguage stage, TIntermediate& stageIntermediate) = 0;
 };
 
 #endif // !GLSLANG_WEB && !GLSLANG_ANGLE
@@ -927,6 +948,7 @@ public:
 
 protected:
     GLSLANG_EXPORT bool linkStage(EShLanguage, EShMessages);
+    GLSLANG_EXPORT bool crossStageCheck(EShMessages);
 
     TPoolAllocator* pool;
     std::list<TShader*> stages[EShLangCount];

+ 1 - 1
thirdparty/glslang/glslang/build_info.h

@@ -35,7 +35,7 @@
 #define GLSLANG_BUILD_INFO
 
 #define GLSLANG_VERSION_MAJOR 11
-#define GLSLANG_VERSION_MINOR 0
+#define GLSLANG_VERSION_MINOR 6
 #define GLSLANG_VERSION_PATCH 0
 #define GLSLANG_VERSION_FLAVOR ""
 

+ 30 - 3
thirdparty/volk/volk.c

@@ -631,9 +631,12 @@ static void volkGenLoadDevice(void* context, PFN_vkVoidFunction (*load)(void*, c
 	vkGetPastPresentationTimingGOOGLE = (PFN_vkGetPastPresentationTimingGOOGLE)load(context, "vkGetPastPresentationTimingGOOGLE");
 	vkGetRefreshCycleDurationGOOGLE = (PFN_vkGetRefreshCycleDurationGOOGLE)load(context, "vkGetRefreshCycleDurationGOOGLE");
 #endif /* defined(VK_GOOGLE_display_timing) */
+#if defined(VK_HUAWEI_invocation_mask)
+	vkCmdBindInvocationMaskHUAWEI = (PFN_vkCmdBindInvocationMaskHUAWEI)load(context, "vkCmdBindInvocationMaskHUAWEI");
+#endif /* defined(VK_HUAWEI_invocation_mask) */
 #if defined(VK_HUAWEI_subpass_shading)
 	vkCmdSubpassShadingHUAWEI = (PFN_vkCmdSubpassShadingHUAWEI)load(context, "vkCmdSubpassShadingHUAWEI");
-	vkGetSubpassShadingMaxWorkgroupSizeHUAWEI = (PFN_vkGetSubpassShadingMaxWorkgroupSizeHUAWEI)load(context, "vkGetSubpassShadingMaxWorkgroupSizeHUAWEI");
+	vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI = (PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI)load(context, "vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI");
 #endif /* defined(VK_HUAWEI_subpass_shading) */
 #if defined(VK_INTEL_performance_query)
 	vkAcquirePerformanceConfigurationINTEL = (PFN_vkAcquirePerformanceConfigurationINTEL)load(context, "vkAcquirePerformanceConfigurationINTEL");
@@ -758,6 +761,9 @@ static void volkGenLoadDevice(void* context, PFN_vkVoidFunction (*load)(void*, c
 	vkGetPipelineExecutablePropertiesKHR = (PFN_vkGetPipelineExecutablePropertiesKHR)load(context, "vkGetPipelineExecutablePropertiesKHR");
 	vkGetPipelineExecutableStatisticsKHR = (PFN_vkGetPipelineExecutableStatisticsKHR)load(context, "vkGetPipelineExecutableStatisticsKHR");
 #endif /* defined(VK_KHR_pipeline_executable_properties) */
+#if defined(VK_KHR_present_wait)
+	vkWaitForPresentKHR = (PFN_vkWaitForPresentKHR)load(context, "vkWaitForPresentKHR");
+#endif /* defined(VK_KHR_present_wait) */
 #if defined(VK_KHR_push_descriptor)
 	vkCmdPushDescriptorSetKHR = (PFN_vkCmdPushDescriptorSetKHR)load(context, "vkCmdPushDescriptorSetKHR");
 #endif /* defined(VK_KHR_push_descriptor) */
@@ -847,6 +853,9 @@ static void volkGenLoadDevice(void* context, PFN_vkVoidFunction (*load)(void*, c
 	vkDestroyIndirectCommandsLayoutNV = (PFN_vkDestroyIndirectCommandsLayoutNV)load(context, "vkDestroyIndirectCommandsLayoutNV");
 	vkGetGeneratedCommandsMemoryRequirementsNV = (PFN_vkGetGeneratedCommandsMemoryRequirementsNV)load(context, "vkGetGeneratedCommandsMemoryRequirementsNV");
 #endif /* defined(VK_NV_device_generated_commands) */
+#if defined(VK_NV_external_memory_rdma)
+	vkGetMemoryRemoteAddressNV = (PFN_vkGetMemoryRemoteAddressNV)load(context, "vkGetMemoryRemoteAddressNV");
+#endif /* defined(VK_NV_external_memory_rdma) */
 #if defined(VK_NV_external_memory_win32)
 	vkGetMemoryWin32HandleNV = (PFN_vkGetMemoryWin32HandleNV)load(context, "vkGetMemoryWin32HandleNV");
 #endif /* defined(VK_NV_external_memory_win32) */
@@ -1182,9 +1191,12 @@ static void volkGenLoadDeviceTable(struct VolkDeviceTable* table, void* context,
 	table->vkGetPastPresentationTimingGOOGLE = (PFN_vkGetPastPresentationTimingGOOGLE)load(context, "vkGetPastPresentationTimingGOOGLE");
 	table->vkGetRefreshCycleDurationGOOGLE = (PFN_vkGetRefreshCycleDurationGOOGLE)load(context, "vkGetRefreshCycleDurationGOOGLE");
 #endif /* defined(VK_GOOGLE_display_timing) */
+#if defined(VK_HUAWEI_invocation_mask)
+	table->vkCmdBindInvocationMaskHUAWEI = (PFN_vkCmdBindInvocationMaskHUAWEI)load(context, "vkCmdBindInvocationMaskHUAWEI");
+#endif /* defined(VK_HUAWEI_invocation_mask) */
 #if defined(VK_HUAWEI_subpass_shading)
 	table->vkCmdSubpassShadingHUAWEI = (PFN_vkCmdSubpassShadingHUAWEI)load(context, "vkCmdSubpassShadingHUAWEI");
-	table->vkGetSubpassShadingMaxWorkgroupSizeHUAWEI = (PFN_vkGetSubpassShadingMaxWorkgroupSizeHUAWEI)load(context, "vkGetSubpassShadingMaxWorkgroupSizeHUAWEI");
+	table->vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI = (PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI)load(context, "vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI");
 #endif /* defined(VK_HUAWEI_subpass_shading) */
 #if defined(VK_INTEL_performance_query)
 	table->vkAcquirePerformanceConfigurationINTEL = (PFN_vkAcquirePerformanceConfigurationINTEL)load(context, "vkAcquirePerformanceConfigurationINTEL");
@@ -1309,6 +1321,9 @@ static void volkGenLoadDeviceTable(struct VolkDeviceTable* table, void* context,
 	table->vkGetPipelineExecutablePropertiesKHR = (PFN_vkGetPipelineExecutablePropertiesKHR)load(context, "vkGetPipelineExecutablePropertiesKHR");
 	table->vkGetPipelineExecutableStatisticsKHR = (PFN_vkGetPipelineExecutableStatisticsKHR)load(context, "vkGetPipelineExecutableStatisticsKHR");
 #endif /* defined(VK_KHR_pipeline_executable_properties) */
+#if defined(VK_KHR_present_wait)
+	table->vkWaitForPresentKHR = (PFN_vkWaitForPresentKHR)load(context, "vkWaitForPresentKHR");
+#endif /* defined(VK_KHR_present_wait) */
 #if defined(VK_KHR_push_descriptor)
 	table->vkCmdPushDescriptorSetKHR = (PFN_vkCmdPushDescriptorSetKHR)load(context, "vkCmdPushDescriptorSetKHR");
 #endif /* defined(VK_KHR_push_descriptor) */
@@ -1398,6 +1413,9 @@ static void volkGenLoadDeviceTable(struct VolkDeviceTable* table, void* context,
 	table->vkDestroyIndirectCommandsLayoutNV = (PFN_vkDestroyIndirectCommandsLayoutNV)load(context, "vkDestroyIndirectCommandsLayoutNV");
 	table->vkGetGeneratedCommandsMemoryRequirementsNV = (PFN_vkGetGeneratedCommandsMemoryRequirementsNV)load(context, "vkGetGeneratedCommandsMemoryRequirementsNV");
 #endif /* defined(VK_NV_device_generated_commands) */
+#if defined(VK_NV_external_memory_rdma)
+	table->vkGetMemoryRemoteAddressNV = (PFN_vkGetMemoryRemoteAddressNV)load(context, "vkGetMemoryRemoteAddressNV");
+#endif /* defined(VK_NV_external_memory_rdma) */
 #if defined(VK_NV_external_memory_win32)
 	table->vkGetMemoryWin32HandleNV = (PFN_vkGetMemoryWin32HandleNV)load(context, "vkGetMemoryWin32HandleNV");
 #endif /* defined(VK_NV_external_memory_win32) */
@@ -1822,9 +1840,12 @@ PFN_vkCreateStreamDescriptorSurfaceGGP vkCreateStreamDescriptorSurfaceGGP;
 PFN_vkGetPastPresentationTimingGOOGLE vkGetPastPresentationTimingGOOGLE;
 PFN_vkGetRefreshCycleDurationGOOGLE vkGetRefreshCycleDurationGOOGLE;
 #endif /* defined(VK_GOOGLE_display_timing) */
+#if defined(VK_HUAWEI_invocation_mask)
+PFN_vkCmdBindInvocationMaskHUAWEI vkCmdBindInvocationMaskHUAWEI;
+#endif /* defined(VK_HUAWEI_invocation_mask) */
 #if defined(VK_HUAWEI_subpass_shading)
 PFN_vkCmdSubpassShadingHUAWEI vkCmdSubpassShadingHUAWEI;
-PFN_vkGetSubpassShadingMaxWorkgroupSizeHUAWEI vkGetSubpassShadingMaxWorkgroupSizeHUAWEI;
+PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI;
 #endif /* defined(VK_HUAWEI_subpass_shading) */
 #if defined(VK_INTEL_performance_query)
 PFN_vkAcquirePerformanceConfigurationINTEL vkAcquirePerformanceConfigurationINTEL;
@@ -1995,6 +2016,9 @@ PFN_vkGetPipelineExecutableInternalRepresentationsKHR vkGetPipelineExecutableInt
 PFN_vkGetPipelineExecutablePropertiesKHR vkGetPipelineExecutablePropertiesKHR;
 PFN_vkGetPipelineExecutableStatisticsKHR vkGetPipelineExecutableStatisticsKHR;
 #endif /* defined(VK_KHR_pipeline_executable_properties) */
+#if defined(VK_KHR_present_wait)
+PFN_vkWaitForPresentKHR vkWaitForPresentKHR;
+#endif /* defined(VK_KHR_present_wait) */
 #if defined(VK_KHR_push_descriptor)
 PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR;
 #endif /* defined(VK_KHR_push_descriptor) */
@@ -2131,6 +2155,9 @@ PFN_vkGetGeneratedCommandsMemoryRequirementsNV vkGetGeneratedCommandsMemoryRequi
 #if defined(VK_NV_external_memory_capabilities)
 PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV vkGetPhysicalDeviceExternalImageFormatPropertiesNV;
 #endif /* defined(VK_NV_external_memory_capabilities) */
+#if defined(VK_NV_external_memory_rdma)
+PFN_vkGetMemoryRemoteAddressNV vkGetMemoryRemoteAddressNV;
+#endif /* defined(VK_NV_external_memory_rdma) */
 #if defined(VK_NV_external_memory_win32)
 PFN_vkGetMemoryWin32HandleNV vkGetMemoryWin32HandleNV;
 #endif /* defined(VK_NV_external_memory_win32) */

+ 25 - 4
thirdparty/volk/volk.h

@@ -15,7 +15,7 @@
 #endif
 
 /* VOLK_GENERATE_VERSION_DEFINE */
-#define VOLK_HEADER_VERSION 182
+#define VOLK_HEADER_VERSION 190
 /* VOLK_GENERATE_VERSION_DEFINE */
 
 #ifndef VK_NO_PROTOTYPES
@@ -51,10 +51,13 @@
 #	endif
 #endif
 
-/* Disable VK_NVX_image_view_handle because SDK 140 introduced a change that can't be used with prior versions */
+/* Disable several extensions on earlier SDKs because later SDKs introduce a backwards incompatible change to function signatures */
 #if VK_HEADER_VERSION < 140
 #	undef VK_NVX_image_view_handle
 #endif
+#if VK_HEADER_VERSION < 184
+#	undef VK_HUAWEI_subpass_shading
+#endif
 
 #ifdef __cplusplus
 extern "C" {
@@ -410,9 +413,12 @@ struct VolkDeviceTable
 	PFN_vkGetPastPresentationTimingGOOGLE vkGetPastPresentationTimingGOOGLE;
 	PFN_vkGetRefreshCycleDurationGOOGLE vkGetRefreshCycleDurationGOOGLE;
 #endif /* defined(VK_GOOGLE_display_timing) */
+#if defined(VK_HUAWEI_invocation_mask)
+	PFN_vkCmdBindInvocationMaskHUAWEI vkCmdBindInvocationMaskHUAWEI;
+#endif /* defined(VK_HUAWEI_invocation_mask) */
 #if defined(VK_HUAWEI_subpass_shading)
 	PFN_vkCmdSubpassShadingHUAWEI vkCmdSubpassShadingHUAWEI;
-	PFN_vkGetSubpassShadingMaxWorkgroupSizeHUAWEI vkGetSubpassShadingMaxWorkgroupSizeHUAWEI;
+	PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI;
 #endif /* defined(VK_HUAWEI_subpass_shading) */
 #if defined(VK_INTEL_performance_query)
 	PFN_vkAcquirePerformanceConfigurationINTEL vkAcquirePerformanceConfigurationINTEL;
@@ -537,6 +543,9 @@ struct VolkDeviceTable
 	PFN_vkGetPipelineExecutablePropertiesKHR vkGetPipelineExecutablePropertiesKHR;
 	PFN_vkGetPipelineExecutableStatisticsKHR vkGetPipelineExecutableStatisticsKHR;
 #endif /* defined(VK_KHR_pipeline_executable_properties) */
+#if defined(VK_KHR_present_wait)
+	PFN_vkWaitForPresentKHR vkWaitForPresentKHR;
+#endif /* defined(VK_KHR_present_wait) */
 #if defined(VK_KHR_push_descriptor)
 	PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR;
 #endif /* defined(VK_KHR_push_descriptor) */
@@ -626,6 +635,9 @@ struct VolkDeviceTable
 	PFN_vkDestroyIndirectCommandsLayoutNV vkDestroyIndirectCommandsLayoutNV;
 	PFN_vkGetGeneratedCommandsMemoryRequirementsNV vkGetGeneratedCommandsMemoryRequirementsNV;
 #endif /* defined(VK_NV_device_generated_commands) */
+#if defined(VK_NV_external_memory_rdma)
+	PFN_vkGetMemoryRemoteAddressNV vkGetMemoryRemoteAddressNV;
+#endif /* defined(VK_NV_external_memory_rdma) */
 #if defined(VK_NV_external_memory_win32)
 	PFN_vkGetMemoryWin32HandleNV vkGetMemoryWin32HandleNV;
 #endif /* defined(VK_NV_external_memory_win32) */
@@ -1042,9 +1054,12 @@ extern PFN_vkCreateStreamDescriptorSurfaceGGP vkCreateStreamDescriptorSurfaceGGP
 extern PFN_vkGetPastPresentationTimingGOOGLE vkGetPastPresentationTimingGOOGLE;
 extern PFN_vkGetRefreshCycleDurationGOOGLE vkGetRefreshCycleDurationGOOGLE;
 #endif /* defined(VK_GOOGLE_display_timing) */
+#if defined(VK_HUAWEI_invocation_mask)
+extern PFN_vkCmdBindInvocationMaskHUAWEI vkCmdBindInvocationMaskHUAWEI;
+#endif /* defined(VK_HUAWEI_invocation_mask) */
 #if defined(VK_HUAWEI_subpass_shading)
 extern PFN_vkCmdSubpassShadingHUAWEI vkCmdSubpassShadingHUAWEI;
-extern PFN_vkGetSubpassShadingMaxWorkgroupSizeHUAWEI vkGetSubpassShadingMaxWorkgroupSizeHUAWEI;
+extern PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI;
 #endif /* defined(VK_HUAWEI_subpass_shading) */
 #if defined(VK_INTEL_performance_query)
 extern PFN_vkAcquirePerformanceConfigurationINTEL vkAcquirePerformanceConfigurationINTEL;
@@ -1215,6 +1230,9 @@ extern PFN_vkGetPipelineExecutableInternalRepresentationsKHR vkGetPipelineExecut
 extern PFN_vkGetPipelineExecutablePropertiesKHR vkGetPipelineExecutablePropertiesKHR;
 extern PFN_vkGetPipelineExecutableStatisticsKHR vkGetPipelineExecutableStatisticsKHR;
 #endif /* defined(VK_KHR_pipeline_executable_properties) */
+#if defined(VK_KHR_present_wait)
+extern PFN_vkWaitForPresentKHR vkWaitForPresentKHR;
+#endif /* defined(VK_KHR_present_wait) */
 #if defined(VK_KHR_push_descriptor)
 extern PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR;
 #endif /* defined(VK_KHR_push_descriptor) */
@@ -1351,6 +1369,9 @@ extern PFN_vkGetGeneratedCommandsMemoryRequirementsNV vkGetGeneratedCommandsMemo
 #if defined(VK_NV_external_memory_capabilities)
 extern PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV vkGetPhysicalDeviceExternalImageFormatPropertiesNV;
 #endif /* defined(VK_NV_external_memory_capabilities) */
+#if defined(VK_NV_external_memory_rdma)
+extern PFN_vkGetMemoryRemoteAddressNV vkGetMemoryRemoteAddressNV;
+#endif /* defined(VK_NV_external_memory_rdma) */
 #if defined(VK_NV_external_memory_win32)
 extern PFN_vkGetMemoryWin32HandleNV vkGetMemoryWin32HandleNV;
 #endif /* defined(VK_NV_external_memory_win32) */

File diff suppressed because it is too large
+ 232 - 118
thirdparty/vulkan/include/vulkan/vulkan.hpp


+ 48 - 48
thirdparty/vulkan/include/vulkan/vulkan_beta.h

@@ -22,7 +22,7 @@ extern "C" {
 #define VK_KHR_video_queue 1
 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkVideoSessionKHR)
 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkVideoSessionParametersKHR)
-#define VK_KHR_VIDEO_QUEUE_SPEC_VERSION   1
+#define VK_KHR_VIDEO_QUEUE_SPEC_VERSION   2
 #define VK_KHR_VIDEO_QUEUE_EXTENSION_NAME "VK_KHR_video_queue"
 
 typedef enum VkQueryResultStatusKHR {
@@ -66,12 +66,12 @@ typedef enum VkVideoComponentBitDepthFlagBitsKHR {
 } VkVideoComponentBitDepthFlagBitsKHR;
 typedef VkFlags VkVideoComponentBitDepthFlagsKHR;
 
-typedef enum VkVideoCapabilitiesFlagBitsKHR {
-    VK_VIDEO_CAPABILITIES_PROTECTED_CONTENT_BIT_KHR = 0x00000001,
-    VK_VIDEO_CAPABILITIES_SEPARATE_REFERENCE_IMAGES_BIT_KHR = 0x00000002,
-    VK_VIDEO_CAPABILITIES_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
-} VkVideoCapabilitiesFlagBitsKHR;
-typedef VkFlags VkVideoCapabilitiesFlagsKHR;
+typedef enum VkVideoCapabilityFlagBitsKHR {
+    VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR = 0x00000001,
+    VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR = 0x00000002,
+    VK_VIDEO_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkVideoCapabilityFlagBitsKHR;
+typedef VkFlags VkVideoCapabilityFlagsKHR;
 
 typedef enum VkVideoSessionCreateFlagBitsKHR {
     VK_VIDEO_SESSION_CREATE_DEFAULT_KHR = 0,
@@ -120,21 +120,21 @@ typedef struct VkVideoProfilesKHR {
 } VkVideoProfilesKHR;
 
 typedef struct VkVideoCapabilitiesKHR {
-    VkStructureType                sType;
-    void*                          pNext;
-    VkVideoCapabilitiesFlagsKHR    capabilityFlags;
-    VkDeviceSize                   minBitstreamBufferOffsetAlignment;
-    VkDeviceSize                   minBitstreamBufferSizeAlignment;
-    VkExtent2D                     videoPictureExtentGranularity;
-    VkExtent2D                     minExtent;
-    VkExtent2D                     maxExtent;
-    uint32_t                       maxReferencePicturesSlotsCount;
-    uint32_t                       maxReferencePicturesActiveCount;
+    VkStructureType              sType;
+    void*                        pNext;
+    VkVideoCapabilityFlagsKHR    capabilityFlags;
+    VkDeviceSize                 minBitstreamBufferOffsetAlignment;
+    VkDeviceSize                 minBitstreamBufferSizeAlignment;
+    VkExtent2D                   videoPictureExtentGranularity;
+    VkExtent2D                   minExtent;
+    VkExtent2D                   maxExtent;
+    uint32_t                     maxReferencePicturesSlotsCount;
+    uint32_t                     maxReferencePicturesActiveCount;
 } VkVideoCapabilitiesKHR;
 
 typedef struct VkPhysicalDeviceVideoFormatInfoKHR {
     VkStructureType              sType;
-    const void*                  pNext;
+    void*                        pNext;
     VkImageUsageFlags            imageUsage;
     const VkVideoProfilesKHR*    pVideoProfiles;
 } VkPhysicalDeviceVideoFormatInfoKHR;
@@ -433,10 +433,10 @@ VKAPI_ATTR void VKAPI_CALL vkCmdEncodeVideoKHR(
 #define VK_EXT_video_encode_h264 1
 #include "vk_video/vulkan_video_codec_h264std.h"
 #include "vk_video/vulkan_video_codec_h264std_encode.h"
-#define VK_EXT_VIDEO_ENCODE_H264_SPEC_VERSION 1
+#define VK_EXT_VIDEO_ENCODE_H264_SPEC_VERSION 2
 #define VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME "VK_EXT_video_encode_h264"
 
-typedef enum VkVideoEncodeH264CapabilitiesFlagBitsEXT {
+typedef enum VkVideoEncodeH264CapabilityFlagBitsEXT {
     VK_VIDEO_ENCODE_H264_CAPABILITY_CABAC_BIT_EXT = 0x00000001,
     VK_VIDEO_ENCODE_H264_CAPABILITY_CAVLC_BIT_EXT = 0x00000002,
     VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BI_PRED_IMPLICIT_BIT_EXT = 0x00000004,
@@ -448,9 +448,9 @@ typedef enum VkVideoEncodeH264CapabilitiesFlagBitsEXT {
     VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_PARTIAL_BIT_EXT = 0x00000100,
     VK_VIDEO_ENCODE_H264_CAPABILITY_MULTIPLE_SLICE_PER_FRAME_BIT_EXT = 0x00000200,
     VK_VIDEO_ENCODE_H264_CAPABILITY_EVENLY_DISTRIBUTED_SLICE_SIZE_BIT_EXT = 0x00000400,
-    VK_VIDEO_ENCODE_H264_CAPABILITIES_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
-} VkVideoEncodeH264CapabilitiesFlagBitsEXT;
-typedef VkFlags VkVideoEncodeH264CapabilitiesFlagsEXT;
+    VK_VIDEO_ENCODE_H264_CAPABILITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkVideoEncodeH264CapabilityFlagBitsEXT;
+typedef VkFlags VkVideoEncodeH264CapabilityFlagsEXT;
 
 typedef enum VkVideoEncodeH264InputModeFlagBitsEXT {
     VK_VIDEO_ENCODE_H264_INPUT_MODE_FRAME_BIT_EXT = 0x00000001,
@@ -475,19 +475,19 @@ typedef enum VkVideoEncodeH264CreateFlagBitsEXT {
 } VkVideoEncodeH264CreateFlagBitsEXT;
 typedef VkFlags VkVideoEncodeH264CreateFlagsEXT;
 typedef struct VkVideoEncodeH264CapabilitiesEXT {
-    VkStructureType                          sType;
-    const void*                              pNext;
-    VkVideoEncodeH264CapabilitiesFlagsEXT    flags;
-    VkVideoEncodeH264InputModeFlagsEXT       inputModeFlags;
-    VkVideoEncodeH264OutputModeFlagsEXT      outputModeFlags;
-    VkExtent2D                               minPictureSizeInMbs;
-    VkExtent2D                               maxPictureSizeInMbs;
-    VkExtent2D                               inputImageDataAlignment;
-    uint8_t                                  maxNumL0ReferenceForP;
-    uint8_t                                  maxNumL0ReferenceForB;
-    uint8_t                                  maxNumL1Reference;
-    uint8_t                                  qualityLevelCount;
-    VkExtensionProperties                    stdExtensionVersion;
+    VkStructureType                        sType;
+    const void*                            pNext;
+    VkVideoEncodeH264CapabilityFlagsEXT    flags;
+    VkVideoEncodeH264InputModeFlagsEXT     inputModeFlags;
+    VkVideoEncodeH264OutputModeFlagsEXT    outputModeFlags;
+    VkExtent2D                             minPictureSizeInMbs;
+    VkExtent2D                             maxPictureSizeInMbs;
+    VkExtent2D                             inputImageDataAlignment;
+    uint8_t                                maxNumL0ReferenceForP;
+    uint8_t                                maxNumL0ReferenceForB;
+    uint8_t                                maxNumL1Reference;
+    uint8_t                                qualityLevelCount;
+    VkExtensionProperties                  stdExtensionVersion;
 } VkVideoEncodeH264CapabilitiesEXT;
 
 typedef struct VkVideoEncodeH264SessionCreateInfoEXT {
@@ -567,22 +567,22 @@ typedef struct VkVideoEncodeH264ProfileEXT {
 
 #define VK_EXT_video_decode_h264 1
 #include "vk_video/vulkan_video_codec_h264std_decode.h"
-#define VK_EXT_VIDEO_DECODE_H264_SPEC_VERSION 1
+#define VK_EXT_VIDEO_DECODE_H264_SPEC_VERSION 3
 #define VK_EXT_VIDEO_DECODE_H264_EXTENSION_NAME "VK_EXT_video_decode_h264"
 
-typedef enum VkVideoDecodeH264FieldLayoutFlagBitsEXT {
-    VK_VIDEO_DECODE_H264_PROGRESSIVE_PICTURES_ONLY_EXT = 0,
-    VK_VIDEO_DECODE_H264_FIELD_LAYOUT_LINE_INTERLACED_PLANE_BIT_EXT = 0x00000001,
-    VK_VIDEO_DECODE_H264_FIELD_LAYOUT_SEPARATE_INTERLACED_PLANE_BIT_EXT = 0x00000002,
-    VK_VIDEO_DECODE_H264_FIELD_LAYOUT_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
-} VkVideoDecodeH264FieldLayoutFlagBitsEXT;
-typedef VkFlags VkVideoDecodeH264FieldLayoutFlagsEXT;
+typedef enum VkVideoDecodeH264PictureLayoutFlagBitsEXT {
+    VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_EXT = 0,
+    VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_EXT = 0x00000001,
+    VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_SEPARATE_PLANES_BIT_EXT = 0x00000002,
+    VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkVideoDecodeH264PictureLayoutFlagBitsEXT;
+typedef VkFlags VkVideoDecodeH264PictureLayoutFlagsEXT;
 typedef VkFlags VkVideoDecodeH264CreateFlagsEXT;
 typedef struct VkVideoDecodeH264ProfileEXT {
-    VkStructureType                         sType;
-    const void*                             pNext;
-    StdVideoH264ProfileIdc                  stdProfileIdc;
-    VkVideoDecodeH264FieldLayoutFlagsEXT    fieldLayout;
+    VkStructureType                           sType;
+    const void*                               pNext;
+    StdVideoH264ProfileIdc                    stdProfileIdc;
+    VkVideoDecodeH264PictureLayoutFlagsEXT    pictureLayout;
 } VkVideoDecodeH264ProfileEXT;
 
 typedef struct VkVideoDecodeH264CapabilitiesEXT {

+ 223 - 30
thirdparty/vulkan/include/vulkan/vulkan_core.h

@@ -72,7 +72,7 @@ extern "C" {
 #define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0
 
 // Version of this file
-#define VK_HEADER_VERSION 182
+#define VK_HEADER_VERSION 190
 
 // Complete version of this file
 #define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 2, VK_HEADER_VERSION)
@@ -120,6 +120,7 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet)
 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool)
 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer)
 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool)
+#define VK_UUID_SIZE                      16U
 #define VK_ATTACHMENT_UNUSED              (~0U)
 #define VK_FALSE                          0U
 #define VK_LOD_CLAMP_NONE                 1000.0F
@@ -132,7 +133,6 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool)
 #define VK_MAX_MEMORY_TYPES               32U
 #define VK_MAX_MEMORY_HEAPS               16U
 #define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE  256U
-#define VK_UUID_SIZE                      16U
 #define VK_MAX_EXTENSION_NAME_SIZE        256U
 #define VK_MAX_DESCRIPTION_SIZE           256U
 
@@ -714,6 +714,7 @@ typedef enum VkStructureType {
     VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = 1000245000,
     VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT = 1000247000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR = 1000248000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000,
     VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249002,
@@ -741,6 +742,7 @@ typedef enum VkStructureType {
     VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR = 1000269003,
     VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004,
     VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT = 1000273000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = 1000276000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV = 1000277000,
     VK_STRUCTURE_TYPE_GRAPHICS_SHADER_GROUP_CREATE_INFO_NV = 1000277001,
@@ -752,6 +754,8 @@ typedef enum VkStructureType {
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV = 1000277007,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV = 1000278000,
     VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV = 1000278001,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR = 1000280000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR = 1000280001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = 1000281001,
     VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM = 1000282000,
@@ -765,6 +769,8 @@ typedef enum VkStructureType {
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT = 1000287001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT = 1000287002,
     VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000,
+    VK_STRUCTURE_TYPE_PRESENT_ID_KHR = 1000294000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR = 1000294001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = 1000295000,
     VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = 1000295001,
     VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT = 1000295002,
@@ -820,14 +826,18 @@ typedef enum VkStructureType {
     VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT = 1000352001,
     VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT = 1000352002,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT = 1000353000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT = 1000356000,
     VK_STRUCTURE_TYPE_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364000,
     VK_STRUCTURE_TYPE_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA = 1000364001,
     VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364002,
     VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365000,
     VK_STRUCTURE_TYPE_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365001,
-    VK_STRUCTURE_TYPE_SUBPASSS_SHADING_PIPELINE_CREATE_INFO_HUAWEI = 1000369000,
+    VK_STRUCTURE_TYPE_SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI = 1000369000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI = 1000369001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_PROPERTIES_HUAWEI = 1000369002,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI = 1000370000,
+    VK_STRUCTURE_TYPE_MEMORY_GET_REMOTE_ADDRESS_INFO_NV = 1000371000,
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV = 1000371001,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT = 1000377000,
     VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX = 1000378000,
     VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT = 1000381000,
@@ -1058,6 +1068,11 @@ typedef enum VkObjectType {
     VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF
 } VkObjectType;
 
+typedef enum VkPipelineCacheHeaderVersion {
+    VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1,
+    VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF
+} VkPipelineCacheHeaderVersion;
+
 typedef enum VkVendorId {
     VK_VENDOR_ID_VIV = 0x10001,
     VK_VENDOR_ID_VSI = 0x10002,
@@ -1068,11 +1083,6 @@ typedef enum VkVendorId {
     VK_VENDOR_ID_MAX_ENUM = 0x7FFFFFFF
 } VkVendorId;
 
-typedef enum VkPipelineCacheHeaderVersion {
-    VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1,
-    VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF
-} VkPipelineCacheHeaderVersion;
-
 typedef enum VkSystemAllocationScope {
     VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0,
     VK_SYSTEM_ALLOCATION_SCOPE_OBJECT = 1,
@@ -1699,13 +1709,15 @@ typedef enum VkAttachmentLoadOp {
     VK_ATTACHMENT_LOAD_OP_LOAD = 0,
     VK_ATTACHMENT_LOAD_OP_CLEAR = 1,
     VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2,
+    VK_ATTACHMENT_LOAD_OP_NONE_EXT = 1000400000,
     VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF
 } VkAttachmentLoadOp;
 
 typedef enum VkAttachmentStoreOp {
     VK_ATTACHMENT_STORE_OP_STORE = 0,
     VK_ATTACHMENT_STORE_OP_DONT_CARE = 1,
-    VK_ATTACHMENT_STORE_OP_NONE_QCOM = 1000301000,
+    VK_ATTACHMENT_STORE_OP_NONE_EXT = 1000301000,
+    VK_ATTACHMENT_STORE_OP_NONE_QCOM = VK_ATTACHMENT_STORE_OP_NONE_EXT,
     VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF
 } VkAttachmentStoreOp;
 
@@ -1917,6 +1929,7 @@ typedef enum VkImageUsageFlagBits {
 #ifdef VK_ENABLE_BETA_EXTENSIONS
     VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR = 0x00008000,
 #endif
+    VK_IMAGE_USAGE_INVOCATION_MASK_BIT_HUAWEI = 0x00040000,
     VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV = VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR,
     VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkImageUsageFlagBits;
@@ -1940,6 +1953,7 @@ typedef enum VkMemoryPropertyFlagBits {
     VK_MEMORY_PROPERTY_PROTECTED_BIT = 0x00000020,
     VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD = 0x00000040,
     VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD = 0x00000080,
+    VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV = 0x00000100,
     VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkMemoryPropertyFlagBits;
 typedef VkFlags VkMemoryPropertyFlags;
@@ -2114,10 +2128,6 @@ typedef enum VkImageViewCreateFlagBits {
     VK_IMAGE_VIEW_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
 } VkImageViewCreateFlagBits;
 typedef VkFlags VkImageViewCreateFlags;
-
-typedef enum VkShaderModuleCreateFlagBits {
-    VK_SHADER_MODULE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
-} VkShaderModuleCreateFlagBits;
 typedef VkFlags VkShaderModuleCreateFlags;
 
 typedef enum VkPipelineCacheCreateFlagBits {
@@ -2421,6 +2431,14 @@ typedef struct VkMemoryBarrier {
     VkAccessFlags      dstAccessMask;
 } VkMemoryBarrier;
 
+typedef struct VkPipelineCacheHeaderVersionOne {
+    uint32_t                        headerSize;
+    VkPipelineCacheHeaderVersion    headerVersion;
+    uint32_t                        vendorID;
+    uint32_t                        deviceID;
+    uint8_t                         pipelineCacheUUID[VK_UUID_SIZE];
+} VkPipelineCacheHeaderVersionOne;
+
 typedef void* (VKAPI_PTR *PFN_vkAllocationFunction)(
     void*                                       pUserData,
     size_t                                      size,
@@ -4492,6 +4510,7 @@ typedef enum VkExternalMemoryHandleTypeFlagBits {
     VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT = 0x00000080,
     VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT = 0x00000100,
     VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA = 0x00000800,
+    VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV = 0x00001000,
     VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
     VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT,
     VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
@@ -5264,6 +5283,7 @@ typedef enum VkDriverId {
     VK_DRIVER_ID_MOLTENVK = 14,
     VK_DRIVER_ID_COREAVI_PROPRIETARY = 15,
     VK_DRIVER_ID_JUICE_PROPRIETARY = 16,
+    VK_DRIVER_ID_VERISILICON_PROPRIETARY = 17,
     VK_DRIVER_ID_AMD_PROPRIETARY_KHR = VK_DRIVER_ID_AMD_PROPRIETARY,
     VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = VK_DRIVER_ID_AMD_OPEN_SOURCE,
     VK_DRIVER_ID_MESA_RADV_KHR = VK_DRIVER_ID_MESA_RADV,
@@ -6177,7 +6197,7 @@ typedef struct VkAcquireNextImageInfoKHR {
 
 typedef struct VkDeviceGroupPresentCapabilitiesKHR {
     VkStructureType                     sType;
-    const void*                         pNext;
+    void*                               pNext;
     uint32_t                            presentMask[VK_MAX_DEVICE_GROUP_SIZE];
     VkDeviceGroupPresentModeFlagsKHR    modes;
 } VkDeviceGroupPresentCapabilitiesKHR;
@@ -7052,7 +7072,7 @@ typedef struct VkPhysicalDevicePerformanceQueryPropertiesKHR {
 
 typedef struct VkPerformanceCounterKHR {
     VkStructureType                   sType;
-    const void*                       pNext;
+    void*                             pNext;
     VkPerformanceCounterUnitKHR       unit;
     VkPerformanceCounterScopeKHR      scope;
     VkPerformanceCounterStorageKHR    storage;
@@ -7061,7 +7081,7 @@ typedef struct VkPerformanceCounterKHR {
 
 typedef struct VkPerformanceCounterDescriptionKHR {
     VkStructureType                            sType;
-    const void*                                pNext;
+    void*                                      pNext;
     VkPerformanceCounterDescriptionFlagsKHR    flags;
     char                                       name[VK_MAX_DESCRIPTION_SIZE];
     char                                       category[VK_MAX_DESCRIPTION_SIZE];
@@ -7662,6 +7682,26 @@ typedef VkAttachmentDescriptionStencilLayout VkAttachmentDescriptionStencilLayou
 
 
 
+#define VK_KHR_present_wait 1
+#define VK_KHR_PRESENT_WAIT_SPEC_VERSION  1
+#define VK_KHR_PRESENT_WAIT_EXTENSION_NAME "VK_KHR_present_wait"
+typedef struct VkPhysicalDevicePresentWaitFeaturesKHR {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           presentWait;
+} VkPhysicalDevicePresentWaitFeaturesKHR;
+
+typedef VkResult (VKAPI_PTR *PFN_vkWaitForPresentKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t presentId, uint64_t timeout);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkWaitForPresentKHR(
+    VkDevice                                    device,
+    VkSwapchainKHR                              swapchain,
+    uint64_t                                    presentId,
+    uint64_t                                    timeout);
+#endif
+
+
 #define VK_KHR_uniform_buffer_standard_layout 1
 #define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_SPEC_VERSION 1
 #define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME "VK_KHR_uniform_buffer_standard_layout"
@@ -7826,6 +7866,52 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutableInternalRepresentationsKHR
 #endif
 
 
+#define VK_KHR_shader_integer_dot_product 1
+#define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_SPEC_VERSION 1
+#define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME "VK_KHR_shader_integer_dot_product"
+typedef struct VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           shaderIntegerDotProduct;
+} VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR;
+
+typedef struct VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           integerDotProduct8BitUnsignedAccelerated;
+    VkBool32           integerDotProduct8BitSignedAccelerated;
+    VkBool32           integerDotProduct8BitMixedSignednessAccelerated;
+    VkBool32           integerDotProduct4x8BitPackedUnsignedAccelerated;
+    VkBool32           integerDotProduct4x8BitPackedSignedAccelerated;
+    VkBool32           integerDotProduct4x8BitPackedMixedSignednessAccelerated;
+    VkBool32           integerDotProduct16BitUnsignedAccelerated;
+    VkBool32           integerDotProduct16BitSignedAccelerated;
+    VkBool32           integerDotProduct16BitMixedSignednessAccelerated;
+    VkBool32           integerDotProduct32BitUnsignedAccelerated;
+    VkBool32           integerDotProduct32BitSignedAccelerated;
+    VkBool32           integerDotProduct32BitMixedSignednessAccelerated;
+    VkBool32           integerDotProduct64BitUnsignedAccelerated;
+    VkBool32           integerDotProduct64BitSignedAccelerated;
+    VkBool32           integerDotProduct64BitMixedSignednessAccelerated;
+    VkBool32           integerDotProductAccumulatingSaturating8BitUnsignedAccelerated;
+    VkBool32           integerDotProductAccumulatingSaturating8BitSignedAccelerated;
+    VkBool32           integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated;
+    VkBool32           integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated;
+    VkBool32           integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated;
+    VkBool32           integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated;
+    VkBool32           integerDotProductAccumulatingSaturating16BitUnsignedAccelerated;
+    VkBool32           integerDotProductAccumulatingSaturating16BitSignedAccelerated;
+    VkBool32           integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated;
+    VkBool32           integerDotProductAccumulatingSaturating32BitUnsignedAccelerated;
+    VkBool32           integerDotProductAccumulatingSaturating32BitSignedAccelerated;
+    VkBool32           integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated;
+    VkBool32           integerDotProductAccumulatingSaturating64BitUnsignedAccelerated;
+    VkBool32           integerDotProductAccumulatingSaturating64BitSignedAccelerated;
+    VkBool32           integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated;
+} VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR;
+
+
+
 #define VK_KHR_pipeline_library 1
 #define VK_KHR_PIPELINE_LIBRARY_SPEC_VERSION 1
 #define VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME "VK_KHR_pipeline_library"
@@ -7843,6 +7929,24 @@ typedef struct VkPipelineLibraryCreateInfoKHR {
 #define VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME "VK_KHR_shader_non_semantic_info"
 
 
+#define VK_KHR_present_id 1
+#define VK_KHR_PRESENT_ID_SPEC_VERSION    1
+#define VK_KHR_PRESENT_ID_EXTENSION_NAME  "VK_KHR_present_id"
+typedef struct VkPresentIdKHR {
+    VkStructureType    sType;
+    const void*        pNext;
+    uint32_t           swapchainCount;
+    const uint64_t*    pPresentIds;
+} VkPresentIdKHR;
+
+typedef struct VkPhysicalDevicePresentIdFeaturesKHR {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           presentId;
+} VkPhysicalDevicePresentIdFeaturesKHR;
+
+
+
 #define VK_KHR_synchronization2 1
 typedef uint64_t VkFlags64;
 #define VK_KHR_SYNCHRONIZATION_2_SPEC_VERSION 1
@@ -7865,7 +7969,7 @@ static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS
 static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR = 0x00000400ULL;
 static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR = 0x00000800ULL;
 static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR = 0x00001000ULL;
-static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR = 0x00001000;
+static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR = 0x00001000ULL;
 static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR = 0x00002000ULL;
 static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_HOST_BIT_KHR = 0x00004000ULL;
 static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR = 0x00008000ULL;
@@ -7887,15 +7991,16 @@ static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_
 static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000ULL;
 static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV = 0x00020000ULL;
 static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000ULL;
-static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_SHADING_RATE_IMAGE_BIT_NV = 0x00400000;
+static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_SHADING_RATE_IMAGE_BIT_NV = 0x00400000ULL;
 static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000ULL;
 static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR = 0x00200000ULL;
-static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_NV = 0x00200000;
-static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000;
+static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_NV = 0x00200000ULL;
+static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000ULL;
 static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000ULL;
 static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV = 0x00080000ULL;
 static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV = 0x00100000ULL;
 static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI = 0x8000000000ULL;
+static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI = 0x10000000000ULL;
 
 typedef VkFlags64 VkAccessFlags2KHR;
 
@@ -7941,13 +8046,14 @@ static const VkAccessFlagBits2KHR VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT
 static const VkAccessFlagBits2KHR VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000ULL;
 static const VkAccessFlagBits2KHR VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000ULL;
 static const VkAccessFlagBits2KHR VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000ULL;
-static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000;
+static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000ULL;
 static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000ULL;
 static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000ULL;
-static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000;
-static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000;
+static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000ULL;
+static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000ULL;
 static const VkAccessFlagBits2KHR VK_ACCESS_2_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000ULL;
 static const VkAccessFlagBits2KHR VK_ACCESS_2_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000ULL;
+static const VkAccessFlagBits2KHR VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI = 0x8000000000ULL;
 
 
 typedef enum VkSubmitFlagBitsKHR {
@@ -10075,9 +10181,10 @@ typedef VkGeometryFlagBitsKHR VkGeometryFlagBitsNV;
 
 typedef enum VkGeometryInstanceFlagBitsKHR {
     VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR = 0x00000001,
-    VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR = 0x00000002,
+    VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR = 0x00000002,
     VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR = 0x00000004,
     VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR = 0x00000008,
+    VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR = VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR,
     VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR,
     VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR,
     VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NV = VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR,
@@ -11588,6 +11695,28 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilOpEXT(
 #endif
 
 
+#define VK_EXT_shader_atomic_float2 1
+#define VK_EXT_SHADER_ATOMIC_FLOAT_2_SPEC_VERSION 1
+#define VK_EXT_SHADER_ATOMIC_FLOAT_2_EXTENSION_NAME "VK_EXT_shader_atomic_float2"
+typedef struct VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           shaderBufferFloat16Atomics;
+    VkBool32           shaderBufferFloat16AtomicAdd;
+    VkBool32           shaderBufferFloat16AtomicMinMax;
+    VkBool32           shaderBufferFloat32AtomicMinMax;
+    VkBool32           shaderBufferFloat64AtomicMinMax;
+    VkBool32           shaderSharedFloat16Atomics;
+    VkBool32           shaderSharedFloat16AtomicAdd;
+    VkBool32           shaderSharedFloat16AtomicMinMax;
+    VkBool32           shaderSharedFloat32AtomicMinMax;
+    VkBool32           shaderSharedFloat64AtomicMinMax;
+    VkBool32           shaderImageFloat32AtomicMinMax;
+    VkBool32           sparseImageFloat32AtomicMinMax;
+} VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT;
+
+
+
 #define VK_EXT_shader_demote_to_helper_invocation 1
 #define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_SPEC_VERSION 1
 #define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME "VK_EXT_shader_demote_to_helper_invocation"
@@ -11867,7 +11996,7 @@ typedef struct VkPhysicalDeviceDeviceMemoryReportFeaturesEXT {
 
 typedef struct VkDeviceMemoryReportCallbackDataEXT {
     VkStructureType                     sType;
-    const void*                         pNext;
+    void*                               pNext;
     VkDeviceMemoryReportFlagsEXT        flags;
     VkDeviceMemoryReportEventTypeEXT    type;
     uint64_t                            memoryObjectId;
@@ -12202,7 +12331,7 @@ typedef struct VkAccelerationStructureMotionInstanceNV {
 
 typedef struct VkPhysicalDeviceRayTracingMotionBlurFeaturesNV {
     VkStructureType    sType;
-    const void*        pNext;
+    void*              pNext;
     VkBool32           rayTracingMotionBlur;
     VkBool32           rayTracingMotionBlurPipelineTraceRaysIndirect;
 } VkPhysicalDeviceRayTracingMotionBlurFeaturesNV;
@@ -12370,8 +12499,20 @@ typedef struct VkPhysicalDeviceDrmPropertiesEXT {
 
 
 
+#define VK_EXT_primitive_topology_list_restart 1
+#define VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_SPEC_VERSION 1
+#define VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME "VK_EXT_primitive_topology_list_restart"
+typedef struct VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           primitiveTopologyListRestart;
+    VkBool32           primitiveTopologyPatchListRestart;
+} VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT;
+
+
+
 #define VK_HUAWEI_subpass_shading 1
-#define VK_HUAWEI_SUBPASS_SHADING_SPEC_VERSION 0
+#define VK_HUAWEI_SUBPASS_SHADING_SPEC_VERSION 2
 #define VK_HUAWEI_SUBPASS_SHADING_EXTENSION_NAME "VK_HUAWEI_subpass_shading"
 typedef struct VkSubpassShadingPipelineCreateInfoHUAWEI {
     VkStructureType    sType;
@@ -12392,11 +12533,12 @@ typedef struct VkPhysicalDeviceSubpassShadingPropertiesHUAWEI {
     uint32_t           maxSubpassShadingWorkgroupSizeAspectRatio;
 } VkPhysicalDeviceSubpassShadingPropertiesHUAWEI;
 
-typedef VkResult (VKAPI_PTR *PFN_vkGetSubpassShadingMaxWorkgroupSizeHUAWEI)(VkRenderPass renderpass, VkExtent2D* pMaxWorkgroupSize);
+typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI)(VkDevice device, VkRenderPass renderpass, VkExtent2D* pMaxWorkgroupSize);
 typedef void (VKAPI_PTR *PFN_vkCmdSubpassShadingHUAWEI)(VkCommandBuffer commandBuffer);
 
 #ifndef VK_NO_PROTOTYPES
-VKAPI_ATTR VkResult VKAPI_CALL vkGetSubpassShadingMaxWorkgroupSizeHUAWEI(
+VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI(
+    VkDevice                                    device,
     VkRenderPass                                renderpass,
     VkExtent2D*                                 pMaxWorkgroupSize);
 
@@ -12405,6 +12547,52 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSubpassShadingHUAWEI(
 #endif
 
 
+#define VK_HUAWEI_invocation_mask 1
+#define VK_HUAWEI_INVOCATION_MASK_SPEC_VERSION 1
+#define VK_HUAWEI_INVOCATION_MASK_EXTENSION_NAME "VK_HUAWEI_invocation_mask"
+typedef struct VkPhysicalDeviceInvocationMaskFeaturesHUAWEI {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           invocationMask;
+} VkPhysicalDeviceInvocationMaskFeaturesHUAWEI;
+
+typedef void (VKAPI_PTR *PFN_vkCmdBindInvocationMaskHUAWEI)(VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkCmdBindInvocationMaskHUAWEI(
+    VkCommandBuffer                             commandBuffer,
+    VkImageView                                 imageView,
+    VkImageLayout                               imageLayout);
+#endif
+
+
+#define VK_NV_external_memory_rdma 1
+typedef void* VkRemoteAddressNV;
+#define VK_NV_EXTERNAL_MEMORY_RDMA_SPEC_VERSION 1
+#define VK_NV_EXTERNAL_MEMORY_RDMA_EXTENSION_NAME "VK_NV_external_memory_rdma"
+typedef struct VkMemoryGetRemoteAddressInfoNV {
+    VkStructureType                       sType;
+    const void*                           pNext;
+    VkDeviceMemory                        memory;
+    VkExternalMemoryHandleTypeFlagBits    handleType;
+} VkMemoryGetRemoteAddressInfoNV;
+
+typedef struct VkPhysicalDeviceExternalMemoryRDMAFeaturesNV {
+    VkStructureType    sType;
+    void*              pNext;
+    VkBool32           externalMemoryRDMA;
+} VkPhysicalDeviceExternalMemoryRDMAFeaturesNV;
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryRemoteAddressNV)(VkDevice device, const VkMemoryGetRemoteAddressInfoNV* pMemoryGetRemoteAddressInfo, VkRemoteAddressNV* pAddress);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryRemoteAddressNV(
+    VkDevice                                    device,
+    const VkMemoryGetRemoteAddressInfoNV*       pMemoryGetRemoteAddressInfo,
+    VkRemoteAddressNV*                          pAddress);
+#endif
+
+
 #define VK_EXT_extended_dynamic_state2 1
 #define VK_EXT_EXTENDED_DYNAMIC_STATE_2_SPEC_VERSION 1
 #define VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME "VK_EXT_extended_dynamic_state2"
@@ -12539,9 +12727,14 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawMultiIndexedEXT(
 #endif
 
 
+#define VK_EXT_load_store_op_none 1
+#define VK_EXT_LOAD_STORE_OP_NONE_SPEC_VERSION 1
+#define VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME "VK_EXT_load_store_op_none"
+
+
 #define VK_KHR_acceleration_structure 1
 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureKHR)
-#define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 11
+#define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 12
 #define VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME "VK_KHR_acceleration_structure"
 
 typedef enum VkBuildAccelerationStructureModeKHR {

File diff suppressed because it is too large
+ 342 - 316
thirdparty/vulkan/include/vulkan/vulkan_enums.hpp


File diff suppressed because it is too large
+ 126 - 0
thirdparty/vulkan/include/vulkan/vulkan_funcs.hpp


File diff suppressed because it is too large
+ 1150 - 902
thirdparty/vulkan/include/vulkan/vulkan_handles.hpp


File diff suppressed because it is too large
+ 1855 - 1359
thirdparty/vulkan/include/vulkan/vulkan_raii.hpp


File diff suppressed because it is too large
+ 134 - 15
thirdparty/vulkan/include/vulkan/vulkan_structs.hpp


+ 1 - 1
thirdparty/vulkan/patches/VKEnumStringHelper-use-volk.patch

@@ -1,5 +1,5 @@
 diff --git a/thirdparty/vulkan/vk_enum_string_helper.h b/thirdparty/vulkan/vk_enum_string_helper.h
-index 4c36430341..004a861774 100755
+index 4c36430341..004a861774 100644
 --- a/thirdparty/vulkan/vk_enum_string_helper.h
 +++ b/thirdparty/vulkan/vk_enum_string_helper.h
 @@ -36,7 +36,11 @@

+ 4 - 4
thirdparty/vulkan/patches/VMA-use-volk.patch

@@ -1,9 +1,9 @@
 diff --git a/thirdparty/vulkan/vk_mem_alloc.h b/thirdparty/vulkan/vk_mem_alloc.h
-index 8a42699e7f..510fa4d3ef 100644
+index 65d6243419..9890f20f7c 100644
 --- a/thirdparty/vulkan/vk_mem_alloc.h
 +++ b/thirdparty/vulkan/vk_mem_alloc.h
-@@ -1771,7 +1771,11 @@ available through VmaAllocatorCreateInfo::pRecordSettings.
- #endif
+@@ -2063,7 +2063,11 @@ available through VmaAllocatorCreateInfo::pRecordSettings.
+ #endif // #if defined(__ANDROID__) && VMA_STATIC_VULKAN_FUNCTIONS && VK_NO_PROTOTYPES
  
  #ifndef VULKAN_H_
 -    #include <vulkan/vulkan.h>
@@ -14,4 +14,4 @@ index 8a42699e7f..510fa4d3ef 100644
 +    #endif
  #endif
  
- #if VMA_RECORDING_ENABLED
+ // Define this macro to declare maximum supported Vulkan version in format AAABBBCCC,

+ 82 - 44
thirdparty/vulkan/vk_enum_string_helper.h

@@ -558,6 +558,8 @@ static inline const char* string_VkStructureType(VkStructureType input_value)
             return "VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID";
         case VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR:
             return "VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR";
+        case VK_STRUCTURE_TYPE_MEMORY_GET_REMOTE_ADDRESS_INFO_NV:
+            return "VK_STRUCTURE_TYPE_MEMORY_GET_REMOTE_ADDRESS_INFO_NV";
         case VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR:
             return "VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR";
         case VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA:
@@ -674,6 +676,8 @@ static inline const char* string_VkStructureType(VkStructureType input_value)
             return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO";
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT:
             return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT";
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV:
+            return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV";
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO:
             return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO";
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2:
@@ -728,6 +732,8 @@ static inline const char* string_VkStructureType(VkStructureType input_value)
             return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT";
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT:
             return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT";
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI:
+            return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI";
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT:
             return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT";
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT:
@@ -776,6 +782,12 @@ static inline const char* string_VkStructureType(VkStructureType input_value)
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR:
             return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR";
 #endif // VK_ENABLE_BETA_EXTENSIONS
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR:
+            return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR";
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR:
+            return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR";
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT:
+            return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT";
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT:
             return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT";
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2:
@@ -816,6 +828,8 @@ static inline const char* string_VkStructureType(VkStructureType input_value)
             return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES";
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES:
             return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES";
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT:
+            return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT";
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT:
             return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT";
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES:
@@ -836,6 +850,10 @@ static inline const char* string_VkStructureType(VkStructureType input_value)
             return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT";
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV:
             return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV";
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR:
+            return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR";
+        case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR:
+            return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR";
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL:
             return "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL";
         case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV:
@@ -1006,6 +1024,8 @@ static inline const char* string_VkStructureType(VkStructureType input_value)
             return "VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV";
         case VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP:
             return "VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP";
+        case VK_STRUCTURE_TYPE_PRESENT_ID_KHR:
+            return "VK_STRUCTURE_TYPE_PRESENT_ID_KHR";
         case VK_STRUCTURE_TYPE_PRESENT_INFO_KHR:
             return "VK_STRUCTURE_TYPE_PRESENT_INFO_KHR";
         case VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR:
@@ -1108,8 +1128,6 @@ static inline const char* string_VkStructureType(VkStructureType input_value)
             return "VK_STRUCTURE_TYPE_SUBMIT_INFO";
         case VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR:
             return "VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR";
-        case VK_STRUCTURE_TYPE_SUBPASSS_SHADING_PIPELINE_CREATE_INFO_HUAWEI:
-            return "VK_STRUCTURE_TYPE_SUBPASSS_SHADING_PIPELINE_CREATE_INFO_HUAWEI";
         case VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO:
             return "VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO";
         case VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2:
@@ -1120,6 +1138,8 @@ static inline const char* string_VkStructureType(VkStructureType input_value)
             return "VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE";
         case VK_STRUCTURE_TYPE_SUBPASS_END_INFO:
             return "VK_STRUCTURE_TYPE_SUBPASS_END_INFO";
+        case VK_STRUCTURE_TYPE_SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI:
+            return "VK_STRUCTURE_TYPE_SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI";
         case VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT:
             return "VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT";
         case VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR:
@@ -1657,6 +1677,17 @@ static inline const char* string_VkObjectType(VkObjectType input_value)
     }
 }
 
+static inline const char* string_VkPipelineCacheHeaderVersion(VkPipelineCacheHeaderVersion input_value)
+{
+    switch (input_value)
+    {
+        case VK_PIPELINE_CACHE_HEADER_VERSION_ONE:
+            return "VK_PIPELINE_CACHE_HEADER_VERSION_ONE";
+        default:
+            return "Unhandled VkPipelineCacheHeaderVersion";
+    }
+}
+
 static inline const char* string_VkVendorId(VkVendorId input_value)
 {
     switch (input_value)
@@ -1678,17 +1709,6 @@ static inline const char* string_VkVendorId(VkVendorId input_value)
     }
 }
 
-static inline const char* string_VkPipelineCacheHeaderVersion(VkPipelineCacheHeaderVersion input_value)
-{
-    switch (input_value)
-    {
-        case VK_PIPELINE_CACHE_HEADER_VERSION_ONE:
-            return "VK_PIPELINE_CACHE_HEADER_VERSION_ONE";
-        default:
-            return "Unhandled VkPipelineCacheHeaderVersion";
-    }
-}
-
 static inline const char* string_VkSystemAllocationScope(VkSystemAllocationScope input_value)
 {
     switch (input_value)
@@ -2455,6 +2475,8 @@ static inline const char* string_VkImageUsageFlagBits(VkImageUsageFlagBits input
             return "VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR";
         case VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT:
             return "VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT";
+        case VK_IMAGE_USAGE_INVOCATION_MASK_BIT_HUAWEI:
+            return "VK_IMAGE_USAGE_INVOCATION_MASK_BIT_HUAWEI";
         case VK_IMAGE_USAGE_SAMPLED_BIT:
             return "VK_IMAGE_USAGE_SAMPLED_BIT";
         case VK_IMAGE_USAGE_STORAGE_BIT:
@@ -2559,6 +2581,8 @@ static inline const char* string_VkMemoryPropertyFlagBits(VkMemoryPropertyFlagBi
             return "VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT";
         case VK_MEMORY_PROPERTY_PROTECTED_BIT:
             return "VK_MEMORY_PROPERTY_PROTECTED_BIT";
+        case VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV:
+            return "VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV";
         default:
             return "Unhandled VkMemoryPropertyFlagBits";
     }
@@ -4066,6 +4090,8 @@ static inline const char* string_VkAttachmentLoadOp(VkAttachmentLoadOp input_val
             return "VK_ATTACHMENT_LOAD_OP_DONT_CARE";
         case VK_ATTACHMENT_LOAD_OP_LOAD:
             return "VK_ATTACHMENT_LOAD_OP_LOAD";
+        case VK_ATTACHMENT_LOAD_OP_NONE_EXT:
+            return "VK_ATTACHMENT_LOAD_OP_NONE_EXT";
         default:
             return "Unhandled VkAttachmentLoadOp";
     }
@@ -4077,8 +4103,8 @@ static inline const char* string_VkAttachmentStoreOp(VkAttachmentStoreOp input_v
     {
         case VK_ATTACHMENT_STORE_OP_DONT_CARE:
             return "VK_ATTACHMENT_STORE_OP_DONT_CARE";
-        case VK_ATTACHMENT_STORE_OP_NONE_QCOM:
-            return "VK_ATTACHMENT_STORE_OP_NONE_QCOM";
+        case VK_ATTACHMENT_STORE_OP_NONE_EXT:
+            return "VK_ATTACHMENT_STORE_OP_NONE_EXT";
         case VK_ATTACHMENT_STORE_OP_STORE:
             return "VK_ATTACHMENT_STORE_OP_STORE";
         default:
@@ -4655,6 +4681,8 @@ static inline const char* string_VkExternalMemoryHandleTypeFlagBits(VkExternalMe
             return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT";
         case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
             return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT";
+        case VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV:
+            return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV";
         case VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA:
             return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA";
         default:
@@ -4927,6 +4955,8 @@ static inline const char* string_VkDriverId(VkDriverId input_value)
             return "VK_DRIVER_ID_NVIDIA_PROPRIETARY";
         case VK_DRIVER_ID_QUALCOMM_PROPRIETARY:
             return "VK_DRIVER_ID_QUALCOMM_PROPRIETARY";
+        case VK_DRIVER_ID_VERISILICON_PROPRIETARY:
+            return "VK_DRIVER_ID_VERISILICON_PROPRIETARY";
         default:
             return "Unhandled VkDriverId";
     }
@@ -5427,32 +5457,32 @@ static inline std::string string_VkVideoComponentBitDepthFlagsKHR(VkVideoCompone
 
 #ifdef VK_ENABLE_BETA_EXTENSIONS
 
-static inline const char* string_VkVideoCapabilitiesFlagBitsKHR(VkVideoCapabilitiesFlagBitsKHR input_value)
+static inline const char* string_VkVideoCapabilityFlagBitsKHR(VkVideoCapabilityFlagBitsKHR input_value)
 {
     switch (input_value)
     {
-        case VK_VIDEO_CAPABILITIES_PROTECTED_CONTENT_BIT_KHR:
-            return "VK_VIDEO_CAPABILITIES_PROTECTED_CONTENT_BIT_KHR";
-        case VK_VIDEO_CAPABILITIES_SEPARATE_REFERENCE_IMAGES_BIT_KHR:
-            return "VK_VIDEO_CAPABILITIES_SEPARATE_REFERENCE_IMAGES_BIT_KHR";
+        case VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR:
+            return "VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR";
+        case VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR:
+            return "VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR";
         default:
-            return "Unhandled VkVideoCapabilitiesFlagBitsKHR";
+            return "Unhandled VkVideoCapabilityFlagBitsKHR";
     }
 }
 
-static inline std::string string_VkVideoCapabilitiesFlagsKHR(VkVideoCapabilitiesFlagsKHR input_value)
+static inline std::string string_VkVideoCapabilityFlagsKHR(VkVideoCapabilityFlagsKHR input_value)
 {
     std::string ret;
     int index = 0;
     while(input_value) {
         if (input_value & 1) {
             if( !ret.empty()) ret.append("|");
-            ret.append(string_VkVideoCapabilitiesFlagBitsKHR(static_cast<VkVideoCapabilitiesFlagBitsKHR>(1U << index)));
+            ret.append(string_VkVideoCapabilityFlagBitsKHR(static_cast<VkVideoCapabilityFlagBitsKHR>(1U << index)));
         }
         ++index;
         input_value >>= 1;
     }
-    if( ret.empty()) ret.append(string_VkVideoCapabilitiesFlagBitsKHR(static_cast<VkVideoCapabilitiesFlagBitsKHR>(0)));
+    if( ret.empty()) ret.append(string_VkVideoCapabilityFlagBitsKHR(static_cast<VkVideoCapabilityFlagBitsKHR>(0)));
     return ret;
 }
 #endif // VK_ENABLE_BETA_EXTENSIONS
@@ -5702,6 +5732,8 @@ static inline const char* string_VkExternalMemoryHandleTypeFlagBitsKHR(VkExterna
             return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT";
         case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
             return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT";
+        case VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV:
+            return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV";
         case VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA:
             return "VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA";
         default:
@@ -6154,6 +6186,8 @@ static inline const char* string_VkDriverIdKHR(VkDriverIdKHR input_value)
             return "VK_DRIVER_ID_NVIDIA_PROPRIETARY";
         case VK_DRIVER_ID_QUALCOMM_PROPRIETARY:
             return "VK_DRIVER_ID_QUALCOMM_PROPRIETARY";
+        case VK_DRIVER_ID_VERISILICON_PROPRIETARY:
+            return "VK_DRIVER_ID_VERISILICON_PROPRIETARY";
         default:
             return "Unhandled VkDriverIdKHR";
     }
@@ -6430,6 +6464,8 @@ static inline const char* string_VkPipelineStageFlagBits2KHR(uint64_t input_valu
             return "VK_PIPELINE_STAGE_2_HOST_BIT_KHR";
         case VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR:
             return "VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR";
+        case VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI:
+            return "VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI";
         case VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR:
             return "VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR";
         case VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV:
@@ -6527,6 +6563,8 @@ static inline const char* string_VkAccessFlagBits2KHR(uint64_t input_value)
             return "VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR";
         case VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR:
             return "VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR";
+        case VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI:
+            return "VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI";
         case VK_ACCESS_2_MEMORY_READ_BIT_KHR:
             return "VK_ACCESS_2_MEMORY_READ_BIT_KHR";
         case VK_ACCESS_2_MEMORY_WRITE_BIT_KHR:
@@ -6757,7 +6795,7 @@ static inline const char* string_VkRasterizationOrderAMD(VkRasterizationOrderAMD
 
 #ifdef VK_ENABLE_BETA_EXTENSIONS
 
-static inline const char* string_VkVideoEncodeH264CapabilitiesFlagBitsEXT(VkVideoEncodeH264CapabilitiesFlagBitsEXT input_value)
+static inline const char* string_VkVideoEncodeH264CapabilityFlagBitsEXT(VkVideoEncodeH264CapabilityFlagBitsEXT input_value)
 {
     switch (input_value)
     {
@@ -6784,23 +6822,23 @@ static inline const char* string_VkVideoEncodeH264CapabilitiesFlagBitsEXT(VkVide
         case VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BI_PRED_IMPLICIT_BIT_EXT:
             return "VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BI_PRED_IMPLICIT_BIT_EXT";
         default:
-            return "Unhandled VkVideoEncodeH264CapabilitiesFlagBitsEXT";
+            return "Unhandled VkVideoEncodeH264CapabilityFlagBitsEXT";
     }
 }
 
-static inline std::string string_VkVideoEncodeH264CapabilitiesFlagsEXT(VkVideoEncodeH264CapabilitiesFlagsEXT input_value)
+static inline std::string string_VkVideoEncodeH264CapabilityFlagsEXT(VkVideoEncodeH264CapabilityFlagsEXT input_value)
 {
     std::string ret;
     int index = 0;
     while(input_value) {
         if (input_value & 1) {
             if( !ret.empty()) ret.append("|");
-            ret.append(string_VkVideoEncodeH264CapabilitiesFlagBitsEXT(static_cast<VkVideoEncodeH264CapabilitiesFlagBitsEXT>(1U << index)));
+            ret.append(string_VkVideoEncodeH264CapabilityFlagBitsEXT(static_cast<VkVideoEncodeH264CapabilityFlagBitsEXT>(1U << index)));
         }
         ++index;
         input_value >>= 1;
     }
-    if( ret.empty()) ret.append(string_VkVideoEncodeH264CapabilitiesFlagBitsEXT(static_cast<VkVideoEncodeH264CapabilitiesFlagBitsEXT>(0)));
+    if( ret.empty()) ret.append(string_VkVideoEncodeH264CapabilityFlagBitsEXT(static_cast<VkVideoEncodeH264CapabilityFlagBitsEXT>(0)));
     return ret;
 }
 #endif // VK_ENABLE_BETA_EXTENSIONS
@@ -6911,34 +6949,34 @@ static inline std::string string_VkVideoEncodeH264CreateFlagsEXT(VkVideoEncodeH2
 
 #ifdef VK_ENABLE_BETA_EXTENSIONS
 
-static inline const char* string_VkVideoDecodeH264FieldLayoutFlagBitsEXT(VkVideoDecodeH264FieldLayoutFlagBitsEXT input_value)
+static inline const char* string_VkVideoDecodeH264PictureLayoutFlagBitsEXT(VkVideoDecodeH264PictureLayoutFlagBitsEXT input_value)
 {
     switch (input_value)
     {
-        case VK_VIDEO_DECODE_H264_FIELD_LAYOUT_LINE_INTERLACED_PLANE_BIT_EXT:
-            return "VK_VIDEO_DECODE_H264_FIELD_LAYOUT_LINE_INTERLACED_PLANE_BIT_EXT";
-        case VK_VIDEO_DECODE_H264_FIELD_LAYOUT_SEPARATE_INTERLACED_PLANE_BIT_EXT:
-            return "VK_VIDEO_DECODE_H264_FIELD_LAYOUT_SEPARATE_INTERLACED_PLANE_BIT_EXT";
-        case VK_VIDEO_DECODE_H264_PROGRESSIVE_PICTURES_ONLY_EXT:
-            return "VK_VIDEO_DECODE_H264_PROGRESSIVE_PICTURES_ONLY_EXT";
+        case VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_EXT:
+            return "VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_EXT";
+        case VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_SEPARATE_PLANES_BIT_EXT:
+            return "VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_SEPARATE_PLANES_BIT_EXT";
+        case VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_EXT:
+            return "VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_EXT";
         default:
-            return "Unhandled VkVideoDecodeH264FieldLayoutFlagBitsEXT";
+            return "Unhandled VkVideoDecodeH264PictureLayoutFlagBitsEXT";
     }
 }
 
-static inline std::string string_VkVideoDecodeH264FieldLayoutFlagsEXT(VkVideoDecodeH264FieldLayoutFlagsEXT input_value)
+static inline std::string string_VkVideoDecodeH264PictureLayoutFlagsEXT(VkVideoDecodeH264PictureLayoutFlagsEXT input_value)
 {
     std::string ret;
     int index = 0;
     while(input_value) {
         if (input_value & 1) {
             if( !ret.empty()) ret.append("|");
-            ret.append(string_VkVideoDecodeH264FieldLayoutFlagBitsEXT(static_cast<VkVideoDecodeH264FieldLayoutFlagBitsEXT>(1U << index)));
+            ret.append(string_VkVideoDecodeH264PictureLayoutFlagBitsEXT(static_cast<VkVideoDecodeH264PictureLayoutFlagBitsEXT>(1U << index)));
         }
         ++index;
         input_value >>= 1;
     }
-    if( ret.empty()) ret.append(string_VkVideoDecodeH264FieldLayoutFlagBitsEXT(static_cast<VkVideoDecodeH264FieldLayoutFlagBitsEXT>(0)));
+    if( ret.empty()) ret.append(string_VkVideoDecodeH264PictureLayoutFlagBitsEXT(static_cast<VkVideoDecodeH264PictureLayoutFlagBitsEXT>(0)));
     return ret;
 }
 #endif // VK_ENABLE_BETA_EXTENSIONS
@@ -7542,8 +7580,8 @@ static inline const char* string_VkGeometryInstanceFlagBitsKHR(VkGeometryInstanc
             return "VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR";
         case VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR:
             return "VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR";
-        case VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR:
-            return "VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR";
+        case VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR:
+            return "VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR";
         default:
             return "Unhandled VkGeometryInstanceFlagBitsKHR";
     }
@@ -7575,8 +7613,8 @@ static inline const char* string_VkGeometryInstanceFlagBitsNV(VkGeometryInstance
             return "VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR";
         case VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR:
             return "VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR";
-        case VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR:
-            return "VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR";
+        case VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR:
+            return "VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR";
         default:
             return "Unhandled VkGeometryInstanceFlagBitsNV";
     }

Some files were not shown because too many files changed in this diff