Kaynağa Gözat

Updated glslang.

Бранимир Караџић 8 saat önce
ebeveyn
işleme
21e71a6141
36 değiştirilmiş dosya ile 2969 ekleme ve 1013 silme
  1. 1 0
      3rdparty/glslang/SPIRV/GLSL.ext.EXT.h
  2. 2 1
      3rdparty/glslang/SPIRV/GLSL.ext.KHR.h
  3. 4 0
      3rdparty/glslang/SPIRV/GLSL.ext.NV.h
  4. 346 17
      3rdparty/glslang/SPIRV/GlslangToSpv.cpp
  5. 307 18
      3rdparty/glslang/SPIRV/SpvBuilder.cpp
  6. 55 1
      3rdparty/glslang/SPIRV/SpvBuilder.h
  7. 4 1
      3rdparty/glslang/SPIRV/SpvPostProcess.cpp
  8. 1 0
      3rdparty/glslang/SPIRV/SpvTools.cpp
  9. 1 0
      3rdparty/glslang/SPIRV/disassemble.cpp
  10. 48 0
      3rdparty/glslang/SPIRV/doc.cpp
  11. 33 4
      3rdparty/glslang/SPIRV/spirv.hpp11
  12. 3 1
      3rdparty/glslang/SPIRV/spvIR.h
  13. 8 1
      3rdparty/glslang/StandAlone/StandAlone.cpp
  14. 1 1
      3rdparty/glslang/build_info.h
  15. 4 0
      3rdparty/glslang/glslang/CInterface/glslang_c_interface.cpp
  16. 24 0
      3rdparty/glslang/glslang/Include/BaseTypes.h
  17. 145 12
      3rdparty/glslang/glslang/Include/Types.h
  18. 1 0
      3rdparty/glslang/glslang/Include/glslang_c_shader_types.h
  19. 602 4
      3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp
  20. 3 0
      3rdparty/glslang/glslang/MachineIndependent/Initialize.h
  21. 25 8
      3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp
  22. 231 19
      3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp
  23. 4 1
      3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h
  24. 84 47
      3rdparty/glslang/glslang/MachineIndependent/Scan.cpp
  25. 1 0
      3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp
  26. 18 0
      3rdparty/glslang/glslang/MachineIndependent/Versions.cpp
  27. 4 0
      3rdparty/glslang/glslang/MachineIndependent/Versions.h
  28. 84 4
      3rdparty/glslang/glslang/MachineIndependent/glslang.y
  29. 528 519
      3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp
  30. 309 306
      3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp.h
  31. 39 39
      3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp
  32. 9 6
      3rdparty/glslang/glslang/MachineIndependent/iomapper.h
  33. 29 3
      3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp
  34. 9 0
      3rdparty/glslang/glslang/MachineIndependent/localintermediate.h
  35. 1 0
      3rdparty/glslang/glslang/MachineIndependent/parseVersions.h
  36. 1 0
      3rdparty/glslang/glslang/Public/ShaderLang.h

+ 1 - 0
3rdparty/glslang/SPIRV/GLSL.ext.EXT.h

@@ -44,5 +44,6 @@ static const char* const E_SPV_EXT_mesh_shader = "SPV_EXT_mesh_shader";
 static const char* const E_SPV_EXT_float8 = "SPV_EXT_float8";
 static const char* const E_SPV_EXT_shader_64bit_indexing = "SPV_EXT_shader_64bit_indexing";
 static const char* const E_SPV_EXT_shader_invocation_reorder = "SPV_EXT_shader_invocation_reorder";
+static const char* const E_SPV_EXT_long_vector = "SPV_EXT_long_vector";
 
 #endif  // #ifndef GLSLextEXT_H

+ 2 - 1
3rdparty/glslang/SPIRV/GLSL.ext.KHR.h

@@ -66,5 +66,6 @@ static const char* const E_SPV_KHR_relaxed_extended_instruction = "SPV_KHR_relax
 static const char* const E_SPV_KHR_integer_dot_product          = "SPV_KHR_integer_dot_product";
 static const char* const E_SPV_NV_cooperative_vector            = "SPV_NV_cooperative_vector";
 static const char* const E_SPV_KHR_bfloat16                     = "SPV_KHR_bfloat16";
-
+static const char* const E_SPV_EXT_descriptor_heap              = "SPV_EXT_descriptor_heap";
+static const char* const E_SPV_KHR_untyped_pointers             = "SPV_KHR_untyped_pointers";
 #endif  // #ifndef GLSLextKHR_H

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

@@ -101,4 +101,8 @@ const char* const E_SPV_NV_cluster_acceleration_structure = "SPV_NV_cluster_acce
 
 //SPV_NV_linear_swept_spheres
 const char* const E_SPV_NV_linear_swept_spheres = "SPV_NV_linear_swept_spheres";
+
+//SPV_NV_push_constant_bank
+const char* const E_SPV_NV_push_constant_bank = "SPV_NV_push_constant_bank";
+
 #endif  // #ifndef GLSLextNV_H

+ 346 - 17
3rdparty/glslang/SPIRV/GlslangToSpv.cpp

@@ -174,6 +174,8 @@ protected:
     spv::Id convertGlslangStructToSpvType(const glslang::TType&, const glslang::TTypeList* glslangStruct,
                                           glslang::TLayoutPacking, const glslang::TQualifier&);
     spv::LinkageType convertGlslangLinkageToSpv(glslang::TLinkType glslangLinkType);
+    spv::Id decorateDescHeapType(const glslang::TType& type, spv::Id& memberBaseOffset, spv::Id& alignment,
+                                 int& maxPlainDataAlignment);
     void decorateStructType(const glslang::TType&, const glslang::TTypeList* glslangStruct, glslang::TLayoutPacking,
                             const glslang::TQualifier&, spv::Id, const std::vector<spv::Id>& spvMembers);
     spv::Id makeArraySizeId(const glslang::TArraySizes&, int dim, bool allowZero = false, bool boolType = false);
@@ -243,6 +245,7 @@ protected:
     std::pair<spv::Id, spv::Id> getForcedType(glslang::TBuiltInVariable builtIn, const glslang::TType&);
     spv::Id translateForcedType(spv::Id object);
     spv::Id createCompositeConstruct(spv::Id typeId, std::vector<spv::Id> constituents);
+    void recordDescHeapAccessChainInfo(glslang::TIntermBinary* node);
 
     glslang::SpvOptions& options;
     spv::Function* shaderEntry;
@@ -288,6 +291,15 @@ protected:
     // Used later for generating OpTraceKHR/OpExecuteCallableKHR/OpHitObjectRecordHit*/OpHitObjectGetShaderBindingTableData
     std::unordered_map<unsigned int, glslang::TIntermSymbol *> locationToSymbol[4];
     std::unordered_map<spv::Id, std::vector<spv::Decoration> > idToQCOMDecorations;
+    // For nested or inner resource heap structure's alignment and offset records.
+    typedef struct heapMetaData {
+        spv::Id typeStride;
+        spv::Id maxRsrcTypeAlignment;
+        int maxPlainDataAlignment;
+    } HeapMetaData;
+    std::unordered_map<const glslang::TType*, HeapMetaData> heapStructureTypeMetaData;
+    std::unordered_map<spv::Id, spv::Id> heapStructureTypeSize;
+    std::vector<spv::Id> heapStructureMemberOffsets;
 };
 
 //
@@ -391,6 +403,8 @@ spv::Decoration TranslateBlockDecoration(const glslang::TStorageQualifier storag
     case glslang::EvqCallableDataIn: return spv::Decoration::Block;
     case glslang::EvqHitObjectAttrNV: return spv::Decoration::Block;
     case glslang::EvqHitObjectAttrEXT: return spv::Decoration::Block;
+    case glslang::EvqResourceHeap:  return spv::Decoration::Block;
+    case glslang::EvqSamplerHeap:   return spv::Decoration::Block;
     default:
         assert(0);
         break;
@@ -467,6 +481,8 @@ spv::Decoration TranslateLayoutDecoration(const glslang::TType& type, glslang::T
             case glslang::EvqCallableDataIn:
             case glslang::EvqHitObjectAttrNV:
             case glslang::EvqHitObjectAttrEXT:
+            case glslang::EvqResourceHeap:
+            case glslang::EvqSamplerHeap:
                 return spv::Decoration::Max;
             default:
                 assert(0);
@@ -1160,6 +1176,38 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
         builder.addExtension(spv::E_SPV_QCOM_tile_shading);
         return spv::BuiltIn::TileApronSizeQCOM;
 
+    // SPV_EXT_descriptor_heap
+    case glslang::EbvSamplerHeapEXT:
+        builder.addExtension(spv::E_SPV_EXT_descriptor_heap);
+        builder.addExtension(spv::E_SPV_KHR_untyped_pointers);
+        builder.addCapability(spv::Capability::DescriptorHeapEXT);
+        builder.addCapability(spv::Capability::UntypedPointersKHR);
+        // Add SamplerHeapEXT Symbol for spv level.
+        if (builtInVariableIds.find(uint32_t(spv::BuiltIn::SamplerHeapEXT)) == builtInVariableIds.end()) {
+            spv::Id samplerHeapEXT =
+                builder.createUntypedVariable(spv::NoPrecision, spv::StorageClass::UniformConstant, "sampler_heap");
+            if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4)
+                entryPoint->addIdOperand(samplerHeapEXT);
+            builder.addDecoration(samplerHeapEXT, spv::Decoration::BuiltIn, (int)spv::BuiltIn::SamplerHeapEXT);
+            builtInVariableIds.insert({uint32_t(spv::BuiltIn::SamplerHeapEXT), samplerHeapEXT});
+        }
+        return spv::BuiltIn::SamplerHeapEXT;
+    case glslang::EbvResourceHeapEXT:
+        builder.addExtension(spv::E_SPV_EXT_descriptor_heap);
+        builder.addExtension(spv::E_SPV_KHR_untyped_pointers);
+        builder.addCapability(spv::Capability::DescriptorHeapEXT);
+        builder.addCapability(spv::Capability::UntypedPointersKHR);
+        // Add ResourceHeapEXT Symbol for spv level.
+        if (builtInVariableIds.find(uint32_t(spv::BuiltIn::ResourceHeapEXT)) == builtInVariableIds.end()) {
+            spv::Id resourceHeapEXT =
+                builder.createUntypedVariable(spv::NoPrecision, spv::StorageClass::UniformConstant, "resource_heap");
+            if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4)
+                entryPoint->addIdOperand(resourceHeapEXT);
+            builder.addDecoration(resourceHeapEXT, spv::Decoration::BuiltIn, (int)spv::BuiltIn::ResourceHeapEXT);
+            builtInVariableIds.insert({uint32_t(spv::BuiltIn::ResourceHeapEXT), resourceHeapEXT});
+        }
+        return spv::BuiltIn::ResourceHeapEXT;
+
     default:
         return spv::BuiltIn::Max;
     }
@@ -1352,8 +1400,13 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
             type.getQualifier().storage == glslang::EvqUniform) {
         if (type.isAtomic())
             return spv::StorageClass::AtomicCounter;
-        if (type.containsOpaque() && !glslangIntermediate->getBindlessMode())
-            return spv::StorageClass::UniformConstant;
+        if (type.containsOpaque() && !glslangIntermediate->getBindlessMode()) {
+            if (type.getQualifier().storage == glslang::EvqResourceHeap ||
+                type.getQualifier().storage == glslang::EvqSamplerHeap)
+                return spv::StorageClass::Uniform;
+            else
+                return spv::StorageClass::UniformConstant;
+        }
     }
 
     if (type.getQualifier().isUniformOrBuffer() &&
@@ -1369,7 +1422,8 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
     if (type.getQualifier().isUniformOrBuffer()) {
         if (type.getQualifier().isPushConstant())
             return spv::StorageClass::PushConstant;
-        if (type.getBasicType() == glslang::EbtBlock)
+        if (type.getBasicType() == glslang::EbtBlock ||
+            type.getQualifier().layoutDescriptorHeap)
             return spv::StorageClass::Uniform;
         return spv::StorageClass::UniformConstant;
     }
@@ -2207,7 +2261,7 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
         // C) R-Values from type translation, see above call to translateForcedType()
         glslang::TQualifier qualifier = symbol->getQualifier();
         if (qualifier.isSpecConstant() || rValueParameters.find(symbol->getId()) != rValueParameters.end() ||
-            !builder.isPointerType(builder.getTypeId(id)))
+            (!builder.isPointerType(builder.getTypeId(id)) && !builder.isUntypedPointer(id)))
             builder.setAccessChainRValue(id);
         else
             builder.setAccessChainLValue(id);
@@ -2248,6 +2302,28 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
 #endif
 }
 
+// Create new untyped access chain instruction to descriptor heap, based on EXT_descriptor_heap extension.
+void TGlslangToSpvTraverser::recordDescHeapAccessChainInfo(glslang::TIntermBinary* node)
+{
+    // EXT_descriptor_heap
+    glslang::TType* nodeTy = node->getWritableType().clone();
+    // For buffer/structure type, using its basic structure type:
+    // data ptr will be first loaded into a BufferPointerType before finally gets chained accessed.
+    if (node->getLeft()->getQualifier().isUniformOrBuffer())
+        nodeTy = node->getLeft()->getType().clone();
+    if (nodeTy->isArray())
+        nodeTy->clearArraySizes();
+    spv::BuiltIn bt = spv::BuiltIn::Max;
+    unsigned int firstArrIndex = 0;
+    auto rsrcOffsetIdx = builder.isStructureHeapMember(builder.getTypeId(builder.getAccessChain().base),
+                                                       builder.getAccessChain().indexChain, 0, &bt, &firstArrIndex);
+    spv::Id remappedBuiltin = bt == spv::BuiltIn::Max ? 0 : builtInVariableIds[unsigned(bt)];
+    nodeTy->getQualifier().layoutDescriptorInnerBlock = false;
+    // Extra dimension is not needed when translate storage and type. Real loading type is based on orignal AST nodes.
+    builder.setAccessChainDescHeapInfo(TranslateStorageClass(*nodeTy), convertGlslangToSpvType(*nodeTy),
+          nodeTy->getQualifier().layoutDescriptorStride, rsrcOffsetIdx, remappedBuiltin, firstArrIndex);
+}
+
 bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node)
 {
     builder.setDebugSourceLocation(node->getLoc().line, node->getLoc().getFilename());
@@ -2402,6 +2478,14 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
                 // We have deferred generation of associated capabilities until now.
                 if (node->getLeft()->getType().isStruct() && ! node->getLeft()->getType().isArray())
                     declareUseOfStructMember(*(node->getLeft()->getType().getStruct()), glslangIndex);
+
+                // EXT_descriptor_heap
+                // Record untyped descriptor heap access info.
+                if (node->getLeft()->getType().isBuiltIn() &&
+                    (node->getLeft()->getQualifier().builtIn == glslang::EbvResourceHeapEXT ||
+                     node->getLeft()->getQualifier().builtIn == glslang::EbvSamplerHeapEXT)) {
+                    recordDescHeapAccessChainInfo(node);
+                }
             }
         }
         return false;
@@ -2459,6 +2543,14 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
                 builder.accessChainPush(index, coherent_flags,
                                         node->getLeft()->getType().getBufferReferenceAlignment());
             }
+
+            // EXT_descriptor_heap
+            // Record untyped descriptor heap access info.
+            if (node->getLeft()->getType().isBuiltIn() &&
+                (node->getLeft()->getQualifier().builtIn == glslang::EbvResourceHeapEXT ||
+                 node->getLeft()->getQualifier().builtIn == glslang::EbvSamplerHeapEXT)) {
+                recordDescHeapAccessChainInfo(node);
+            }
         }
         return false;
     case glslang::EOpVectorSwizzle:
@@ -2698,9 +2790,13 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
                 spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
                 length = builder.createCooperativeMatrixLengthNV(typeId);
             }
-        } else if (node->getOperand()->getType().isCoopVecNV()) {
+        } else if (node->getOperand()->getType().isCoopVecOrLongVector()) {
             spv::Id typeId = convertGlslangToSpvType(node->getOperand()->getType());
-            length = builder.getCooperativeVectorNumComponents(typeId);
+            if (builder.isCooperativeVectorType(typeId)) {
+                length = builder.getCooperativeVectorNumComponents(typeId);
+            } else {
+                length = builder.makeIntConstant(builder.getNumTypeConstituents(typeId));
+            }
         } else {
             glslang::TIntermTyped* block = node->getOperand()->getAsBinaryNode()->getLeft();
             block->traverse(this);
@@ -3351,7 +3447,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
             builder.addCapability(spv::Capability::CooperativeMatrixConversionsNV);
             builder.addExtension(spv::E_SPV_NV_cooperative_matrix2);
             constructed = builder.createCooperativeMatrixConversion(resultType(), arguments[0]);
-        } else if (node->getOp() == glslang::EOpConstructCooperativeVectorNV &&
+        } else if (node->getType().isCoopVecOrLongVector() &&
                    arguments.size() == 1 &&
                    builder.getTypeId(arguments[0]) == resultType()) {
             constructed = arguments[0];
@@ -3361,7 +3457,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
                  node->getType().isArray() ||
                  // Handle constructing coopvec from one component here, to avoid the component
                  // getting smeared
-                 (node->getOp() == glslang::EOpConstructCooperativeVectorNV && arguments.size() == 1 && builder.isScalar(arguments[0]))) {
+                 (node->getType().hasSpecConstantVectorComponents() && arguments.size() == 1 && builder.isScalar(arguments[0]))) {
             std::vector<spv::Id> constituents;
             for (int c = 0; c < (int)arguments.size(); ++c)
                 constituents.push_back(arguments[c]);
@@ -3423,7 +3519,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
     {
         // for scalar dot product, use multiply
         glslang::TIntermSequence& glslangOperands = node->getSequence();
-        if (glslangOperands[0]->getAsTyped()->getVectorSize() == 1)
+        if (!glslangOperands[0]->getAsTyped()->getType().isLongVector() &&
+            glslangOperands[0]->getAsTyped()->getVectorSize() == 1)
             binOp = glslang::EOpMul;
         break;
     }
@@ -5430,6 +5527,14 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
     case glslang::EbtStruct:
     case glslang::EbtBlock:
         {
+            // If it's an inner declared heap buffer or uniform block, using OpTypeBufferEXT
+            // to convert it to an untyped type.
+            if (type.getQualifier().isUniformOrBuffer() &&
+                type.getQualifier().layoutDescriptorHeap && type.getQualifier().layoutDescriptorInnerBlock) {
+                spvType = builder.makeUntypedPointer(TranslateStorageClass(type), true);
+                break;
+            }
+
             // If we've seen this struct type, return it
             const glslang::TTypeList* glslangMembers = type.getStruct();
 
@@ -5647,6 +5752,24 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
         spvType = builder.makeCooperativeVectorTypeNV(spvType, components);
     }
 
+    if (type.isLongVector()) {
+        builder.addCapability(spv::Capability::LongVectorEXT);
+        builder.addExtension(spv::E_SPV_EXT_long_vector);
+
+        if (type.getBasicType() == glslang::EbtFloat16)
+            builder.addCapability(spv::Capability::Float16);
+        if (type.getBasicType() == glslang::EbtUint8 || type.getBasicType() == glslang::EbtInt8) {
+            builder.addCapability(spv::Capability::Int8);
+        }
+
+        if (type.hasSpecConstantVectorComponents()) {
+            spv::Id components = makeArraySizeId(*type.getTypeParameters()->arraySizes, 0);
+            spvType = builder.makeCooperativeVectorTypeNV(spvType, components);
+        } else {
+            spvType = builder.makeVectorType(spvType, type.getTypeParameters()->arraySizes->getDimSize(0));
+        }
+    }
+
     if (type.isArray()) {
         int stride = 0;  // keep this 0 unless doing an explicit layout; 0 will mean no decoration, no stride
 
@@ -5680,9 +5803,15 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
                 stride = getArrayStride(type, explicitLayout, qualifier.layoutMatrix);
         }
 
+        if (type.getQualifier().storage == glslang::EvqResourceHeap ||
+            type.getQualifier().storage == glslang::EvqSamplerHeap) {
+            auto structSize = heapStructureTypeSize[spvType];
+            spvType = builder.makeRuntimeArray(spvType);
+            builder.addDecorationId(spvType, spv::Decoration::ArrayStrideIdEXT, structSize);
+        }
         // Do the outer dimension, which might not be known for a runtime-sized array.
         // (Unsized arrays that survive through linking will be runtime-sized arrays)
-        if (type.isSizedArray())
+        else if (type.isSizedArray())
             spvType = builder.makeArrayType(spvType, makeArraySizeId(*type.getArraySizes(), 0), stride);
         else {
             // If we see an runtime array in a buffer_reference, it is not a descriptor
@@ -5888,11 +6017,41 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy
         }
     }
 
+    // For those whose storage is ResourceHeap or SamplerHeap, we needs to recursively add
+    // member decorator for inner structure member declaration with spec Constant.
+    spv::Id heapStructSize = 0;
+    if (qualifier.storage == glslang::EvqResourceHeap || qualifier.storage == glslang::EvqSamplerHeap ||
+        qualifier.layoutDescriptorInnerBlock) {
+        auto memberBaseOffset = builder.makeUintConstant(0);
+        int maxPlainDataTypeAlignment = 0;
+        spv::Id descTypeMaxAlignment = 0;
+        auto structLastMemberSize =
+            decorateDescHeapType(type, memberBaseOffset, descTypeMaxAlignment, maxPlainDataTypeAlignment);
+        auto structureUnaligned = builder.createSpecConstantOp(
+            spv::Op::OpIAdd, builder.makeUintType(32), {memberBaseOffset, structLastMemberSize}, {});
+        auto structurePadding = builder.createSpecConstantOp(
+            spv::Op::OpUMod, builder.makeUintType(32), {descTypeMaxAlignment, structureUnaligned}, {});
+        heapStructSize = builder.createSpecConstantOp(
+            spv::Op::OpIAdd, builder.makeUintType(32), {structureUnaligned, structurePadding}, {});
+        HeapMetaData meta = {heapStructSize, descTypeMaxAlignment, maxPlainDataTypeAlignment};
+        heapStructureTypeMetaData[&type] = meta;
+    }
+
     // Make the SPIR-V type
     spv::Id spvType = builder.makeStructType(spvMembers, memberDebugInfo, type.getTypeName().c_str(), false);
     if (! HasNonLayoutQualifiers(type, qualifier))
         structMap[explicitLayout][qualifier.layoutMatrix][glslangMembers] = spvType;
 
+    // Keep decoration data order after spv structure type.
+    if (qualifier.storage == glslang::EvqResourceHeap || qualifier.storage == glslang::EvqSamplerHeap ||
+        qualifier.layoutDescriptorInnerBlock) {
+        heapStructureTypeSize[spvType] = heapStructSize;
+        for (unsigned int i = 0; i < spvMembers.size(); i++) {
+            builder.addMemberDecorationIdEXT(spvType, i, spv::Decoration::OffsetIdEXT, {heapStructureMemberOffsets[i]});
+        }
+        heapStructureMemberOffsets.clear();
+    }
+
     // Decorate it
     decorateStructType(type, glslangMembers, explicitLayout, qualifier, spvType, spvMembers);
 
@@ -5904,6 +6063,126 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy
     return spvType;
 }
 
+// Return not aligned size of current type.
+spv::Id TGlslangToSpvTraverser::decorateDescHeapType(
+    const glslang::TType& type,
+    spv::Id &memberBaseOffset,
+    spv::Id &descTypeAlignment,
+    int& maxPlainDataAlignment)
+{
+    glslang::TLayoutPacking explicitLayout = glslang::ElpScalar;
+    auto selectMaxRsrcTyAlign = [&](spv::Id typeSize) {
+        if (descTypeAlignment != 0) {
+            auto compareInst = builder.createSpecConstantOp(spv::Op::OpUGreaterThan, builder.makeBoolType(),
+                                                            {descTypeAlignment, typeSize}, {});
+            auto selectMaxAlign = builder.createSpecConstantOp(spv::Op::OpSelect, builder.makeUintType(32),
+                                                               {compareInst, descTypeAlignment, typeSize}, {});
+            descTypeAlignment = selectMaxAlign;
+        } else
+            descTypeAlignment = typeSize;
+    };
+
+    // Get or calculate following info ordered.
+    //  Member Type | Type size | Type alignment within current structure | Type offset.
+    // PS. resource blocks declared within a structure will not be processed as a normal declaration before,
+    //  and its' size is dependent on constantSizeOfEXT op, so we won't trigger it as a normal structure here.
+    bool isArray = type.isArray();
+    if (type.isStruct() && !type.getQualifier().layoutDescriptorInnerBlock) {
+        // 1. Structure type is processed from inner to higher level.
+        //    If member is a sturcture, it will be processed earlier,
+        //    parent structure could just load early results.
+        if (heapStructureTypeMetaData.find(&type) != heapStructureTypeMetaData.end()) {
+            auto metadata = heapStructureTypeMetaData[&type];
+            selectMaxRsrcTyAlign(metadata.maxRsrcTypeAlignment);
+            maxPlainDataAlignment = std::max(metadata.maxPlainDataAlignment, maxPlainDataAlignment);
+            return metadata.typeStride;
+        }
+        //  For other nested structure, it would be declared before its parent,
+        //  so it should be directly returned a result in above check.
+        const glslang::TTypeList* structTyList = type.getStruct();
+        spv::Id previousTypeSize = 0;
+        auto currentOffset = memberBaseOffset;
+        for (int i = 0; i < (int)structTyList->size(); i++) {
+            // Get offset :
+            // OffsetsBase = default ? 0 : OffsetInLayout;
+            // OffsetsBase = OffsetsBase + previousOffset + previousPadding.
+            const glslang::TType& memberTy = *(*structTyList)[i].type;
+            spv::Id typeSize = decorateDescHeapType(memberTy, currentOffset, descTypeAlignment, maxPlainDataAlignment);
+            // 2. Get each member's unaligned offset, padding and aligned offset.
+            //    As this function is processed recursively, from bottom to upper, so in here,
+            //    non-structure member's alignment should have been known.
+            if (i != 0) {
+                auto offsetNotAligned = builder.createSpecConstantOp(spv::Op::OpIAdd, builder.makeUintType(32),
+                                                                     {currentOffset, previousTypeSize}, {});
+                auto offsetPadding = builder.createSpecConstantOp(spv::Op::OpUMod, builder.makeUintType(32),
+                                                                  {typeSize, offsetNotAligned}, {});
+                currentOffset = builder.createSpecConstantOp(spv::Op::OpIAdd, builder.makeUintType(32),
+                                                             {offsetNotAligned, offsetPadding}, {});
+            }
+            heapStructureMemberOffsets.push_back(currentOffset);
+            previousTypeSize = typeSize;
+        }
+        // 3. Structure level, get max resource type's alignment, max plain data alignment and final
+        //    structure inner alignment.
+        // Get compared result for alignment within whole structure.
+        spv::Id maxPlainAlignmentSize = builder.makeIntConstant(maxPlainDataAlignment);
+
+        // Select biggest alignemnt size between desc types and plain old types.
+        selectMaxRsrcTyAlign(maxPlainAlignmentSize);
+        memberBaseOffset = currentOffset;
+
+        // Now, return generates size of the MaterialData type
+        // Get structure level unaligned offset, padding and final offset outside.
+        return previousTypeSize;
+    }
+
+    // Following are normal types, structures/blocks have been processed in above part.
+    // Normal type or member type within a structure.
+    bool useConstantSizeOf =
+        ((type.getQualifier().isUniformOrBuffer() && type.getQualifier().layoutDescriptorHeap) ||
+         type.isImage() || type.isTexture() || type.isTensorARM() || type.getBasicType() == glslang::EbtAccStruct);
+
+    // Get single type and layout info.
+    int elemCurrentOffset, elemAlignedSize;
+    int memberSize, dummyStride, typeAlignment;
+    spv::Id spvType = 0; 
+    if (isArray) {
+        glslang::TType elemTy(type, 0);
+        elemTy.clearArraySizes();
+        if (!useConstantSizeOf) {
+            typeAlignment = glslangIntermediate->getMemberAlignment(
+                elemTy, memberSize, dummyStride, glslang::ElpScalar, elemTy.getQualifier().layoutMatrix == glslang::ElmRowMajor);
+            updateMemberOffset(elemTy, elemTy, elemCurrentOffset, elemAlignedSize, explicitLayout, elemTy.getQualifier().layoutMatrix);
+            elemAlignedSize *= type.getCumulativeArraySize();
+        }
+        spvType = convertGlslangToSpvType(elemTy);
+    } else {
+        if (!useConstantSizeOf) {
+            typeAlignment = glslangIntermediate->getMemberAlignment(
+                type, memberSize, dummyStride, glslang::ElpScalar, type.getQualifier().layoutMatrix == glslang::ElmRowMajor);
+            updateMemberOffset(type, type, elemCurrentOffset, elemAlignedSize, explicitLayout, type.getQualifier().layoutMatrix);
+        }
+        spvType = convertGlslangToSpvType(type);
+    }
+
+    // Get alignment and type size.
+    spv::Id typeSize = 0;
+    if (useConstantSizeOf) {
+        typeSize = builder.createConstantSizeOfEXT(spvType);
+        // For resource type, needs to check current's largest alignment to select.
+        // New parent structure's alignment is equal to:
+        //     maxInnerAlignment = currentAlignment > maxInnerAlignment
+        //                                            ? currentAlignment
+        //                                            : maxInnerAlignment;
+        selectMaxRsrcTyAlign(typeSize);
+    } else {
+        typeSize = builder.makeIntConstant(elemAlignedSize);
+        maxPlainDataAlignment = std::max(typeAlignment, maxPlainDataAlignment);
+    }
+
+    return typeSize;
+}
+
 void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
                                                 const glslang::TTypeList* glslangMembers,
                                                 glslang::TLayoutPacking explicitLayout,
@@ -5972,7 +6251,12 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
         if (glslangMember.getQualifier().hasXfbOffset())
             builder.addMemberDecoration(spvType, member, spv::Decoration::Offset,
                                         glslangMember.getQualifier().layoutXfbOffset);
-        else if (explicitLayout != glslang::ElpNone) {
+        else if (glslangMember.getQualifier().hasMemberOffset()) {
+            builder.addExtension(spv::E_SPV_NV_push_constant_bank);
+            builder.addCapability(spv::Capability::PushConstantBanksNV);
+            builder.addMemberDecoration(spvType, member, spv::Decoration::MemberOffsetNV,
+                                        glslangMember.getQualifier().layoutMemberOffset);
+        } else if (explicitLayout != glslang::ElpNone) {
             // figure out what to do with offset, which is accumulating
             int nextOffset;
             updateMemberOffset(type, glslangMember, offset, nextOffset, explicitLayout, memberQualifier.layoutMatrix);
@@ -5987,7 +6271,9 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
 
         // built-in variable decorations
         spv::BuiltIn builtIn = TranslateBuiltInDecoration(glslangMember.getQualifier().builtIn, true);
-        if (builtIn != spv::BuiltIn::Max)
+        // built-in decoration is used to detect AST nodes, but won't be decorated on member variables.
+        if (builtIn != spv::BuiltIn::Max &&
+            builtIn != spv::BuiltIn::ResourceHeapEXT && builtIn != spv::BuiltIn::SamplerHeapEXT)
             builder.addMemberDecoration(spvType, member, spv::Decoration::BuiltIn, (int)builtIn);
 
         // nonuniform
@@ -6040,6 +6326,13 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
 
     if (qualifier.hasHitObjectShaderRecordNV())
         builder.addDecoration(spvType, spv::Decoration::HitObjectShaderRecordBufferNV);
+
+    if (qualifier.hasBank()) {
+        builder.addExtension(spv::E_SPV_NV_push_constant_bank);
+        builder.addCapability(spv::Capability::PushConstantBanksNV);
+        builder.addDecoration(spvType, spv::Decoration::BankNV, qualifier.layoutBank);
+    }
+  
     if (qualifier.hasHitObjectShaderRecordEXT())
         builder.addDecoration(spvType, spv::Decoration::HitObjectShaderRecordBufferEXT);
 }
@@ -6111,6 +6404,12 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
         loadedId = convertLoadedBoolInUniformToUint(type, nominalTypeId, loadedId);
     }
 
+    if (!builder.getAccessChain().descHeapInfo.descHeapInstId.empty()) {
+        for (auto heapInst : builder.getAccessChain().descHeapInfo.descHeapInstId)
+            heapInst->setTypeId(convertGlslangToSpvType(type));
+        builder.clearAccessChain();
+    }
+
     return loadedId;
 }
 
@@ -7082,7 +7381,18 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
             } else {
                 resultTypeId = builder.makePointer(spv::StorageClass::Image, resultType());
             }
-            spv::Id pointer = builder.createOp(spv::Op::OpImageTexelPointer, resultTypeId, operands);
+
+            // EXT_descriptor_heap
+            // For image atomic parameter, using untyped image texel pointer to carry on type metadata.
+            spv::Op imgTexelOp = spv::Op::OpImageTexelPointer;
+            if (node->getQualifier().isUsedByAtomic() &&
+                imageType.getQualifier().builtIn == glslang::EbvResourceHeapEXT) {
+                operands.insert(operands.begin(), {true, convertGlslangToSpvType(imageType)});
+                imgTexelOp = spv::Op::OpUntypedImageTexelPointerEXT;
+                resultTypeId = builder.makeUntypedPointer(spv::StorageClass::Image);
+            }
+
+            spv::Id pointer = builder.createOp(imgTexelOp, resultTypeId, operands);
             if (imageType.getQualifier().nonUniform) {
                 builder.addDecoration(pointer, spv::Decoration::NonUniformEXT);
             }
@@ -9843,9 +10153,12 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
                 builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16);
             if (builder.getNumComponents(operands[0]) == 1)
                 frexpIntType = builder.makeIntegerType(width, true);
+            else if (builder.isCooperativeVector(operands[0]))
+                frexpIntType = builder.makeCooperativeVectorTypeNV(builder.makeIntegerType(width, true),
+                                                                   builder.getCooperativeVectorNumComponents(builder.getTypeId(operands[0])));
             else
                 frexpIntType = builder.makeVectorType(builder.makeIntegerType(width, true),
-                    builder.getNumComponents(operands[0]));
+                                                      builder.getNumComponents(operands[0]));
             typeId = builder.makeStructResultType(typeId0, frexpIntType);
             consumedOperands = 1;
         }
@@ -10755,7 +11068,11 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
         builtIn == spv::BuiltIn::ObjectToWorldKHR ||
         builtIn == spv::BuiltIn::WorldToObjectKHR;
 
-    if (mayNeedToReuseBuiltIn) {
+    // EXT_descriptor_heap
+    const bool needToRemapDescHeap =
+        builtIn == spv::BuiltIn::ResourceHeapEXT || builtIn == spv::BuiltIn::SamplerHeapEXT;
+
+    if (mayNeedToReuseBuiltIn || needToRemapDescHeap) {
         auto iter = builtInVariableIds.find(uint32_t(builtIn));
         if (builtInVariableIds.end() != iter) {
             id = iter->second;
@@ -10929,6 +11246,18 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
     if (symbol->getType().getQualifier().hasSpirvDecorate())
         applySpirvDecorate(symbol->getType(), id, {});
 
+    if (symbol->getQualifier().hasBank()) {
+        builder.addExtension(spv::E_SPV_NV_push_constant_bank);
+        builder.addCapability(spv::Capability::PushConstantBanksNV);
+        builder.addDecoration(id, spv::Decoration::BankNV, symbol->getQualifier().layoutBank);
+    }
+
+    if (symbol->getQualifier().hasMemberOffset()) {
+        builder.addExtension(spv::E_SPV_NV_push_constant_bank);
+        builder.addCapability(spv::Capability::PushConstantBanksNV);
+        builder.addDecoration(id, spv::Decoration::MemberOffsetNV, symbol->getQualifier().layoutMemberOffset);
+    }
+
     return id;
 }
 
@@ -11149,8 +11478,8 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla
         glslang::TVector<glslang::TTypeLoc>::const_iterator iter;
         for (iter = glslangType.getStruct()->begin(); iter != glslangType.getStruct()->end(); ++iter)
             spvConsts.push_back(createSpvConstantFromConstUnionArray(*iter->type, consts, nextConst, false));
-    } else if (glslangType.getVectorSize() > 1 || glslangType.isCoopVecNV()) {
-        unsigned int numComponents = glslangType.isCoopVecNV() ? glslangType.getTypeParameters()->arraySizes->getDimSize(0) : glslangType.getVectorSize();
+    } else if (glslangType.getVectorSize() > 1 || glslangType.isCoopVecOrLongVector()) {
+        unsigned int numComponents = glslangType.isCoopVecOrLongVector() ? glslangType.getTypeParameters()->arraySizes->getDimSize(0) : glslangType.getVectorSize();
         for (unsigned int i = 0; i < numComponents; ++i) {
             bool zero = nextConst >= consts.size();
             switch (glslangType.getBasicType()) {

+ 307 - 18
3rdparty/glslang/SPIRV/SpvBuilder.cpp

@@ -190,6 +190,27 @@ Id Builder::makeForwardPointer(StorageClass storageClass)
     return type->getResultId();
 }
 
+Id Builder::makeUntypedPointer(StorageClass storageClass, bool setBufferPointer)
+{
+    // try to find it
+    Instruction* type;
+    // both typeBufferEXT and UntypedPointer only contains storage class info.
+    spv::Op typeOp = setBufferPointer ? Op::OpTypeBufferEXT : Op::OpTypeUntypedPointerKHR;
+    for (int t = 0; t < (int)groupedTypes[enumCast(typeOp)].size(); ++t) {
+        type = groupedTypes[enumCast(typeOp)][t];
+        if (type->getImmediateOperand(0) == (unsigned)storageClass)
+            return type->getResultId();
+    }
+
+    // not found, make it
+    type = new Instruction(getUniqueId(), NoType, typeOp);
+    type->addImmediateOperand(storageClass);
+    groupedTypes[enumCast(typeOp)].push_back(type);
+    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
+    module.mapInstruction(type);
+    return type->getResultId();
+}
+
 Id Builder::makePointerFromForwardPointer(StorageClass storageClass, Id forwardPointerType, Id pointee)
 {
     // try to find it
@@ -1767,6 +1788,7 @@ bool Builder::isConstantOpCode(Op opcode) const
     case Op::OpSpecConstantComposite:
     case Op::OpSpecConstantCompositeReplicateEXT:
     case Op::OpSpecConstantOp:
+    case Op::OpConstantSizeOfEXT:
         return true;
     default:
         return false;
@@ -2429,6 +2451,23 @@ void Builder::addDecorationId(Id id, Decoration decoration, const std::vector<Id
     decorations.insert(std::unique_ptr<Instruction>(dec));
 }
 
+void Builder::addMemberDecorationIdEXT(Id id, unsigned int member, Decoration decoration,
+                                       const std::vector<unsigned>& operands)
+{
+    if (decoration == spv::Decoration::Max)
+        return;
+
+    Instruction* dec = new Instruction(Op::OpMemberDecorateIdEXT);
+    dec->reserveOperands(operands.size() + 3);
+    dec->addIdOperand(id);
+    dec->addImmediateOperand(member);
+    dec->addImmediateOperand(decoration);
+    for (auto operand : operands)
+        dec->addIdOperand(operand);
+
+    decorations.insert(std::unique_ptr<Instruction>(dec));
+}
+
 void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, int num)
 {
     if (decoration == spv::Decoration::Max)
@@ -2844,6 +2883,38 @@ void Builder::createConstVariable(Id type, const char* name, Id constant, bool i
     }
 }
 
+// Comments in header
+Id Builder::createUntypedVariable(Decoration precision, StorageClass storageClass, const char* name, Id dataType,
+                                  Id initializer)
+{
+    Id resultUntypedPointerType = makeUntypedPointer(storageClass);
+    Instruction* inst = new Instruction(getUniqueId(), resultUntypedPointerType, Op::OpUntypedVariableKHR);
+    inst->addImmediateOperand(storageClass);
+    if (dataType != NoResult) {
+        Id dataPointerType = makePointer(storageClass, dataType);
+        inst->addIdOperand(dataPointerType);
+    }
+    if (initializer != NoResult)
+        inst->addIdOperand(initializer);
+
+    switch (storageClass) {
+    case StorageClass::Function:
+        // Validation rules require the declaration in the entry block
+        buildPoint->getParent().addLocalVariable(std::unique_ptr<Instruction>(inst));
+        break;
+    default:
+        constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(inst));
+        module.mapInstruction(inst);
+        break;
+    }
+
+    if (name)
+        addName(inst->getResultId(), name);
+    setPrecision(inst->getResultId(), precision);
+
+    return inst->getResultId();
+}
+
 // Comments in header
 Id Builder::createVariable(Decoration precision, StorageClass storageClass, Id type, const char* name, Id initializer,
     bool const compilerGenerated)
@@ -2916,9 +2987,14 @@ spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAc
 void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope,
     unsigned int alignment)
 {
-    Instruction* store = new Instruction(Op::OpStore);
-    store->reserveOperands(2);
-    store->addIdOperand(lValue);
+    Instruction* store = nullptr;
+    if (isUntypedPointer(lValue))
+        store = createDescHeapLoadStoreBaseRemap(lValue, Op::OpStore);
+    else {
+        store = new Instruction(Op::OpStore);
+        store->reserveOperands(2);
+        store->addIdOperand(lValue);
+    }
     store->addIdOperand(rValue);
 
     memoryAccess = sanitizeMemoryAccessForStorageClass(memoryAccess, getStorageClass(lValue));
@@ -2940,8 +3016,13 @@ void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAcce
 Id Builder::createLoad(Id lValue, spv::Decoration precision, spv::MemoryAccessMask memoryAccess,
     spv::Scope scope, unsigned int alignment)
 {
-    Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), Op::OpLoad);
-    load->addIdOperand(lValue);
+    Instruction* load = nullptr;
+    if (isUntypedPointer(lValue))
+        load = createDescHeapLoadStoreBaseRemap(lValue, Op::OpLoad);
+    else {
+        load = new Instruction(getUniqueId(), getDerefTypeId(lValue), Op::OpLoad);
+        load->addIdOperand(lValue);
+    }
 
     memoryAccess = sanitizeMemoryAccessForStorageClass(memoryAccess, getStorageClass(lValue));
 
@@ -2961,6 +3042,172 @@ Id Builder::createLoad(Id lValue, spv::Decoration precision, spv::MemoryAccessMa
     return load->getResultId();
 }
 
+Instruction* Builder::createDescHeapLoadStoreBaseRemap(Id baseId, Op op)
+{
+    // could only be untypedAccessChain or BufferPointerEXT op.
+    spv::Op instOp = module.getInstruction(baseId)->getOpCode();
+    spv::Id baseVal = baseId;
+    // base type (from run time array)
+    spv::Id resultTy = getIdOperand(baseId, 0);
+    // Descriptor heap using run time array.
+    if (accessChain.descHeapInfo.descHeapStorageClass != StorageClass::Max)
+        resultTy = getIdOperand(resultTy, 0);
+    if (instOp == Op::OpBufferPointerEXT) {
+        // get base structure type from run time array of buffer structure type.
+        // create an extra untyped access chain for buffer pointer.
+        resultTy = accessChain.descHeapInfo.descHeapBaseTy;
+        Instruction* chain = new Instruction(getUniqueId(), getTypeId(baseId), Op::OpUntypedAccessChainKHR);
+        // base type.
+        chain->addIdOperand(resultTy);
+        // base
+        chain->addIdOperand(baseId);
+        // index
+        for (int i = 0; i < (int)accessChain.indexChain.size(); ++i) {
+            chain->addIdOperand(accessChain.indexChain[i]);
+        }
+        addInstruction(std::unique_ptr<Instruction>(chain));
+        baseVal = chain->getResultId();
+        clearAccessChain();
+    } else if (instOp != Op::OpUntypedAccessChainKHR) {
+        assert("Not a untyped load type");
+    }
+
+    Instruction* inst = nullptr;
+    if (op == Op::OpStore)
+        inst = new Instruction(Op::OpStore);
+    else {
+        inst = new Instruction(getUniqueId(), resultTy, Op::OpLoad);
+        accessChain.descHeapInfo.descHeapInstId.push_back(inst);
+    }
+    inst->addIdOperand(baseVal);
+    return inst;
+}
+
+uint32_t Builder::isStructureHeapMember(Id id, std::vector<Id> indexChain,
+    unsigned int idx, spv::BuiltIn* bt, uint32_t* firstArrIndex)
+{
+    unsigned currentIdx = idx;
+    // Process types, only array types could contain no constant id operands.
+    Id baseId = id;
+    if (baseId == NoType)
+        return 0;
+    if (isPointerType(baseId))
+        baseId = getContainedTypeId(baseId);
+    auto baseInst = module.getInstruction(baseId);
+    if (baseInst->getOpCode() == spv::Op::OpTypeArray ||
+        baseInst->getOpCode() == spv::Op::OpTypeRuntimeArray) {
+        if (firstArrIndex)
+            *firstArrIndex = currentIdx;
+        baseId = getContainedTypeId(baseId);
+        baseInst = module.getInstruction(baseId);
+        currentIdx++;
+    }
+    if (currentIdx >= indexChain.size())
+        return 0;
+    // Process index op.
+    auto indexInst = module.getInstruction(indexChain[currentIdx]);
+    if (indexInst->getOpCode() != spv::Op::OpConstant)
+        return 0;
+    auto index = indexInst->getImmediateOperand(0);
+    for (auto dec = decorations.begin(); dec != decorations.end(); dec++) {
+        if (dec->get()->getOpCode() == spv::Op::OpMemberDecorate && dec->get()->getIdOperand(0) == baseId &&
+            dec->get()->getImmediateOperand(1) == index &&
+            dec->get()->getImmediateOperand(2) == spv::Decoration::BuiltIn &&
+            (dec->get()->getImmediateOperand(3) == (unsigned)spv::BuiltIn::ResourceHeapEXT ||
+             dec->get()->getImmediateOperand(3) == (unsigned)spv::BuiltIn::SamplerHeapEXT)) {
+            if (bt)
+                *bt = (spv::BuiltIn)dec->get()->getImmediateOperand(3);
+            return currentIdx;
+        }
+    }
+    // New base.
+    if (baseInst->getOpCode() == spv::Op::OpTypeStruct) {
+        if (!baseInst->isIdOperand(index) || idx == indexChain.size() - 1)
+            return 0;
+        return isStructureHeapMember(baseInst->getIdOperand(index), indexChain, currentIdx + 1, bt, firstArrIndex);
+    }
+
+    return 0;
+}
+
+// Comments in header
+Id Builder::createDescHeapAccessChain()
+{
+    uint32_t rsrcOffsetIdx = accessChain.descHeapInfo.structRsrcTyOffsetCount;
+    if (rsrcOffsetIdx != 0)
+        accessChain.base = accessChain.descHeapInfo.structRemappedBase;
+    Id base = accessChain.base;
+    Id untypedResultTy = accessChain.descHeapInfo.descHeapBaseTy;
+    uint32_t explicitArrayStride = accessChain.descHeapInfo.descHeapBaseArrayStride;
+    std::vector<Id>& offsets = accessChain.indexChain;
+    uint32_t firstArrIndex = accessChain.descHeapInfo.structRsrcTyFirstArrIndex;
+    // both typeBufferEXT and UntypedPointer only contains storage class info.
+    StorageClass storageClass = (StorageClass)accessChain.descHeapInfo.descHeapStorageClass;
+    Id resultTy = makeUntypedPointer(storageClass == spv::StorageClass::StorageBuffer ? spv::StorageClass::StorageBuffer
+                                                                                      : spv::StorageClass::Uniform);
+
+    // Make the untyped access chain instruction
+    Instruction* chain = new Instruction(getUniqueId(), makeUntypedPointer(getStorageClass(base)), Op::OpUntypedAccessChainKHR);
+
+    if (storageClass == spv::StorageClass::Uniform || storageClass == spv::StorageClass::StorageBuffer) {
+        // For buffer and uniform heap, split first index as heap array index
+        // Insert BufferPointer op and construct another access chain with following indexes.
+        Id bufferTy = makeUntypedPointer(storageClass, true);
+        Id strideId = NoResult;
+        if (explicitArrayStride == 0) {
+            strideId = createConstantSizeOfEXT(bufferTy);
+        } else {
+            strideId = makeUintConstant(explicitArrayStride);
+        }
+        Id runtimeArrTy = makeRuntimeArray(bufferTy);
+        addDecorationId(runtimeArrTy, spv::Decoration::ArrayStrideIdEXT, strideId);
+        chain->addIdOperand(runtimeArrTy);
+        chain->addIdOperand(base);
+        // We would only re-target current member resource directly to resource/sampler heap base.
+        // So the previous access chain index towards final resource type is not needed?
+        // In current draft, only keep the first 'array index' into last access chain index.
+        // As those resource can't be declared as an array, in current first draft, array index will
+        // be the second index. This will be refined later.
+        chain->addIdOperand(offsets[firstArrIndex]);
+        if (rsrcOffsetIdx != 0) {
+            for (uint32_t i = 0; i < rsrcOffsetIdx + 1; i++) {
+                if (rsrcOffsetIdx + i + 1 < offsets.size())
+                    offsets[i] = offsets[i + rsrcOffsetIdx + 1];
+            }
+        } else {
+            for (uint32_t i = 0; i < offsets.size() - 1; i++) {
+                offsets[i] = offsets[i + 1];
+            }
+        }
+        for (uint32_t i = 0; i < rsrcOffsetIdx + 1; i++)
+            offsets.pop_back();
+        addInstruction(std::unique_ptr<Instruction>(chain));
+        // Create OpBufferPointer for loading target buffer descriptor.
+        Instruction* bufferUntypedDataPtr = new Instruction(getUniqueId(), resultTy, Op::OpBufferPointerEXT);
+        bufferUntypedDataPtr->addIdOperand(chain->getResultId());
+        addInstruction(std::unique_ptr<Instruction>(bufferUntypedDataPtr));
+        // Final/Second untyped access chain loading will be created during loading, current results only
+        // refer to the loading 'base'.
+        return bufferUntypedDataPtr->getResultId();
+    } else {
+        // image/sampler heap
+        Id strideId = NoResult;
+        if (explicitArrayStride == 0) {
+            strideId = createConstantSizeOfEXT(untypedResultTy);
+        } else {
+            strideId = makeUintConstant(explicitArrayStride);
+        }
+        Id runtimeArrTy = makeRuntimeArray(untypedResultTy);
+        addDecorationId(runtimeArrTy, spv::Decoration::ArrayStrideIdEXT, strideId);
+        chain->addIdOperand(runtimeArrTy);
+        chain->addIdOperand(base);
+        for (int i = 0; i < (int)offsets.size(); ++i)
+            chain->addIdOperand(offsets[i]);
+        addInstruction(std::unique_ptr<Instruction>(chain));
+        return chain->getResultId();
+    }
+}
+
 // Comments in header
 Id Builder::createAccessChain(StorageClass storageClass, Id base, const std::vector<Id>& offsets)
 {
@@ -3344,12 +3591,21 @@ Id Builder::createLvalueSwizzle(Id typeId, Id target, Id source, const std::vect
 // Comments in header
 void Builder::promoteScalar(Decoration precision, Id& left, Id& right)
 {
-    int direction = getNumComponents(right) - getNumComponents(left);
+    // choose direction of promotion (+1 for left to right, -1 for right to left)
+    int direction = !isScalar(right) - !isScalar(left);
+
+    auto const &makeVec = [&](Id component, Id other) {
+        if (isCooperativeVector(other)) {
+            return makeCooperativeVectorTypeNV(getTypeId(component), getCooperativeVectorNumComponents(getTypeId(other)));
+        } else {
+            return makeVectorType(getTypeId(component), getNumComponents(other));
+        }
+    };
 
     if (direction > 0)
-        left = smearScalar(precision, left, makeVectorType(getTypeId(left), getNumComponents(right)));
+        left = smearScalar(precision, left, makeVec(left, right));
     else if (direction < 0)
-        right = smearScalar(precision, right, makeVectorType(getTypeId(right), getNumComponents(left)));
+        right = smearScalar(precision, right, makeVec(right, left));
 
     return;
 }
@@ -3361,7 +3617,7 @@ Id Builder::smearScalar(Decoration precision, Id scalar, Id vectorType)
     assert(getTypeId(scalar) == getScalarTypeId(vectorType));
 
     int numComponents = getNumTypeComponents(vectorType);
-    if (numComponents == 1 && !isCooperativeVectorType(vectorType))
+    if (numComponents == 1 && !isCooperativeVectorType(vectorType) && !isVectorType(vectorType))
         return scalar;
 
     Instruction* smear = nullptr;
@@ -3773,7 +4029,7 @@ Id Builder::createCompositeConstruct(Id typeId, const std::vector<Id>& constitue
 {
     assert(isAggregateType(typeId) || (getNumTypeConstituents(typeId) > 1 &&
            getNumTypeConstituents(typeId) == constituents.size()) ||
-           (isCooperativeVectorType(typeId) && constituents.size() == 1));
+           ((isCooperativeVectorType(typeId) || isVectorType(typeId)) && constituents.size() == 1));
 
     if (generatingOpCodeForSpecConst) {
         // Sometime, even in spec-constant-op mode, the constant composite to be
@@ -3862,9 +4118,16 @@ Id Builder::createConstructor(Decoration precision, const std::vector<Id>& sourc
         return smearScalar(precision, sources[0], resultTypeId);
 
     // Special case: 2 vectors of equal size
-    if (sources.size() == 1 && isVector(sources[0]) && numTargetComponents == getNumComponents(sources[0])) {
-        assert(resultTypeId == getTypeId(sources[0]));
-        return sources[0];
+    if (sources.size() == 1 &&
+        (isVector(sources[0]) || isCooperativeVector(sources[0])) &&
+        numTargetComponents == getNumComponents(sources[0])) {
+        if (isCooperativeVector(sources[0]) != isCooperativeVectorType(resultTypeId)) {
+            assert(isVector(sources[0]) != isVectorType(resultTypeId));
+            return createUnaryOp(spv::Op::OpBitcast, resultTypeId, sources[0]);
+        } else {
+            assert(resultTypeId == getTypeId(sources[0]));
+            return sources[0];
+        }
     }
 
     // accumulate the arguments for OpCompositeConstruct
@@ -3873,7 +4136,7 @@ Id Builder::createConstructor(Decoration precision, const std::vector<Id>& sourc
 
     // lambda to store the result of visiting an argument component
     const auto latchResult = [&](Id comp) {
-        if (numTargetComponents > 1)
+        if (numTargetComponents > 1 || isVectorType(resultTypeId))
             constituents.push_back(comp);
         else
             result = comp;
@@ -4251,6 +4514,13 @@ void Builder::clearAccessChain()
     accessChain.isRValue = false;
     accessChain.coherentFlags.clear();
     accessChain.alignment = 0;
+    accessChain.descHeapInfo.descHeapBaseTy = NoResult;
+    accessChain.descHeapInfo.descHeapStorageClass = StorageClass::Max;
+    accessChain.descHeapInfo.descHeapInstId.clear();
+    accessChain.descHeapInfo.descHeapBaseArrayStride = NoResult;
+    accessChain.descHeapInfo.structRemappedBase = NoResult;
+    accessChain.descHeapInfo.structRsrcTyOffsetCount = 0;
+    accessChain.descHeapInfo.structRsrcTyFirstArrIndex = 0;
 }
 
 // Comments in header
@@ -4372,7 +4642,7 @@ Id Builder::accessChainLoad(Decoration precision, Decoration l_nonUniform,
             if (constant) {
                 id = createCompositeExtract(accessChain.base, swizzleBase, indexes);
                 setPrecision(id, precision);
-            } else if (isCooperativeVector(accessChain.base)) {
+            } else if (isVector(accessChain.base) || isCooperativeVector(accessChain.base)) {
                 assert(accessChain.indexChain.size() == 1);
                 id = createVectorExtractDynamic(accessChain.base, resultType, accessChain.indexChain[0]);
             } else {
@@ -4461,10 +4731,13 @@ Id Builder::accessChainGetLValue()
 Id Builder::accessChainGetInferredType()
 {
     // anything to operate on?
-    if (accessChain.base == NoResult)
+    // for untyped pointer, it may be remapped to a descriptor heap.
+    // for descriptor heap, its base data type will be determined later,
+    // according to load/store results' types.
+    if (accessChain.base == NoResult || isUntypedPointer(accessChain.base) ||
+        isStructureHeapMember(getTypeId(accessChain.base), accessChain.indexChain, 0) != 0)
         return NoType;
     Id type = getTypeId(accessChain.base);
-
     // do initial dereference
     if (! accessChain.isRValue)
         type = getContainedTypeId(type);
@@ -4582,7 +4855,13 @@ Id Builder::collapseAccessChain()
 
     // emit the access chain
     StorageClass storageClass = (StorageClass)module.getStorageClass(getTypeId(accessChain.base));
-    accessChain.instr = createAccessChain(storageClass, accessChain.base, accessChain.indexChain);
+    // when descHeap info is set, use another access chain process.
+    if ((isUntypedPointer(accessChain.base) || accessChain.descHeapInfo.structRsrcTyOffsetCount!= 0) &&
+        accessChain.descHeapInfo.descHeapStorageClass != StorageClass::Max) {
+        accessChain.instr = createDescHeapAccessChain();
+    } else {
+        accessChain.instr = createAccessChain(storageClass, accessChain.base, accessChain.indexChain);
+    }
 
     return accessChain.instr;
 }
@@ -4691,6 +4970,16 @@ void Builder::createBranch(bool implicit, Block* block)
     block->addPredecessor(buildPoint);
 }
 
+// Create OpConstantSizeOfEXT
+Id Builder::createConstantSizeOfEXT(Id typeId)
+{
+    Instruction* inst = new Instruction(getUniqueId(), makeIntType(32), Op::OpConstantSizeOfEXT);
+    inst->addIdOperand(typeId);
+    constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(inst));
+    module.mapInstruction(inst);
+    return inst->getResultId();
+}
+
 void Builder::createSelectionMerge(Block* mergeBlock, SelectionControlMask control)
 {
     Instruction* merge = new Instruction(Op::OpSelectionMerge);

+ 55 - 1
3rdparty/glslang/SPIRV/SpvBuilder.h

@@ -230,6 +230,7 @@ public:
     Id makePointer(StorageClass, Id pointee);
     Id makeForwardPointer(StorageClass);
     Id makePointerFromForwardPointer(StorageClass, Id forwardPointerType, Id pointee);
+    Id makeUntypedPointer(StorageClass storageClass, bool setBufferPointer = false);
     Id makeIntegerType(int width, bool hasSign);   // generic
     Id makeIntType(int width) { return makeIntegerType(width, true); }
     Id makeUintType(int width) { return makeIntegerType(width, false); }
@@ -317,6 +318,14 @@ public:
     Id getCooperativeVectorNumComponents(Id typeId) const { return module.getInstruction(typeId)->getIdOperand(1); }
 
     bool isPointer(Id resultId)      const { return isPointerType(getTypeId(resultId)); }
+    bool isUntypedPointer(Id resultId) const
+    {
+        const Id tid = getTypeId(resultId);
+        // Expect that OpString have no type
+        if (tid == 0)
+            return false;
+        return isUntypedPointerType(tid);
+    }
     bool isScalar(Id resultId)       const { return isScalarType(getTypeId(resultId)); }
     bool isVector(Id resultId)       const { return isVectorType(getTypeId(resultId)); }
     bool isMatrix(Id resultId)       const { return isMatrixType(getTypeId(resultId)); }
@@ -334,6 +343,7 @@ public:
         { return getTypeClass(typeId) == Op::OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; }
     bool isFloatType(Id typeId)        const { return getTypeClass(typeId) == Op::OpTypeFloat; }
     bool isPointerType(Id typeId)      const { return getTypeClass(typeId) == Op::OpTypePointer; }
+    bool isUntypedPointerType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeUntypedPointerKHR; }
     bool isScalarType(Id typeId)       const
         { return getTypeClass(typeId) == Op::OpTypeFloat || getTypeClass(typeId) == Op::OpTypeInt ||
           getTypeClass(typeId) == Op::OpTypeBool; }
@@ -469,6 +479,7 @@ public:
     void addMemberDecoration(Id, unsigned int member, Decoration, const char*);
     void addMemberDecoration(Id, unsigned int member, Decoration, const std::vector<unsigned>& literals);
     void addMemberDecoration(Id, unsigned int member, Decoration, const std::vector<const char*>& strings);
+    void addMemberDecorationIdEXT(Id, unsigned int member, Decoration, const std::vector<unsigned>& operands);
 
     // At the end of what block do the next create*() instructions go?
     // Also reset current last DebugScope and current source line to unknown
@@ -531,9 +542,16 @@ public:
     Id createVariable(Decoration precision, StorageClass storageClass, Id type, const char* name = nullptr,
         Id initializer = NoResult, bool const compilerGenerated = true);
 
+    // Create an untyped global or function local or IO variable.
+    Id createUntypedVariable(Decoration precision, StorageClass storageClass, const char* name = nullptr,
+                             Id dataType = NoResult, Id initializer = NoResult);
+
     // Create an intermediate with an undefined value.
     Id createUndefined(Id type);
 
+    // Create load/store instruction with a remapped descriptor heap base.
+    Instruction* createDescHeapLoadStoreBaseRemap(Id base, Op op);
+
     // Store into an Id and return the l-value
     void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMask::MaskNone,
         spv::Scope scope = spv::Scope::Max, unsigned int alignment = 0);
@@ -790,6 +808,18 @@ public:
         unsigned int alignment;        // bitwise OR of alignment values passed in. Accumulates worst alignment.
                                        // Only tracks base and (optional) component selection alignment.
 
+        struct DescHeapInfo {
+            Id descHeapBaseTy;                  // for descriptor heap, record its base data type.
+            StorageClass descHeapStorageClass;  // for descriptor heap, record its basic storage class.
+            uint32_t descHeapBaseArrayStride;   // for descriptor heap, record its explicit array stride.
+            std::vector<Instruction*> descHeapInstId;
+                                                // for descriptor heap, record its data type for loading/store results.
+            uint32_t structRsrcTyOffsetCount;
+            uint32_t structRsrcTyFirstArrIndex;
+            Id structRemappedBase;
+        };
+        DescHeapInfo descHeapInfo;
+
         // Accumulate whether anything in the chain of structures has coherent decorations.
         struct CoherentFlags {
             CoherentFlags() { clear(); }
@@ -856,10 +886,15 @@ public:
     // clear accessChain
     void clearAccessChain();
 
+    Id createDescHeapAccessChain();
+    Id createConstantSizeOfEXT(Id typeId);
+    uint32_t isStructureHeapMember(Id id, std::vector<Id> indexChain, unsigned int idx, spv::BuiltIn* bt = nullptr,
+                                   uint32_t* firstArrIndex = nullptr);
+
     // set new base as an l-value base
     void setAccessChainLValue(Id lValue)
     {
-        assert(isPointer(lValue));
+        assert(isPointer(lValue) || isUntypedPointer(lValue));
         accessChain.base = lValue;
     }
 
@@ -870,6 +905,25 @@ public:
         accessChain.base = rValue;
     }
 
+    // set access chain info for untyped descriptor heap variable
+    void setAccessChainDescHeapInfo(StorageClass storageClass = StorageClass::Max, Id baseTy = NoResult,
+                                    uint32_t explicitArrayStride = NoResult, uint32_t structRsrcTyOffsetCount = 0,
+                                    spv::Id structRemappedBase = NoResult, uint32_t firstArrIndex = NoResult)
+    {
+        if (accessChain.descHeapInfo.descHeapStorageClass == StorageClass::Max)
+            accessChain.descHeapInfo.descHeapStorageClass = storageClass;
+        if (accessChain.descHeapInfo.descHeapBaseTy == NoResult)
+            accessChain.descHeapInfo.descHeapBaseTy = baseTy;
+        if (accessChain.descHeapInfo.descHeapBaseArrayStride == NoResult)
+            accessChain.descHeapInfo.descHeapBaseArrayStride = explicitArrayStride;
+        if (accessChain.descHeapInfo.structRemappedBase == NoResult)
+            accessChain.descHeapInfo.structRemappedBase = structRemappedBase;
+        if (accessChain.descHeapInfo.structRsrcTyOffsetCount == 0)
+            accessChain.descHeapInfo.structRsrcTyOffsetCount = structRsrcTyOffsetCount;
+        if (accessChain.descHeapInfo.structRsrcTyFirstArrIndex == 0)
+            accessChain.descHeapInfo.structRsrcTyFirstArrIndex = firstArrIndex;
+    }
+
     // push offset onto the end of the chain
     void accessChainPush(Id offset, AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
     {

+ 4 - 1
3rdparty/glslang/SPIRV/SpvPostProcess.cpp

@@ -83,7 +83,10 @@ void Builder::postProcessType(const Instruction& inst, Id typeId)
             if (containsType(typeId, Op::OpTypeFloat, 16))
                 addCapability(Capability::Float16);
         } else {
-            StorageClass storageClass = getStorageClass(inst.getIdOperand(0));
+            StorageClass storageClass = StorageClass::Max;
+            if (module.getInstruction(inst.getIdOperand(0))->getOpCode() != Op::OpUntypedAccessChainKHR) {
+                storageClass = getStorageClass(inst.getIdOperand(0));
+            }
             if (width == 8) {
                 switch (storageClass) {
                 case StorageClass::PhysicalStorageBufferEXT:

+ 1 - 0
3rdparty/glslang/SPIRV/SpvTools.cpp

@@ -166,6 +166,7 @@ void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<
     spvValidatorOptionsSetScalarBlockLayout(options, intermediate.usingScalarBlockLayout());
     spvValidatorOptionsSetWorkgroupScalarBlockLayout(options, intermediate.usingScalarBlockLayout());
     spvValidatorOptionsSetAllowOffsetTextureOperand(options, intermediate.usingTextureOffsetNonConst());
+    spvValidatorOptionsSetAllowVulkan32BitBitwise(options, true);
     spvValidateWithOptions(context, options, &binary, &diagnostic);
 
     // report

+ 1 - 0
3rdparty/glslang/SPIRV/disassemble.cpp

@@ -414,6 +414,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
                 idDescriptor[resultId] = "struct";
                 break;
             case Op::OpTypePointer:
+            case Op::OpTypeUntypedPointerKHR:
                 idDescriptor[resultId] = "ptr";
                 break;
             case Op::OpTypeVector:

+ 48 - 0
3rdparty/glslang/SPIRV/doc.cpp

@@ -350,6 +350,12 @@ const char* DecorationString(int decoration)
     case (int)Decoration::HitObjectShaderRecordBufferEXT:  return "DecorationHitObjectShaderRecordBufferEXT";
 
     case (int)Decoration::SaturatedToLargestFloat8NormalConversionEXT: return "DecorationSaturatedToLargestFloat8NormalConversionEXT";
+
+    case (int)Decoration::BankNV:                        return "BankNV";
+    case (int)Decoration::MemberOffsetNV:                return "MemberOffsetNV";
+
+    case (int)Decoration::ArrayStrideIdEXT:        return "DecorationArrayStrideIdEXT";
+    case (int)Decoration::OffsetIdEXT:             return "DecorationOffsetIdEXT";
     }
 }
 
@@ -491,6 +497,8 @@ const char* BuiltInString(int builtIn)
     case (int)BuiltIn::CoreMaxIDARM:           return "CoreMaxIDARM";
     case (int)BuiltIn::WarpIDARM:              return "WarpIDARM";
     case (int)BuiltIn::WarpMaxIDARM:           return "BuiltInWarpMaxIDARM";
+    case (int)BuiltIn::SamplerHeapEXT:         return "SamplerHeapEXT";
+    case (int)BuiltIn::ResourceHeapEXT:        return "ResourceHeapEXT";
 
     default: return "Bad";
     }
@@ -1093,6 +1101,8 @@ const char* CapabilityString(int info)
     case (int)Capability::ShaderClockKHR:                          return "ShaderClockKHR";
     case (int)Capability::QuadControlKHR:                          return "QuadControlKHR";
     case (int)Capability::Int64ImageEXT:                           return "Int64ImageEXT";
+    case (int)Capability::DescriptorHeapEXT:                       return "DescriptorHeapEXT";
+    case (int)Capability::UntypedPointersKHR:                      return "UntypedPointersKHR";
 
     case (int)Capability::IntegerFunctions2INTEL:              return "IntegerFunctions2INTEL";
 
@@ -1140,7 +1150,10 @@ const char* CapabilityString(int info)
     case (int)Capability::Float8EXT:                           return "Float8EXT";
     case (int)Capability::Float8CooperativeMatrixEXT:          return "Float8CooperativeMatrixEXT";
 
+    case (int)Capability::PushConstantBanksNV:                 return "PushConstantBanksNV";
+        
     case (int)Capability::Shader64BitIndexingEXT:              return "CapabilityShader64BitIndexingEXT";
+    case (int)Capability::LongVectorEXT:                       return "LongVectorEXT";
 
     default: return "Bad";
     }
@@ -1523,6 +1536,14 @@ const char* OpcodeString(int op)
 
     case (int)Op::OpGroupNonUniformQuadAllKHR: return "OpGroupNonUniformQuadAllKHR";
     case (int)Op::OpGroupNonUniformQuadAnyKHR: return "OpGroupNonUniformQuadAnyKHR";
+    case (int)Op::OpBufferPointerEXT:          return "OpBufferPointerEXT";
+    case (int)Op::OpConstantSizeOfEXT:         return "OpConstantSizeOfEXT";
+    case (int)Op::OpTypeBufferEXT:             return "OpTypeBufferEXT";
+    case (int)Op::OpUntypedAccessChainKHR:     return "OpUntypedAccessChainKHR";
+    case (int)Op::OpUntypedVariableKHR:        return "OpUntypedVariableKHR";
+    case (int)Op::OpTypeUntypedPointerKHR:     return "OpTypeUntypedPointerKHR";
+    case (int)Op::OpMemberDecorateIdEXT:       return "OpMemberDecorateIdEXT";
+    case (int)Op::OpUntypedImageTexelPointerEXT:     return "OpUntypedImageTexelPointerEXT";
 
     case (int)Op::OpAtomicFAddEXT: return "OpAtomicFAddEXT";
     case (int)Op::OpAtomicFMinEXT: return "OpAtomicFMinEXT";
@@ -1819,6 +1840,7 @@ void Parameterize()
         InstructionDesc[enumCast(Op::OpTypeStruct)].setResultAndType(true, false);
         InstructionDesc[enumCast(Op::OpTypeOpaque)].setResultAndType(true, false);
         InstructionDesc[enumCast(Op::OpTypePointer)].setResultAndType(true, false);
+        InstructionDesc[enumCast(Op::OpTypeUntypedPointerKHR)].setResultAndType(true, false);
         InstructionDesc[enumCast(Op::OpTypeForwardPointer)].setResultAndType(false, false);
         InstructionDesc[enumCast(Op::OpTypeFunction)].setResultAndType(true, false);
         InstructionDesc[enumCast(Op::OpTypeEvent)].setResultAndType(true, false);
@@ -1889,6 +1911,7 @@ void Parameterize()
         InstructionDesc[enumCast(Op::OpCooperativeVectorStoreNV)].setResultAndType(false, false);
         InstructionDesc[enumCast(Op::OpCooperativeVectorOuterProductAccumulateNV)].setResultAndType(false, false);
         InstructionDesc[enumCast(Op::OpCooperativeVectorReduceSumAccumulateNV)].setResultAndType(false, false);
+        InstructionDesc[enumCast(Op::OpMemberDecorateIdEXT)].setResultAndType(false, false);
 
         InstructionDesc[enumCast(Op::OpTypeTensorARM)].setResultAndType(true, false);
         InstructionDesc[enumCast(Op::OpTensorReadARM)].setResultAndType(true, true);
@@ -2043,6 +2066,7 @@ void Parameterize()
         InstructionDesc[enumCast(Op::OpTypeStruct)].operands.push(OperandVariableIds, "'Member 0 type', +\n'member 1 type', +\n...");
 
         InstructionDesc[enumCast(Op::OpTypeOpaque)].operands.push(OperandLiteralString, "The name of the opaque type.");
+        InstructionDesc[enumCast(Op::OpTypeUntypedPointerKHR)].operands.push(OperandStorage, "");
 
         InstructionDesc[enumCast(Op::OpTypePointer)].operands.push(OperandStorage, "");
         InstructionDesc[enumCast(Op::OpTypePointer)].operands.push(OperandId, "'Type'");
@@ -2070,6 +2094,9 @@ void Parameterize()
         InstructionDesc[enumCast(Op::OpSpecConstantOp)].operands.push(OperandLiteralNumber, "'Opcode'");
         InstructionDesc[enumCast(Op::OpSpecConstantOp)].operands.push(OperandVariableIds, "'Operands'");
 
+        InstructionDesc[enumCast(Op::OpUntypedVariableKHR)].operands.push(OperandStorage, "");
+        InstructionDesc[enumCast(Op::OpUntypedVariableKHR)].operands.push(OperandId, "'Type'", true);
+        InstructionDesc[enumCast(Op::OpUntypedVariableKHR)].operands.push(OperandId, "'Initializer'", true);
         InstructionDesc[enumCast(Op::OpVariable)].operands.push(OperandStorage, "");
         InstructionDesc[enumCast(Op::OpVariable)].operands.push(OperandId, "'Initializer'", true);
 
@@ -2117,6 +2144,11 @@ void Parameterize()
         InstructionDesc[enumCast(Op::OpMemberDecorate)].operands.push(OperandDecoration, "");
         InstructionDesc[enumCast(Op::OpMemberDecorate)].operands.push(OperandVariableLiterals, "See <<Decoration,'Decoration'>>.");
 
+        InstructionDesc[enumCast(Op::OpMemberDecorateIdEXT)].operands.push(OperandId, "'Structure Type'");
+        InstructionDesc[enumCast(Op::OpMemberDecorateIdEXT)].operands.push(OperandLiteralNumber, "'Member'");
+        InstructionDesc[enumCast(Op::OpMemberDecorateIdEXT)].operands.push(OperandDecoration, "");
+        InstructionDesc[enumCast(Op::OpMemberDecorateIdEXT)].operands.push(OperandVariableIds, "See <<Decoration,'Decoration'>>.");
+
         InstructionDesc[enumCast(Op::OpMemberDecorateStringGOOGLE)].operands.push(OperandId, "'Structure Type'");
         InstructionDesc[enumCast(Op::OpMemberDecorateStringGOOGLE)].operands.push(OperandLiteralNumber, "'Member'");
         InstructionDesc[enumCast(Op::OpMemberDecorateStringGOOGLE)].operands.push(OperandDecoration, "");
@@ -2323,6 +2355,9 @@ void Parameterize()
         InstructionDesc[enumCast(Op::OpAccessChain)].operands.push(OperandId, "'Base'");
         InstructionDesc[enumCast(Op::OpAccessChain)].operands.push(OperandVariableIds, "'Indexes'");
 
+        InstructionDesc[enumCast(Op::OpUntypedAccessChainKHR)].operands.push(OperandId, "'Base Type'");
+        InstructionDesc[enumCast(Op::OpUntypedAccessChainKHR)].operands.push(OperandId, "'Base'");
+        InstructionDesc[enumCast(Op::OpUntypedAccessChainKHR)].operands.push(OperandVariableIds, "'Indexes'");
         InstructionDesc[enumCast(Op::OpInBoundsAccessChain)].operands.push(OperandId, "'Base'");
         InstructionDesc[enumCast(Op::OpInBoundsAccessChain)].operands.push(OperandVariableIds, "'Indexes'");
 
@@ -3160,6 +3195,19 @@ void Parameterize()
         InstructionDesc[enumCast(Op::OpFragmentFetchAMD)].operands.push(OperandId, "'Coordinate'");
         InstructionDesc[enumCast(Op::OpFragmentFetchAMD)].operands.push(OperandId, "'Fragment Index'");
 
+
+        InstructionDesc[enumCast(Op::OpTypeBufferEXT)].operands.push(OperandStorage, "");
+        InstructionDesc[enumCast(Op::OpTypeBufferEXT)].setResultAndType(true, false);
+
+        InstructionDesc[enumCast(Op::OpConstantSizeOfEXT)].operands.push(OperandId, "'Type'");
+
+        InstructionDesc[enumCast(Op::OpBufferPointerEXT)].operands.push(OperandId, "'Buffer'");
+
+        InstructionDesc[enumCast(Op::OpUntypedImageTexelPointerEXT)].operands.push(OperandId, "'ImageType'");
+        InstructionDesc[enumCast(Op::OpUntypedImageTexelPointerEXT)].operands.push(OperandId, "'Image'");
+        InstructionDesc[enumCast(Op::OpUntypedImageTexelPointerEXT)].operands.push(OperandId, "'Coordinate'");
+        InstructionDesc[enumCast(Op::OpUntypedImageTexelPointerEXT)].operands.push(OperandId, "'Sample'");
+
         InstructionDesc[enumCast(Op::OpGroupNonUniformPartitionNV)].operands.push(OperandId, "X");
 
         InstructionDesc[enumCast(Op::OpGroupNonUniformQuadAllKHR)].operands.push(OperandId, "'Predicate'");

+ 33 - 4
3rdparty/glslang/SPIRV/spirv.hpp11

@@ -206,7 +206,7 @@ enum class ExecutionMode : unsigned {
     SampleInterlockOrderedEXT = 5368,
     SampleInterlockUnorderedEXT = 5369,
     ShadingRateInterlockOrderedEXT = 5370,
-    ShadingRateInterlockUnorderedEXT = 5371,
+    ShadingRateInterlockUnorderedEXT = 5371,
     Shader64BitIndexingEXT = 5427,
     SharedLocalMemorySizeINTEL = 5618,
     RoundingModeRTPINTEL = 5620,
@@ -564,6 +564,8 @@ enum class Decoration : unsigned {
     PayloadNodeSparseArrayAMDX = 5099,
     PayloadNodeArraySizeAMDX = 5100,
     PayloadDispatchIndirectAMDX = 5105,
+    ArrayStrideIdEXT = 5124,
+    OffsetIdEXT = 5125,
     OverrideCoverageNV = 5248,
     PassthroughNV = 5250,
     ViewportRelativeNV = 5252,
@@ -580,8 +582,10 @@ enum class Decoration : unsigned {
     RestrictPointerEXT = 5355,
     AliasedPointer = 5356,
     AliasedPointerEXT = 5356,
+    MemberOffsetNV = 5358,
     HitObjectShaderRecordBufferNV = 5386,
     HitObjectShaderRecordBufferEXT = 5389,
+    BankNV = 5397,
     BindlessSamplerNV = 5398,
     BindlessImageNV = 5399,
     BoundSamplerNV = 5400,
@@ -733,6 +737,8 @@ enum class BuiltIn : unsigned {
     FragStencilRefEXT = 5014,
     RemainingRecursionLevelsAMDX = 5021,
     ShaderIndexAMDX = 5073,
+    SamplerHeapEXT = 5122,
+    ResourceHeapEXT = 5123,
     ViewportMaskNV = 5253,
     SecondaryPositionNV = 5257,
     SecondaryViewportMaskNV = 5258,
@@ -1127,6 +1133,7 @@ enum class Capability : unsigned {
     BFloat16TypeKHR = 5116,
     BFloat16DotProductKHR = 5117,
     BFloat16CooperativeMatrixKHR = 5118,
+    DescriptorHeapEXT = 5128,
     SampleMaskOverrideCoverageNV = 5249,
     GeometryShaderPassthroughNV = 5251,
     ShaderViewportIndexLayerEXT = 5254,
@@ -1199,7 +1206,9 @@ enum class Capability : unsigned {
     RayTracingDisplacementMicromapNV = 5409,
     RawAccessChainsNV = 5414,
     RayTracingSpheresGeometryNV = 5418,
-    RayTracingLinearSweptSpheresGeometryNV = 5419,
+    RayTracingLinearSweptSpheresGeometryNV = 5419,
+    PushConstantBanksNV = 5423,
+    LongVectorEXT = 5425,
     Shader64BitIndexingEXT = 5426,
     CooperativeMatrixReductionsNV = 5430,
     CooperativeMatrixConversionsNV = 5431,
@@ -2031,6 +2040,11 @@ enum class Op : unsigned {
     OpSpecConstantStringAMDX = 5104,
     OpGroupNonUniformQuadAllKHR = 5110,
     OpGroupNonUniformQuadAnyKHR = 5111,
+    OpTypeBufferEXT = 5115,
+    OpBufferPointerEXT = 5119,
+    OpUntypedImageTexelPointerEXT = 5126,
+    OpMemberDecorateIdEXT = 5127,
+    OpConstantSizeOfEXT = 5129,
     OpHitObjectRecordHitMotionNV = 5249,
     OpHitObjectRecordHitWithIndexMotionNV = 5250,
     OpHitObjectRecordMissMotionNV = 5251,
@@ -2066,6 +2080,7 @@ enum class Op : unsigned {
     OpTypeHitObjectNV = 5281,
     OpImageSampleFootprintNV = 5283,
     OpTypeCooperativeVectorNV = 5288,
+    OpTypeVectorIdEXT = 5288,
     OpCooperativeVectorMatrixMulNV = 5289,
     OpCooperativeVectorOuterProductAccumulateNV = 5290,
     OpCooperativeVectorReduceSumAccumulateNV = 5291,
@@ -2816,6 +2831,11 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
     case Op::OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break;
     case Op::OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break;
     case Op::OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break;
+    case Op::OpBufferPointerEXT: *hasResult = true; *hasResultType = true; break;
+    case Op::OpUntypedImageTexelPointerEXT: *hasResult = true; *hasResultType = true; break;
+    case Op::OpMemberDecorateIdEXT: *hasResult = false; *hasResultType = false; break;
+    case Op::OpConstantSizeOfEXT: *hasResult = true; *hasResultType = true; break;
+    case Op::OpTypeBufferEXT: *hasResult = true; *hasResultType = false; break;
     case Op::OpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break;
     case Op::OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break;
     case Op::OpExtInstWithForwardRefsKHR: *hasResult = true; *hasResultType = true; break;
@@ -3426,7 +3446,7 @@ inline const char* ExecutionModeToString(ExecutionMode value) {
     case ExecutionMode::SampleInterlockOrderedEXT: return "SampleInterlockOrderedEXT";
     case ExecutionMode::SampleInterlockUnorderedEXT: return "SampleInterlockUnorderedEXT";
     case ExecutionMode::ShadingRateInterlockOrderedEXT: return "ShadingRateInterlockOrderedEXT";
-    case ExecutionMode::ShadingRateInterlockUnorderedEXT: return "ShadingRateInterlockUnorderedEXT";
+    case ExecutionMode::ShadingRateInterlockUnorderedEXT: return "ShadingRateInterlockUnorderedEXT";
     case ExecutionMode::Shader64BitIndexingEXT: return "Shader64BitIndexingEXT";
     case ExecutionMode::SharedLocalMemorySizeINTEL: return "SharedLocalMemorySizeINTEL";
     case ExecutionMode::RoundingModeRTPINTEL: return "RoundingModeRTPINTEL";
@@ -3736,7 +3756,9 @@ inline const char* DecorationToString(Decoration value) {
     case Decoration::NonUniform: return "NonUniform";
     case Decoration::RestrictPointer: return "RestrictPointer";
     case Decoration::AliasedPointer: return "AliasedPointer";
+    case Decoration::MemberOffsetNV: return "MemberOffsetNV";
     case Decoration::HitObjectShaderRecordBufferNV: return "HitObjectShaderRecordBufferNV";
+    case Decoration::BankNV: return "BankNV";
     case Decoration::HitObjectShaderRecordBufferEXT: return "HitObjectShaderRecordBufferEXT";
     case Decoration::BindlessSamplerNV: return "BindlessSamplerNV";
     case Decoration::BindlessImageNV: return "BindlessImageNV";
@@ -4157,7 +4179,9 @@ inline const char* CapabilityToString(Capability value) {
     case Capability::RayTracingDisplacementMicromapNV: return "RayTracingDisplacementMicromapNV";
     case Capability::RawAccessChainsNV: return "RawAccessChainsNV";
     case Capability::RayTracingSpheresGeometryNV: return "RayTracingSpheresGeometryNV";
-    case Capability::RayTracingLinearSweptSpheresGeometryNV: return "RayTracingLinearSweptSpheresGeometryNV";
+    case Capability::RayTracingLinearSweptSpheresGeometryNV: return "RayTracingLinearSweptSpheresGeometryNV";
+    case Capability::PushConstantBanksNV: return "PushConstantBanksNV";
+    case Capability::LongVectorEXT: return "LongVectorEXT";
     case Capability::Shader64BitIndexingEXT: return "Shader64BitIndexingEXT";
     case Capability::CooperativeMatrixReductionsNV: return "CooperativeMatrixReductionsNV";
     case Capability::CooperativeMatrixConversionsNV: return "CooperativeMatrixConversionsNV";
@@ -4803,6 +4827,11 @@ inline const char* OpToString(Op value) {
     case Op::OpSubgroupAllKHR: return "OpSubgroupAllKHR";
     case Op::OpSubgroupAnyKHR: return "OpSubgroupAnyKHR";
     case Op::OpSubgroupAllEqualKHR: return "OpSubgroupAllEqualKHR";
+    case Op::OpBufferPointerEXT: return "OpBufferPointerEXT";
+    case Op::OpUntypedImageTexelPointerEXT: return "OpUntypedImageTexelPointerEXT";
+    case Op::OpMemberDecorateIdEXT: return "OpMemberDecorateIdEXT";
+    case Op::OpConstantSizeOfEXT: return "OpConstantSizeOfEXT";
+    case Op::OpTypeBufferEXT: return "OpTypeBufferEXT";
     case Op::OpGroupNonUniformRotateKHR: return "OpGroupNonUniformRotateKHR";
     case Op::OpSubgroupReadInvocationKHR: return "OpSubgroupReadInvocationKHR";
     case Op::OpExtInstWithForwardRefsKHR: return "OpExtInstWithForwardRefsKHR";

+ 3 - 1
3rdparty/glslang/SPIRV/spvIR.h

@@ -222,6 +222,7 @@ public:
     }
     Id getResultId() const { return resultId; }
     Id getTypeId() const { return typeId; }
+    void setTypeId(Id tId) { typeId = tId; }
     Id getIdOperand(int op) const {
         assert(idOperand[op]);
         return operands[op];
@@ -574,7 +575,8 @@ public:
     }
     StorageClass getStorageClass(Id typeId) const
     {
-        assert(idToInstruction[typeId]->getOpCode() == spv::Op::OpTypePointer);
+        assert(idToInstruction[typeId]->getOpCode() == spv::Op::OpTypePointer ||
+               idToInstruction[typeId]->getOpCode() == spv::Op::OpTypeUntypedPointerKHR);
         return (StorageClass)idToInstruction[typeId]->getImmediateOperand(0);
     }
 

+ 8 - 1
3rdparty/glslang/StandAlone/StandAlone.cpp

@@ -113,6 +113,7 @@ enum TOptions : uint64_t {
     EOptionDisplayErrorColumn = (1ull << 33),
     EOptionLinkTimeOptimization = (1ull << 34),
     EOptionValidateCrossStageIO = (1ull << 35),
+    EOptionBindingsPerResourceType = (1ull << 36),
 };
 bool targetHlslFunctionality1 = false;
 bool SpvToolsDisassembler = false;
@@ -918,6 +919,8 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
                         Options |= EOptionLinkTimeOptimization;
                     } else if (lowerword == "validate-io") {
                         Options |= EOptionValidateCrossStageIO;
+                    } else if (lowerword == "bindings-per-resource-type") {
+                        Options |= EOptionBindingsPerResourceType;
                     } else if (lowerword == "help") {
                         usage();
                         break;
@@ -1465,6 +1468,9 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
         if (emitNonSemanticShaderDebugInfo)
             shader->setDebugInfo(true);
 
+        if (Options & EOptionBindingsPerResourceType)
+            shader->setBindingsPerResourceType();
+
         // Set up the environment, some subsettings take precedence over earlier
         // ways of setting things.
         if (Options & EOptionSpv) {
@@ -2194,7 +2200,8 @@ void usage()
            "                                    creates a C header file that contains a\n"
            "                                    uint32_t array named <name> initialized with\n"
            "                                    the shader binary code\n"
-           "  --validate-io                     validate cross stage IO\n");
+           "  --validate-io                     validate cross stage IO\n"
+           "  --bindings-per-resource-type\n");
 
     exit(EFailUsage);
 }

+ 1 - 1
3rdparty/glslang/build_info.h

@@ -35,7 +35,7 @@
 #define GLSLANG_BUILD_INFO
 
 #define GLSLANG_VERSION_MAJOR 16
-#define GLSLANG_VERSION_MINOR 1
+#define GLSLANG_VERSION_MINOR 2
 #define GLSLANG_VERSION_PATCH 0
 #define GLSLANG_VERSION_FLAVOR ""
 

+ 4 - 0
3rdparty/glslang/glslang/CInterface/glslang_c_interface.cpp

@@ -384,6 +384,10 @@ GLSLANG_EXPORT void glslang_shader_set_options(glslang_shader_t* shader, int opt
     if (options & GLSLANG_SHADER_VULKAN_RULES_RELAXED) {
         shader->shader->setEnvInputVulkanRulesRelaxed();
     }
+
+    if (options & GLSLANG_SHADER_BINDINGS_PER_RESOURCE_TYPE) {
+        shader->shader->setBindingsPerResourceType();
+    }
 }
 
 GLSLANG_EXPORT void glslang_shader_set_glsl_version(glslang_shader_t* shader, int version)

+ 24 - 0
3rdparty/glslang/glslang/Include/BaseTypes.h

@@ -76,6 +76,7 @@ enum TBasicType {
     EbtTensorViewNV,
     EbtCoopvecNV,
     EbtTensorARM,
+    EbtLongVector,
     // SPIR-V type defined by spirv_type
     EbtSpirvType,
 
@@ -143,6 +144,10 @@ enum TStorageQualifier {
 
     EvqTileImageEXT,
 
+    // EXT_structured_descriptor_heap
+    EvqSamplerHeap,
+    EvqResourceHeap,
+
     // end of list
     EvqLast
 };
@@ -353,6 +358,9 @@ enum TBuiltInVariable {
     EbvTileOffsetQCOM,
     EbvTileDimensionQCOM,
     EbvTileApronSizeQCOM,
+    // GL_EXT_descriptor_heap
+    EbvSamplerHeapEXT,
+    EbvResourceHeapEXT,
 
     EbvLast
 };
@@ -603,6 +611,22 @@ __inline bool isTypeUnsignedInt(TBasicType type)
     }
 }
 
+__inline TBasicType unsignedTypeToSigned(TBasicType type)
+{
+    switch (type) {
+    case EbtUint8:
+        return EbtInt8;
+    case EbtUint16:
+        return EbtInt16;
+    case EbtUint:
+        return EbtInt;
+    case EbtUint64:
+        return EbtInt64;
+    default:
+        return type;
+    }
+}
+
 __inline bool isTypeInt(TBasicType type)
 {
     return isTypeSignedInt(type) || isTypeUnsignedInt(type);

+ 145 - 12
3rdparty/glslang/glslang/Include/Types.h

@@ -517,6 +517,7 @@ public:
         spirvByReference = false;
         spirvLiteral = false;
         defaultBlock = false;
+        usedByAtomic = false;
     }
 
     // drop qualifiers that don't belong in a temporary variable
@@ -536,6 +537,7 @@ public:
         spirvDecorate = nullptr;
         spirvByReference = false;
         spirvLiteral = false;
+        usedByAtomic = false;
     }
 
     void clearInterstage()
@@ -617,6 +619,7 @@ public:
     bool nullInit : 1;
     bool spirvByReference : 1;
     bool spirvLiteral : 1;
+    bool usedByAtomic : 1; // EXT_descriptor_heap
     bool isWriteOnly() const { return writeonly; }
     bool isReadOnly() const { return readonly; }
     bool isRestrict() const { return restrict; }
@@ -660,6 +663,8 @@ public:
     bool isSpirvByReference() const { return spirvByReference; }
     void setSpirvLiteral() { spirvLiteral = true; }
     bool isSpirvLiteral() const { return spirvLiteral; }
+    void setUsedByAtomic() { usedByAtomic = true; }
+    bool isUsedByAtomic() const { return usedByAtomic; }
 
     bool isPipeInput() const
     {
@@ -875,6 +880,11 @@ public:
         clearInterstageLayout();
 
         layoutSpecConstantId = layoutSpecConstantIdEnd;
+        layoutBank = layoutBankEnd;
+        layoutDescriptorHeap = false;
+        layoutDescriptorStride = layoutDescriptorStrideEnd;
+        layoutHeapOffset = 0;
+        layoutDescriptorInnerBlock = false;
     }
     void clearInterstageLayout()
     {
@@ -916,6 +926,7 @@ public:
     TLayoutPacking layoutPacking : 4;
     int layoutOffset;
     int layoutAlign;
+    int layoutMemberOffset;
 
                  unsigned int layoutLocation             : 12;
     static const unsigned int layoutLocationEnd      =  0xFFF;
@@ -950,6 +961,12 @@ public:
                  unsigned int layoutSpecConstantId       : 11;
     static const unsigned int layoutSpecConstantIdEnd = 0x7FF;
 
+                 unsigned int layoutBank                 : 4;
+    static const unsigned int layoutBankEnd            = 0xF;
+
+                 unsigned int layoutDescriptorStride     : 4;
+    static const unsigned int layoutDescriptorStrideEnd = 0x0;
+
     // stored as log2 of the actual alignment value
                  unsigned int layoutBufferReferenceAlign :  6;
     static const unsigned int layoutBufferReferenceAlignEnd = 0x3F;
@@ -966,6 +983,9 @@ public:
     bool layoutQuadDeriv;
     bool layoutHitObjectShaderRecordNV;
     bool layoutHitObjectShaderRecordEXT;
+    bool layoutDescriptorHeap;
+    bool layoutDescriptorInnerBlock;
+    int layoutHeapOffset;
 
     // GL_EXT_spirv_intrinsics
     int spirvStorageClass;
@@ -991,6 +1011,7 @@ public:
         layoutPacking = ElpNone;
         layoutOffset = layoutNotSet;
         layoutAlign = layoutNotSet;
+        layoutMemberOffset = layoutNotSet;
 
         layoutSet = layoutSetEnd;
         layoutBinding = layoutBindingEnd;
@@ -1115,6 +1136,14 @@ public:
         // is just whether or not it was declared with an ID.
         return layoutSpecConstantId != layoutSpecConstantIdEnd;
     }
+    bool hasBank() const
+    {
+        return layoutBank != layoutBankEnd;
+    }
+    bool hasMemberOffset() const
+    {
+        return layoutMemberOffset != layoutNotSet;
+    }
     bool isSpecConstant() const
     {
         // True if type is a specialization constant, whether or not it
@@ -1514,6 +1543,7 @@ public:
     bool coopmatNV  : 1;
     bool coopmatKHR : 1;
     bool coopvecNV  : 1;
+    bool longVector : 1;
     bool tileAttachmentQCOM: 1;
     uint32_t tensorRankARM : 4;
     TArraySizes* arraySizes;
@@ -1527,8 +1557,11 @@ public:
     bool isCoopmatNV() const { return coopmatNV; }
     bool isCoopmatKHR() const { return coopmatKHR; }
     bool isCoopvecNV() const { return coopvecNV; }
+    bool isCoopmatOrvec() const { return isCoopmat() || isCoopvecNV() || isLongVector(); }
+    bool isLongVector() const { return longVector; }
+    bool isCoopvecOrLongVector() const { return isCoopvecNV() || isLongVector(); }
     bool isTensorARM() const { return tensorRankARM; }
-    bool hasTypeParameter() const { return isCoopmat() || isCoopvecNV() || isTensorARM(); }
+    bool hasTypeParameter() const { return isCoopmat() || isCoopvecNV() || isLongVector() || isTensorARM(); }
 
     bool isTensorLayoutNV() const { return basicType == EbtTensorLayoutNV; }
     bool isTensorViewNV() const { return basicType == EbtTensorViewNV; }
@@ -1546,6 +1579,7 @@ public:
         coopmatNV = false;
         coopmatKHR = false;
         coopvecNV = false;
+        longVector = false;
         tileAttachmentQCOM = false;
         tensorRankARM = 0;
         spirvType = nullptr;
@@ -1607,7 +1641,7 @@ public:
     // for "empty" type (no args) or simple scalar/vector/matrix
     explicit TType(TBasicType t = EbtVoid, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0,
                    bool isVector = false) :
-                            basicType(t), vectorSize(static_cast<uint32_t>(vs) & 0b1111), matrixCols(static_cast<uint32_t>(mc) & 0b1111), matrixRows(static_cast<uint32_t>(mr) & 0b1111), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), coopvecNV(false),
+                            basicType(t), vectorSize(static_cast<uint32_t>(vs) & 0b1111), matrixCols(static_cast<uint32_t>(mc) & 0b1111), matrixRows(static_cast<uint32_t>(mr) & 0b1111), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), coopvecNV(false), longVector(false),
                             tileAttachmentQCOM(false), tensorRankARM(0), arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
                             spirvType(nullptr)
                             {
@@ -1623,7 +1657,7 @@ public:
     // for explicit precision qualifier
     TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0,
           bool isVector = false) :
-                            basicType(t), vectorSize(static_cast<uint32_t>(vs) & 0b1111), matrixCols(static_cast<uint32_t>(mc) & 0b1111), matrixRows(static_cast<uint32_t>(mr) & 0b1111), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), coopvecNV(false),
+                            basicType(t), vectorSize(static_cast<uint32_t>(vs) & 0b1111), matrixCols(static_cast<uint32_t>(mc) & 0b1111), matrixRows(static_cast<uint32_t>(mr) & 0b1111), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), coopvecNV(false), longVector(false),
                             tileAttachmentQCOM(false), tensorRankARM(0), arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
                             spirvType(nullptr)
                             {
@@ -1641,7 +1675,7 @@ public:
     // for turning a TPublicType into a TType, using a shallow copy
     explicit TType(const TPublicType& p) :
                             basicType(p.basicType),
-                            vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmatNV(p.coopmatNV), coopmatKHR(p.coopmatKHR), coopmatKHRuse(0), coopmatKHRUseValid(false), coopvecNV(p.coopvecNV),
+                            vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmatNV(p.coopmatNV), coopmatKHR(p.coopmatKHR), coopmatKHRuse(0), coopmatKHRUseValid(false), coopvecNV(p.coopvecNV), longVector(p.longVector),
                             tileAttachmentQCOM(p.tileAttachmentQCOM), tensorRankARM(p.tensorRankARM), arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(p.typeParameters),
                             spirvType(p.spirvType)
                             {
@@ -1692,7 +1726,7 @@ public:
                                         coopmatKHRUseValid = true;
                                     }
                                 }
-                                if (p.isCoopvecNV() && p.typeParameters) {
+                                if ((p.isCoopvecNV() || p.isLongVector()) && p.typeParameters) {
                                     basicType = p.typeParameters->basicType;
                                 }
                                 if (p.isTensorARM() && p.typeParameters) {
@@ -1704,7 +1738,7 @@ public:
                             }
     // for construction of sampler types
     TType(const TSampler& sampler, TStorageQualifier q = EvqUniform, TArraySizes* as = nullptr) :
-        basicType(EbtSampler), vectorSize(1u), matrixCols(0u), matrixRows(0u), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), coopvecNV(false),
+        basicType(EbtSampler), vectorSize(1u), matrixCols(0u), matrixRows(0u), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), coopvecNV(false), longVector(false),
         tileAttachmentQCOM(false), tensorRankARM(0), arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr),
         sampler(sampler), typeParameters(nullptr), spirvType(nullptr)
     {
@@ -1747,12 +1781,13 @@ public:
                                         // dereference from vector to scalar
                                         vectorSize = 1;
                                         vector1 = false;
-                                    } else if (isCoopMat() || isCoopVecNV()) {
+                                    } else if (isCoopMat() || isCoopVecNV() || isLongVector()) {
                                         coopmatNV = false;
                                         coopmatKHR = false;
                                         coopmatKHRuse = 0;
                                         coopmatKHRUseValid = false;
                                         coopvecNV = false;
+                                        longVector = false;
                                         typeParameters = nullptr;
                                     } else if (isTileAttachmentQCOM()) {
                                         tileAttachmentQCOM = false;
@@ -1762,7 +1797,7 @@ public:
                             }
     // for making structures, ...
     TType(TTypeList* userDef, const TString& n) :
-                            basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), coopvecNV(false),
+                            basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), coopvecNV(false), longVector(false),
                             tileAttachmentQCOM(false), tensorRankARM(0), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr),
                             spirvType(nullptr)
                             {
@@ -1772,7 +1807,7 @@ public:
                             }
     // For interface blocks
     TType(TTypeList* userDef, const TString& n, const TQualifier& q) :
-                            basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), coopvecNV(false),
+                            basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), coopvecNV(false), longVector(false),
                             tileAttachmentQCOM(false), tensorRankARM(0), qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr),
                             spirvType(nullptr)
                             {
@@ -1821,6 +1856,7 @@ public:
         coopmatKHRuse = copyOf.coopmatKHRuse;
         coopmatKHRUseValid = copyOf.coopmatKHRUseValid;
         coopvecNV = copyOf.isCoopVecNV();
+        longVector = copyOf.isLongVector();
         tileAttachmentQCOM = copyOf.tileAttachmentQCOM;
         tensorRankARM = copyOf.tensorRankARM;
     }
@@ -1907,7 +1943,7 @@ public:
     virtual const TTypeParameters* getTypeParameters() const { return typeParameters; }
     virtual       TTypeParameters* getTypeParameters()       { return typeParameters; }
 
-    virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray() && ! isCoopVecNV(); }
+    virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray() && ! isCoopVecNV() && ! isLongVector(); }
     virtual bool isScalarOrVec1() const { return isScalar() || vector1; }
     virtual bool isScalarOrVector() const { return !isMatrix() && !isStruct() && !isArray(); }
     virtual bool isVector() const { return vectorSize > 1u || vector1; }
@@ -1962,9 +1998,12 @@ public:
     bool isCoopMatNV() const { return coopmatNV; }
     bool isCoopMatKHR() const { return coopmatKHR; }
     bool isCoopVecNV() const { return coopvecNV; }
+    bool isCoopMatOrVec() const { return isCoopMat() || isCoopVecNV() || isLongVector(); }
+    bool isLongVector() const { return longVector; }
+    bool isCoopVecOrLongVector() const { return isCoopVecNV() || isLongVector(); }
     bool isTileAttachmentQCOM() const { return tileAttachmentQCOM; }
     bool isTensorARM() const { return tensorRankARM; }
-    bool hasTypeParameter() const { return isCoopMat() || isCoopVecNV() || isTensorARM(); }
+    bool hasTypeParameter() const { return isCoopMat() || isCoopVecNV() || isLongVector() || isTensorARM(); }
     int getTensorRankARM() const { return static_cast<int>(tensorRankARM); }
     bool isReference() const { return getBasicType() == EbtReference; }
     bool isSpirvType() const { return getBasicType() == EbtSpirvType; }
@@ -1997,6 +2036,22 @@ public:
         return contains([](const TType* t) { return t->isArray(); } );
     }
 
+    // Recursively check the structure for any arrays, needed for some error checks
+    virtual bool containsHeapArray() const
+    {
+        const auto containsResourceArray = [](const TType* t) {
+            return (t->isArray() &&
+                    (t->isImage() || t->isTexture() || t->getBasicType() == EbtSampler ||
+                     t->getBasicType() == EbtAccStruct ||
+                     t->getQualifier().storage == EvqUniform ||
+                     t->getQualifier().storage == EvqResourceHeap ||
+                     t->getQualifier().storage == EvqSamplerHeap ||
+                     t->getQualifier().storage == EvqBuffer));
+        };
+
+        return contains(containsResourceArray);
+    }
+
     // Check the structure for any structures, needed for some error checks
     virtual bool containsStructure() const
     {
@@ -2101,6 +2156,10 @@ public:
     {
         return contains([](const TType* t) { return t->coopvecNV; } );
     }
+    bool containsLongVector() const
+    {
+        return contains([](const TType* t) { return t->longVector; } );
+    }
     bool containsReference() const
     {
         return containsBasicType(EbtReference);
@@ -2225,6 +2284,7 @@ public:
         case EbtTensorViewNV:      return "tensorViewNV";
         case EbtCoopvecNV:         return "coopvecNV";
         case EbtTensorARM:         return "tensorARM";
+        case EbtLongVector:        return "vector";
         default:                   return "unknown type";
         }
     }
@@ -2342,11 +2402,29 @@ public:
               if (qualifier.layoutHitObjectShaderRecordEXT)
                 appendStr(" hitobjectshaderrecordext");
 
+              if (qualifier.hasBank()) {
+                appendStr(" bank=");
+                appendUint(qualifier.layoutBank);
+              }
+              if (qualifier.hasMemberOffset()) {
+                appendStr(" member_offset=");
+                appendInt(qualifier.layoutMemberOffset);
+              }
+
               if (qualifier.layoutBindlessSampler)
                   appendStr(" layoutBindlessSampler");
               if (qualifier.layoutBindlessImage)
                   appendStr(" layoutBindlessImage");
 
+              if (qualifier.layoutDescriptorHeap)
+                  appendStr(" descriptor_heap");
+              if (qualifier.layoutDescriptorStride != TQualifier::layoutDescriptorStrideEnd) {
+                  appendStr(" descriptor_stride=");
+                  appendInt(qualifier.layoutDescriptorStride);
+              }
+              if (qualifier.layoutHeapOffset)
+                  appendStr(" heap_offset=");
+
               appendStr(")");
             }
           }
@@ -2551,6 +2629,10 @@ public:
                 appendStr(" ");
                 appendStr("coopvecNV");
               }
+              if (isLongVector()) {
+                appendStr(" ");
+                appendStr("vector");
+              }
 
               appendStr("<");
               for (int i = 0; i < (int)typeParameters->arraySizes->getNumDims(); ++i) {
@@ -2632,7 +2714,7 @@ public:
     {
         uint32_t components = 0;
 
-        if (isCoopVecNV()) {
+        if (isCoopVecOrLongVector()) {
             components = typeParameters->arraySizes->getDimSize(0);
         } else if (getBasicType() == EbtStruct || getBasicType() == EbtBlock) {
             for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
@@ -2649,6 +2731,10 @@ public:
         return static_cast<int>(components);
     }
 
+    bool hasSpecConstantVectorComponents() const {
+        return getTypeParameters() && getTypeParameters()->arraySizes->getDimNode(0) != nullptr;
+    }
+
     // append this type's mangled name to the passed in 'name'
     void appendMangledName(TString& name) const
     {
@@ -2839,6 +2925,7 @@ public:
               isCoopMatNV() == right.isCoopMatNV() &&
               isCoopMatKHR() == right.isCoopMatKHR() &&
               isCoopVecNV() == right.isCoopVecNV() &&
+              isLongVector() == right.isLongVector() &&
                isTensorARM() == right.isTensorARM() &&
                sameStructType(right, lpidx, rpidx) &&
                sameReferenceType(right);
@@ -2935,6 +3022,26 @@ public:
         return rv;
     }
 
+    bool sameLongVectorBaseType(const TType &right) const {
+        bool rv = false;
+
+        if (isLongVector() && right.isLongVector()) {
+            if (isFloatingDomain())
+                rv = right.isFloatingDomain() || right.getBasicType() == EbtLongVector;
+            else if (isTypeUnsignedInt(getBasicType()))
+                rv = isTypeUnsignedInt(right.getBasicType()) || right.getBasicType() == EbtLongVector;
+            else if (isTypeSignedInt(getBasicType()))
+                rv = isTypeSignedInt(right.getBasicType()) || right.getBasicType() == EbtLongVector;
+            else if (getBasicType() == EbtBool)
+                rv = right.getBasicType() == EbtBool || right.getBasicType() == EbtLongVector;
+            else if (getBasicType() == EbtLongVector)
+                rv = right.isLongVector();
+            else
+                rv = false;
+        }
+        return rv;
+    }
+
     bool sameCoopMatUse(const TType &right) const {
         return coopmatKHRuse == right.coopmatKHRuse;
     }
@@ -2965,6 +3072,31 @@ public:
         return true;
     }
 
+    bool sameLongVectorShape(const TType &right) const
+    {
+        if (!isLongVector() || !right.isLongVector() || !typeParameters || !right.typeParameters)
+            return false;
+
+        return typeParameters->arraySizes->getDimSize(0) == right.typeParameters->arraySizes->getDimSize(0);
+    }
+
+    static bool vectorAndLongVectorMatch(const TType &left, const TType &right)
+    {
+        if (left.isVector() && right.isLongVector() &&
+            right.getTypeParameters() &&
+            !right.hasSpecConstantVectorComponents() &&
+            left.getVectorSize() == right.getTypeParameters()->arraySizes->getDimSize(0)) {
+            return true;
+        }
+        if (right.isVector() && left.isLongVector() &&
+            left.getTypeParameters() &&
+            !left.hasSpecConstantVectorComponents() &&
+            right.getVectorSize() == left.getTypeParameters()->arraySizes->getDimSize(0)) {
+            return true;
+        }
+        return false;
+    }
+
     // See if two types match in all ways (just the actual type, not qualification)
     bool operator==(const TType& right) const
     {
@@ -3065,6 +3197,7 @@ protected:
     uint32_t coopmatKHRuse    : 3;  // Accepts one of three values: 0, 1, 2 (gl_MatrixUseA, gl_MatrixUseB, gl_MatrixUseAccumulator)
     bool coopmatKHRUseValid   : 1;  // True if coopmatKHRuse has been set
     bool coopvecNV       : 1;
+    bool longVector      : 1;
     bool tileAttachmentQCOM : 1;
     uint32_t tensorRankARM       : 4;  // 0 means not a tensor; non-zero indicates the tensor rank.
     TQualifier qualifier;

+ 1 - 0
3rdparty/glslang/glslang/Include/glslang_c_shader_types.h

@@ -213,6 +213,7 @@ typedef enum {
     GLSLANG_SHADER_AUTO_MAP_BINDINGS = (1 << 0),
     GLSLANG_SHADER_AUTO_MAP_LOCATIONS = (1 << 1),
     GLSLANG_SHADER_VULKAN_RULES_RELAXED = (1 << 2),
+    GLSLANG_SHADER_BINDINGS_PER_RESOURCE_TYPE = (1 << 3),
     LAST_ELEMENT_MARKER(GLSLANG_SHADER_COUNT),
 } glslang_shader_options_t;
 

+ 602 - 4
3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp

@@ -394,6 +394,83 @@ void AddTabledBuiltin(TString& decls, const BuiltInFunction& function)
     }
 }
 
+// Add long vector prototype for the builtin function. This is similar to
+// AddTabledBuiltin, but only generates builtins where one type is an
+// arbitrary vector. See comments on "enum ArgClass" for more details.
+void AddLongVectorBuiltin(TString& decls, const BuiltInFunction& function)
+{
+    const auto isScalarType = [](int type) { return (type & TypeStringColumnMask) == 0; };
+
+    // loop across these two:
+    //  0: the varying arg set, and
+    //  1: the fixed scalar args
+    const ArgClass ClassFixed = (ArgClass)(ClassLS | ClassXLS | ClassLS2 | ClassFS | ClassFS2);
+    for (int fixed = 0; fixed < ((function.classes & ClassFixed) > 0 ? 2 : 1); ++fixed) {
+
+        if (fixed == 0 && (function.classes & ClassXLS))
+            continue;
+
+        // Iterate over the different scalar types (needed for ClassRS)
+        for (int type = 0; type < TypeStringCount; ++type) {
+            if (!isScalarType(type))
+                continue;
+
+            // skip types not selected: go from type to row number to type bit
+            if ((function.types & (1 << (type >> TypeStringRowShift))) == 0)
+                continue;
+
+            // skip scalar-only
+            if (function.classes & ClassV1)
+                continue;
+
+            // skip 3-vector
+            if (function.classes & ClassV3)
+                continue;
+
+            TString decl;
+            // return type
+            if (function.classes & ClassB)
+                decl.append("vector");
+            else if (function.classes & ClassRS)
+                decl.append(TypeString[type & TypeStringScalarMask]);
+            else
+                decl.append("vector");
+            decl.append(" ");
+            decl.append(function.name);
+            decl.append("(");
+
+            // arguments
+            for (int arg = 0; arg < function.numArguments; ++arg) {
+                if (arg == function.numArguments - 1 && (function.classes & ClassLO))
+                    decl.append("out ");
+                if (arg == 0) {
+                    if (function.classes & ClassCVN)
+                        decl.append("coherent volatile nontemporal ");
+                    if (function.classes & ClassFIO)
+                        decl.append("inout ");
+                    if (function.classes & ClassFO)
+                        decl.append("out ");
+                }
+                if ((function.classes & ClassLB) && arg == function.numArguments - 1)
+                    decl.append("vector");
+                else if (fixed && ((arg == function.numArguments - 1 && (function.classes & (ClassLS | ClassXLS |
+                                                                                                       ClassLS2))) ||
+                                   (arg == function.numArguments - 2 && (function.classes & ClassLS2))             ||
+                                   (arg == 0                         && (function.classes & (ClassFS | ClassFS2))) ||
+                                   (arg == 1                         && (function.classes & ClassFS2))))
+                    decl.append(TypeString[type & TypeStringScalarMask]);
+                else
+                    decl.append("vector");
+                if (arg < function.numArguments - 1)
+                    decl.append(",");
+            }
+            decl.append(");\n");
+
+            decls.append(decl);
+        }
+    }
+}
+
 // See if the tabled versioning information allows the current version.
 bool ValidVersion(const BuiltInFunction& function, int version, EProfile profile, const SpvVersion& /* spVersion */)
 {
@@ -432,8 +509,12 @@ void TBuiltIns::addTabledBuiltins(int version, EProfile profile, const SpvVersio
 {
     const auto forEachFunction = [&](TString& decls, const span<const BuiltInFunction>& functions) {
         for (const auto& fn : functions) {
-            if (ValidVersion(fn, version, profile, spvVersion))
+            if (ValidVersion(fn, version, profile, spvVersion)) {
                 AddTabledBuiltin(decls, fn);
+                if (profile != EEsProfile) {
+                    AddLongVectorBuiltin(decls, fn);
+                }
+            }
         }
     };
 
@@ -2498,6 +2579,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
                 snprintf(buf, bufSize, op, intTypes[j], intTypes[j]);
                 commonBuiltins.append(buf);
             }
+            snprintf(buf, bufSize, op, "vector", "vector");
+            commonBuiltins.append(buf);
         }
 
         stageBuiltins[EShLangCompute].append(
@@ -5060,12 +5143,124 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             "coopvecNV log(coopvecNV);\n"            
             "coopvecNV tanh(coopvecNV);\n"            
             "coopvecNV atan(coopvecNV);\n"            
-            "coopvecNV clamp(coopvecNV, coopvecNV, coopvecNV);\n"
-            "\n"
-            ;
+            "coopvecNV clamp(coopvecNV, coopvecNV, coopvecNV);\n";
 
         commonBuiltins.append(cooperativeVectorFuncs.c_str());
 
+        if (profile != EEsProfile) {
+            std::string longVectorFuncs =
+
+                // manually add long vector prototypes for functions not in BaseFunctions/etc
+                "vector frexp(vector, vector);\n"
+                "vector ldexp(vector, vector);\n"
+                "vector fma(vector, vector, vector);\n"
+
+                "vector floatBitsToInt(vector);\n"
+                "vector floatBitsToUint(vector);\n"
+                "vector intBitsToFloat(vector);\n"
+                "vector uintBitsToFloat(vector);\n"
+                "vector doubleBitsToInt64(vector);"
+                "vector doubleBitsToUint64(vector);"
+                "vector int64BitsToDouble(vector);"
+                "vector uint64BitsToDouble(vector);"
+                "vector bfloat16BitsToIntEXT(vector);"
+                "vector bfloat16BitsToUintEXT(vector);"
+                "vector intBitsToBFloat16EXT(vector);"
+                "vector uintBitsToBFloat16EXT(vector);"
+                "vector halfBitsToInt16(vector);"
+                "vector halfBitsToUint16(vector);"
+                "vector float16BitsToInt16(vector);"
+                "vector float16BitsToUint16(vector);"
+                "vector int16BitsToFloat16(vector);"
+                "vector uint16BitsToFloat16(vector);"
+                "vector int16BitsToHalf(vector);"
+                "vector uint16BitsToHalf(vector);"
+                "vector floate5m2BitsToIntEXT(vector);"
+                "vector floate5m2BitsToUintEXT(vector);"
+                "vector intBitsToFloate5m2EXT(vector);"
+                "vector uintBitsToFloate5m2EXT(vector);"
+                "vector floate4m3BitsToIntEXT(vector);"
+                "vector floate4m3BitsToUintEXT(vector);"
+                "vector intBitsToFloate4m3EXT(vector);"
+                "vector uintBitsToFloate4m3EXT(vector);"
+
+                "vector uaddCarry(highp vector, highp vector, out lowp vector carry);"
+                "vector usubBorrow(highp vector, highp vector, out lowp vector borrow);"
+                "void umulExtended(highp vector, highp vector, out highp vector, out highp vector);"
+                "void imulExtended(highp vector, highp vector, out highp vector, out highp vector);"
+                "vector bitfieldExtract(vector, int, int);"
+                "vector bitfieldInsert(vector, vector, int, int);"
+                "vector bitfieldReverse(highp vector);"
+                "vector bitCount(vector);"
+                "vector findLSB(vector);"
+                "vector findMSB(vector);"
+
+                // BaseFunctions overloads with a scalar parameter don't get generated in AddLongVectorBuiltin
+                "vector mod(vector, double);\n"
+                "vector min(vector, double);\n"
+                "vector max(vector, double);\n"
+                "vector clamp(vector, double, double);"
+                "vector mix(vector, vector,  double);"
+                "vector step(double, vector);"
+                "vector smoothstep(double, double, vector);"
+                "vector refract(vector, vector, double);"
+
+                "vector mod(vector, float16_t);\n"
+                "vector min(vector, float16_t);\n"
+                "vector max(vector, float16_t);\n"
+                "vector clamp(vector, float16_t, float16_t);"
+                "vector mix(vector, vector,  float16_t);"
+                "vector step(float16_t, vector);"
+                "vector smoothstep(float16_t, float16_t, vector);"
+                "vector refract(vector, vector, float16_t);"
+
+                "vector min(vector, uint64_t);\n"
+                "vector max(vector, uint64_t);\n"
+                "vector clamp(vector, uint64_t, uint64_t);"
+                "vector mix(vector, vector,  uint64_t);"
+
+                "vector min(vector, int64_t);\n"
+                "vector max(vector, int64_t);\n"
+                "vector clamp(vector, int64_t, int64_t);"
+                "vector mix(vector, vector,  int64_t);"
+
+                "vector min(vector, uint16_t);\n"
+                "vector max(vector, uint16_t);\n"
+                "vector clamp(vector, uint16_t, uint16_t);"
+                "vector mix(vector, vector,  uint16_t);"
+
+                "vector min(vector, int16_t);\n"
+                "vector max(vector, int16_t);\n"
+                "vector clamp(vector, int16_t, int16_t);"
+                "vector mix(vector, vector,  int16_t);"
+
+                "vector min(vector, uint8_t);\n"
+                "vector max(vector, uint8_t);\n"
+                "vector clamp(vector, uint8_t, uint8_t);"
+                "vector mix(vector, vector,  uint8_t);"
+
+                "vector min(vector, int8_t);\n"
+                "vector max(vector, int8_t);\n"
+                "vector clamp(vector, int8_t, int8_t);"
+                "vector mix(vector, vector,  int8_t);"
+
+                "vector expectEXT(vector, vector);"
+                ;
+
+            std::string longVectorDerivativeFuncs =
+                "vector dFdxFine(vector);"
+                "vector dFdyFine(vector);"
+                "vector fwidthFine(vector);"
+                "vector dFdxCoarse(vector);"
+                "vector dFdyCoarse(vector);"
+                "vector fwidthCoarse(vector);"
+
+                ;
+            commonBuiltins.append(longVectorFuncs.c_str());
+            stageBuiltins[EShLangFragment].append(longVectorDerivativeFuncs.c_str());
+            stageBuiltins[EShLangCompute].append(longVectorDerivativeFuncs.c_str());
+        }
+
         const char *scalarAndVectorTypes[] = {
             "int8_t",
             "int16_t",
@@ -11548,4 +11743,407 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
     }
 }
 
+// Determine whether this fnCandidate overload is supported for these arguments.
+// Some of this is based on the BaseFunctions table, but for functions not in that
+// table there's some handcoded logic.
+// If the overload is supported, then this sets the specific parameter/result
+// types and returns true.
+bool IsSupportedLongVectorBuiltin(const TFunction* fnCandidate, TType* resultType, TIntermNode* arguments)
+{
+    TOperator op = fnCandidate->getBuiltInOp();
+
+    const auto &getArg = [&](uint32_t i) {
+        TIntermAggregate* aggregate = arguments->getAsAggregate();
+        return fnCandidate->getParamCount() == 1 ? arguments->getAsTyped() : (aggregate ? aggregate->getSequence()[i]->getAsTyped() : arguments->getAsTyped());
+    };
+
+    bool valid = true;
+
+    const auto &checkFnTypes = [&](TIntermTyped *t, uint32_t types) {
+        if (t->getType().isFloatingDomain() && !(types & TypeF)) {
+            valid = false;
+        }
+        if (isTypeSignedInt(t->getType().getBasicType()) && !(types & TypeI)) {
+            valid = false;
+        }
+        if (isTypeUnsignedInt(t->getType().getBasicType()) && !(types & TypeU)) {
+            valid = false;
+        }
+        if (t->getType().getBasicType() == EbtBool && !(types & TypeB)) {
+            valid = false;
+        }
+    };
+
+    const auto &checkShape = [&](TIntermTyped *t0, TIntermTyped *t1) {
+        if (!t0->getType().sameLongVectorShape(t1->getType())) {
+            valid = false;
+        }
+    };
+
+    const auto &checkSameType = [&](TIntermTyped *t0, TIntermTyped *t1) {
+        if (t0->getType() != t1->getType()) {
+            valid = false;
+        }
+    };
+
+    const auto &checkArgsMatch = [&](uint32_t argStart, uint32_t argEnd, uint32_t types) {
+        for (uint32_t i = argStart; i < argEnd; ++i) {
+            checkFnTypes(getArg(i), types);
+            if (i != argStart) {
+                checkSameType(getArg(argStart), getArg(i));
+            }
+        }
+    };
+
+    uint32_t paramCount = fnCandidate->getParamCount();
+
+    bool foundInBase = false;
+    for (const auto &fn : BaseFunctions) {
+        if (fn.op != op) {
+            continue;
+        }
+        valid = true;
+        foundInBase = true;
+
+        TIntermTyped *firstLongVector = nullptr;
+        for (uint32_t i = 0; i < paramCount; ++i) {
+            TIntermTyped* arg = getArg(i);
+
+            ArgType argType = fn.types;
+            if (i == paramCount - 1 && (fn.classes & ClassLB)) {
+                argType = TypeB;
+            }
+
+            checkFnTypes(arg, argType);
+
+            if ((fn.classes & ClassLS) && getArg(paramCount-1)->getType().isScalar()) {
+                if (getArg(paramCount-1)->getType().getBasicType() != arg->getBasicType()) {
+                    valid = false;
+                }
+            }
+
+            if (arg->getType().isLongVector()) {
+                if (firstLongVector != nullptr) {
+                    checkShape(firstLongVector, arg);
+                }
+                if (firstLongVector == nullptr) {
+                    firstLongVector = arg;
+                }
+            }
+        }
+
+        uint32_t argsToMatchStart = 0;
+        uint32_t argsToMatchEnd = paramCount;
+        if (fn.classes & ClassFS)
+            argsToMatchStart++;
+        if (fn.classes & ClassFS2)
+            argsToMatchStart += 2;
+        if ((fn.classes & ClassLS) && getArg(paramCount-1)->getType().isScalar())
+            argsToMatchEnd--;
+        if (fn.classes & ClassXLS)
+            argsToMatchEnd--;
+        if (fn.classes & ClassLS2)
+            argsToMatchEnd -= 2;
+        if (fn.classes & ClassLB)
+            argsToMatchEnd--;
+            
+        checkArgsMatch(argsToMatchStart, argsToMatchEnd, fn.types);
+
+        // These ops (arbitrarily) don't support double precision
+        switch (op) {
+        case EOpRadians:
+        case EOpDegrees:
+        case EOpSin:
+        case EOpCos:
+        case EOpTan:
+        case EOpAcos:
+        case EOpAsin:
+        case EOpAtan:
+        case EOpAcosh:
+        case EOpAsinh:
+        case EOpAtanh:
+        case EOpTanh:
+        case EOpCosh:
+        case EOpSinh:
+        case EOpPow:
+        case EOpExp:
+        case EOpLog:
+        case EOpExp2:
+        case EOpLog2:
+            if (getArg(0)->getType().getBasicType() == EbtDouble) {
+                return false;
+            }
+            break;
+        default:
+            break;
+        }
+
+        if (valid) {
+            // It's valid, so override the types and return true
+            assert(firstLongVector);
+            resultType->deepCopy(firstLongVector->getType());
+            if (fn.classes & ClassB) {
+                resultType->setBasicType(EbtBool);
+            }
+            if (fn.classes & ClassRS) {
+                resultType->deepCopy(TType(firstLongVector->getType().getBasicType()));
+            }
+            if (fn.classes & ClassLO) {
+                getArg(fnCandidate->getParamCount() - 1)->setType(getArg(0)->getType());
+            }
+            return true;
+        }
+    }
+    // If it was in the base table but not supported, fail. The rest of the logic
+    // is for ops not in the base table.
+    if (foundInBase) {
+        return false;
+    }
+
+    // Check the arg0 type and if this and other checks have passed, then set
+    // the result type to the bitcasted result
+    const auto &checkBitCast = [&](TBasicType fromBasicType, TBasicType newBasicType) {
+        if (getArg(0)->getType().getBasicType() != fromBasicType) {
+            valid = false;
+        }
+        if (valid) {
+            resultType->deepCopy(getArg(0)->getType());
+            resultType->setBasicType(newBasicType);
+        }
+    };
+
+    valid = true;
+    switch (op) {
+    case EOpFrexp:
+    case EOpLdexp:
+        checkFnTypes(getArg(0), TypeF);
+        checkFnTypes(getArg(1), TypeI);
+        checkShape(getArg(0), getArg(1));
+        if (valid) {
+            resultType->deepCopy(getArg(0)->getType());
+        }
+        return valid;
+    case EOpFloatBitsToInt:
+        if (fnCandidate->getName() == "bfloat16BitsToIntEXT") {
+            checkBitCast(EbtBFloat16, EbtInt16);
+        } else if (fnCandidate->getName() == "floate5m2BitsToIntEXT") {
+            checkBitCast(EbtFloatE5M2, EbtInt8);
+        } else if (fnCandidate->getName() == "floate4m3BitsToIntEXT") {
+            checkBitCast(EbtFloatE4M3, EbtInt8);
+        } else {
+            checkBitCast(EbtFloat, EbtInt);
+        }
+        return valid;
+    case EOpFloatBitsToUint:
+        if (fnCandidate->getName() == "bfloat16BitsToUintEXT") {
+            checkBitCast(EbtBFloat16, EbtUint16);
+        } else if (fnCandidate->getName() == "floate5m2BitsToUintEXT") {
+            checkBitCast(EbtFloatE5M2, EbtUint8);
+        } else if (fnCandidate->getName() == "floate4m3BitsToUintEXT") {
+            checkBitCast(EbtFloatE4M3, EbtUint8);
+        } else {
+            checkBitCast(EbtFloat, EbtUint);
+        }
+        return valid;
+    case EOpIntBitsToFloat:
+        if (fnCandidate->getName() == "intBitsToBFloat16EXT") {
+            checkBitCast(EbtInt16, EbtBFloat16);
+        } else if (fnCandidate->getName() == "intBitsToFloate5m2EXT") {
+            checkBitCast(EbtInt8, EbtFloatE5M2);
+        } else if (fnCandidate->getName() == "intBitsToFloate4m3EXT") {
+            checkBitCast(EbtInt8, EbtFloatE4M3);
+        } else {
+            checkBitCast(EbtInt, EbtFloat);
+        }
+        return valid;
+    case EOpUintBitsToFloat:
+        if (fnCandidate->getName() == "uintBitsToBFloat16EXT") {
+            checkBitCast(EbtUint16, EbtBFloat16);
+        } else if (fnCandidate->getName() == "uintBitsToFloate5m2EXT") {
+            checkBitCast(EbtUint8, EbtFloatE5M2);
+        } else if (fnCandidate->getName() == "uintBitsToFloate4m3EXT") {
+            checkBitCast(EbtUint8, EbtFloatE4M3);
+        } else {
+            checkBitCast(EbtUint, EbtFloat);
+        }
+        return valid;
+    case EOpDoubleBitsToInt64:
+        checkBitCast(EbtDouble, EbtInt64);
+        return valid;
+    case EOpDoubleBitsToUint64:
+        checkBitCast(EbtDouble, EbtUint64);
+        return valid;
+    case EOpInt64BitsToDouble:
+        checkBitCast(EbtInt64, EbtDouble);
+        return valid;
+    case EOpUint64BitsToDouble:
+        checkBitCast(EbtUint64, EbtDouble);
+        return valid;
+    case EOpFloat16BitsToInt16:
+        checkBitCast(EbtFloat16, EbtInt16);
+        return valid;
+    case EOpFloat16BitsToUint16:
+        checkBitCast(EbtFloat16, EbtUint16);
+        return valid;
+    case EOpInt16BitsToFloat16:
+        checkBitCast(EbtInt16, EbtFloat16);
+        return valid;
+    case EOpUint16BitsToFloat16:
+        checkBitCast(EbtUint16, EbtFloat16);
+        return valid;
+
+    case EOpFma:
+        checkArgsMatch(0, paramCount, TypeF);
+        if (valid) {
+            resultType->deepCopy(getArg(0)->getType());
+        }
+        return valid;
+    case EOpAddCarry:
+    case EOpSubBorrow:
+        checkArgsMatch(0, paramCount, TypeU);
+        if (valid) {
+            resultType->deepCopy(getArg(0)->getType());
+        }
+        return valid;
+    case EOpUMulExtended:
+        checkArgsMatch(0, paramCount, TypeU);
+        return valid;
+    case EOpIMulExtended:
+        checkArgsMatch(0, paramCount, TypeI);
+        return valid;
+    case EOpBitfieldExtract:
+    case EOpBitFieldReverse:
+        checkFnTypes(getArg(0), TypeIU);
+        if (valid) {
+            resultType->deepCopy(getArg(0)->getType());
+        }
+        return valid;
+    case EOpBitfieldInsert:
+        checkArgsMatch(0, 2, TypeIU);
+        checkSameType(getArg(0), getArg(1));
+        if (valid) {
+            resultType->deepCopy(getArg(0)->getType());
+        }
+        return valid;
+    case EOpFindLSB:
+    case EOpFindMSB:
+    case EOpBitCount:
+        checkFnTypes(getArg(0), TypeIU);
+        if (valid) {
+            TType newType;
+            newType.deepCopy(getArg(0)->getType());
+            newType.setBasicType(unsignedTypeToSigned(newType.getBasicType()));
+            resultType->deepCopy(newType);
+        }
+        return valid;
+    case EOpDPdx:
+    case EOpDPdxFine:
+    case EOpDPdxCoarse:
+    case EOpDPdy:
+    case EOpDPdyFine:
+    case EOpDPdyCoarse:
+    case EOpFwidth:
+    case EOpFwidthFine:
+    case EOpFwidthCoarse:
+        checkFnTypes(getArg(0), TypeF);
+        if (valid) {
+            resultType->deepCopy(getArg(0)->getType());
+        }
+        return valid;
+    case EOpExpectEXT:
+        checkArgsMatch(0, paramCount, TypeIU | TypeB);
+        if (valid) {
+            resultType->deepCopy(getArg(0)->getType());
+        }
+        return valid;
+
+    case EOpSubgroupPartition:
+        resultType->deepCopy(TType(EbtUint, EvqTemporary, 4));
+        return valid;
+    case EOpSubgroupAllEqual:
+        resultType->deepCopy(TType(EbtBool));
+        return valid;
+
+    case EOpSubgroupAnd:
+    case EOpSubgroupOr:
+    case EOpSubgroupXor:
+    case EOpSubgroupInclusiveAnd:
+    case EOpSubgroupInclusiveOr:
+    case EOpSubgroupInclusiveXor:
+    case EOpSubgroupExclusiveAnd:
+    case EOpSubgroupExclusiveOr:
+    case EOpSubgroupExclusiveXor:
+    case EOpSubgroupClusteredAnd:
+    case EOpSubgroupClusteredOr:
+    case EOpSubgroupClusteredXor:
+    case EOpSubgroupPartitionedAnd:
+    case EOpSubgroupPartitionedOr:
+    case EOpSubgroupPartitionedXor:
+    case EOpSubgroupPartitionedInclusiveAnd:
+    case EOpSubgroupPartitionedInclusiveOr:
+    case EOpSubgroupPartitionedInclusiveXor:
+    case EOpSubgroupPartitionedExclusiveAnd:
+    case EOpSubgroupPartitionedExclusiveOr:
+    case EOpSubgroupPartitionedExclusiveXor:
+        checkFnTypes(getArg(0), TypeIU | TypeB);
+        if (valid) {
+            resultType->deepCopy(getArg(0)->getType());
+        }
+        return valid;
+    case EOpSubgroupBroadcast:
+    case EOpSubgroupBroadcastFirst:
+    case EOpSubgroupShuffle:
+    case EOpSubgroupShuffleXor:
+    case EOpSubgroupShuffleUp:
+    case EOpSubgroupShuffleDown:
+    case EOpSubgroupRotate:
+    case EOpSubgroupClusteredRotate:
+    case EOpSubgroupQuadBroadcast:
+    case EOpSubgroupQuadSwapHorizontal:
+    case EOpSubgroupQuadSwapVertical:
+    case EOpSubgroupQuadSwapDiagonal:
+        checkFnTypes(getArg(0), TypeIU | TypeB | TypeF);
+        if (valid) {
+            resultType->deepCopy(getArg(0)->getType());
+        }
+        return valid;
+    case EOpSubgroupAdd:
+    case EOpSubgroupMul:
+    case EOpSubgroupMin:
+    case EOpSubgroupMax:
+    case EOpSubgroupInclusiveAdd:
+    case EOpSubgroupInclusiveMul:
+    case EOpSubgroupInclusiveMin:
+    case EOpSubgroupInclusiveMax:
+    case EOpSubgroupExclusiveAdd:
+    case EOpSubgroupExclusiveMul:
+    case EOpSubgroupExclusiveMin:
+    case EOpSubgroupExclusiveMax:
+    case EOpSubgroupClusteredAdd:
+    case EOpSubgroupClusteredMul:
+    case EOpSubgroupClusteredMin:
+    case EOpSubgroupClusteredMax:
+    case EOpSubgroupPartitionedAdd:
+    case EOpSubgroupPartitionedMul:
+    case EOpSubgroupPartitionedMin:
+    case EOpSubgroupPartitionedMax:
+    case EOpSubgroupPartitionedInclusiveAdd:
+    case EOpSubgroupPartitionedInclusiveMul:
+    case EOpSubgroupPartitionedInclusiveMin:
+    case EOpSubgroupPartitionedInclusiveMax:
+    case EOpSubgroupPartitionedExclusiveAdd:
+    case EOpSubgroupPartitionedExclusiveMul:
+    case EOpSubgroupPartitionedExclusiveMin:
+    case EOpSubgroupPartitionedExclusiveMax:
+        checkFnTypes(getArg(0), TypeIU | TypeF);
+        if (valid) {
+            resultType->deepCopy(getArg(0)->getType());
+        }
+        return valid;
+    default:
+        break;
+    }
+    return false;
+}
+
 } // end namespace glslang

+ 3 - 0
3rdparty/glslang/glslang/MachineIndependent/Initialize.h

@@ -110,6 +110,9 @@ protected:
 // change this back to false if depending on textual spellings of texturing calls when consuming the AST
 // Using PureOperatorBuiltins=false is deprecated.
 constexpr bool PureOperatorBuiltins = true;
+
+bool IsSupportedLongVectorBuiltin(const TFunction* fnCandidate, TType* resultType, TIntermNode* arguments);
+
 } // end namespace glslang
 
 #endif // _INITIALIZE_INCLUDED_

+ 25 - 8
3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp

@@ -407,11 +407,15 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child,
     }
 
     if (newType != EbtVoid) {
-        child = addConversion(op, TType(newType, EvqTemporary, child->getVectorSize(),
-                                                               child->getMatrixCols(),
-                                                               child->getMatrixRows(),
-                                                               child->isVector()),
-                              child);
+        TType newTType(newType, EvqTemporary, child->getVectorSize(), child->getMatrixCols(), child->getMatrixRows(), child->isVector());
+        if (child->getType().isLongVector()) {
+            newTType.shallowCopy(child->getType());
+            newTType.setBasicType(newType);
+            newTType.makeTemporary();
+            newTType.getQualifier().clear();
+        }
+
+        child = addConversion(op, newTType, child);
         if (child == nullptr)
             return nullptr;
     }
@@ -647,6 +651,12 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped
     }
 
     TType newType(convertTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows());
+    if (node->getType().isLongVector()) {
+        newType.shallowCopy(node->getType());
+        newType.setBasicType(convertTo);
+        newType.makeTemporary();
+        newType.getQualifier().clear();
+    }
     newNode = addUnaryNode(newOp, node, node->getLoc(), newType);
 
     if (node->getAsConstantUnion()) {
@@ -1859,7 +1869,7 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const
     if (type.isCoopMatKHR())
         return EOpConstructCooperativeMatrixKHR;
 
-    if (type.isCoopVecNV())
+    if (type.isCoopVecOrLongVector())
         return EOpConstructCooperativeVectorNV;
 
     switch (type.getBasicType()) {
@@ -3456,6 +3466,8 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
         return false;
     }
 
+    bool vectorAndLongVectorMatch = TType::vectorAndLongVectorMatch(left->getType(), right->getType());
+
     // Finish handling the case, for all ops, where both operands are scalars.
     if (left->isScalar() && right->isScalar())
         return true;
@@ -3464,6 +3476,10 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
     if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize() && right->getVectorSize() > 1)
         return false;
 
+    // Finish handling the case, for all ops, where there are two vectors of different sizes
+    if (left->getType().isLongVector() && right->getType().isLongVector() && !left->getType().sameLongVectorShape(right->getType()))
+        return false;
+
     //
     // We now have a mix of scalars, vectors, or matrices, for non-relational operations.
     //
@@ -3549,7 +3565,8 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
         break;
 
     case EOpAssign:
-        if (left->getVectorSize() != right->getVectorSize() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows())
+        if ((left->getVectorSize() != right->getVectorSize() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows()) &&
+            !vectorAndLongVectorMatch)
             return false;
         [[fallthrough]];
 
@@ -3576,7 +3593,7 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
             return false;
         if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize())
             return false;
-        if (right->isVector() || right->isMatrix()) {
+        if ((right->isVector() || right->isMatrix()) && !vectorAndLongVectorMatch) {
             node.getWritableType().shallowCopy(right->getType());
             node.getWritableType().getQualifier().makeTemporary();
         }

+ 231 - 19
3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp

@@ -565,7 +565,7 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
     variableCheck(base);
 
     if (! base->isArray() && ! base->isMatrix() && ! base->isVector() && ! base->getType().isCoopMat() &&
-        ! base->isReference() && ! base->getType().isCoopVecNV()) {
+        ! base->isReference() && ! base->getType().isCoopVecOrLongVector()) {
         if (base->getAsSymbolNode())
             error(loc, " left of '[' is not of type array, matrix, or vector ", base->getAsSymbolNode()->getName().c_str(), "");
         else
@@ -996,7 +996,7 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
             const char* feature = ".length() on vectors and matrices";
             requireProfile(loc, ~EEsProfile, feature);
             profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, feature);
-        } else if (!base->getType().isCoopMat() && !base->getType().isCoopVecNV()) {
+        } else if (!base->getType().isCoopMat() && !base->getType().isCoopVecOrLongVector()) {
             bool enhanced = intermediate.getEnhancedMsgs();
             error(loc, "does not operate on this type:", field.c_str(), base->getType().getCompleteString(enhanced).c_str());
             return base;
@@ -1421,6 +1421,7 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
                 if ((*fnCandidate)[0].type->getSampler().isMultiSample() && version <= 140)
                     requireExtensions(loc, 1, &E_GL_ARB_texture_multisample, fnCandidate->getName().c_str());
             }
+            bool hasLongVectorArg = false;
             if (arguments != nullptr) {
                 // Make sure qualifications work for these arguments.
                 TIntermAggregate* aggregate = arguments->getAsAggregate();
@@ -1516,6 +1517,10 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
                         }
                     }
 
+                    if (argType.isLongVector()) {
+                        hasLongVectorArg = true;
+                    }
+
                     // TODO 4.5 functionality:  A shader will fail to compile
                     // if the value passed to the memargument of an atomic memory function does not correspond to a buffer or
                     // shared variable. It is acceptable to pass an element of an array or a single component of a vector to the
@@ -1558,6 +1563,12 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
                     userFunctionCallCheck(loc, *call);
             }
 
+            if (hasLongVectorArg && fnCandidate->getBuiltInOp() != EOpNull) {
+                TType longVectorResultType(EbtVoid);
+                handleLongVectorBuiltin(loc, fnCandidate, &longVectorResultType, arguments);
+                result->setType(longVectorResultType);
+            }
+
             // Convert 'out' arguments.  If it was a constant folded built-in, it won't be an aggregate anymore.
             // Built-ins with a single argument aren't called with an aggregate, but they also don't have an output.
             // Also, build the qualifier list for user function calls, which are always called with an aggregate.
@@ -1574,7 +1585,7 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
 
             handleVector2CoopMatConversionCall(loc, fnCandidate, result, arguments);
 
-            if (result->getAsTyped()->getType().isCoopVecNV() &&
+            if (result->getAsTyped()->getType().isCoopVecOrLongVector() &&
                !result->getAsTyped()->getType().isParameterized()) {
                 if (auto unaryNode = result->getAsUnaryNode())
                     result->setType(unaryNode->getOperand()->getAsTyped()->getType());
@@ -2179,6 +2190,12 @@ void TParseContext::handleVector2CoopMatConversionCall(const TSourceLoc& loc, co
   }
 }
 
+void TParseContext::handleLongVectorBuiltin(const TSourceLoc& loc, const TFunction* fnCandidate, TType* resultType, TIntermNode* arguments)
+{
+    if (!IsSupportedLongVectorBuiltin(fnCandidate, resultType, arguments)) {
+        error(loc, "can't resolve types (ambiguous long vector overload)", fnCandidate->getName().c_str(), "");
+    }
+}
 
 TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNode* arguments,
                                                        const TFunction& function)
@@ -2187,6 +2204,26 @@ TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNo
     TIntermTyped *result = intermediate.addBuiltInFunctionCall(loc, function.getBuiltInOp(),
                                                                function.getParamCount() == 1,
                                                                arguments, function.getType());
+
+    // EXT_descriptor_heap
+    // All the image atomic ops' first param is image variable.
+    if (extensionTurnedOn(E_GL_EXT_descriptor_heap) && function.getBuiltInOp() <= EOpImageAtomicStore &&
+        function.getBuiltInOp() >= EOpImageAtomicAdd) {
+        TIntermNode* imageNode = nullptr;
+        if (arguments->getAsAggregate() && arguments->getAsAggregate()->getSequence().size() > 0)
+            imageNode = arguments->getAsAggregate()->getSequence()[0];
+        else if (arguments->getAsUnaryNode())
+            imageNode = arguments->getAsUnaryNode();
+
+        if (imageNode && imageNode->getAsBinaryNode()) {
+            auto imageSymbol = imageNode->getAsBinaryNode()->getLeft();
+            if (imageSymbol && imageSymbol->getType().isImage()) {
+                imageSymbol->getQualifier().setUsedByAtomic();
+                result->getQualifier().setUsedByAtomic();
+            }
+        }
+    }
+
     if (result != nullptr && obeyPrecisionQualifiers())
         computeBuiltinPrecisions(*result, function);
 
@@ -2475,7 +2512,7 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction
             length = type.getMatrixCols();
         else if (type.isVector())
             length = type.getVectorSize();
-        else if (type.isCoopMat() || type.isCoopVecNV())
+        else if (type.isCoopMat() || type.isCoopVecOrLongVector())
             return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt));
         else {
             // we should not get here, because earlier semantic checking should have prevented this path
@@ -3600,10 +3637,10 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
             error(loc, "second parameter must not have floate5m2 or floate4m3 basic type", "", "");
         }
 
-        if (!(op0Type.isScalar() || op0Type.isVector() || op0Type.isCoopMatKHR())) {
+        if (!(op0Type.isScalar() || op0Type.isVector() || op0Type.isLongVector() || op0Type.isCoopMatKHR())) {
             error(loc, "first parameter must be scalar, vector, or cooperative matrix", "", "");
         }
-        if (!(op1Type.isScalar() || op1Type.isVector() || op1Type.isCoopMatKHR())) {
+        if (!(op1Type.isScalar() || op1Type.isVector() || op1Type.isLongVector() || op1Type.isCoopMatKHR())) {
             error(loc, "second parameter must be scalar, vector, or cooperative matrix", "", "");
         }
         if (!(op0Type.sameElementShape(op1Type) || op0Type.sameCoopMatShape(op1Type))) {
@@ -6289,9 +6326,11 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali
     paramCheckFixStorage(loc, qualifier.storage, type);
 }
 
-void TParseContext::nestedBlockCheck(const TSourceLoc& loc)
+void TParseContext::nestedBlockCheck(const TSourceLoc& loc, const bool allowedInnerStruct)
 {
-    if (structNestingLevel > 0 || blockNestingLevel > 0)
+    if ((!allowedInnerStruct && structNestingLevel > 0) ||
+        (allowedInnerStruct && structNestingLevel <= 0) ||
+        blockNestingLevel > 0)
         error(loc, "cannot nest a block definition inside a structure or block", "", "");
     ++blockNestingLevel;
 }
@@ -6373,7 +6412,8 @@ void TParseContext::structTypeCheck(const TSourceLoc& /*loc*/, TPublicType& publ
         const TSourceLoc& memberLoc = typeList[member].loc;
         if (memberQualifier.isAuxiliary() ||
             memberQualifier.isInterpolation() ||
-            (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal))
+            (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal &&
+             !memberQualifier.layoutDescriptorHeap && !memberQualifier.layoutDescriptorInnerBlock))
             error(memberLoc, "cannot use storage or interpolation qualifiers on structure members", typeList[member].type->getFieldName().c_str(), "");
         if (memberQualifier.isMemory())
             error(memberLoc, "cannot use memory qualifiers on structure members", typeList[member].type->getFieldName().c_str(), "");
@@ -6667,6 +6707,12 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
             return;
         }
     }
+    if (id == "descriptor_heap") {
+        requireExtensions(loc, 1, &E_GL_EXT_descriptor_heap, "descriptor_stride");
+        requireVulkan(loc, "descriptor_heap");
+        publicType.qualifier.layoutDescriptorHeap = true;
+        return;
+    }
     if (id == "push_constant") {
         requireVulkan(loc, "push_constant");
         publicType.qualifier.layoutPushConstant = true;
@@ -7187,6 +7233,45 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
         return;
     }
 
+    if (id == "bank") {
+        requireExtensions(loc, 1, &E_GL_NV_push_constant_bank, "bank");
+        if (nonLiteral)
+            error(loc, "needs a literal integer", id.c_str(), "");
+        else if (value < 0 || (unsigned int)value >= TQualifier::layoutBankEnd)
+            error(loc, "bank out of range", id.c_str(), "");
+        else
+            publicType.qualifier.layoutBank = value;
+        return;
+    }
+    if (id == "member_offset") {
+        requireExtensions(loc, 1, &E_GL_NV_push_constant_bank, "member_offset");
+        if (nonLiteral)
+            error(loc, "needs a literal integer", id.c_str(), "");
+        else if (value < 0)
+            error(loc, "must be equal or greater than 0", id.c_str(), "");
+        else
+            publicType.qualifier.layoutMemberOffset = value;
+        return;
+    }
+
+    if (id == "descriptor_stride") {
+        requireExtensions(loc, 1, &E_GL_EXT_descriptor_heap, "descriptor_stride");
+        requireVulkan(loc, "descriptor_stride");
+        if (!IsPow2(value))
+            error(loc, "must be a power of 2", "descriptor_stride", "");
+        else
+            publicType.qualifier.layoutDescriptorStride = uint32_t(value);
+        return;
+    }
+
+    if (id == "heap_offset") {
+        requireExtensions(loc, 1, &E_GL_EXT_descriptor_heap, "heap_offset");
+        requireExtensions(loc, 1, &E_GL_EXT_structured_descriptor_heap, "heap_offset");
+        requireVulkan(loc, "heap_offset");
+        publicType.qualifier.layoutHeapOffset = uint32_t(value);
+        return;
+    }
+
     switch (language) {
     case EShLangTessControl:
         if (id == "vertices") {
@@ -7427,6 +7512,14 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
             dst.layoutXfbOffset = src.layoutXfbOffset;
         if (src.hasAttachment())
             dst.layoutAttachment = src.layoutAttachment;
+        if (src.layoutDescriptorHeap)
+            dst.layoutDescriptorHeap = true;
+        if (src.layoutDescriptorInnerBlock)
+            dst.layoutDescriptorInnerBlock = true;
+        if (src.layoutDescriptorStride != TQualifier::layoutDescriptorStrideEnd)
+            dst.layoutDescriptorStride = src.layoutDescriptorStride;
+        if (src.layoutHeapOffset != 0)
+            dst.layoutHeapOffset = src.layoutHeapOffset;
         if (src.layoutPushConstant)
             dst.layoutPushConstant = true;
 
@@ -7458,6 +7551,10 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
         dst.layoutTileAttachmentQCOM |= src.layoutTileAttachmentQCOM;
         if (src.layoutHitObjectShaderRecordEXT)
             dst.layoutHitObjectShaderRecordEXT = true;
+        if (src.hasBank())
+            dst.layoutBank = src.layoutBank;
+        if (src.hasMemberOffset())
+            dst.layoutMemberOffset = src.layoutMemberOffset;
     }
 }
 
@@ -7713,7 +7810,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
 
         // SPIR-V
         if (spvVersion.spv > 0) {
-            if (qualifier.isUniformOrBuffer()) {
+            if (qualifier.isUniformOrBuffer() && !intermediate.IsRequestedExtension(E_GL_EXT_descriptor_heap)) {
                 if (type.getBasicType() == EbtBlock && !qualifier.isPushConstant() &&
                        !qualifier.isShaderRecord() &&
                        !qualifier.hasAttachment() &&
@@ -7837,6 +7934,8 @@ static bool storageCanHaveLayoutInBlock(const enum TStorageQualifier storage)
     case EvqUniform:
     case EvqBuffer:
     case EvqShared:
+    case EvqSamplerHeap:
+    case EvqResourceHeap:
         return true;
     default:
         return false;
@@ -7972,6 +8071,21 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier
     if (qualifier.storage == EvqHitAttr && qualifier.hasLayout()) {
         error(loc, "cannot apply layout qualifiers to hitAttributeNV variable", "hitAttributeNV", "");
     }
+    if (qualifier.hasBank()) {
+        if (!qualifier.isPushConstant())
+            error(loc, "can only be used with push_constant", "bank", "");
+    }
+    if (qualifier.hasMemberOffset()) {
+        if (!qualifier.isPushConstant())
+            error(loc, "can only be used with push_constant", "member_offset", "");
+    }
+
+    if (qualifier.layoutDescriptorStride != TQualifier::layoutDescriptorStrideEnd &&
+        !qualifier.layoutDescriptorHeap)
+        error(loc, "must specify 'descriptor_heap' to use 'descriptor_stride'", "descriptor_stride", "");
+    if (qualifier.layoutHeapOffset != 0 && !qualifier.layoutDescriptorHeap &&
+        qualifier.storage != EvqSamplerHeap && qualifier.storage != EvqResourceHeap)
+        error(loc, "must specify 'descriptor_heap' to use 'heap_offset'", "heap_offset", "");
 }
 
 // For places that can't have shader-level layout qualifiers
@@ -8303,12 +8417,16 @@ const TFunction* TParseContext::findFunction400(const TSourceLoc& loc, const TFu
             if (fromElementType == toElementType)
                 return true;
         }
+        if (TType::vectorAndLongVectorMatch(from, to))
+            return true;
         if (from.isArray() || to.isArray() || ! from.sameElementShape(to))
             return false;
         if (from.isCoopMat() && to.isCoopMat())
             return from.sameCoopMatBaseType(to);
         if (from.isCoopVecNV() && to.isCoopVecNV())
             return from.sameCoopVecBaseType(to);
+        if (from.isLongVector() && to.isLongVector())
+            return from.sameLongVectorBaseType(to);
         if (from.isTensorARM() && to.isTensorARM())
             return from.sameTensorBaseTypeARM(to);
         return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType());
@@ -8319,10 +8437,13 @@ const TFunction* TParseContext::findFunction400(const TSourceLoc& loc, const TFu
     // Assumes 'convertible' already said true.
     const auto better = [&](const TType& from, const TType& to1, const TType& to2) -> bool {
         // 1. exact match
-        if (from == to2)
-            return from != to1;
-        if (from == to1)
+        bool to2Matches = from == to2 || (from.isLongVector() && to2.getBasicType() == EbtLongVector);
+        bool to1Matches = from == to1 || (from.isLongVector() && to1.getBasicType() == EbtLongVector);
+        if (to2Matches)
+            return !to1Matches;
+        if (to1Matches)
             return false;
+
         if (extensionTurnedOn(E_GL_NV_gpu_shader5)) {
             // This map refers to the conversion table mentioned under the 
             // section "Modify Section 6.1, Function Definitions, p. 63" in NV_gpu_shader5 spec
@@ -8416,12 +8537,16 @@ const TFunction* TParseContext::findFunctionExplicitTypes(const TSourceLoc& loc,
             if (fromElementType == toElementType)
                 return true;
         }
+        if (TType::vectorAndLongVectorMatch(from, to))
+            return true;
         if (from.isArray() || to.isArray() || ! from.sameElementShape(to))
             return false;
         if (from.isCoopMat() && to.isCoopMat())
             return from.sameCoopMatBaseType(to);
         if (from.isCoopVecNV() && to.isCoopVecNV())
             return from.sameCoopVecBaseType(to);
+        if (from.isLongVector() && to.isLongVector())
+            return from.sameLongVectorBaseType(to);
         if (from.isTensorARM() && to.isTensorARM())
             return from.sameTensorBaseTypeARM(to);
         return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType());
@@ -8432,9 +8557,11 @@ const TFunction* TParseContext::findFunctionExplicitTypes(const TSourceLoc& loc,
     // Assumes 'convertible' already said true.
     const auto better = [this](const TType& from, const TType& to1, const TType& to2) -> bool {
         // 1. exact match
-        if (from == to2)
-            return from != to1;
-        if (from == to1)
+        bool to2Matches = from == to2 || (from.isLongVector() && to2.getBasicType() == EbtLongVector);
+        bool to1Matches = from == to1 || (from.isLongVector() && to1.getBasicType() == EbtLongVector);
+        if (to2Matches)
+            return !to1Matches;
+        if (to1Matches)
             return false;
 
         // 2. Promotion (integral, floating-point) is better
@@ -8728,6 +8855,11 @@ bool TParseContext::vkRelaxedRemapUniformVariable(const TSourceLoc& loc, TString
     // merge qualifiers
     mergeObjectLayoutQualifiers(updatedBlock->getWritableType().getQualifier(), type.getQualifier(), true);
 
+    // set default value for bank when no decoration is present. 
+    if (updatedBlock->getWritableType().getQualifier().isPushConstant() && !updatedBlock->getWritableType().getQualifier().hasBank()) {
+        updatedBlock->getWritableType().getQualifier().layoutBank = 0;
+    }
+
     return true;
 }
 
@@ -9077,7 +9209,15 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
 
         if (!publicType.typeParameters || !publicType.typeParameters->arraySizes || publicType.typeParameters->arraySizes->getNumDims() != 1) {
             error(loc, "expected two type parameters", identifier.c_str(), "");
-        } else if (publicType.typeParameters->arraySizes->getDimSize(0) <= 0) {
+        } else if (publicType.typeParameters->arraySizes->getDimNode(0) == nullptr && publicType.typeParameters->arraySizes->getDimSize(0) <= 0) {
+            error(loc, "expected positive number of components", identifier.c_str(), "");
+        }
+    } else if (type.isLongVector()) {
+        intermediate.setUseStorageBuffer();
+
+        if (!publicType.typeParameters || !publicType.typeParameters->arraySizes || publicType.typeParameters->arraySizes->getNumDims() != 1) {
+            error(loc, "expected two type parameters", identifier.c_str(), "");
+        } else if (publicType.typeParameters->arraySizes->getDimNode(0) == nullptr && publicType.typeParameters->arraySizes->getDimSize(0) <= 0) {
             error(loc, "expected positive number of components", identifier.c_str(), "");
         }
     } else if (type.isTensorARM()) {
@@ -9221,6 +9361,11 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
         initNode = executeInitializer(loc, initializer, variable);
     }
 
+    // EXT_descriptor_heap
+    if (!untypedHeapCheck(symbol, type, loc, identifier.c_str())) {
+        return nullptr;
+    }
+
     // look for errors in layout qualifier use
     layoutObjectCheck(loc, *symbol);
 
@@ -10162,6 +10307,60 @@ void TParseContext::updateBindlessQualifier(TType& memberType)
     }
 }
 
+void TParseContext::descHeapBuiltinRemap(TType* type, bool isInnerBlock)
+{
+    if (type->isStruct()) {
+        TTypeList* types = type->getWritableStruct();
+        for (auto typeLoc : *types) {
+            descHeapBuiltinRemap(typeLoc.type, isInnerBlock);
+        }
+    }
+
+    auto* qualifier = &type->getQualifier();
+    if (type->getBasicType() == EbtSampler) {
+        if (type->isImage() || type->isTexture())
+            qualifier->builtIn = EbvResourceHeapEXT;
+        else
+            qualifier->builtIn = EbvSamplerHeapEXT;
+        qualifier->layoutDescriptorHeap = true;
+    } else if (qualifier->isUniformOrBuffer() || type->getBasicType() == EbtAccStruct) {
+        qualifier->builtIn = EbvResourceHeapEXT;
+        qualifier->layoutDescriptorHeap = true;
+        qualifier->layoutDescriptorInnerBlock = isInnerBlock;
+    }
+ }
+
+bool TParseContext::untypedHeapCheck(TSymbol* symbol, const TType& type, const TSourceLoc& loc, const char* name)
+{
+    // EXT_descriptor_heap
+    bool isHeapStruct =
+        (type.getQualifier().storage == EvqSamplerHeap || type.getQualifier().storage == EvqResourceHeap);
+
+    if (intermediate.IsRequestedExtension(E_GL_EXT_descriptor_heap) && spvVersion.vulkan > 0 &&
+        !type.getQualifier().hasSet() && !type.getQualifier().hasBinding()) {
+        if (type.getQualifier().layoutDescriptorHeap || isHeapStruct) {
+            if ((intermediate.isEsProfile() && intermediate.getVersion() < 310) ||
+                (!intermediate.isEsProfile() && intermediate.getVersion() < 420)) {
+                TString warnMsg = "layout(descriptor_heap) is turned on beyond version/profile limits.";
+                infoSink.info.message(EPrefixWarning, warnMsg.c_str());
+            }
+            if (IsAnonymous(symbol->getName()) &&
+                (type.getQualifier().isUniformOrBuffer() || type.getBasicType() == EbtBlock)) {
+                error(loc, "layout(descriptor_heap) decorated block should be explicitly "
+                    "declared with a run-time sized array type.", name, "");
+                return false;
+            }
+            if (!type.containsHeapArray()) {
+                error(loc, "layout(descriptor_heap) decorated variable could only be declared as an array.",
+                      name, "");
+                return false;
+            }
+            descHeapBuiltinRemap(&symbol->getWritableType(), isHeapStruct);
+        }
+    }
+    return true;
+}
+
 //
 // Do everything needed to add an interface block. Returns the declarator node if there's an instance declaration.
 //
@@ -10213,12 +10412,12 @@ TIntermNode* TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeL
         }
 
         // For bindless texture, sampler can be declared as uniform/storage block member,
-        if (memberType.containsOpaque()) {
+        if (memberType.containsOpaque() && !extensionTurnedOn(E_GL_EXT_structured_descriptor_heap)) {
             if (memberType.containsSampler() && extensionTurnedOn(E_GL_ARB_bindless_texture))
                 updateBindlessQualifier(memberType);
             else
                 error(memberLoc, "member of block cannot be or contain a sampler, image, or atomic_uint type", typeList[member].type->getFieldName().c_str(), "");
-            }
+        }
 
         if (memberType.containsCoopMat())
             error(memberLoc, "member of block cannot be or contain a cooperative matrix type", typeList[member].type->getFieldName().c_str(), "");
@@ -10444,6 +10643,11 @@ TIntermNode* TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeL
         return nullptr;
     }
 
+    // EXT_descriptor_heap
+    if (!untypedHeapCheck(&variable, blockType, loc, blockName->c_str())) {
+        return nullptr;
+    }
+
     // Check for general layout qualifier errors
     layoutObjectCheck(loc, variable);
 
@@ -10559,6 +10763,14 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q
         profileRequires(loc, ~EEsProfile, 460, E_GL_EXT_shader_invocation_reorder, "hitObjectAttributeEXT block");
         requireStage(loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | EShLangMissMask), "hitObjectAttributeEXT block");
         break;
+    case EvqResourceHeap:
+        profileRequires(loc, ~EEsProfile, 460, E_GL_EXT_structured_descriptor_heap, "resourceheap block");
+        profileRequires(loc, ~EEsProfile, 460, E_GL_EXT_descriptor_heap, "resourceheap block");
+        break;
+    case EvqSamplerHeap:
+        profileRequires(loc, ~EEsProfile, 460, E_GL_EXT_structured_descriptor_heap, "samplerheap block");
+        profileRequires(loc, ~EEsProfile, 460, E_GL_EXT_descriptor_heap, "samplerheap block");
+        break;
     default:
         error(loc, "only uniform, buffer, in, or out blocks are supported", blockName->c_str(), "");
         break;

+ 4 - 1
3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h

@@ -416,7 +416,7 @@ public:
     void redeclareBuiltinBlock(const TSourceLoc&, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes);
     void paramCheckFixStorage(const TSourceLoc&, const TStorageQualifier&, TType& type);
     void paramCheckFix(const TSourceLoc&, const TQualifier&, TType& type);
-    void nestedBlockCheck(const TSourceLoc&);
+    void nestedBlockCheck(const TSourceLoc&, const bool allowedInnerStruct = false);
     void nestedStructCheck(const TSourceLoc&);
     void arrayObjectCheck(const TSourceLoc&, const TType&, const char* op);
     void opaqueCheck(const TSourceLoc&, const TType&, const char* op);
@@ -456,6 +456,8 @@ public:
     TParameter getParamWithDefault(const TPublicType& ty, TString* identifier, TIntermTyped* initializer,
                                    const TSourceLoc& loc);
     void inheritMemoryQualifiers(const TQualifier& from, TQualifier& to);
+    void descHeapBuiltinRemap(TType* type, bool isInnerBlock);
+    bool untypedHeapCheck(TSymbol* symbol, const TType& type, const TSourceLoc& loc, const char* name);
     TIntermNode* declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = nullptr, TArraySizes* arraySizes = nullptr);
     void blockStorageRemap(const TSourceLoc&, const TString*, TQualifier&);
     void blockStageIoCheck(const TSourceLoc&, const TQualifier&);
@@ -516,6 +518,7 @@ protected:
     void finish() override;
     void handleCoopMat2FunctionCall(const TSourceLoc& loc, const TFunction* fnCandidate, TIntermTyped* result, TIntermNode* arguments);
     void handleVector2CoopMatConversionCall(const TSourceLoc& loc, const TFunction* fnCandidate, TIntermTyped* &result, TIntermNode* arguments);
+    void handleLongVectorBuiltin(const TSourceLoc& loc, const TFunction* fnCandidate, TType* resultType, TIntermNode* arguments);
 
     virtual const char* getGlobalUniformBlockName() const override;
     virtual void finalizeGlobalUniformBlockLayout(TVariable&) override;

+ 84 - 47
3rdparty/glslang/glslang/MachineIndependent/Scan.cpp

@@ -779,6 +779,9 @@ const std::unordered_map<const char*, int, str_hash, str_eq> KeywordMap {
     {"tensorViewNV",TENSORVIEWNV},
 
     {"coopvecNV",COOPVECNV},
+    {"vector",VECTOR},
+    {"resourceheap",RESOURCEHEAP},
+    {"samplerheap",SAMPLERHEAP},
 };
 const std::unordered_set<const char*, str_hash, str_eq> ReservedSet {
     "common",
@@ -1353,13 +1356,14 @@ int TScanContext::tokenizeIdentifier()
     case U64VEC2:
     case U64VEC3:
     case U64VEC4:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
             parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64) ||
             parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
             parseContext.extensionTurnedOn(E_GL_NV_gpu_shader5) ||
-            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int64))
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int64)) {
+            afterType = true;
             return keyword;
+        }
         return identifierOrType();
 
     case INT8_T:
@@ -1370,13 +1374,14 @@ int TScanContext::tokenizeIdentifier()
     case U8VEC2:
     case U8VEC3:
     case U8VEC4:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
             parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
             parseContext.extensionTurnedOn(E_GL_EXT_shader_8bit_storage) ||
             parseContext.extensionTurnedOn(E_GL_NV_gpu_shader5) ||
-            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int8))
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int8)) {
+            afterType = true;
             return keyword;
+        }
         return identifierOrType();
 
     case INT16_T:
@@ -1387,14 +1392,15 @@ int TScanContext::tokenizeIdentifier()
     case U16VEC2:
     case U16VEC3:
     case U16VEC4:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
             parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16) ||
             parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) ||
             parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
             parseContext.extensionTurnedOn(E_GL_NV_gpu_shader5) ||
-            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int16))
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int16)) {
+            afterType = true;
             return keyword;
+        }
         return identifierOrType();
     case INT32_T:
     case UINT32_T:
@@ -1404,23 +1410,25 @@ int TScanContext::tokenizeIdentifier()
     case U32VEC2:
     case U32VEC3:
     case U32VEC4:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
             parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
             parseContext.extensionTurnedOn(E_GL_NV_gpu_shader5) ||
-            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int32))
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_int32)) {
+            afterType = true;
             return keyword;
+        }
         return identifierOrType();
     case FLOAT32_T:
     case F32VEC2:
     case F32VEC3:
     case F32VEC4:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
             parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
             parseContext.extensionTurnedOn(E_GL_NV_gpu_shader5) ||
-            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32))
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32)) {
+            afterType = true;
             return keyword;
+        }
         return identifierOrType();
     case F32MAT2:
     case F32MAT3:
@@ -1434,25 +1442,27 @@ int TScanContext::tokenizeIdentifier()
     case F32MAT4X2:
     case F32MAT4X3:
     case F32MAT4X4:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
             parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
-            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32))
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32)) {
+            afterType = true;
             return keyword;
+        }
         return identifierOrType();
 
     case FLOAT64_T:
     case F64VEC2:
     case F64VEC3:
     case F64VEC4:
-    afterType = true;
-    if (parseContext.symbolTable.atBuiltInLevel() ||
-        parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
-        (parseContext.extensionTurnedOn(E_GL_NV_gpu_shader5) && 
-         parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_fp64)) ||
-        parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64))
-        return keyword;
-    return identifierOrType();
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
+            (parseContext.extensionTurnedOn(E_GL_NV_gpu_shader5) && 
+             parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_fp64)) ||
+             parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64)) {
+            afterType = true;
+            return keyword;
+        }
+        return identifierOrType();
     case F64MAT2:
     case F64MAT3:
     case F64MAT4:
@@ -1465,26 +1475,27 @@ int TScanContext::tokenizeIdentifier()
     case F64MAT4X2:
     case F64MAT4X3:
     case F64MAT4X4:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
             parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
-            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64))
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64)) {
+            afterType = true;
             return keyword;
+        }
         return identifierOrType();
 
     case FLOAT16_T:
     case F16VEC2:
     case F16VEC3:
     case F16VEC4:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
             parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) ||
             parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) ||
             parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
             parseContext.extensionTurnedOn(E_GL_NV_gpu_shader5) ||
-            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16))
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16)) {
+            afterType = true;
             return keyword;
-
+        }
         return identifierOrType();
 
     case F16MAT2:
@@ -1499,12 +1510,13 @@ int TScanContext::tokenizeIdentifier()
     case F16MAT4X2:
     case F16MAT4X3:
     case F16MAT4X4:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
             parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) ||
             parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types) ||
-            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16))
+            parseContext.extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float16)) {
+            afterType = true;
             return keyword;
+        }
 
         return identifierOrType();
 
@@ -1512,10 +1524,11 @@ int TScanContext::tokenizeIdentifier()
     case BF16VEC2:
     case BF16VEC3:
     case BF16VEC4:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            parseContext.extensionTurnedOn(E_GL_EXT_bfloat16))
+            parseContext.extensionTurnedOn(E_GL_EXT_bfloat16)) {
+            afterType = true;
             return keyword;
+        }
 
         return identifierOrType();
 
@@ -1523,10 +1536,11 @@ int TScanContext::tokenizeIdentifier()
     case FE5M2VEC2:
     case FE5M2VEC3:
     case FE5M2VEC4:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            parseContext.extensionTurnedOn(E_GL_EXT_float_e5m2))
+            parseContext.extensionTurnedOn(E_GL_EXT_float_e5m2)) {
+            afterType = true;
             return keyword;
+        }
 
         return identifierOrType();
 
@@ -1534,10 +1548,11 @@ int TScanContext::tokenizeIdentifier()
     case FE4M3VEC2:
     case FE4M3VEC3:
     case FE4M3VEC4:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            parseContext.extensionTurnedOn(E_GL_EXT_float_e4m3))
+            parseContext.extensionTurnedOn(E_GL_EXT_float_e4m3)) {
+            afterType = true;
             return keyword;
+        }
 
         return identifierOrType();
 
@@ -1806,10 +1821,11 @@ int TScanContext::tokenizeIdentifier()
 
     case F16SUBPASSINPUT:
     case F16SUBPASSINPUTMS:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float_fetch))
+            parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float_fetch)) {
+            afterType = true;
             return keyword;
+        }
         return identifierOrType();
 
     case EXPLICITINTERPAMD:
@@ -1858,38 +1874,51 @@ int TScanContext::tokenizeIdentifier()
         return identifierOrType();
 
     case FCOOPMATNV:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            parseContext.extensionTurnedOn(E_GL_NV_cooperative_matrix))
+            parseContext.extensionTurnedOn(E_GL_NV_cooperative_matrix)) {
+            afterType = true;
             return keyword;
+        }
         return identifierOrType();
 
     case UCOOPMATNV:
     case ICOOPMATNV:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            parseContext.extensionTurnedOn(E_GL_NV_integer_cooperative_matrix))
+            parseContext.extensionTurnedOn(E_GL_NV_integer_cooperative_matrix)) {
+            afterType = true;
             return keyword;
+        }
         return identifierOrType();
     case TENSORARM:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            parseContext.extensionTurnedOn(E_GL_ARM_tensors))
+            parseContext.extensionTurnedOn(E_GL_ARM_tensors)) {
+            afterType = true;
             return keyword;
+        }
         return identifierOrType();
 
     case COOPMAT:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            parseContext.extensionTurnedOn(E_GL_KHR_cooperative_matrix))
+            parseContext.extensionTurnedOn(E_GL_KHR_cooperative_matrix)) {
+            afterType = true;
             return keyword;
+        }
         return identifierOrType();
 
     case COOPVECNV:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            parseContext.extensionTurnedOn(E_GL_NV_cooperative_vector))
+            parseContext.extensionTurnedOn(E_GL_NV_cooperative_vector)) {
+            afterType = true;
+            return keyword;
+        }
+        return identifierOrType();
+
+    case VECTOR:
+        if (parseContext.symbolTable.atBuiltInLevel() ||
+            parseContext.extensionTurnedOn(E_GL_EXT_long_vector)) {
+            afterType = true;
             return keyword;
+        }
         return identifierOrType();
 
     case DEMOTE:
@@ -1944,9 +1973,17 @@ int TScanContext::tokenizeIdentifier()
     case FUNCTION:
     case TENSORLAYOUTNV:
     case TENSORVIEWNV:
-        afterType = true;
         if (parseContext.symbolTable.atBuiltInLevel() ||
-            parseContext.extensionTurnedOn(E_GL_NV_cooperative_matrix2))
+            parseContext.extensionTurnedOn(E_GL_NV_cooperative_matrix2)) {
+            afterType = true;
+            return keyword;
+        }
+        return identifierOrType();
+
+    case RESOURCEHEAP:
+    case SAMPLERHEAP:
+        if (parseContext.extensionTurnedOn(E_GL_EXT_structured_descriptor_heap) &&
+            parseContext.extensionTurnedOn(E_GL_EXT_descriptor_heap))
             return keyword;
         return identifierOrType();
 

+ 1 - 0
3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp

@@ -1855,6 +1855,7 @@ void TShader::setUniformLocationBase(int base)
 {
     intermediate->setUniformLocationBase(base);
 }
+void TShader::setBindingsPerResourceType() { intermediate->setBindingsPerResourceType(); }
 void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
 void TShader::setResourceSetBinding(const std::vector<std::string>& base)   { intermediate->setResourceSetBinding(base); }
 void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); }

+ 18 - 0
3rdparty/glslang/glslang/MachineIndependent/Versions.cpp

@@ -317,6 +317,7 @@ void TParseVersions::initializeExtensionBehavior()
     extensionBehavior[E_GL_NV_cooperative_matrix2]                   = EBhDisable;
     extensionBehavior[E_GL_NV_cluster_acceleration_structure]        = EBhDisable;
     extensionBehavior[E_GL_NV_linear_swept_spheres]                  = EBhDisable;
+    extensionBehavior[E_GL_NV_push_constant_bank]                    = EBhDisable;
 
     // ARM
     extensionBehavior[E_GL_ARM_shader_core_builtins]                 = EBhDisable;
@@ -345,6 +346,7 @@ void TParseVersions::initializeExtensionBehavior()
     extensionBehavior[E_GL_EXT_texture_buffer]                       = EBhDisable;
     extensionBehavior[E_GL_EXT_texture_cube_map_array]               = EBhDisable;
     extensionBehavior[E_GL_EXT_null_initializer]                     = EBhDisable;
+    extensionBehavior[E_GL_EXT_descriptor_heap]                      = EBhDisable;
 
     // OES matching AEP
     extensionBehavior[E_GL_OES_geometry_shader]          = EBhDisable;
@@ -389,6 +391,7 @@ void TParseVersions::initializeExtensionBehavior()
     extensionBehavior[E_GL_EXT_uniform_buffer_unsized_array] = EBhDisable;
     extensionBehavior[E_GL_EXT_shader_64bit_indexing]       = EBhDisable;
     extensionBehavior[E_GL_EXT_conservative_depth]          = EBhDisable;
+    extensionBehavior[E_GL_EXT_long_vector]                 = EBhDisable;
 
     // OVR extensions
     extensionBehavior[E_GL_OVR_multiview]                = EBhDisable;
@@ -457,6 +460,7 @@ void TParseVersions::getPreamble(std::string& preamble)
             "#define GL_EXT_shader_implicit_conversions 1\n"
             "#define GL_EXT_shader_integer_mix 1\n"
             "#define GL_EXT_blend_func_extended 1\n"
+            "#define GL_EXT_descriptor_heap 1\n"
 
             // OES matching AEP
             "#define GL_OES_geometry_shader 1\n"
@@ -639,6 +643,7 @@ void TParseVersions::getPreamble(std::string& preamble)
             "#define GL_EXT_shader_64bit_indexing 1\n"
 
             "#define GL_EXT_shader_invocation_reorder 1\n"
+            "#define GL_EXT_descriptor_heap 1\n"
             ;
 
         if (spvVersion.spv == 0) {
@@ -662,6 +667,11 @@ void TParseVersions::getPreamble(std::string& preamble)
         }
     }
 
+    if ((!isEsProfile() && version >= 460) ||
+        (isEsProfile() && version >= 320)) {
+        preamble += "#define GL_EXT_nontemporal_keyword 1\n";
+    }
+
     if ((!isEsProfile() && version >= 140) ||
         (isEsProfile() && version >= 310)) {
         preamble +=
@@ -1519,6 +1529,14 @@ void TParseVersions::tensorCheckARM(const TSourceLoc& loc, const char* op, bool
     }
 }
 
+void TParseVersions::longVectorCheck(const TSourceLoc& loc, const char* op, bool builtIn)
+{
+    if (!builtIn) {
+        const char* const extensions[] = {E_GL_EXT_long_vector};
+        requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
+    }
+}
+
 // Call for any operation removed because SPIR-V is in use.
 void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op)
 {

+ 4 - 0
3rdparty/glslang/glslang/MachineIndependent/Versions.h

@@ -229,6 +229,8 @@ const char* const E_GL_EXT_texture_offset_non_const         = "GL_EXT_texture_of
 const char* const E_GL_EXT_nontemporal_keyword              = "GL_EXT_nontemporal_keyword";
 const char* const E_GL_EXT_uniform_buffer_unsized_array     = "GL_EXT_uniform_buffer_unsized_array";
 const char* const E_GL_EXT_conservative_depth               = "GL_EXT_conservative_depth";
+const char* const E_GL_EXT_descriptor_heap                  = "GL_EXT_descriptor_heap";
+const char* const E_GL_EXT_structured_descriptor_heap       = "GL_EXT_structured_descriptor_heap";
 
 // Arrays of extensions for the above viewportEXTs duplications
 
@@ -293,6 +295,7 @@ const char* const E_GL_NV_cooperative_vector                    = "GL_NV_coopera
 const char* const E_GL_NV_cluster_acceleration_structure        = "GL_NV_cluster_acceleration_structure";
 const char* const E_GL_NV_linear_swept_spheres                  = "GL_NV_linear_swept_spheres";
 const char* const E_GL_NV_gpu_shader5                           = "GL_NV_gpu_shader5";
+const char* const E_GL_NV_push_constant_bank                    = "GL_NV_push_constant_bank";
 
 // ARM
 const char* const E_GL_ARM_shader_core_builtins                 = "GL_ARM_shader_core_builtins";
@@ -366,6 +369,7 @@ const char* const E_GL_EXT_integer_dot_product                    = "GL_EXT_inte
 const char* const E_GL_EXT_bfloat16 = "GL_EXT_bfloat16";
 const char* const E_GL_EXT_float_e5m2 = "GL_EXT_float_e5m2";
 const char* const E_GL_EXT_float_e4m3 = "GL_EXT_float_e4m3";
+const char* const E_GL_EXT_long_vector = "GL_EXT_long_vector";
 
 const char* const E_GL_EXT_shader_64bit_indexing = "GL_EXT_shader_64bit_indexing";
 

+ 84 - 4
3rdparty/glslang/glslang/MachineIndependent/glslang.y

@@ -182,6 +182,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
 %token <lex> FCOOPMATNV ICOOPMATNV UCOOPMATNV
 %token <lex> COOPMAT
 %token <lex> COOPVECNV
+%token <lex> VECTOR
 %token <lex> HITOBJECTNV HITOBJECTATTRNV HITOBJECTEXT HITOBJECTATTREXT
 %token <lex> TENSORLAYOUTNV TENSORVIEWNV
 %token <lex> TENSORARM
@@ -284,7 +285,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
 %token <lex> SUBROUTINE DEMOTE FUNCTION
 %token <lex> PAYLOADNV PAYLOADINNV HITATTRNV CALLDATANV CALLDATAINNV 
 %token <lex> PAYLOADEXT PAYLOADINEXT HITATTREXT CALLDATAEXT CALLDATAINEXT
-%token <lex> PATCH SAMPLE NONUNIFORM
+%token <lex> PATCH SAMPLE NONUNIFORM RESOURCEHEAP SAMPLERHEAP
 %token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY NONTEMPORAL DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT
 %token <lex> SUBGROUPCOHERENT NONPRIVATE SHADERCALLCOHERENT
 %token <lex> NOPERSPECTIVE EXPLICITINTERPAMD PERVERTEXEXT PERVERTEXNV PERPRIMITIVENV PERVIEWNV PERTASKNV PERPRIMITIVEEXT TASKPAYLOADWORKGROUPEXT
@@ -326,8 +327,10 @@ extern int yylex(YYSTYPE*, TParseContext&);
 %type <interm.type> single_type_qualifier
 %type <interm.type> type_specifier_nonarray
 %type <interm.type> struct_specifier
+%type <interm.type> block_heap_inner_structure
 %type <interm.typeLine> struct_declarator
 %type <interm.typeList> struct_declarator_list struct_declaration struct_declaration_list
+%type <interm.typeList> struct_declaration_with_heap struct_declaration_without_heap
 %type <interm> block_structure
 %type <interm.function> function_header function_declarator
 %type <interm.function> function_header_with_parameters
@@ -934,7 +937,7 @@ declaration
     ;
 
 block_structure
-    : type_qualifier IDENTIFIER LEFT_BRACE { parseContext.nestedBlockCheck($1.loc); } struct_declaration_list RIGHT_BRACE {
+    : type_qualifier IDENTIFIER LEFT_BRACE { parseContext.nestedBlockCheck($1.loc); } struct_declaration_without_heap RIGHT_BRACE {
         --parseContext.blockNestingLevel;
         parseContext.blockName = $2.string;
         parseContext.globalQualifierFixCheck($1.loc, $1.qualifier);
@@ -943,6 +946,7 @@ block_structure
         $$.loc = $1.loc;
         $$.typeList = $5;
     }
+    ;
 
 identifier_list
     : IDENTIFIER {
@@ -1530,6 +1534,16 @@ storage_qualifier
         $$.init($1.loc);
         $$.qualifier.sample = true;
     }
+    | RESOURCEHEAP {
+        parseContext.globalCheck($1.loc, "resourceHeap");
+        $$.init($1.loc);
+        $$.qualifier.storage = EvqResourceHeap;
+    }
+    | SAMPLERHEAP {
+        parseContext.globalCheck($1.loc, "samplerHeap");
+        $$.init($1.loc);
+        $$.qualifier.storage = EvqSamplerHeap;
+    }
     | HITATTRNV {
         parseContext.globalCheck($1.loc, "hitAttributeNV");
         parseContext.requireStage($1.loc, (EShLanguageMask)(EShLangIntersectMask | EShLangClosestHitMask
@@ -3652,6 +3666,12 @@ type_specifier_nonarray
         $$.tensorRankARM = 1; // placeholder value
         $$.basicType = EbtTensorARM;
     }
+    | VECTOR {
+        parseContext.longVectorCheck($1.loc, "vector", parseContext.symbolTable.atBuiltInLevel());
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
+        $$.basicType = EbtLongVector;
+        $$.longVector = true;
+    }
     | spirv_type_specifier {
         parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V type specifier");
         $$ = $1;
@@ -3704,7 +3724,6 @@ precision_qualifier
 
 struct_specifier
     : STRUCT IDENTIFIER LEFT_BRACE { parseContext.nestedStructCheck($1.loc); } struct_declaration_list RIGHT_BRACE {
-
         TType* structure = new TType($5, *$2.string);
         parseContext.structArrayCheck($2.loc, *structure);
 
@@ -3730,10 +3749,71 @@ struct_specifier
     ;
 
 struct_declaration_list
+    : struct_declaration_without_heap {
+        $$ = $1;
+    }
+    | struct_declaration_with_heap {
+        $$ = $1;
+    }
+    | struct_declaration_with_heap struct_declaration_without_heap {
+        $$ = $1;
+        for (unsigned int i = 0; i < $2->size(); ++i) {
+            for (unsigned int j = 0; j < $$->size(); ++j) {
+                if ((*$$)[j].type->getFieldName() == (*$2)[i].type->getFieldName())
+                    parseContext.error((*$2)[i].loc, "duplicate member name:", "", (*$2)[i].type->getFieldName().c_str());
+            }
+            $$->push_back((*$2)[i]);
+        }
+    }
+    | struct_declaration_without_heap struct_declaration_with_heap {
+        $$ = $1;
+        for (unsigned int i = 0; i < $2->size(); ++i) {
+            for (unsigned int j = 0; j < $$->size(); ++j) {
+                if ((*$$)[j].type->getFieldName() == (*$2)[i].type->getFieldName())
+                    parseContext.error((*$2)[i].loc, "duplicate member name:", "", (*$2)[i].type->getFieldName().c_str());
+            }
+            $$->push_back((*$2)[i]);
+        }
+    }
+    ;
+
+struct_declaration_with_heap
+    : block_heap_inner_structure struct_declarator_list SEMICOLON {
+        $$ = $2;
+        parseContext.voidErrorCheck($1.loc, (*$2)[0].type->getFieldName(), $1.basicType);
+        parseContext.precisionQualifierCheck($1.loc, $1.basicType, $1.qualifier, $1.hasTypeParameter());
+
+        for (unsigned int i = 0; i < $$->size(); ++i) {
+            TType type($1);
+            type.setFieldName((*$$)[i].type->getFieldName());
+            type.transferArraySizes((*$$)[i].type->getArraySizes());
+            type.copyArrayInnerSizes($1.arraySizes);
+            parseContext.arrayOfArrayVersionCheck((*$$)[i].loc, type.getArraySizes());
+            (*$$)[i].type->shallowCopy(type);
+        }
+    }
+    ;
+
+block_heap_inner_structure
+    : type_qualifier LEFT_BRACE { parseContext.nestedBlockCheck($1.loc, true); } struct_declaration_without_heap RIGHT_BRACE {
+        --parseContext.blockNestingLevel;
+        parseContext.globalQualifierFixCheck($1.loc, $1.qualifier);
+        parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
+        $$.init($1.loc);
+        TType* innerStructure = new TType($4, TString(""));
+        $$.basicType = EbtBlock;
+        $$.userDef = innerStructure;
+        $$.qualifier = $1.qualifier;
+        $$.qualifier.layoutDescriptorHeap = true;
+        $$.qualifier.layoutDescriptorInnerBlock = true;
+    }
+    ;
+
+struct_declaration_without_heap
     : struct_declaration {
         $$ = $1;
     }
-    | struct_declaration_list struct_declaration {
+    | struct_declaration_without_heap struct_declaration {
         $$ = $1;
         for (unsigned int i = 0; i < $2->size(); ++i) {
             for (unsigned int j = 0; j < $$->size(); ++j) {

Dosya farkı çok büyük olduğundan ihmal edildi
+ 528 - 519
3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp


+ 309 - 306
3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp.h

@@ -231,311 +231,314 @@ extern int yydebug;
     UCOOPMATNV = 432,              /* UCOOPMATNV  */
     COOPMAT = 433,                 /* COOPMAT  */
     COOPVECNV = 434,               /* COOPVECNV  */
-    HITOBJECTNV = 435,             /* HITOBJECTNV  */
-    HITOBJECTATTRNV = 436,         /* HITOBJECTATTRNV  */
-    HITOBJECTEXT = 437,            /* HITOBJECTEXT  */
-    HITOBJECTATTREXT = 438,        /* HITOBJECTATTREXT  */
-    TENSORLAYOUTNV = 439,          /* TENSORLAYOUTNV  */
-    TENSORVIEWNV = 440,            /* TENSORVIEWNV  */
-    TENSORARM = 441,               /* TENSORARM  */
-    SAMPLERCUBEARRAY = 442,        /* SAMPLERCUBEARRAY  */
-    SAMPLERCUBEARRAYSHADOW = 443,  /* SAMPLERCUBEARRAYSHADOW  */
-    ISAMPLERCUBEARRAY = 444,       /* ISAMPLERCUBEARRAY  */
-    USAMPLERCUBEARRAY = 445,       /* USAMPLERCUBEARRAY  */
-    SAMPLER1D = 446,               /* SAMPLER1D  */
-    SAMPLER1DARRAY = 447,          /* SAMPLER1DARRAY  */
-    SAMPLER1DARRAYSHADOW = 448,    /* SAMPLER1DARRAYSHADOW  */
-    ISAMPLER1D = 449,              /* ISAMPLER1D  */
-    SAMPLER1DSHADOW = 450,         /* SAMPLER1DSHADOW  */
-    SAMPLER2DRECT = 451,           /* SAMPLER2DRECT  */
-    SAMPLER2DRECTSHADOW = 452,     /* SAMPLER2DRECTSHADOW  */
-    ISAMPLER2DRECT = 453,          /* ISAMPLER2DRECT  */
-    USAMPLER2DRECT = 454,          /* USAMPLER2DRECT  */
-    SAMPLERBUFFER = 455,           /* SAMPLERBUFFER  */
-    ISAMPLERBUFFER = 456,          /* ISAMPLERBUFFER  */
-    USAMPLERBUFFER = 457,          /* USAMPLERBUFFER  */
-    SAMPLER2DMS = 458,             /* SAMPLER2DMS  */
-    ISAMPLER2DMS = 459,            /* ISAMPLER2DMS  */
-    USAMPLER2DMS = 460,            /* USAMPLER2DMS  */
-    SAMPLER2DMSARRAY = 461,        /* SAMPLER2DMSARRAY  */
-    ISAMPLER2DMSARRAY = 462,       /* ISAMPLER2DMSARRAY  */
-    USAMPLER2DMSARRAY = 463,       /* USAMPLER2DMSARRAY  */
-    SAMPLEREXTERNALOES = 464,      /* SAMPLEREXTERNALOES  */
-    SAMPLEREXTERNAL2DY2YEXT = 465, /* SAMPLEREXTERNAL2DY2YEXT  */
-    ISAMPLER1DARRAY = 466,         /* ISAMPLER1DARRAY  */
-    USAMPLER1D = 467,              /* USAMPLER1D  */
-    USAMPLER1DARRAY = 468,         /* USAMPLER1DARRAY  */
-    F16SAMPLER1D = 469,            /* F16SAMPLER1D  */
-    F16SAMPLER2D = 470,            /* F16SAMPLER2D  */
-    F16SAMPLER3D = 471,            /* F16SAMPLER3D  */
-    F16SAMPLER2DRECT = 472,        /* F16SAMPLER2DRECT  */
-    F16SAMPLERCUBE = 473,          /* F16SAMPLERCUBE  */
-    F16SAMPLER1DARRAY = 474,       /* F16SAMPLER1DARRAY  */
-    F16SAMPLER2DARRAY = 475,       /* F16SAMPLER2DARRAY  */
-    F16SAMPLERCUBEARRAY = 476,     /* F16SAMPLERCUBEARRAY  */
-    F16SAMPLERBUFFER = 477,        /* F16SAMPLERBUFFER  */
-    F16SAMPLER2DMS = 478,          /* F16SAMPLER2DMS  */
-    F16SAMPLER2DMSARRAY = 479,     /* F16SAMPLER2DMSARRAY  */
-    F16SAMPLER1DSHADOW = 480,      /* F16SAMPLER1DSHADOW  */
-    F16SAMPLER2DSHADOW = 481,      /* F16SAMPLER2DSHADOW  */
-    F16SAMPLER1DARRAYSHADOW = 482, /* F16SAMPLER1DARRAYSHADOW  */
-    F16SAMPLER2DARRAYSHADOW = 483, /* F16SAMPLER2DARRAYSHADOW  */
-    F16SAMPLER2DRECTSHADOW = 484,  /* F16SAMPLER2DRECTSHADOW  */
-    F16SAMPLERCUBESHADOW = 485,    /* F16SAMPLERCUBESHADOW  */
-    F16SAMPLERCUBEARRAYSHADOW = 486, /* F16SAMPLERCUBEARRAYSHADOW  */
-    IMAGE1D = 487,                 /* IMAGE1D  */
-    IIMAGE1D = 488,                /* IIMAGE1D  */
-    UIMAGE1D = 489,                /* UIMAGE1D  */
-    IMAGE2D = 490,                 /* IMAGE2D  */
-    IIMAGE2D = 491,                /* IIMAGE2D  */
-    UIMAGE2D = 492,                /* UIMAGE2D  */
-    IMAGE3D = 493,                 /* IMAGE3D  */
-    IIMAGE3D = 494,                /* IIMAGE3D  */
-    UIMAGE3D = 495,                /* UIMAGE3D  */
-    IMAGE2DRECT = 496,             /* IMAGE2DRECT  */
-    IIMAGE2DRECT = 497,            /* IIMAGE2DRECT  */
-    UIMAGE2DRECT = 498,            /* UIMAGE2DRECT  */
-    IMAGECUBE = 499,               /* IMAGECUBE  */
-    IIMAGECUBE = 500,              /* IIMAGECUBE  */
-    UIMAGECUBE = 501,              /* UIMAGECUBE  */
-    IMAGEBUFFER = 502,             /* IMAGEBUFFER  */
-    IIMAGEBUFFER = 503,            /* IIMAGEBUFFER  */
-    UIMAGEBUFFER = 504,            /* UIMAGEBUFFER  */
-    IMAGE1DARRAY = 505,            /* IMAGE1DARRAY  */
-    IIMAGE1DARRAY = 506,           /* IIMAGE1DARRAY  */
-    UIMAGE1DARRAY = 507,           /* UIMAGE1DARRAY  */
-    IMAGE2DARRAY = 508,            /* IMAGE2DARRAY  */
-    IIMAGE2DARRAY = 509,           /* IIMAGE2DARRAY  */
-    UIMAGE2DARRAY = 510,           /* UIMAGE2DARRAY  */
-    IMAGECUBEARRAY = 511,          /* IMAGECUBEARRAY  */
-    IIMAGECUBEARRAY = 512,         /* IIMAGECUBEARRAY  */
-    UIMAGECUBEARRAY = 513,         /* UIMAGECUBEARRAY  */
-    IMAGE2DMS = 514,               /* IMAGE2DMS  */
-    IIMAGE2DMS = 515,              /* IIMAGE2DMS  */
-    UIMAGE2DMS = 516,              /* UIMAGE2DMS  */
-    IMAGE2DMSARRAY = 517,          /* IMAGE2DMSARRAY  */
-    IIMAGE2DMSARRAY = 518,         /* IIMAGE2DMSARRAY  */
-    UIMAGE2DMSARRAY = 519,         /* UIMAGE2DMSARRAY  */
-    F16IMAGE1D = 520,              /* F16IMAGE1D  */
-    F16IMAGE2D = 521,              /* F16IMAGE2D  */
-    F16IMAGE3D = 522,              /* F16IMAGE3D  */
-    F16IMAGE2DRECT = 523,          /* F16IMAGE2DRECT  */
-    F16IMAGECUBE = 524,            /* F16IMAGECUBE  */
-    F16IMAGE1DARRAY = 525,         /* F16IMAGE1DARRAY  */
-    F16IMAGE2DARRAY = 526,         /* F16IMAGE2DARRAY  */
-    F16IMAGECUBEARRAY = 527,       /* F16IMAGECUBEARRAY  */
-    F16IMAGEBUFFER = 528,          /* F16IMAGEBUFFER  */
-    F16IMAGE2DMS = 529,            /* F16IMAGE2DMS  */
-    F16IMAGE2DMSARRAY = 530,       /* F16IMAGE2DMSARRAY  */
-    I64IMAGE1D = 531,              /* I64IMAGE1D  */
-    U64IMAGE1D = 532,              /* U64IMAGE1D  */
-    I64IMAGE2D = 533,              /* I64IMAGE2D  */
-    U64IMAGE2D = 534,              /* U64IMAGE2D  */
-    I64IMAGE3D = 535,              /* I64IMAGE3D  */
-    U64IMAGE3D = 536,              /* U64IMAGE3D  */
-    I64IMAGE2DRECT = 537,          /* I64IMAGE2DRECT  */
-    U64IMAGE2DRECT = 538,          /* U64IMAGE2DRECT  */
-    I64IMAGECUBE = 539,            /* I64IMAGECUBE  */
-    U64IMAGECUBE = 540,            /* U64IMAGECUBE  */
-    I64IMAGEBUFFER = 541,          /* I64IMAGEBUFFER  */
-    U64IMAGEBUFFER = 542,          /* U64IMAGEBUFFER  */
-    I64IMAGE1DARRAY = 543,         /* I64IMAGE1DARRAY  */
-    U64IMAGE1DARRAY = 544,         /* U64IMAGE1DARRAY  */
-    I64IMAGE2DARRAY = 545,         /* I64IMAGE2DARRAY  */
-    U64IMAGE2DARRAY = 546,         /* U64IMAGE2DARRAY  */
-    I64IMAGECUBEARRAY = 547,       /* I64IMAGECUBEARRAY  */
-    U64IMAGECUBEARRAY = 548,       /* U64IMAGECUBEARRAY  */
-    I64IMAGE2DMS = 549,            /* I64IMAGE2DMS  */
-    U64IMAGE2DMS = 550,            /* U64IMAGE2DMS  */
-    I64IMAGE2DMSARRAY = 551,       /* I64IMAGE2DMSARRAY  */
-    U64IMAGE2DMSARRAY = 552,       /* U64IMAGE2DMSARRAY  */
-    TEXTURECUBEARRAY = 553,        /* TEXTURECUBEARRAY  */
-    ITEXTURECUBEARRAY = 554,       /* ITEXTURECUBEARRAY  */
-    UTEXTURECUBEARRAY = 555,       /* UTEXTURECUBEARRAY  */
-    TEXTURE1D = 556,               /* TEXTURE1D  */
-    ITEXTURE1D = 557,              /* ITEXTURE1D  */
-    UTEXTURE1D = 558,              /* UTEXTURE1D  */
-    TEXTURE1DARRAY = 559,          /* TEXTURE1DARRAY  */
-    ITEXTURE1DARRAY = 560,         /* ITEXTURE1DARRAY  */
-    UTEXTURE1DARRAY = 561,         /* UTEXTURE1DARRAY  */
-    TEXTURE2DRECT = 562,           /* TEXTURE2DRECT  */
-    ITEXTURE2DRECT = 563,          /* ITEXTURE2DRECT  */
-    UTEXTURE2DRECT = 564,          /* UTEXTURE2DRECT  */
-    TEXTUREBUFFER = 565,           /* TEXTUREBUFFER  */
-    ITEXTUREBUFFER = 566,          /* ITEXTUREBUFFER  */
-    UTEXTUREBUFFER = 567,          /* UTEXTUREBUFFER  */
-    TEXTURE2DMS = 568,             /* TEXTURE2DMS  */
-    ITEXTURE2DMS = 569,            /* ITEXTURE2DMS  */
-    UTEXTURE2DMS = 570,            /* UTEXTURE2DMS  */
-    TEXTURE2DMSARRAY = 571,        /* TEXTURE2DMSARRAY  */
-    ITEXTURE2DMSARRAY = 572,       /* ITEXTURE2DMSARRAY  */
-    UTEXTURE2DMSARRAY = 573,       /* UTEXTURE2DMSARRAY  */
-    F16TEXTURE1D = 574,            /* F16TEXTURE1D  */
-    F16TEXTURE2D = 575,            /* F16TEXTURE2D  */
-    F16TEXTURE3D = 576,            /* F16TEXTURE3D  */
-    F16TEXTURE2DRECT = 577,        /* F16TEXTURE2DRECT  */
-    F16TEXTURECUBE = 578,          /* F16TEXTURECUBE  */
-    F16TEXTURE1DARRAY = 579,       /* F16TEXTURE1DARRAY  */
-    F16TEXTURE2DARRAY = 580,       /* F16TEXTURE2DARRAY  */
-    F16TEXTURECUBEARRAY = 581,     /* F16TEXTURECUBEARRAY  */
-    F16TEXTUREBUFFER = 582,        /* F16TEXTUREBUFFER  */
-    F16TEXTURE2DMS = 583,          /* F16TEXTURE2DMS  */
-    F16TEXTURE2DMSARRAY = 584,     /* F16TEXTURE2DMSARRAY  */
-    SUBPASSINPUT = 585,            /* SUBPASSINPUT  */
-    SUBPASSINPUTMS = 586,          /* SUBPASSINPUTMS  */
-    ISUBPASSINPUT = 587,           /* ISUBPASSINPUT  */
-    ISUBPASSINPUTMS = 588,         /* ISUBPASSINPUTMS  */
-    USUBPASSINPUT = 589,           /* USUBPASSINPUT  */
-    USUBPASSINPUTMS = 590,         /* USUBPASSINPUTMS  */
-    F16SUBPASSINPUT = 591,         /* F16SUBPASSINPUT  */
-    F16SUBPASSINPUTMS = 592,       /* F16SUBPASSINPUTMS  */
-    SPIRV_INSTRUCTION = 593,       /* SPIRV_INSTRUCTION  */
-    SPIRV_EXECUTION_MODE = 594,    /* SPIRV_EXECUTION_MODE  */
-    SPIRV_EXECUTION_MODE_ID = 595, /* SPIRV_EXECUTION_MODE_ID  */
-    SPIRV_DECORATE = 596,          /* SPIRV_DECORATE  */
-    SPIRV_DECORATE_ID = 597,       /* SPIRV_DECORATE_ID  */
-    SPIRV_DECORATE_STRING = 598,   /* SPIRV_DECORATE_STRING  */
-    SPIRV_TYPE = 599,              /* SPIRV_TYPE  */
-    SPIRV_STORAGE_CLASS = 600,     /* SPIRV_STORAGE_CLASS  */
-    SPIRV_BY_REFERENCE = 601,      /* SPIRV_BY_REFERENCE  */
-    SPIRV_LITERAL = 602,           /* SPIRV_LITERAL  */
-    ATTACHMENTEXT = 603,           /* ATTACHMENTEXT  */
-    IATTACHMENTEXT = 604,          /* IATTACHMENTEXT  */
-    UATTACHMENTEXT = 605,          /* UATTACHMENTEXT  */
-    LEFT_OP = 606,                 /* LEFT_OP  */
-    RIGHT_OP = 607,                /* RIGHT_OP  */
-    INC_OP = 608,                  /* INC_OP  */
-    DEC_OP = 609,                  /* DEC_OP  */
-    LE_OP = 610,                   /* LE_OP  */
-    GE_OP = 611,                   /* GE_OP  */
-    EQ_OP = 612,                   /* EQ_OP  */
-    NE_OP = 613,                   /* NE_OP  */
-    AND_OP = 614,                  /* AND_OP  */
-    OR_OP = 615,                   /* OR_OP  */
-    XOR_OP = 616,                  /* XOR_OP  */
-    MUL_ASSIGN = 617,              /* MUL_ASSIGN  */
-    DIV_ASSIGN = 618,              /* DIV_ASSIGN  */
-    ADD_ASSIGN = 619,              /* ADD_ASSIGN  */
-    MOD_ASSIGN = 620,              /* MOD_ASSIGN  */
-    LEFT_ASSIGN = 621,             /* LEFT_ASSIGN  */
-    RIGHT_ASSIGN = 622,            /* RIGHT_ASSIGN  */
-    AND_ASSIGN = 623,              /* AND_ASSIGN  */
-    XOR_ASSIGN = 624,              /* XOR_ASSIGN  */
-    OR_ASSIGN = 625,               /* OR_ASSIGN  */
-    SUB_ASSIGN = 626,              /* SUB_ASSIGN  */
-    STRING_LITERAL = 627,          /* STRING_LITERAL  */
-    LEFT_PAREN = 628,              /* LEFT_PAREN  */
-    RIGHT_PAREN = 629,             /* RIGHT_PAREN  */
-    LEFT_BRACKET = 630,            /* LEFT_BRACKET  */
-    RIGHT_BRACKET = 631,           /* RIGHT_BRACKET  */
-    LEFT_BRACE = 632,              /* LEFT_BRACE  */
-    RIGHT_BRACE = 633,             /* RIGHT_BRACE  */
-    DOT = 634,                     /* DOT  */
-    COMMA = 635,                   /* COMMA  */
-    COLON = 636,                   /* COLON  */
-    EQUAL = 637,                   /* EQUAL  */
-    SEMICOLON = 638,               /* SEMICOLON  */
-    BANG = 639,                    /* BANG  */
-    DASH = 640,                    /* DASH  */
-    TILDE = 641,                   /* TILDE  */
-    PLUS = 642,                    /* PLUS  */
-    STAR = 643,                    /* STAR  */
-    SLASH = 644,                   /* SLASH  */
-    PERCENT = 645,                 /* PERCENT  */
-    LEFT_ANGLE = 646,              /* LEFT_ANGLE  */
-    RIGHT_ANGLE = 647,             /* RIGHT_ANGLE  */
-    VERTICAL_BAR = 648,            /* VERTICAL_BAR  */
-    CARET = 649,                   /* CARET  */
-    AMPERSAND = 650,               /* AMPERSAND  */
-    QUESTION = 651,                /* QUESTION  */
-    INVARIANT = 652,               /* INVARIANT  */
-    HIGH_PRECISION = 653,          /* HIGH_PRECISION  */
-    MEDIUM_PRECISION = 654,        /* MEDIUM_PRECISION  */
-    LOW_PRECISION = 655,           /* LOW_PRECISION  */
-    PRECISION = 656,               /* PRECISION  */
-    PACKED = 657,                  /* PACKED  */
-    RESOURCE = 658,                /* RESOURCE  */
-    SUPERP = 659,                  /* SUPERP  */
-    FLOATCONSTANT = 660,           /* FLOATCONSTANT  */
-    INTCONSTANT = 661,             /* INTCONSTANT  */
-    UINTCONSTANT = 662,            /* UINTCONSTANT  */
-    BOOLCONSTANT = 663,            /* BOOLCONSTANT  */
-    IDENTIFIER = 664,              /* IDENTIFIER  */
-    TYPE_NAME = 665,               /* TYPE_NAME  */
-    CENTROID = 666,                /* CENTROID  */
-    IN = 667,                      /* IN  */
-    OUT = 668,                     /* OUT  */
-    INOUT = 669,                   /* INOUT  */
-    STRUCT = 670,                  /* STRUCT  */
-    VOID = 671,                    /* VOID  */
-    WHILE = 672,                   /* WHILE  */
-    BREAK = 673,                   /* BREAK  */
-    CONTINUE = 674,                /* CONTINUE  */
-    DO = 675,                      /* DO  */
-    ELSE = 676,                    /* ELSE  */
-    FOR = 677,                     /* FOR  */
-    IF = 678,                      /* IF  */
-    DISCARD = 679,                 /* DISCARD  */
-    RETURN = 680,                  /* RETURN  */
-    SWITCH = 681,                  /* SWITCH  */
-    CASE = 682,                    /* CASE  */
-    DEFAULT = 683,                 /* DEFAULT  */
-    TERMINATE_INVOCATION = 684,    /* TERMINATE_INVOCATION  */
-    TERMINATE_RAY = 685,           /* TERMINATE_RAY  */
-    IGNORE_INTERSECTION = 686,     /* IGNORE_INTERSECTION  */
-    UNIFORM = 687,                 /* UNIFORM  */
-    SHARED = 688,                  /* SHARED  */
-    BUFFER = 689,                  /* BUFFER  */
-    TILEIMAGEEXT = 690,            /* TILEIMAGEEXT  */
-    FLAT = 691,                    /* FLAT  */
-    SMOOTH = 692,                  /* SMOOTH  */
-    LAYOUT = 693,                  /* LAYOUT  */
-    DOUBLECONSTANT = 694,          /* DOUBLECONSTANT  */
-    INT16CONSTANT = 695,           /* INT16CONSTANT  */
-    UINT16CONSTANT = 696,          /* UINT16CONSTANT  */
-    FLOAT16CONSTANT = 697,         /* FLOAT16CONSTANT  */
-    INT32CONSTANT = 698,           /* INT32CONSTANT  */
-    UINT32CONSTANT = 699,          /* UINT32CONSTANT  */
-    INT64CONSTANT = 700,           /* INT64CONSTANT  */
-    UINT64CONSTANT = 701,          /* UINT64CONSTANT  */
-    SUBROUTINE = 702,              /* SUBROUTINE  */
-    DEMOTE = 703,                  /* DEMOTE  */
-    FUNCTION = 704,                /* FUNCTION  */
-    PAYLOADNV = 705,               /* PAYLOADNV  */
-    PAYLOADINNV = 706,             /* PAYLOADINNV  */
-    HITATTRNV = 707,               /* HITATTRNV  */
-    CALLDATANV = 708,              /* CALLDATANV  */
-    CALLDATAINNV = 709,            /* CALLDATAINNV  */
-    PAYLOADEXT = 710,              /* PAYLOADEXT  */
-    PAYLOADINEXT = 711,            /* PAYLOADINEXT  */
-    HITATTREXT = 712,              /* HITATTREXT  */
-    CALLDATAEXT = 713,             /* CALLDATAEXT  */
-    CALLDATAINEXT = 714,           /* CALLDATAINEXT  */
-    PATCH = 715,                   /* PATCH  */
-    SAMPLE = 716,                  /* SAMPLE  */
-    NONUNIFORM = 717,              /* NONUNIFORM  */
-    COHERENT = 718,                /* COHERENT  */
-    VOLATILE = 719,                /* VOLATILE  */
-    RESTRICT = 720,                /* RESTRICT  */
-    READONLY = 721,                /* READONLY  */
-    WRITEONLY = 722,               /* WRITEONLY  */
-    NONTEMPORAL = 723,             /* NONTEMPORAL  */
-    DEVICECOHERENT = 724,          /* DEVICECOHERENT  */
-    QUEUEFAMILYCOHERENT = 725,     /* QUEUEFAMILYCOHERENT  */
-    WORKGROUPCOHERENT = 726,       /* WORKGROUPCOHERENT  */
-    SUBGROUPCOHERENT = 727,        /* SUBGROUPCOHERENT  */
-    NONPRIVATE = 728,              /* NONPRIVATE  */
-    SHADERCALLCOHERENT = 729,      /* SHADERCALLCOHERENT  */
-    NOPERSPECTIVE = 730,           /* NOPERSPECTIVE  */
-    EXPLICITINTERPAMD = 731,       /* EXPLICITINTERPAMD  */
-    PERVERTEXEXT = 732,            /* PERVERTEXEXT  */
-    PERVERTEXNV = 733,             /* PERVERTEXNV  */
-    PERPRIMITIVENV = 734,          /* PERPRIMITIVENV  */
-    PERVIEWNV = 735,               /* PERVIEWNV  */
-    PERTASKNV = 736,               /* PERTASKNV  */
-    PERPRIMITIVEEXT = 737,         /* PERPRIMITIVEEXT  */
-    TASKPAYLOADWORKGROUPEXT = 738, /* TASKPAYLOADWORKGROUPEXT  */
-    PRECISE = 739                  /* PRECISE  */
+    VECTOR = 435,                  /* VECTOR  */
+    HITOBJECTNV = 436,             /* HITOBJECTNV  */
+    HITOBJECTATTRNV = 437,         /* HITOBJECTATTRNV  */
+    HITOBJECTEXT = 438,            /* HITOBJECTEXT  */
+    HITOBJECTATTREXT = 439,        /* HITOBJECTATTREXT  */
+    TENSORLAYOUTNV = 440,          /* TENSORLAYOUTNV  */
+    TENSORVIEWNV = 441,            /* TENSORVIEWNV  */
+    TENSORARM = 442,               /* TENSORARM  */
+    SAMPLERCUBEARRAY = 443,        /* SAMPLERCUBEARRAY  */
+    SAMPLERCUBEARRAYSHADOW = 444,  /* SAMPLERCUBEARRAYSHADOW  */
+    ISAMPLERCUBEARRAY = 445,       /* ISAMPLERCUBEARRAY  */
+    USAMPLERCUBEARRAY = 446,       /* USAMPLERCUBEARRAY  */
+    SAMPLER1D = 447,               /* SAMPLER1D  */
+    SAMPLER1DARRAY = 448,          /* SAMPLER1DARRAY  */
+    SAMPLER1DARRAYSHADOW = 449,    /* SAMPLER1DARRAYSHADOW  */
+    ISAMPLER1D = 450,              /* ISAMPLER1D  */
+    SAMPLER1DSHADOW = 451,         /* SAMPLER1DSHADOW  */
+    SAMPLER2DRECT = 452,           /* SAMPLER2DRECT  */
+    SAMPLER2DRECTSHADOW = 453,     /* SAMPLER2DRECTSHADOW  */
+    ISAMPLER2DRECT = 454,          /* ISAMPLER2DRECT  */
+    USAMPLER2DRECT = 455,          /* USAMPLER2DRECT  */
+    SAMPLERBUFFER = 456,           /* SAMPLERBUFFER  */
+    ISAMPLERBUFFER = 457,          /* ISAMPLERBUFFER  */
+    USAMPLERBUFFER = 458,          /* USAMPLERBUFFER  */
+    SAMPLER2DMS = 459,             /* SAMPLER2DMS  */
+    ISAMPLER2DMS = 460,            /* ISAMPLER2DMS  */
+    USAMPLER2DMS = 461,            /* USAMPLER2DMS  */
+    SAMPLER2DMSARRAY = 462,        /* SAMPLER2DMSARRAY  */
+    ISAMPLER2DMSARRAY = 463,       /* ISAMPLER2DMSARRAY  */
+    USAMPLER2DMSARRAY = 464,       /* USAMPLER2DMSARRAY  */
+    SAMPLEREXTERNALOES = 465,      /* SAMPLEREXTERNALOES  */
+    SAMPLEREXTERNAL2DY2YEXT = 466, /* SAMPLEREXTERNAL2DY2YEXT  */
+    ISAMPLER1DARRAY = 467,         /* ISAMPLER1DARRAY  */
+    USAMPLER1D = 468,              /* USAMPLER1D  */
+    USAMPLER1DARRAY = 469,         /* USAMPLER1DARRAY  */
+    F16SAMPLER1D = 470,            /* F16SAMPLER1D  */
+    F16SAMPLER2D = 471,            /* F16SAMPLER2D  */
+    F16SAMPLER3D = 472,            /* F16SAMPLER3D  */
+    F16SAMPLER2DRECT = 473,        /* F16SAMPLER2DRECT  */
+    F16SAMPLERCUBE = 474,          /* F16SAMPLERCUBE  */
+    F16SAMPLER1DARRAY = 475,       /* F16SAMPLER1DARRAY  */
+    F16SAMPLER2DARRAY = 476,       /* F16SAMPLER2DARRAY  */
+    F16SAMPLERCUBEARRAY = 477,     /* F16SAMPLERCUBEARRAY  */
+    F16SAMPLERBUFFER = 478,        /* F16SAMPLERBUFFER  */
+    F16SAMPLER2DMS = 479,          /* F16SAMPLER2DMS  */
+    F16SAMPLER2DMSARRAY = 480,     /* F16SAMPLER2DMSARRAY  */
+    F16SAMPLER1DSHADOW = 481,      /* F16SAMPLER1DSHADOW  */
+    F16SAMPLER2DSHADOW = 482,      /* F16SAMPLER2DSHADOW  */
+    F16SAMPLER1DARRAYSHADOW = 483, /* F16SAMPLER1DARRAYSHADOW  */
+    F16SAMPLER2DARRAYSHADOW = 484, /* F16SAMPLER2DARRAYSHADOW  */
+    F16SAMPLER2DRECTSHADOW = 485,  /* F16SAMPLER2DRECTSHADOW  */
+    F16SAMPLERCUBESHADOW = 486,    /* F16SAMPLERCUBESHADOW  */
+    F16SAMPLERCUBEARRAYSHADOW = 487, /* F16SAMPLERCUBEARRAYSHADOW  */
+    IMAGE1D = 488,                 /* IMAGE1D  */
+    IIMAGE1D = 489,                /* IIMAGE1D  */
+    UIMAGE1D = 490,                /* UIMAGE1D  */
+    IMAGE2D = 491,                 /* IMAGE2D  */
+    IIMAGE2D = 492,                /* IIMAGE2D  */
+    UIMAGE2D = 493,                /* UIMAGE2D  */
+    IMAGE3D = 494,                 /* IMAGE3D  */
+    IIMAGE3D = 495,                /* IIMAGE3D  */
+    UIMAGE3D = 496,                /* UIMAGE3D  */
+    IMAGE2DRECT = 497,             /* IMAGE2DRECT  */
+    IIMAGE2DRECT = 498,            /* IIMAGE2DRECT  */
+    UIMAGE2DRECT = 499,            /* UIMAGE2DRECT  */
+    IMAGECUBE = 500,               /* IMAGECUBE  */
+    IIMAGECUBE = 501,              /* IIMAGECUBE  */
+    UIMAGECUBE = 502,              /* UIMAGECUBE  */
+    IMAGEBUFFER = 503,             /* IMAGEBUFFER  */
+    IIMAGEBUFFER = 504,            /* IIMAGEBUFFER  */
+    UIMAGEBUFFER = 505,            /* UIMAGEBUFFER  */
+    IMAGE1DARRAY = 506,            /* IMAGE1DARRAY  */
+    IIMAGE1DARRAY = 507,           /* IIMAGE1DARRAY  */
+    UIMAGE1DARRAY = 508,           /* UIMAGE1DARRAY  */
+    IMAGE2DARRAY = 509,            /* IMAGE2DARRAY  */
+    IIMAGE2DARRAY = 510,           /* IIMAGE2DARRAY  */
+    UIMAGE2DARRAY = 511,           /* UIMAGE2DARRAY  */
+    IMAGECUBEARRAY = 512,          /* IMAGECUBEARRAY  */
+    IIMAGECUBEARRAY = 513,         /* IIMAGECUBEARRAY  */
+    UIMAGECUBEARRAY = 514,         /* UIMAGECUBEARRAY  */
+    IMAGE2DMS = 515,               /* IMAGE2DMS  */
+    IIMAGE2DMS = 516,              /* IIMAGE2DMS  */
+    UIMAGE2DMS = 517,              /* UIMAGE2DMS  */
+    IMAGE2DMSARRAY = 518,          /* IMAGE2DMSARRAY  */
+    IIMAGE2DMSARRAY = 519,         /* IIMAGE2DMSARRAY  */
+    UIMAGE2DMSARRAY = 520,         /* UIMAGE2DMSARRAY  */
+    F16IMAGE1D = 521,              /* F16IMAGE1D  */
+    F16IMAGE2D = 522,              /* F16IMAGE2D  */
+    F16IMAGE3D = 523,              /* F16IMAGE3D  */
+    F16IMAGE2DRECT = 524,          /* F16IMAGE2DRECT  */
+    F16IMAGECUBE = 525,            /* F16IMAGECUBE  */
+    F16IMAGE1DARRAY = 526,         /* F16IMAGE1DARRAY  */
+    F16IMAGE2DARRAY = 527,         /* F16IMAGE2DARRAY  */
+    F16IMAGECUBEARRAY = 528,       /* F16IMAGECUBEARRAY  */
+    F16IMAGEBUFFER = 529,          /* F16IMAGEBUFFER  */
+    F16IMAGE2DMS = 530,            /* F16IMAGE2DMS  */
+    F16IMAGE2DMSARRAY = 531,       /* F16IMAGE2DMSARRAY  */
+    I64IMAGE1D = 532,              /* I64IMAGE1D  */
+    U64IMAGE1D = 533,              /* U64IMAGE1D  */
+    I64IMAGE2D = 534,              /* I64IMAGE2D  */
+    U64IMAGE2D = 535,              /* U64IMAGE2D  */
+    I64IMAGE3D = 536,              /* I64IMAGE3D  */
+    U64IMAGE3D = 537,              /* U64IMAGE3D  */
+    I64IMAGE2DRECT = 538,          /* I64IMAGE2DRECT  */
+    U64IMAGE2DRECT = 539,          /* U64IMAGE2DRECT  */
+    I64IMAGECUBE = 540,            /* I64IMAGECUBE  */
+    U64IMAGECUBE = 541,            /* U64IMAGECUBE  */
+    I64IMAGEBUFFER = 542,          /* I64IMAGEBUFFER  */
+    U64IMAGEBUFFER = 543,          /* U64IMAGEBUFFER  */
+    I64IMAGE1DARRAY = 544,         /* I64IMAGE1DARRAY  */
+    U64IMAGE1DARRAY = 545,         /* U64IMAGE1DARRAY  */
+    I64IMAGE2DARRAY = 546,         /* I64IMAGE2DARRAY  */
+    U64IMAGE2DARRAY = 547,         /* U64IMAGE2DARRAY  */
+    I64IMAGECUBEARRAY = 548,       /* I64IMAGECUBEARRAY  */
+    U64IMAGECUBEARRAY = 549,       /* U64IMAGECUBEARRAY  */
+    I64IMAGE2DMS = 550,            /* I64IMAGE2DMS  */
+    U64IMAGE2DMS = 551,            /* U64IMAGE2DMS  */
+    I64IMAGE2DMSARRAY = 552,       /* I64IMAGE2DMSARRAY  */
+    U64IMAGE2DMSARRAY = 553,       /* U64IMAGE2DMSARRAY  */
+    TEXTURECUBEARRAY = 554,        /* TEXTURECUBEARRAY  */
+    ITEXTURECUBEARRAY = 555,       /* ITEXTURECUBEARRAY  */
+    UTEXTURECUBEARRAY = 556,       /* UTEXTURECUBEARRAY  */
+    TEXTURE1D = 557,               /* TEXTURE1D  */
+    ITEXTURE1D = 558,              /* ITEXTURE1D  */
+    UTEXTURE1D = 559,              /* UTEXTURE1D  */
+    TEXTURE1DARRAY = 560,          /* TEXTURE1DARRAY  */
+    ITEXTURE1DARRAY = 561,         /* ITEXTURE1DARRAY  */
+    UTEXTURE1DARRAY = 562,         /* UTEXTURE1DARRAY  */
+    TEXTURE2DRECT = 563,           /* TEXTURE2DRECT  */
+    ITEXTURE2DRECT = 564,          /* ITEXTURE2DRECT  */
+    UTEXTURE2DRECT = 565,          /* UTEXTURE2DRECT  */
+    TEXTUREBUFFER = 566,           /* TEXTUREBUFFER  */
+    ITEXTUREBUFFER = 567,          /* ITEXTUREBUFFER  */
+    UTEXTUREBUFFER = 568,          /* UTEXTUREBUFFER  */
+    TEXTURE2DMS = 569,             /* TEXTURE2DMS  */
+    ITEXTURE2DMS = 570,            /* ITEXTURE2DMS  */
+    UTEXTURE2DMS = 571,            /* UTEXTURE2DMS  */
+    TEXTURE2DMSARRAY = 572,        /* TEXTURE2DMSARRAY  */
+    ITEXTURE2DMSARRAY = 573,       /* ITEXTURE2DMSARRAY  */
+    UTEXTURE2DMSARRAY = 574,       /* UTEXTURE2DMSARRAY  */
+    F16TEXTURE1D = 575,            /* F16TEXTURE1D  */
+    F16TEXTURE2D = 576,            /* F16TEXTURE2D  */
+    F16TEXTURE3D = 577,            /* F16TEXTURE3D  */
+    F16TEXTURE2DRECT = 578,        /* F16TEXTURE2DRECT  */
+    F16TEXTURECUBE = 579,          /* F16TEXTURECUBE  */
+    F16TEXTURE1DARRAY = 580,       /* F16TEXTURE1DARRAY  */
+    F16TEXTURE2DARRAY = 581,       /* F16TEXTURE2DARRAY  */
+    F16TEXTURECUBEARRAY = 582,     /* F16TEXTURECUBEARRAY  */
+    F16TEXTUREBUFFER = 583,        /* F16TEXTUREBUFFER  */
+    F16TEXTURE2DMS = 584,          /* F16TEXTURE2DMS  */
+    F16TEXTURE2DMSARRAY = 585,     /* F16TEXTURE2DMSARRAY  */
+    SUBPASSINPUT = 586,            /* SUBPASSINPUT  */
+    SUBPASSINPUTMS = 587,          /* SUBPASSINPUTMS  */
+    ISUBPASSINPUT = 588,           /* ISUBPASSINPUT  */
+    ISUBPASSINPUTMS = 589,         /* ISUBPASSINPUTMS  */
+    USUBPASSINPUT = 590,           /* USUBPASSINPUT  */
+    USUBPASSINPUTMS = 591,         /* USUBPASSINPUTMS  */
+    F16SUBPASSINPUT = 592,         /* F16SUBPASSINPUT  */
+    F16SUBPASSINPUTMS = 593,       /* F16SUBPASSINPUTMS  */
+    SPIRV_INSTRUCTION = 594,       /* SPIRV_INSTRUCTION  */
+    SPIRV_EXECUTION_MODE = 595,    /* SPIRV_EXECUTION_MODE  */
+    SPIRV_EXECUTION_MODE_ID = 596, /* SPIRV_EXECUTION_MODE_ID  */
+    SPIRV_DECORATE = 597,          /* SPIRV_DECORATE  */
+    SPIRV_DECORATE_ID = 598,       /* SPIRV_DECORATE_ID  */
+    SPIRV_DECORATE_STRING = 599,   /* SPIRV_DECORATE_STRING  */
+    SPIRV_TYPE = 600,              /* SPIRV_TYPE  */
+    SPIRV_STORAGE_CLASS = 601,     /* SPIRV_STORAGE_CLASS  */
+    SPIRV_BY_REFERENCE = 602,      /* SPIRV_BY_REFERENCE  */
+    SPIRV_LITERAL = 603,           /* SPIRV_LITERAL  */
+    ATTACHMENTEXT = 604,           /* ATTACHMENTEXT  */
+    IATTACHMENTEXT = 605,          /* IATTACHMENTEXT  */
+    UATTACHMENTEXT = 606,          /* UATTACHMENTEXT  */
+    LEFT_OP = 607,                 /* LEFT_OP  */
+    RIGHT_OP = 608,                /* RIGHT_OP  */
+    INC_OP = 609,                  /* INC_OP  */
+    DEC_OP = 610,                  /* DEC_OP  */
+    LE_OP = 611,                   /* LE_OP  */
+    GE_OP = 612,                   /* GE_OP  */
+    EQ_OP = 613,                   /* EQ_OP  */
+    NE_OP = 614,                   /* NE_OP  */
+    AND_OP = 615,                  /* AND_OP  */
+    OR_OP = 616,                   /* OR_OP  */
+    XOR_OP = 617,                  /* XOR_OP  */
+    MUL_ASSIGN = 618,              /* MUL_ASSIGN  */
+    DIV_ASSIGN = 619,              /* DIV_ASSIGN  */
+    ADD_ASSIGN = 620,              /* ADD_ASSIGN  */
+    MOD_ASSIGN = 621,              /* MOD_ASSIGN  */
+    LEFT_ASSIGN = 622,             /* LEFT_ASSIGN  */
+    RIGHT_ASSIGN = 623,            /* RIGHT_ASSIGN  */
+    AND_ASSIGN = 624,              /* AND_ASSIGN  */
+    XOR_ASSIGN = 625,              /* XOR_ASSIGN  */
+    OR_ASSIGN = 626,               /* OR_ASSIGN  */
+    SUB_ASSIGN = 627,              /* SUB_ASSIGN  */
+    STRING_LITERAL = 628,          /* STRING_LITERAL  */
+    LEFT_PAREN = 629,              /* LEFT_PAREN  */
+    RIGHT_PAREN = 630,             /* RIGHT_PAREN  */
+    LEFT_BRACKET = 631,            /* LEFT_BRACKET  */
+    RIGHT_BRACKET = 632,           /* RIGHT_BRACKET  */
+    LEFT_BRACE = 633,              /* LEFT_BRACE  */
+    RIGHT_BRACE = 634,             /* RIGHT_BRACE  */
+    DOT = 635,                     /* DOT  */
+    COMMA = 636,                   /* COMMA  */
+    COLON = 637,                   /* COLON  */
+    EQUAL = 638,                   /* EQUAL  */
+    SEMICOLON = 639,               /* SEMICOLON  */
+    BANG = 640,                    /* BANG  */
+    DASH = 641,                    /* DASH  */
+    TILDE = 642,                   /* TILDE  */
+    PLUS = 643,                    /* PLUS  */
+    STAR = 644,                    /* STAR  */
+    SLASH = 645,                   /* SLASH  */
+    PERCENT = 646,                 /* PERCENT  */
+    LEFT_ANGLE = 647,              /* LEFT_ANGLE  */
+    RIGHT_ANGLE = 648,             /* RIGHT_ANGLE  */
+    VERTICAL_BAR = 649,            /* VERTICAL_BAR  */
+    CARET = 650,                   /* CARET  */
+    AMPERSAND = 651,               /* AMPERSAND  */
+    QUESTION = 652,                /* QUESTION  */
+    INVARIANT = 653,               /* INVARIANT  */
+    HIGH_PRECISION = 654,          /* HIGH_PRECISION  */
+    MEDIUM_PRECISION = 655,        /* MEDIUM_PRECISION  */
+    LOW_PRECISION = 656,           /* LOW_PRECISION  */
+    PRECISION = 657,               /* PRECISION  */
+    PACKED = 658,                  /* PACKED  */
+    RESOURCE = 659,                /* RESOURCE  */
+    SUPERP = 660,                  /* SUPERP  */
+    FLOATCONSTANT = 661,           /* FLOATCONSTANT  */
+    INTCONSTANT = 662,             /* INTCONSTANT  */
+    UINTCONSTANT = 663,            /* UINTCONSTANT  */
+    BOOLCONSTANT = 664,            /* BOOLCONSTANT  */
+    IDENTIFIER = 665,              /* IDENTIFIER  */
+    TYPE_NAME = 666,               /* TYPE_NAME  */
+    CENTROID = 667,                /* CENTROID  */
+    IN = 668,                      /* IN  */
+    OUT = 669,                     /* OUT  */
+    INOUT = 670,                   /* INOUT  */
+    STRUCT = 671,                  /* STRUCT  */
+    VOID = 672,                    /* VOID  */
+    WHILE = 673,                   /* WHILE  */
+    BREAK = 674,                   /* BREAK  */
+    CONTINUE = 675,                /* CONTINUE  */
+    DO = 676,                      /* DO  */
+    ELSE = 677,                    /* ELSE  */
+    FOR = 678,                     /* FOR  */
+    IF = 679,                      /* IF  */
+    DISCARD = 680,                 /* DISCARD  */
+    RETURN = 681,                  /* RETURN  */
+    SWITCH = 682,                  /* SWITCH  */
+    CASE = 683,                    /* CASE  */
+    DEFAULT = 684,                 /* DEFAULT  */
+    TERMINATE_INVOCATION = 685,    /* TERMINATE_INVOCATION  */
+    TERMINATE_RAY = 686,           /* TERMINATE_RAY  */
+    IGNORE_INTERSECTION = 687,     /* IGNORE_INTERSECTION  */
+    UNIFORM = 688,                 /* UNIFORM  */
+    SHARED = 689,                  /* SHARED  */
+    BUFFER = 690,                  /* BUFFER  */
+    TILEIMAGEEXT = 691,            /* TILEIMAGEEXT  */
+    FLAT = 692,                    /* FLAT  */
+    SMOOTH = 693,                  /* SMOOTH  */
+    LAYOUT = 694,                  /* LAYOUT  */
+    DOUBLECONSTANT = 695,          /* DOUBLECONSTANT  */
+    INT16CONSTANT = 696,           /* INT16CONSTANT  */
+    UINT16CONSTANT = 697,          /* UINT16CONSTANT  */
+    FLOAT16CONSTANT = 698,         /* FLOAT16CONSTANT  */
+    INT32CONSTANT = 699,           /* INT32CONSTANT  */
+    UINT32CONSTANT = 700,          /* UINT32CONSTANT  */
+    INT64CONSTANT = 701,           /* INT64CONSTANT  */
+    UINT64CONSTANT = 702,          /* UINT64CONSTANT  */
+    SUBROUTINE = 703,              /* SUBROUTINE  */
+    DEMOTE = 704,                  /* DEMOTE  */
+    FUNCTION = 705,                /* FUNCTION  */
+    PAYLOADNV = 706,               /* PAYLOADNV  */
+    PAYLOADINNV = 707,             /* PAYLOADINNV  */
+    HITATTRNV = 708,               /* HITATTRNV  */
+    CALLDATANV = 709,              /* CALLDATANV  */
+    CALLDATAINNV = 710,            /* CALLDATAINNV  */
+    PAYLOADEXT = 711,              /* PAYLOADEXT  */
+    PAYLOADINEXT = 712,            /* PAYLOADINEXT  */
+    HITATTREXT = 713,              /* HITATTREXT  */
+    CALLDATAEXT = 714,             /* CALLDATAEXT  */
+    CALLDATAINEXT = 715,           /* CALLDATAINEXT  */
+    PATCH = 716,                   /* PATCH  */
+    SAMPLE = 717,                  /* SAMPLE  */
+    NONUNIFORM = 718,              /* NONUNIFORM  */
+    RESOURCEHEAP = 719,            /* RESOURCEHEAP  */
+    SAMPLERHEAP = 720,             /* SAMPLERHEAP  */
+    COHERENT = 721,                /* COHERENT  */
+    VOLATILE = 722,                /* VOLATILE  */
+    RESTRICT = 723,                /* RESTRICT  */
+    READONLY = 724,                /* READONLY  */
+    WRITEONLY = 725,               /* WRITEONLY  */
+    NONTEMPORAL = 726,             /* NONTEMPORAL  */
+    DEVICECOHERENT = 727,          /* DEVICECOHERENT  */
+    QUEUEFAMILYCOHERENT = 728,     /* QUEUEFAMILYCOHERENT  */
+    WORKGROUPCOHERENT = 729,       /* WORKGROUPCOHERENT  */
+    SUBGROUPCOHERENT = 730,        /* SUBGROUPCOHERENT  */
+    NONPRIVATE = 731,              /* NONPRIVATE  */
+    SHADERCALLCOHERENT = 732,      /* SHADERCALLCOHERENT  */
+    NOPERSPECTIVE = 733,           /* NOPERSPECTIVE  */
+    EXPLICITINTERPAMD = 734,       /* EXPLICITINTERPAMD  */
+    PERVERTEXEXT = 735,            /* PERVERTEXEXT  */
+    PERVERTEXNV = 736,             /* PERVERTEXNV  */
+    PERPRIMITIVENV = 737,          /* PERPRIMITIVENV  */
+    PERVIEWNV = 738,               /* PERVIEWNV  */
+    PERTASKNV = 739,               /* PERTASKNV  */
+    PERPRIMITIVEEXT = 740,         /* PERPRIMITIVEEXT  */
+    TASKPAYLOADWORKGROUPEXT = 741, /* TASKPAYLOADWORKGROUPEXT  */
+    PRECISE = 742                  /* PRECISE  */
   };
   typedef enum yytokentype yytoken_kind_t;
 #endif
@@ -583,7 +586,7 @@ union YYSTYPE
         glslang::TTypeParameters* typeParameters;
     } interm;
 
-#line 587 "MachineIndependent/glslang_tab.cpp.h"
+#line 590 "MachineIndependent/glslang_tab.cpp.h"
 
 };
 typedef union YYSTYPE YYSTYPE;

+ 39 - 39
3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp

@@ -888,38 +888,38 @@ bool TDefaultIoResolverBase::doAutoBindingMapping() const { return referenceInte
 
 bool TDefaultIoResolverBase::doAutoLocationMapping() const { return referenceIntermediate.getAutoMapLocations(); }
 
-TDefaultIoResolverBase::TSlotSet::iterator TDefaultIoResolverBase::findSlot(int set, int slot) {
-    return std::lower_bound(slots[set].begin(), slots[set].end(), slot);
+TDefaultIoResolverBase::TSlotSet::iterator TDefaultIoResolverBase::findSlot(int resource, int set, int slot) {
+    return std::lower_bound(slots[resource][set].begin(), slots[resource][set].end(), slot);
 }
 
-bool TDefaultIoResolverBase::checkEmpty(int set, int slot) {
-    TSlotSet::iterator at = findSlot(set, slot);
-    return ! (at != slots[set].end() && *at == slot);
+bool TDefaultIoResolverBase::checkEmpty(int resource, int set, int slot) {
+    TSlotSet::iterator at = findSlot(resource, set, slot);
+    return ! (at != slots[resource][set].end() && *at == slot);
 }
 
-int TDefaultIoResolverBase::reserveSlot(int set, int slot, int size) {
-    TSlotSet::iterator at = findSlot(set, slot);
+int TDefaultIoResolverBase::reserveSlot(int resource, int set, int slot, int size) {
+    TSlotSet::iterator at = findSlot(resource, set, slot);
     // tolerate aliasing, by not double-recording aliases
     // (policy about appropriateness of the alias is higher up)
     for (int i = 0; i < size; i++) {
-        if (at == slots[set].end() || *at != slot + i)
-            at = slots[set].insert(at, slot + i);
+        if (at == slots[resource][set].end() || *at != slot + i)
+            at = slots[resource][set].insert(at, slot + i);
         ++at;
     }
     return slot;
 }
 
-int TDefaultIoResolverBase::getFreeSlot(int set, int base, int size) {
-    TSlotSet::iterator at = findSlot(set, base);
-    if (at == slots[set].end())
-        return reserveSlot(set, base, size);
+int TDefaultIoResolverBase::getFreeSlot(int resource, int set, int base, int size) {
+    TSlotSet::iterator at = findSlot(resource, set, base);
+    if (at == slots[resource][set].end())
+        return reserveSlot(resource, set, base, size);
     // look for a big enough gap
-    for (; at != slots[set].end(); ++at) {
+    for (; at != slots[resource][set].end(); ++at) {
         if (*at - base >= size)
             break;
         base = *at + 1;
     }
-    return reserveSlot(set, base, size);
+    return reserveSlot(resource, set, base, size);
 }
 
 int TDefaultIoResolverBase::resolveSet(EShLanguage stage, TVarEntryInfo& ent) {
@@ -1123,13 +1123,13 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf
             //
             // vs: out vec4 a;
             // fs: in vec4 a;
-            location = getFreeSlot(resourceKey, 0, typeLocationSize);
+            location = getFreeSlot(0, resourceKey, 0, typeLocationSize);
             storageSlotMap[resourceKey][name] = location;
         }
     } else {
         // the first interface declarated in a program.
         TVarSlotMap varSlotMap;
-        location = getFreeSlot(resourceKey, 0, typeLocationSize);
+        location = getFreeSlot(0, resourceKey, 0, typeLocationSize);
         varSlotMap[name] = location;
         storageSlotMap[resourceKey] = varSlotMap;
     }
@@ -1196,13 +1196,13 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
             //
             // vs:    uniform vec4 a;
             // fs:    uniform vec4 a;
-            location = getFreeSlot(resourceKey, 0, computeTypeLocationSize(type, currentStage));
+            location = getFreeSlot(0, resourceKey, 0, computeTypeLocationSize(type, currentStage));
             storageSlotMap[resourceKey][name] = location;
         }
     } else {
         // the first uniform declaration in a program.
         TVarSlotMap varSlotMap;
-        location = getFreeSlot(resourceKey, 0, size);
+        location = getFreeSlot(0, resourceKey, 0, size);
         varSlotMap[name] = location;
         storageSlotMap[resourceKey] = varSlotMap;
     }
@@ -1222,13 +1222,12 @@ int TDefaultGlslIoResolver::resolveBinding(EShLanguage stage, TVarEntryInfo& ent
     // 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 = referenceIntermediate.getSpv().openGl != 0 ? resource : ent.newSet;
-    int resourceKey = set;
+    int set = referenceIntermediate.getSpv().openGl != 0 ? 0 : ent.newSet;
+    int resourceKey = referenceIntermediate.getSpv().openGl != 0 || referenceIntermediate.getBindingsPerResourceType() ? resource : 0;
     if (resource < EResCount) {
         if (type.getQualifier().hasBinding()) {
-            int newBinding = reserveSlot(resourceKey, getBaseBinding(stage, resource, set) + type.getQualifier().layoutBinding, numBindings);
+            int newBinding = reserveSlot(resourceKey, set, 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
@@ -1236,9 +1235,9 @@ int TDefaultGlslIoResolver::resolveBinding(EShLanguage stage, TVarEntryInfo& ent
             bool hasBinding = false;
             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()) {
+            if (! resourceSlotMap[resourceKey][set].empty()) {
+                TVarSlotMap::iterator iter = resourceSlotMap[resourceKey][set].find(name);
+                if (iter != resourceSlotMap[resourceKey][set].end()) {
                     hasBinding = true;
                     ent.newBinding = iter->second;
                 }
@@ -1246,8 +1245,8 @@ int TDefaultGlslIoResolver::resolveBinding(EShLanguage stage, TVarEntryInfo& ent
             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(resourceKey, getBaseBinding(stage, resource, set), numBindings);
-                resourceSlotMap[resourceKey][name] = binding;
+                int binding = getFreeSlot(resourceKey, set, getBaseBinding(stage, resource, set), numBindings);
+                resourceSlotMap[resourceKey][set][name] = binding;
                 ent.newBinding = binding;
             }
             return ent.newBinding;
@@ -1302,7 +1301,7 @@ void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink&
             TVarSlotMap::iterator iter = varSlotMap.find(name);
             if (iter == varSlotMap.end()) {
                 int numLocations = TIntermediate::computeTypeUniformLocationSize(type);
-                reserveSlot(storageKey, location, numLocations);
+                reserveSlot(0, storageKey, location, numLocations);
                 varSlotMap[name] = location;
             } else {
                 // Allocate location by name for OpenGL driver, so the uniform in different
@@ -1328,7 +1327,7 @@ void TDefaultGlslIoResolver::reserverStorageSlot(TVarEntryInfo& ent, TInfoSink&
             TVarSlotMap::iterator iter = varSlotMap.find(name);
             if (iter == varSlotMap.end()) {
                 int numLocations = TIntermediate::computeTypeUniformLocationSize(type);
-                reserveSlot(storageKey, location, numLocations);
+                reserveSlot(0, storageKey, location, numLocations);
                 varSlotMap[name] = location;
             } else {
                 // Allocate location by name for OpenGL driver, so the uniform in different
@@ -1350,19 +1349,18 @@ void TDefaultGlslIoResolver::reserverResourceSlot(TVarEntryInfo& ent, TInfoSink&
     const TType& type = ent.symbol->getType();
     const TString& name = ent.symbol->getAccessName();
     TResourceType resource = getResourceType(type);
-    int set = referenceIntermediate.getSpv().openGl != 0 ? resource : resolveSet(ent.stage, ent);
-    int resourceKey = set;
+    int set = referenceIntermediate.getSpv().openGl != 0 ? 0 : resolveSet(ent.stage, ent);
+    int resourceKey = referenceIntermediate.getSpv().openGl != 0 || referenceIntermediate.getBindingsPerResourceType() ? resource : 0;
 
     if (type.getQualifier().hasBinding()) {
-        TVarSlotMap& varSlotMap = resourceSlotMap[resourceKey];
+        TVarSlotMap& varSlotMap = resourceSlotMap[resourceKey][set];
         TVarSlotMap::iterator iter = varSlotMap.find(name);
         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 = referenceIntermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
             varSlotMap[name] = binding;
-            reserveSlot(resourceKey, binding, numBindings);
+            reserveSlot(resourceKey, set, binding, numBindings);
         } else {
             // Allocate binding by name for OpenGL driver, so the resource in different
             // stages should be declared with the same binding
@@ -1427,14 +1425,15 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase {
         // On OpenGL arrays of opaque types take a seperate binding for each element
         int numBindings = referenceIntermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
         TResourceType resource = getResourceType(type);
+        int resourceKey = referenceIntermediate.getBindingsPerResourceType() ? resource : 0;
         if (resource < EResCount) {
             if (type.getQualifier().hasBinding()) {
                 return ent.newBinding = reserveSlot(
-                           set, getBaseBinding(stage, resource, set) + type.getQualifier().layoutBinding, numBindings);
+                           resourceKey, 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(stage, resource, set), numBindings);
+                return ent.newBinding = getFreeSlot(resourceKey, set, getBaseBinding(stage, resource, set), numBindings);
             }
         }
         return ent.newBinding = -1;
@@ -1515,13 +1514,14 @@ struct TDefaultHlslIoResolver : public TDefaultIoResolverBase {
         const TType& type = ent.symbol->getType();
         const int set = getLayoutSet(type);
         TResourceType resource = getResourceType(type);
+        int resourceKey = referenceIntermediate.getBindingsPerResourceType() ? resource : 0;
         if (resource < EResCount) {
             if (type.getQualifier().hasBinding()) {
-                return ent.newBinding = reserveSlot(set, getBaseBinding(stage, resource, set) + type.getQualifier().layoutBinding);
+                return ent.newBinding = reserveSlot(resourceKey, 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(stage, resource, set));
+                return ent.newBinding = getFreeSlot(resourceKey, set, getBaseBinding(stage, resource, set));
             }
         }
         return ent.newBinding = -1;

+ 9 - 6
3rdparty/glslang/glslang/MachineIndependent/iomapper.h

@@ -37,6 +37,7 @@
 #define _IOMAPPER_INCLUDED
 
 #include <cstdint>
+#include <array>
 #include <unordered_map>
 #include <unordered_set>
 //
@@ -55,6 +56,7 @@ public:
     TDefaultIoResolverBase(const TIntermediate& intermediate);
     typedef std::vector<int> TSlotSet;
     typedef std::unordered_map<int, TSlotSet> TSlotSetMap;
+    typedef std::array<TSlotSetMap, EResCount> TSlotSetMapResourceArray;
 
     // grow the reflection stage by stage
     void notifyBinding(EShLanguage, TVarEntryInfo& /*ent*/) override {}
@@ -72,11 +74,11 @@ public:
     virtual TResourceType getResourceType(const glslang::TType& type) = 0;
     bool doAutoBindingMapping() const;
     bool doAutoLocationMapping() const;
-    TSlotSet::iterator findSlot(int set, int slot);
-    bool checkEmpty(int set, int slot);
+    TSlotSet::iterator findSlot(int resource, int set, int slot);
+    bool checkEmpty(int resource, int set, int slot);
     bool validateInOut(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; }
-    int reserveSlot(int set, int slot, int size = 1);
-    int getFreeSlot(int set, int base, int size = 1);
+    int reserveSlot(int resource, int set, int slot, int size = 1);
+    int getFreeSlot(int resource, int set, int base, int size = 1);
     int resolveSet(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
     int resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
     int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) override;
@@ -90,7 +92,7 @@ public:
     }
     uint32_t computeTypeLocationSize(const TType& type, EShLanguage stage);
 
-    TSlotSetMap slots;
+    TSlotSetMapResourceArray slots;
     bool hasError = false;
 
 protected:
@@ -173,6 +175,7 @@ struct TDefaultGlslIoResolver : public TDefaultIoResolverBase {
 public:
     typedef std::map<TString, int> TVarSlotMap;  // <resourceName, location/binding>
     typedef std::map<int, TVarSlotMap> TSlotMap; // <resourceKey, TVarSlotMap>
+    typedef std::array<TSlotMap, EResCount> TResourceSlotMap;
     TDefaultGlslIoResolver(const TIntermediate& intermediate);
     bool validateBinding(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; }
     TResourceType getResourceType(const glslang::TType& type) override;
@@ -200,7 +203,7 @@ protected:
     // Use for mark current shader stage for resolver
     EShLanguage currentStage;
     // Slot map for storage resource(location of uniform and interface symbol) It's a program share slot
-    TSlotMap resourceSlotMap;
+    TResourceSlotMap resourceSlotMap;
     // Slot map for other resource(image, ubo, ssbo), It's a program share slot.
     TSlotMap storageSlotMap;
 };

+ 29 - 3
3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp

@@ -524,7 +524,8 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
     numErrors += unit.getNumErrors();
     // Only one push_constant is allowed, mergeLinkerObjects() will ensure the push_constant
     // is the same for all units.
-    if (numPushConstants > 1 || unit.numPushConstants > 1)
+    if (!IsRequestedExtension(glslang::E_GL_NV_push_constant_bank) &&
+        (numPushConstants > 1 || unit.numPushConstants > 1))
         error(infoSink, "Only one push_constant block is allowed per stage");
     numPushConstants = std::min(numPushConstants + unit.numPushConstants, 1);
 
@@ -1125,7 +1126,8 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
                 mergeErrorCheck(infoSink, *symbol, *unitSymbol);
             }
             // 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() && getStage() == unitStage)
+            else if (!IsRequestedExtension(glslang::E_GL_NV_push_constant_bank) &&
+                (symbol->getQualifier().isPushConstant() && unitSymbol->getQualifier().isPushConstant() && getStage() == unitStage))
                 error(infoSink, "Only one push_constant block is allowed per stage");
         }
 
@@ -1590,7 +1592,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
     // overlap/alias/missing I/O, etc.
     inOutLocationCheck(infoSink);
 
-    if (getNumPushConstants() > 1)
+    if (!IsRequestedExtension(glslang::E_GL_NV_push_constant_bank) && (getNumPushConstants() > 1))
         error(infoSink, "Only one push_constant block is allowed per stage");
 
     // invocations
@@ -2573,6 +2575,22 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, T
         }
     }
 
+    // rules 2 and 3
+    if (type.isLongVector()) {
+        int scalarAlign = getBaseAlignmentScalar(type, size);
+        uint32_t vectorSize = type.getTypeParameters()->arraySizes->getDimSize(0);
+        switch (vectorSize) {
+        case 1: // HLSL has this, GLSL does not
+            return scalarAlign;
+        case 2:
+            size *= 2;
+            return 2 * scalarAlign;
+        default:
+            size *= vectorSize;
+            return 4 * scalarAlign;
+        }
+    }
+
     // rules 5 and 7
     if (type.isMatrix()) {
         // rule 5: deref to row, not to column, meaning the size of vector is num columns instead of num rows
@@ -2653,6 +2671,14 @@ int TIntermediate::getScalarAlignment(const TType& type, int& size, int& stride,
         return scalarAlign;
     }
 
+    if (type.isLongVector()) {
+        int scalarAlign = getBaseAlignmentScalar(type, size);
+
+        uint32_t vectorSize = type.getTypeParameters()->arraySizes->getDimSize(0);
+        size *= vectorSize;
+        return scalarAlign;
+    }
+
     if (type.isMatrix()) {
         TType derefType(type, 0, rowMajor);
 

+ 9 - 0
3rdparty/glslang/glslang/MachineIndependent/localintermediate.h

@@ -352,6 +352,7 @@ public:
         hlslOffsets(false),
         hlslIoMapping(false),
         useVariablePointers(false),
+        bindingsPerResourceType(false),
         textureSamplerTransformMode(EShTexSampTransKeep),
         needToLegalize(false),
         binaryDoubleOutput(false),
@@ -840,6 +841,13 @@ public:
 
     bool usingVariablePointers() const { return useVariablePointers; }
 
+    void setBindingsPerResourceType()
+    {
+        bindingsPerResourceType = true;
+        processes.addProcess("bindings-per-resource-type");
+    }
+    bool getBindingsPerResourceType() const { return bindingsPerResourceType; }
+
 #ifdef ENABLE_HLSL
     template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
     bool hasCounterBufferName(const TString& name) const {
@@ -1302,6 +1310,7 @@ protected:
     bool hlslOffsets;
     bool hlslIoMapping;
     bool useVariablePointers;
+    bool bindingsPerResourceType;
 
     std::set<TString> semanticNameSet;
 

+ 1 - 0
3rdparty/glslang/glslang/MachineIndependent/parseVersions.h

@@ -127,6 +127,7 @@ public:
     virtual void coopmatConverisonCheckQCOM(const TSourceLoc& loc, const char* op, bool builtIn = false);
     virtual void tensorLayoutViewCheck(const TSourceLoc&, const char* op, bool builtIn = false);
     virtual void coopvecCheck(const TSourceLoc&, const char* op, bool builtIn = false);
+    virtual void longVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
     virtual void intattachmentCheck(const TSourceLoc&, const char *op, bool builtIn = false);
     virtual void tensorCheckARM(const TSourceLoc&, const char *op, bool builtIn = false);
     bool relaxedErrors()    const { return (messages & EShMsgRelaxedErrors) != 0; }

+ 1 - 0
3rdparty/glslang/glslang/Public/ShaderLang.h

@@ -496,6 +496,7 @@ public:
     void setResourceSetBinding(const std::vector<std::string>& base);
     void setAutoMapBindings(bool map);
     void setAutoMapLocations(bool map);
+    void setBindingsPerResourceType();
     void addUniformLocationOverride(const char* name, int loc);
     void setUniformLocationBase(int base);
     void setInvertY(bool invert);

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor