Browse Source

Updated glslang.

Бранимир Караџић 2 years ago
parent
commit
0489440481
26 changed files with 1047 additions and 616 deletions
  1. 0 37
      3rdparty/glslang/OGLCompilersDLL/InitializeDll.cpp
  2. 0 49
      3rdparty/glslang/OGLCompilersDLL/InitializeDll.h
  3. 1 1
      3rdparty/glslang/SPIRV/GlslangToSpv.cpp
  4. 15 6
      3rdparty/glslang/SPIRV/SpvBuilder.cpp
  5. 1 1
      3rdparty/glslang/SPIRV/SpvBuilder.h
  6. 2 2
      3rdparty/glslang/SPIRV/doc.h
  7. 3 3
      3rdparty/glslang/build_info.h
  8. 1 1
      3rdparty/glslang/glslang/Include/ConstantUnion.h
  9. 51 31
      3rdparty/glslang/glslang/Include/Types.h
  10. 3 8
      3rdparty/glslang/glslang/Include/intermediate.h
  11. 1 1
      3rdparty/glslang/glslang/MachineIndependent/Constant.cpp
  12. 187 160
      3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp
  13. 36 3
      3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp
  14. 18 0
      3rdparty/glslang/glslang/MachineIndependent/ParseContextBase.cpp
  15. 269 12
      3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp
  16. 5 0
      3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h
  17. 15 1
      3rdparty/glslang/glslang/MachineIndependent/Scan.cpp
  18. 0 17
      3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp
  19. 8 1
      3rdparty/glslang/glslang/MachineIndependent/Versions.cpp
  20. 2 0
      3rdparty/glslang/glslang/MachineIndependent/Versions.h
  21. 49 19
      3rdparty/glslang/glslang/MachineIndependent/glslang.y
  22. 256 240
      3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp
  23. 2 0
      3rdparty/glslang/glslang/MachineIndependent/localintermediate.h
  24. 29 8
      3rdparty/glslang/glslang/MachineIndependent/preprocessor/PpContext.h
  25. 92 0
      3rdparty/glslang/glslang/MachineIndependent/span.h
  26. 1 15
      3rdparty/glslang/glslang/ResourceLimits/resource_limits_c.cpp

+ 0 - 37
3rdparty/glslang/OGLCompilersDLL/InitializeDll.cpp

@@ -1,37 +0,0 @@
-//
-// Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-//    Redistributions of source code must retain the above copyright
-//    notice, this list of conditions and the following disclaimer.
-//
-//    Redistributions in binary form must reproduce the above
-//    copyright notice, this list of conditions and the following
-//    disclaimer in the documentation and/or other materials provided
-//    with the distribution.
-//
-//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-//    contributors may be used to endorse or promote products derived
-//    from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-
-namespace glslang {
-
-} // end namespace glslang

+ 0 - 49
3rdparty/glslang/OGLCompilersDLL/InitializeDll.h

@@ -1,49 +0,0 @@
-//
-// Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-//    Redistributions of source code must retain the above copyright
-//    notice, this list of conditions and the following disclaimer.
-//
-//    Redistributions in binary form must reproduce the above
-//    copyright notice, this list of conditions and the following
-//    disclaimer in the documentation and/or other materials provided
-//    with the distribution.
-//
-//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-//    contributors may be used to endorse or promote products derived
-//    from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-#ifndef __INITIALIZEDLL_H
-#define __INITIALIZEDLL_H
-
-#include "../glslang/OSDependent/osinclude.h"
-
-namespace glslang {
-
-inline bool InitProcess()   { return true; } // DEPRECATED
-inline bool InitThread()    { return true; } // DEPRECATED
-inline bool DetachThread()  { return true; } // DEPRECATED
-inline bool DetachProcess() { return true; } // DEPRECATED
-
-} // end namespace glslang
-
-#endif // __INITIALIZEDLL_H
-

+ 1 - 1
3rdparty/glslang/SPIRV/GlslangToSpv.cpp

@@ -4407,7 +4407,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
         if (explicitLayout != glslang::ElpNone)
             spvType = builder.makeUintType(32);
         else
-            spvType = builder.makeBoolType(false);
+            spvType = builder.makeBoolType();
         break;
     case glslang::EbtInt:
         spvType = builder.makeIntType(32);

+ 15 - 6
3rdparty/glslang/SPIRV/SpvBuilder.cpp

@@ -182,7 +182,7 @@ Id Builder::makeVoidType()
     return type->getResultId();
 }
 
-Id Builder::makeBoolType(bool const compilerGenerated)
+Id Builder::makeBoolType()
 {
     Instruction* type;
     if (groupedTypes[OpTypeBool].size() == 0) {
@@ -190,14 +190,15 @@ Id Builder::makeBoolType(bool const compilerGenerated)
         groupedTypes[OpTypeBool].push_back(type);
         constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
         module.mapInstruction(type);
+
+        if (emitNonSemanticShaderDebugInfo) {
+            auto const debugResultId = makeBoolDebugType(32);
+            debugId[type->getResultId()] = debugResultId;
+        }
+
     } else
         type = groupedTypes[OpTypeBool].back();
 
-    if (emitNonSemanticShaderDebugInfo && !compilerGenerated)
-    {
-        auto const debugResultId = makeBoolDebugType(32);
-        debugId[type->getResultId()] = debugResultId;
-    }
 
     return type->getResultId();
 }
@@ -2740,6 +2741,14 @@ Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector<Id>& op
     module.mapInstruction(op);
     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(op));
 
+    // OpSpecConstantOp's using 8 or 16 bit types require the associated capability
+    if (containsType(typeId, OpTypeInt, 8))
+        addCapability(CapabilityInt8);
+    if (containsType(typeId, OpTypeInt, 16))
+        addCapability(CapabilityInt16);
+    if (containsType(typeId, OpTypeFloat, 16))
+        addCapability(CapabilityFloat16);
+
     return op->getResultId();
 }
 

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

@@ -185,7 +185,7 @@ public:
 
     // For creating new types (will return old type if the requested one was already made).
     Id makeVoidType();
-    Id makeBoolType(bool const compilerGenerated = true);
+    Id makeBoolType();
     Id makePointer(StorageClass, Id pointee);
     Id makeForwardPointer(StorageClass);
     Id makePointerFromForwardPointer(StorageClass, Id forwardPointerType, Id pointee);

+ 2 - 2
3rdparty/glslang/SPIRV/doc.h

@@ -240,8 +240,8 @@ public:
     OperandParameters operands;
 
 protected:
-    int typePresent   : 1;
-    int resultPresent : 1;
+    bool typePresent   : 1;
+    bool resultPresent : 1;
 };
 
 // The set of objects that hold all the instruction/operand

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

@@ -34,9 +34,9 @@
 #ifndef GLSLANG_BUILD_INFO
 #define GLSLANG_BUILD_INFO
 
-#define GLSLANG_VERSION_MAJOR 13
-#define GLSLANG_VERSION_MINOR 1
-#define GLSLANG_VERSION_PATCH 1
+#define GLSLANG_VERSION_MAJOR 14
+#define GLSLANG_VERSION_MINOR 0
+#define GLSLANG_VERSION_PATCH 0
 #define GLSLANG_VERSION_FLAVOR ""
 
 #define GLSLANG_VERSION_GREATER_THAN(major, minor, patch) \

+ 1 - 1
3rdparty/glslang/glslang/Include/ConstantUnion.h

@@ -503,7 +503,7 @@ public:
         case EbtInt:    returnValue.setIConst(iConst % constant.iConst); break;
         case EbtUint:   returnValue.setUConst(uConst % constant.uConst); break;
         case EbtInt8:   returnValue.setI8Const(i8Const % constant.i8Const); break;
-        case EbtInt16:  returnValue.setI8Const(i8Const % constant.i16Const); break;
+        case EbtInt16:  returnValue.setI16Const(i16Const % constant.i16Const); break;
         case EbtInt64:  returnValue.setI64Const(i64Const % constant.i64Const); break;
         case EbtUint8:  returnValue.setU8Const(u8Const % constant.u8Const); break;
         case EbtUint16: returnValue.setU16Const(u16Const % constant.u16Const); break;

+ 51 - 31
3rdparty/glslang/glslang/Include/Types.h

@@ -1451,9 +1451,9 @@ public:
     TSampler sampler;
     TQualifier qualifier;
     TShaderQualifiers shaderQualifiers;
-    int vectorSize  : 4;
-    int matrixCols  : 4;
-    int matrixRows  : 4;
+    uint32_t vectorSize  : 4;
+    uint32_t matrixCols  : 4;
+    uint32_t matrixRows  : 4;
     bool coopmatNV  : 1;
     bool coopmatKHR : 1;
     TArraySizes* arraySizes;
@@ -1470,7 +1470,7 @@ public:
     void initType(const TSourceLoc& l)
     {
         basicType = EbtVoid;
-        vectorSize = 1;
+        vectorSize = 1u;
         matrixRows = 0;
         matrixCols = 0;
         arraySizes = nullptr;
@@ -1501,19 +1501,22 @@ public:
     {
         matrixRows = 0;
         matrixCols = 0;
-        vectorSize = s;
+        assert(s >= 0);
+        vectorSize = static_cast<uint32_t>(s) & 0b1111;
     }
 
     void setMatrix(int c, int r)
     {
-        matrixRows = r;
-        matrixCols = c;
+        assert(r >= 0);
+        matrixRows = static_cast<uint32_t>(r) & 0b1111;
+        assert(c >= 0);
+        matrixCols = static_cast<uint32_t>(c) & 0b1111;
         vectorSize = 0;
     }
 
     bool isScalar() const
     {
-        return matrixCols == 0 && vectorSize == 1 && arraySizes == nullptr && userDef == nullptr;
+        return matrixCols == 0u && vectorSize == 1u && arraySizes == nullptr && userDef == nullptr;
     }
 
     // GL_EXT_spirv_intrinsics
@@ -1535,10 +1538,14 @@ 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(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
+                            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),
                             arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
                             spirvType(nullptr)
                             {
+                                assert(vs >= 0);
+                                assert(mc >= 0);
+                                assert(mr >= 0);
+
                                 sampler.clear();
                                 qualifier.clear();
                                 qualifier.storage = q;
@@ -1547,10 +1554,14 @@ 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(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
+                            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),
                             arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
                             spirvType(nullptr)
                             {
+                                assert(vs >= 0);
+                                assert(mc >= 0);
+                                assert(mr >= 0);
+
                                 sampler.clear();
                                 qualifier.clear();
                                 qualifier.storage = q;
@@ -1561,7 +1572,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(-1),
+                            vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmatNV(p.coopmatNV), coopmatKHR(p.coopmatKHR), coopmatKHRuse(0), coopmatKHRUseValid(false),
                             arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(p.typeParameters),
                             spirvType(p.spirvType)
                             {
@@ -1602,14 +1613,17 @@ public:
                                     basicType = p.typeParameters->basicType;
 
                                     if (p.typeParameters->arraySizes->getNumDims() == 4) {
-                                        coopmatKHRuse = p.typeParameters->arraySizes->getDimSize(3);
+                                        const int dimSize = p.typeParameters->arraySizes->getDimSize(3);
+                                        assert(dimSize >= 0);
+                                        coopmatKHRuse = static_cast<uint32_t>(dimSize) & 0b111;
+                                        coopmatKHRUseValid = true;
                                         p.typeParameters->arraySizes->removeLastSize();
                                     }
                                 }
                             }
     // for construction of sampler types
     TType(const TSampler& sampler, TStorageQualifier q = EvqUniform, TArraySizes* as = nullptr) :
-        basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
+        basicType(EbtSampler), vectorSize(1u), matrixCols(0u), matrixRows(0u), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
         arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr),
         sampler(sampler), typeParameters(nullptr), spirvType(nullptr)
     {
@@ -1655,14 +1669,15 @@ public:
                                     } else if (isCoopMat()) {
                                         coopmatNV = false;
                                         coopmatKHR = false;
-                                        coopmatKHRuse = -1;
+                                        coopmatKHRuse = 0;
+                                        coopmatKHRUseValid = false;
                                         typeParameters = nullptr;
                                     }
                                 }
                             }
     // for making structures, ...
     TType(TTypeList* userDef, const TString& n) :
-                            basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
+                            basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
                             arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr),
                             spirvType(nullptr)
                             {
@@ -1672,7 +1687,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(-1),
+                            basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
                             qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr),
                             spirvType(nullptr)
                             {
@@ -1681,7 +1696,7 @@ public:
                             }
     // for block reference (first parameter must be EbtReference)
     explicit TType(TBasicType t, const TType &p, const TString& n) :
-                            basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
+                            basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false),
                             arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
                             spirvType(nullptr)
                             {
@@ -1719,6 +1734,7 @@ public:
         coopmatNV = copyOf.isCoopMatNV();
         coopmatKHR = copyOf.isCoopMatKHR();
         coopmatKHRuse = copyOf.coopmatKHRuse;
+        coopmatKHRUseValid = copyOf.coopmatKHRUseValid;
     }
 
     // Make complete copy of the whole type graph rooted at 'copyOf'.
@@ -1748,7 +1764,7 @@ public:
 
     void makeVector() { vector1 = true; }
 
-    virtual void hideMember() { basicType = EbtVoid; vectorSize = 1; }
+    virtual void hideMember() { basicType = EbtVoid; vectorSize = 1u; }
     virtual bool hiddenMember() const { return basicType == EbtVoid; }
 
     virtual void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); }
@@ -1788,9 +1804,9 @@ public:
     virtual       TQualifier& getQualifier()       { return qualifier; }
     virtual const TQualifier& getQualifier() const { return qualifier; }
 
-    virtual int getVectorSize() const { return vectorSize; }  // returns 1 for either scalar or vector of size 1, valid for both
-    virtual int getMatrixCols() const { return matrixCols; }
-    virtual int getMatrixRows() const { return matrixRows; }
+    virtual int getVectorSize() const { return static_cast<int>(vectorSize); }  // returns 1 for either scalar or vector of size 1, valid for both
+    virtual int getMatrixCols() const { return static_cast<int>(matrixCols); }
+    virtual int getMatrixRows() const { return static_cast<int>(matrixRows); }
     virtual int getOuterArraySize()  const { return arraySizes->getOuterSize(); }
     virtual TIntermTyped*  getOuterArrayNode() const { return arraySizes->getOuterNode(); }
     virtual int getCumulativeArraySize()  const { return arraySizes->getCumulativeSize(); }
@@ -1805,7 +1821,7 @@ public:
     virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); }
     virtual bool isScalarOrVec1() const { return isScalar() || vector1; }
     virtual bool isScalarOrVector() const { return !isMatrix() && !isStruct() && !isArray(); }
-    virtual bool isVector() const { return vectorSize > 1 || vector1; }
+    virtual bool isVector() const { return vectorSize > 1u || vector1; }
     virtual bool isMatrix() const { return matrixCols ? true : false; }
     virtual bool isArray()  const { return arraySizes != nullptr; }
     virtual bool isSizedArray() const { return isArray() && arraySizes->isSized(); }
@@ -1855,7 +1871,7 @@ public:
     bool isCoopMatKHR() const { return coopmatKHR; }
     bool isReference() const { return getBasicType() == EbtReference; }
     bool isSpirvType() const { return getBasicType() == EbtSpirvType; }
-    int getCoopMatKHRuse() const { return coopmatKHRuse; }
+    int getCoopMatKHRuse() const { return static_cast<int>(coopmatKHRuse); }
 
     // return true if this type contains any subtype which satisfies the given predicate.
     template <typename P>
@@ -2395,7 +2411,7 @@ public:
                 if (i != (int)typeParameters->arraySizes->getNumDims() - 1)
                   appendStr(", ");
               }
-              if (coopmatKHRuse != -1) {
+              if (coopmatKHRUseValid) {
                   appendStr(", ");
                   appendInt(coopmatKHRuse);
               }
@@ -2464,11 +2480,14 @@ public:
     void setStruct(TTypeList* s) { assert(isStruct()); structure = s; }
     TTypeList* getWritableStruct() const { assert(isStruct()); return structure; }  // This should only be used when known to not be sharing with other threads
     void setBasicType(const TBasicType& t) { basicType = t; }
-    void setVectorSize(int s) { vectorSize = s; }
+    void setVectorSize(int s) {
+        assert(s >= 0);
+        vectorSize = static_cast<uint32_t>(s) & 0b1111;
+    }
 
     int computeNumComponents() const
     {
-        int components = 0;
+        uint32_t components = 0;
 
         if (getBasicType() == EbtStruct || getBasicType() == EbtBlock) {
             for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
@@ -2482,7 +2501,7 @@ public:
             components *= arraySizes->getCumulativeSize();
         }
 
-        return components;
+        return static_cast<int>(components);
     }
 
     // append this type's mangled name to the passed in 'name'
@@ -2825,9 +2844,9 @@ protected:
     void buildMangledName(TString&) const;
 
     TBasicType basicType : 8;
-    int vectorSize       : 4;  // 1 means either scalar or 1-component vector; see vector1 to disambiguate.
-    int matrixCols       : 4;
-    int matrixRows       : 4;
+    uint32_t vectorSize       : 4;  // 1 means either scalar or 1-component vector; see vector1 to disambiguate.
+    uint32_t matrixCols       : 4;
+    uint32_t matrixRows       : 4;
     bool vector1         : 1;  // Backward-compatible tracking of a 1-component vector distinguished from a scalar.
                                // GLSL 4.5 never has a 1-component vector; so this will always be false until such
                                // functionality is added.
@@ -2835,7 +2854,8 @@ protected:
                                // from a scalar.
     bool coopmatNV       : 1;
     bool coopmatKHR      : 1;
-    int coopmatKHRuse    : 4;  // Accepts one of three values: 0, 1, 2 (gl_MatrixUseA, gl_MatrixUseB, gl_MatrixUseAccumulator)
+    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
     TQualifier qualifier;
 
     TArraySizes* arraySizes;    // nullptr unless an array; can be shared across types

+ 3 - 8
3rdparty/glslang/glslang/Include/intermediate.h

@@ -48,14 +48,9 @@
 #ifndef __INTERMEDIATE_H
 #define __INTERMEDIATE_H
 
-#if defined(_MSC_VER) && _MSC_VER >= 1900
-    #pragma warning(disable : 4464) // relative include path contains '..'
-    #pragma warning(disable : 5026) // 'glslang::TIntermUnary': move constructor was implicitly defined as deleted
-#endif
-
-#include "../Include/Common.h"
-#include "../Include/Types.h"
-#include "../Include/ConstantUnion.h"
+#include "Common.h"
+#include "Types.h"
+#include "ConstantUnion.h"
 
 namespace glslang {
 

+ 1 - 1
3rdparty/glslang/glslang/MachineIndependent/Constant.cpp

@@ -689,7 +689,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
         case EOpConvInt64ToBool:
             newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
         case EOpConvUint64ToBool:
-            newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
+            newConstArray[i].setBConst(unionArray[i].getU64Const() != 0); break;
         case EOpConvFloat16ToBool:
             newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break;
 

+ 187 - 160
3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp

@@ -52,6 +52,7 @@
 //
 
 #include "Initialize.h"
+#include "span.h"
 
 namespace glslang {
 
@@ -139,20 +140,17 @@ struct Versioning {
 EProfile EDesktopProfile = static_cast<EProfile>(ENoProfile | ECoreProfile | ECompatibilityProfile);
 
 // Declare pointers to put into the table for versioning.
-    const Versioning Es300Desktop130Version[] = { { EEsProfile,      0, 300, 0, nullptr },
-                                                  { EDesktopProfile, 0, 130, 0, nullptr },
-                                                  { EBadProfile } };
-    const Versioning* Es300Desktop130 = &Es300Desktop130Version[0];
+    const std::array Es300Desktop130Version = { Versioning{ EEsProfile,      0, 300, 0, nullptr },
+                                                Versioning{ EDesktopProfile, 0, 130, 0, nullptr },
+                                              };
 
-    const Versioning Es310Desktop400Version[] = { { EEsProfile,      0, 310, 0, nullptr },
-                                                  { EDesktopProfile, 0, 400, 0, nullptr },
-                                                  { EBadProfile } };
-    const Versioning* Es310Desktop400 = &Es310Desktop400Version[0];
+    const std::array Es310Desktop400Version = { Versioning{ EEsProfile,      0, 310, 0, nullptr },
+                                                Versioning{ EDesktopProfile, 0, 400, 0, nullptr },
+                                              };
 
-    const Versioning Es310Desktop450Version[] = { { EEsProfile,      0, 310, 0, nullptr },
-                                                  { EDesktopProfile, 0, 450, 0, nullptr },
-                                                  { EBadProfile } };
-    const Versioning* Es310Desktop450 = &Es310Desktop450Version[0];
+    const std::array Es310Desktop450Version = { Versioning{ EEsProfile,      0, 310, 0, nullptr },
+                                                Versioning{ EDesktopProfile, 0, 450, 0, nullptr },
+                                              };
 
 // The main descriptor of what a set of function prototypes can look like, and
 // a pointer to extra versioning information, when needed.
@@ -162,7 +160,7 @@ struct BuiltInFunction {
     int numArguments;             // number of arguments (overloads with varying arguments need different entries)
     ArgType types;                // ArgType mask
     ArgClass classes;             // the ways this particular function entry manifests
-    const Versioning* versioning; // nullptr means always a valid version
+    const span<const Versioning> versioning; // An empty span means always a valid version
 };
 
 // The tables can have the same built-in function name more than one time,
@@ -174,151 +172,146 @@ struct BuiltInFunction {
 //
 // Table is terminated by an OpNull TOperator.
 
-const BuiltInFunction BaseFunctions[] = {
+const std::array BaseFunctions = {
 //    TOperator,           name,       arg-count,   ArgType,   ArgClass,     versioning
 //    ---------            ----        ---------    -------    --------      ----------
-    { EOpRadians,          "radians",          1,   TypeF,     ClassRegular, nullptr },
-    { EOpDegrees,          "degrees",          1,   TypeF,     ClassRegular, nullptr },
-    { EOpSin,              "sin",              1,   TypeF,     ClassRegular, nullptr },
-    { EOpCos,              "cos",              1,   TypeF,     ClassRegular, nullptr },
-    { EOpTan,              "tan",              1,   TypeF,     ClassRegular, nullptr },
-    { EOpAsin,             "asin",             1,   TypeF,     ClassRegular, nullptr },
-    { EOpAcos,             "acos",             1,   TypeF,     ClassRegular, nullptr },
-    { EOpAtan,             "atan",             2,   TypeF,     ClassRegular, nullptr },
-    { EOpAtan,             "atan",             1,   TypeF,     ClassRegular, nullptr },
-    { EOpPow,              "pow",              2,   TypeF,     ClassRegular, nullptr },
-    { EOpExp,              "exp",              1,   TypeF,     ClassRegular, nullptr },
-    { EOpLog,              "log",              1,   TypeF,     ClassRegular, nullptr },
-    { EOpExp2,             "exp2",             1,   TypeF,     ClassRegular, nullptr },
-    { EOpLog2,             "log2",             1,   TypeF,     ClassRegular, nullptr },
-    { EOpSqrt,             "sqrt",             1,   TypeF,     ClassRegular, nullptr },
-    { EOpInverseSqrt,      "inversesqrt",      1,   TypeF,     ClassRegular, nullptr },
-    { EOpAbs,              "abs",              1,   TypeF,     ClassRegular, nullptr },
-    { EOpSign,             "sign",             1,   TypeF,     ClassRegular, nullptr },
-    { EOpFloor,            "floor",            1,   TypeF,     ClassRegular, nullptr },
-    { EOpCeil,             "ceil",             1,   TypeF,     ClassRegular, nullptr },
-    { EOpFract,            "fract",            1,   TypeF,     ClassRegular, nullptr },
-    { EOpMod,              "mod",              2,   TypeF,     ClassLS,      nullptr },
-    { EOpMin,              "min",              2,   TypeF,     ClassLS,      nullptr },
-    { EOpMax,              "max",              2,   TypeF,     ClassLS,      nullptr },
-    { EOpClamp,            "clamp",            3,   TypeF,     ClassLS2,     nullptr },
-    { EOpMix,              "mix",              3,   TypeF,     ClassLS,      nullptr },
-    { EOpStep,             "step",             2,   TypeF,     ClassFS,      nullptr },
-    { EOpSmoothStep,       "smoothstep",       3,   TypeF,     ClassFS2,     nullptr },
-    { EOpNormalize,        "normalize",        1,   TypeF,     ClassRegular, nullptr },
-    { EOpFaceForward,      "faceforward",      3,   TypeF,     ClassRegular, nullptr },
-    { EOpReflect,          "reflect",          2,   TypeF,     ClassRegular, nullptr },
-    { EOpRefract,          "refract",          3,   TypeF,     ClassXLS,     nullptr },
-    { EOpLength,           "length",           1,   TypeF,     ClassRS,      nullptr },
-    { EOpDistance,         "distance",         2,   TypeF,     ClassRS,      nullptr },
-    { EOpDot,              "dot",              2,   TypeF,     ClassRS,      nullptr },
-    { EOpCross,            "cross",            2,   TypeF,     ClassV3,      nullptr },
-    { EOpLessThan,         "lessThan",         2,   TypeFI,    ClassBNS,     nullptr },
-    { EOpLessThanEqual,    "lessThanEqual",    2,   TypeFI,    ClassBNS,     nullptr },
-    { EOpGreaterThan,      "greaterThan",      2,   TypeFI,    ClassBNS,     nullptr },
-    { EOpGreaterThanEqual, "greaterThanEqual", 2,   TypeFI,    ClassBNS,     nullptr },
-    { EOpVectorEqual,      "equal",            2,   TypeFIB,   ClassBNS,     nullptr },
-    { EOpVectorNotEqual,   "notEqual",         2,   TypeFIB,   ClassBNS,     nullptr },
-    { EOpAny,              "any",              1,   TypeB,     ClassRSNS,    nullptr },
-    { EOpAll,              "all",              1,   TypeB,     ClassRSNS,    nullptr },
-    { EOpVectorLogicalNot, "not",              1,   TypeB,     ClassNS,      nullptr },
-    { EOpSinh,             "sinh",             1,   TypeF,     ClassRegular, Es300Desktop130 },
-    { EOpCosh,             "cosh",             1,   TypeF,     ClassRegular, Es300Desktop130 },
-    { EOpTanh,             "tanh",             1,   TypeF,     ClassRegular, Es300Desktop130 },
-    { EOpAsinh,            "asinh",            1,   TypeF,     ClassRegular, Es300Desktop130 },
-    { EOpAcosh,            "acosh",            1,   TypeF,     ClassRegular, Es300Desktop130 },
-    { EOpAtanh,            "atanh",            1,   TypeF,     ClassRegular, Es300Desktop130 },
-    { EOpAbs,              "abs",              1,   TypeI,     ClassRegular, Es300Desktop130 },
-    { EOpSign,             "sign",             1,   TypeI,     ClassRegular, Es300Desktop130 },
-    { EOpTrunc,            "trunc",            1,   TypeF,     ClassRegular, Es300Desktop130 },
-    { EOpRound,            "round",            1,   TypeF,     ClassRegular, Es300Desktop130 },
-    { EOpRoundEven,        "roundEven",        1,   TypeF,     ClassRegular, Es300Desktop130 },
-    { EOpModf,             "modf",             2,   TypeF,     ClassLO,      Es300Desktop130 },
-    { EOpMin,              "min",              2,   TypeIU,    ClassLS,      Es300Desktop130 },
-    { EOpMax,              "max",              2,   TypeIU,    ClassLS,      Es300Desktop130 },
-    { EOpClamp,            "clamp",            3,   TypeIU,    ClassLS2,     Es300Desktop130 },
-    { EOpMix,              "mix",              3,   TypeF,     ClassLB,      Es300Desktop130 },
-    { EOpIsInf,            "isinf",            1,   TypeF,     ClassB,       Es300Desktop130 },
-    { EOpIsNan,            "isnan",            1,   TypeF,     ClassB,       Es300Desktop130 },
-    { EOpLessThan,         "lessThan",         2,   TypeU,     ClassBNS,     Es300Desktop130 },
-    { EOpLessThanEqual,    "lessThanEqual",    2,   TypeU,     ClassBNS,     Es300Desktop130 },
-    { EOpGreaterThan,      "greaterThan",      2,   TypeU,     ClassBNS,     Es300Desktop130 },
-    { EOpGreaterThanEqual, "greaterThanEqual", 2,   TypeU,     ClassBNS,     Es300Desktop130 },
-    { EOpVectorEqual,      "equal",            2,   TypeU,     ClassBNS,     Es300Desktop130 },
-    { EOpVectorNotEqual,   "notEqual",         2,   TypeU,     ClassBNS,     Es300Desktop130 },
-    { EOpAtomicAdd,        "atomicAdd",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop400 },
-    { EOpAtomicMin,        "atomicMin",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop400 },
-    { EOpAtomicMax,        "atomicMax",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop400 },
-    { EOpAtomicAnd,        "atomicAnd",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop400 },
-    { EOpAtomicOr,         "atomicOr",         2,   TypeIU,    ClassV1FIOCV, Es310Desktop400 },
-    { EOpAtomicXor,        "atomicXor",        2,   TypeIU,    ClassV1FIOCV, Es310Desktop400 },
-    { EOpAtomicExchange,   "atomicExchange",   2,   TypeIU,    ClassV1FIOCV, Es310Desktop400 },
-    { EOpAtomicCompSwap,   "atomicCompSwap",   3,   TypeIU,    ClassV1FIOCV, Es310Desktop400 },
-    { EOpMix,              "mix",              3,   TypeB,     ClassRegular, Es310Desktop450 },
-    { EOpMix,              "mix",              3,   TypeIU,    ClassLB,      Es310Desktop450 },
-
-    { EOpNull }
+    BuiltInFunction{ EOpRadians,          "radians",          1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpDegrees,          "degrees",          1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpSin,              "sin",              1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpCos,              "cos",              1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpTan,              "tan",              1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpAsin,             "asin",             1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpAcos,             "acos",             1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpAtan,             "atan",             2,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpAtan,             "atan",             1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpPow,              "pow",              2,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpExp,              "exp",              1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpLog,              "log",              1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpExp2,             "exp2",             1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpLog2,             "log2",             1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpSqrt,             "sqrt",             1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpInverseSqrt,      "inversesqrt",      1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpAbs,              "abs",              1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpSign,             "sign",             1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpFloor,            "floor",            1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpCeil,             "ceil",             1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpFract,            "fract",            1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpMod,              "mod",              2,   TypeF,     ClassLS,      {} },
+    BuiltInFunction{ EOpMin,              "min",              2,   TypeF,     ClassLS,      {} },
+    BuiltInFunction{ EOpMax,              "max",              2,   TypeF,     ClassLS,      {} },
+    BuiltInFunction{ EOpClamp,            "clamp",            3,   TypeF,     ClassLS2,     {} },
+    BuiltInFunction{ EOpMix,              "mix",              3,   TypeF,     ClassLS,      {} },
+    BuiltInFunction{ EOpStep,             "step",             2,   TypeF,     ClassFS,      {} },
+    BuiltInFunction{ EOpSmoothStep,       "smoothstep",       3,   TypeF,     ClassFS2,     {} },
+    BuiltInFunction{ EOpNormalize,        "normalize",        1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpFaceForward,      "faceforward",      3,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpReflect,          "reflect",          2,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpRefract,          "refract",          3,   TypeF,     ClassXLS,     {} },
+    BuiltInFunction{ EOpLength,           "length",           1,   TypeF,     ClassRS,      {} },
+    BuiltInFunction{ EOpDistance,         "distance",         2,   TypeF,     ClassRS,      {} },
+    BuiltInFunction{ EOpDot,              "dot",              2,   TypeF,     ClassRS,      {} },
+    BuiltInFunction{ EOpCross,            "cross",            2,   TypeF,     ClassV3,      {} },
+    BuiltInFunction{ EOpLessThan,         "lessThan",         2,   TypeFI,    ClassBNS,     {} },
+    BuiltInFunction{ EOpLessThanEqual,    "lessThanEqual",    2,   TypeFI,    ClassBNS,     {} },
+    BuiltInFunction{ EOpGreaterThan,      "greaterThan",      2,   TypeFI,    ClassBNS,     {} },
+    BuiltInFunction{ EOpGreaterThanEqual, "greaterThanEqual", 2,   TypeFI,    ClassBNS,     {} },
+    BuiltInFunction{ EOpVectorEqual,      "equal",            2,   TypeFIB,   ClassBNS,     {} },
+    BuiltInFunction{ EOpVectorNotEqual,   "notEqual",         2,   TypeFIB,   ClassBNS,     {} },
+    BuiltInFunction{ EOpAny,              "any",              1,   TypeB,     ClassRSNS,    {} },
+    BuiltInFunction{ EOpAll,              "all",              1,   TypeB,     ClassRSNS,    {} },
+    BuiltInFunction{ EOpVectorLogicalNot, "not",              1,   TypeB,     ClassNS,      {} },
+    BuiltInFunction{ EOpSinh,             "sinh",             1,   TypeF,     ClassRegular, {Es300Desktop130Version} },
+    BuiltInFunction{ EOpCosh,             "cosh",             1,   TypeF,     ClassRegular, {Es300Desktop130Version} },
+    BuiltInFunction{ EOpTanh,             "tanh",             1,   TypeF,     ClassRegular, {Es300Desktop130Version} },
+    BuiltInFunction{ EOpAsinh,            "asinh",            1,   TypeF,     ClassRegular, {Es300Desktop130Version} },
+    BuiltInFunction{ EOpAcosh,            "acosh",            1,   TypeF,     ClassRegular, {Es300Desktop130Version} },
+    BuiltInFunction{ EOpAtanh,            "atanh",            1,   TypeF,     ClassRegular, {Es300Desktop130Version} },
+    BuiltInFunction{ EOpAbs,              "abs",              1,   TypeI,     ClassRegular, {Es300Desktop130Version} },
+    BuiltInFunction{ EOpSign,             "sign",             1,   TypeI,     ClassRegular, {Es300Desktop130Version} },
+    BuiltInFunction{ EOpTrunc,            "trunc",            1,   TypeF,     ClassRegular, {Es300Desktop130Version} },
+    BuiltInFunction{ EOpRound,            "round",            1,   TypeF,     ClassRegular, {Es300Desktop130Version} },
+    BuiltInFunction{ EOpRoundEven,        "roundEven",        1,   TypeF,     ClassRegular, {Es300Desktop130Version} },
+    BuiltInFunction{ EOpModf,             "modf",             2,   TypeF,     ClassLO,      {Es300Desktop130Version} },
+    BuiltInFunction{ EOpMin,              "min",              2,   TypeIU,    ClassLS,      {Es300Desktop130Version} },
+    BuiltInFunction{ EOpMax,              "max",              2,   TypeIU,    ClassLS,      {Es300Desktop130Version} },
+    BuiltInFunction{ EOpClamp,            "clamp",            3,   TypeIU,    ClassLS2,     {Es300Desktop130Version} },
+    BuiltInFunction{ EOpMix,              "mix",              3,   TypeF,     ClassLB,      {Es300Desktop130Version} },
+    BuiltInFunction{ EOpIsInf,            "isinf",            1,   TypeF,     ClassB,       {Es300Desktop130Version} },
+    BuiltInFunction{ EOpIsNan,            "isnan",            1,   TypeF,     ClassB,       {Es300Desktop130Version} },
+    BuiltInFunction{ EOpLessThan,         "lessThan",         2,   TypeU,     ClassBNS,     {Es300Desktop130Version} },
+    BuiltInFunction{ EOpLessThanEqual,    "lessThanEqual",    2,   TypeU,     ClassBNS,     {Es300Desktop130Version} },
+    BuiltInFunction{ EOpGreaterThan,      "greaterThan",      2,   TypeU,     ClassBNS,     {Es300Desktop130Version} },
+    BuiltInFunction{ EOpGreaterThanEqual, "greaterThanEqual", 2,   TypeU,     ClassBNS,     {Es300Desktop130Version} },
+    BuiltInFunction{ EOpVectorEqual,      "equal",            2,   TypeU,     ClassBNS,     {Es300Desktop130Version} },
+    BuiltInFunction{ EOpVectorNotEqual,   "notEqual",         2,   TypeU,     ClassBNS,     {Es300Desktop130Version} },
+    BuiltInFunction{ EOpAtomicAdd,        "atomicAdd",        2,   TypeIU,    ClassV1FIOCV, {Es310Desktop400Version} },
+    BuiltInFunction{ EOpAtomicMin,        "atomicMin",        2,   TypeIU,    ClassV1FIOCV, {Es310Desktop400Version} },
+    BuiltInFunction{ EOpAtomicMax,        "atomicMax",        2,   TypeIU,    ClassV1FIOCV, {Es310Desktop400Version} },
+    BuiltInFunction{ EOpAtomicAnd,        "atomicAnd",        2,   TypeIU,    ClassV1FIOCV, {Es310Desktop400Version} },
+    BuiltInFunction{ EOpAtomicOr,         "atomicOr",         2,   TypeIU,    ClassV1FIOCV, {Es310Desktop400Version} },
+    BuiltInFunction{ EOpAtomicXor,        "atomicXor",        2,   TypeIU,    ClassV1FIOCV, {Es310Desktop400Version} },
+    BuiltInFunction{ EOpAtomicExchange,   "atomicExchange",   2,   TypeIU,    ClassV1FIOCV, {Es310Desktop400Version} },
+    BuiltInFunction{ EOpAtomicCompSwap,   "atomicCompSwap",   3,   TypeIU,    ClassV1FIOCV, {Es310Desktop400Version} },
+    BuiltInFunction{ EOpMix,              "mix",              3,   TypeB,     ClassRegular, {Es310Desktop450Version} },
+    BuiltInFunction{ EOpMix,              "mix",              3,   TypeIU,    ClassLB,      {Es310Desktop450Version} },
 };
 
-const BuiltInFunction DerivativeFunctions[] = {
-    { EOpDPdx,             "dFdx",             1,   TypeF,     ClassRegular, nullptr },
-    { EOpDPdy,             "dFdy",             1,   TypeF,     ClassRegular, nullptr },
-    { EOpFwidth,           "fwidth",           1,   TypeF,     ClassRegular, nullptr },
-    { EOpNull }
+const std::array DerivativeFunctions = {
+    BuiltInFunction{ EOpDPdx,             "dFdx",             1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpDPdy,             "dFdy",             1,   TypeF,     ClassRegular, {} },
+    BuiltInFunction{ EOpFwidth,           "fwidth",           1,   TypeF,     ClassRegular, {} },
 };
 
 // For functions declared some other way, but still use the table to relate to operator.
 struct CustomFunction {
     TOperator op;                 // operator to map the name to
     const char* name;             // function name
-    const Versioning* versioning; // nullptr means always a valid version
+    const span<const Versioning> versioning; // An empty span means always a valid version
 };
 
 const CustomFunction CustomFunctions[] = {
-    { EOpBarrier,             "barrier",             nullptr },
-    { EOpMemoryBarrierShared, "memoryBarrierShared", nullptr },
-    { EOpGroupMemoryBarrier,  "groupMemoryBarrier",  nullptr },
-    { EOpMemoryBarrier,       "memoryBarrier",       nullptr },
-    { EOpMemoryBarrierBuffer, "memoryBarrierBuffer", nullptr },
-
-    { EOpPackSnorm2x16,       "packSnorm2x16",       nullptr },
-    { EOpUnpackSnorm2x16,     "unpackSnorm2x16",     nullptr },
-    { EOpPackUnorm2x16,       "packUnorm2x16",       nullptr },
-    { EOpUnpackUnorm2x16,     "unpackUnorm2x16",     nullptr },
-    { EOpPackHalf2x16,        "packHalf2x16",        nullptr },
-    { EOpUnpackHalf2x16,      "unpackHalf2x16",      nullptr },
-
-    { EOpMul,                 "matrixCompMult",      nullptr },
-    { EOpOuterProduct,        "outerProduct",        nullptr },
-    { EOpTranspose,           "transpose",           nullptr },
-    { EOpDeterminant,         "determinant",         nullptr },
-    { EOpMatrixInverse,       "inverse",             nullptr },
-    { EOpFloatBitsToInt,      "floatBitsToInt",      nullptr },
-    { EOpFloatBitsToUint,     "floatBitsToUint",     nullptr },
-    { EOpIntBitsToFloat,      "intBitsToFloat",      nullptr },
-    { EOpUintBitsToFloat,     "uintBitsToFloat",     nullptr },
-
-    { EOpTextureQuerySize,      "textureSize",           nullptr },
-    { EOpTextureQueryLod,       "textureQueryLod",       nullptr },
-    { EOpTextureQueryLod,       "textureQueryLOD",       nullptr }, // extension GL_ARB_texture_query_lod
-    { EOpTextureQueryLevels,    "textureQueryLevels",    nullptr },
-    { EOpTextureQuerySamples,   "textureSamples",        nullptr },
-    { EOpTexture,               "texture",               nullptr },
-    { EOpTextureProj,           "textureProj",           nullptr },
-    { EOpTextureLod,            "textureLod",            nullptr },
-    { EOpTextureOffset,         "textureOffset",         nullptr },
-    { EOpTextureFetch,          "texelFetch",            nullptr },
-    { EOpTextureFetchOffset,    "texelFetchOffset",      nullptr },
-    { EOpTextureProjOffset,     "textureProjOffset",     nullptr },
-    { EOpTextureLodOffset,      "textureLodOffset",      nullptr },
-    { EOpTextureProjLod,        "textureProjLod",        nullptr },
-    { EOpTextureProjLodOffset,  "textureProjLodOffset",  nullptr },
-    { EOpTextureGrad,           "textureGrad",           nullptr },
-    { EOpTextureGradOffset,     "textureGradOffset",     nullptr },
-    { EOpTextureProjGrad,       "textureProjGrad",       nullptr },
-    { EOpTextureProjGradOffset, "textureProjGradOffset", nullptr },
-
-    { EOpNull }
+    { EOpBarrier,             "barrier",             {} },
+    { EOpMemoryBarrierShared, "memoryBarrierShared", {} },
+    { EOpGroupMemoryBarrier,  "groupMemoryBarrier",  {} },
+    { EOpMemoryBarrier,       "memoryBarrier",       {} },
+    { EOpMemoryBarrierBuffer, "memoryBarrierBuffer", {} },
+
+    { EOpPackSnorm2x16,       "packSnorm2x16",       {} },
+    { EOpUnpackSnorm2x16,     "unpackSnorm2x16",     {} },
+    { EOpPackUnorm2x16,       "packUnorm2x16",       {} },
+    { EOpUnpackUnorm2x16,     "unpackUnorm2x16",     {} },
+    { EOpPackHalf2x16,        "packHalf2x16",        {} },
+    { EOpUnpackHalf2x16,      "unpackHalf2x16",      {} },
+
+    { EOpMul,                 "matrixCompMult",      {} },
+    { EOpOuterProduct,        "outerProduct",        {} },
+    { EOpTranspose,           "transpose",           {} },
+    { EOpDeterminant,         "determinant",         {} },
+    { EOpMatrixInverse,       "inverse",             {} },
+    { EOpFloatBitsToInt,      "floatBitsToInt",      {} },
+    { EOpFloatBitsToUint,     "floatBitsToUint",     {} },
+    { EOpIntBitsToFloat,      "intBitsToFloat",      {} },
+    { EOpUintBitsToFloat,     "uintBitsToFloat",     {} },
+
+    { EOpTextureQuerySize,      "textureSize",           {} },
+    { EOpTextureQueryLod,       "textureQueryLod",       {} },
+    { EOpTextureQueryLod,       "textureQueryLOD",       {} }, // extension GL_ARB_texture_query_lod
+    { EOpTextureQueryLevels,    "textureQueryLevels",    {} },
+    { EOpTextureQuerySamples,   "textureSamples",        {} },
+    { EOpTexture,               "texture",               {} },
+    { EOpTextureProj,           "textureProj",           {} },
+    { EOpTextureLod,            "textureLod",            {} },
+    { EOpTextureOffset,         "textureOffset",         {} },
+    { EOpTextureFetch,          "texelFetch",            {} },
+    { EOpTextureFetchOffset,    "texelFetchOffset",      {} },
+    { EOpTextureProjOffset,     "textureProjOffset",     {} },
+    { EOpTextureLodOffset,      "textureLodOffset",      {} },
+    { EOpTextureProjLod,        "textureProjLod",        {} },
+    { EOpTextureProjLodOffset,  "textureProjLodOffset",  {} },
+    { EOpTextureGrad,           "textureGrad",           {} },
+    { EOpTextureGradOffset,     "textureGradOffset",     {} },
+    { EOpTextureProjGrad,       "textureProjGrad",       {} },
+    { EOpTextureProjGradOffset, "textureProjGradOffset", {} },
 };
 
 // For the given table of functions, add all the indicated prototypes for each
@@ -403,13 +396,13 @@ void AddTabledBuiltin(TString& decls, const BuiltInFunction& function)
 bool ValidVersion(const BuiltInFunction& function, int version, EProfile profile, const SpvVersion& /* spVersion */)
 {
     // nullptr means always valid
-    if (function.versioning == nullptr)
+    if (function.versioning.empty())
         return true;
 
     // check for what is said about our current profile
-    for (const Versioning* v = function.versioning; v->profiles != EBadProfile; ++v) {
-        if ((v->profiles & profile) != 0) {
-            if (v->minCoreVersion <= version || (v->numExtensions > 0 && v->minExtendedVersion <= version))
+    for (const auto& v : function.versioning) {
+        if ((v.profiles & profile) != 0) {
+            if (v.minCoreVersion <= version || (v.numExtensions > 0 && v.minExtendedVersion <= version))
                 return true;
         }
     }
@@ -422,12 +415,11 @@ bool ValidVersion(const BuiltInFunction& function, int version, EProfile profile
 // called once per stage). This is a performance issue only, not a correctness
 // concern.  It is done for quality arising from simplicity, as there are subtleties
 // to get correct if instead trying to do it surgically.
-template<class FunctionT>
-void RelateTabledBuiltins(const FunctionT* functions, TSymbolTable& symbolTable)
+template<class FunctionContainer>
+void RelateTabledBuiltins(const FunctionContainer& functions, TSymbolTable& symbolTable)
 {
-    while (functions->op != EOpNull) {
-        symbolTable.relateToOperator(functions->name, functions->op);
-        ++functions;
+    for (const auto& fn : functions) {
+        symbolTable.relateToOperator(fn.name, fn.op);
     }
 }
 
@@ -436,11 +428,10 @@ void RelateTabledBuiltins(const FunctionT* functions, TSymbolTable& symbolTable)
 // Add declarations for all tables of built-in functions.
 void TBuiltIns::addTabledBuiltins(int version, EProfile profile, const SpvVersion& spvVersion)
 {
-    const auto forEachFunction = [&](TString& decls, const BuiltInFunction* function) {
-        while (function->op != EOpNull) {
-            if (ValidVersion(*function, version, profile, spvVersion))
-                AddTabledBuiltin(decls, *function);
-            ++function;
+    const auto forEachFunction = [&](TString& decls, const span<const BuiltInFunction>& functions) {
+        for (const auto& fn : functions) {
+            if (ValidVersion(fn, version, profile, spvVersion))
+                AddTabledBuiltin(decls, fn);
         }
     };
 
@@ -1726,6 +1717,16 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
                 "vec4 shadow2DRect(sampler2DRectShadow, vec3);"     // GL_ARB_texture_rectangle, caught by keyword check
                 "vec4 shadow2DRectProj(sampler2DRectShadow, vec4);" // GL_ARB_texture_rectangle, caught by keyword check
 
+                "vec4 texture1DArray(sampler1DArray, vec2);"      // GL_EXT_texture_array
+                "vec4 texture2DArray(sampler2DArray, vec3);"      // GL_EXT_texture_array
+                "vec4 shadow1DArray(sampler1DArrayShadow, vec3);" // GL_EXT_texture_array
+                "vec4 shadow2DArray(sampler2DArrayShadow, vec4);" // GL_EXT_texture_array
+                "vec4 texture1DArray(sampler1DArray, vec2, float);"                // GL_EXT_texture_array
+                "vec4 texture2DArray(sampler2DArray, vec3, float);"                // GL_EXT_texture_array
+                "vec4 shadow1DArray(sampler1DArrayShadow, vec3, float);"           // GL_EXT_texture_array
+                "vec4 texture1DArrayLod(sampler1DArray, vec2, float);"      // GL_EXT_texture_array
+                "vec4 texture2DArrayLod(sampler2DArray, vec3, float);"      // GL_EXT_texture_array
+                "vec4 shadow1DArrayLod(sampler1DArrayShadow, vec3, float);" // GL_EXT_texture_array
                 "\n");
         }
     }
@@ -5246,7 +5247,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             stageBuiltins[EShLangVertex].append(
                 "int gl_VertexID;"            // needs qualifier fixed later
                 );
-        if (version >= 140 && spvVersion.vulkan == 0)
+        if (spvVersion.vulkan == 0)
             stageBuiltins[EShLangVertex].append(
                 "int gl_InstanceID;"          // needs qualifier fixed later
                 );
@@ -5301,6 +5302,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             stageBuiltins[EShLangVertex].append(
                 "highp   vec4  gl_Position;"  // needs qualifier fixed later
                 "mediump float gl_PointSize;" // needs qualifier fixed later
+                "highp int gl_InstanceID;" // needs qualifier fixed later
                 );
         } else {
             if (spvVersion.vulkan == 0 || spvVersion.vulkanRelaxed)
@@ -7851,6 +7853,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
         if (spvVersion.vulkan == 0) {
             SpecialQualifier("gl_VertexID",   EvqVertexId,   EbvVertexId,   symbolTable);
             SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable);
+            if (version < 140)
+                symbolTable.setVariableExtensions("gl_InstanceID", 1, &E_GL_EXT_draw_instanced);
         }
 
         if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) {
@@ -8002,6 +8006,18 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
             symbolTable.setFunctionExtensions("shadow2DEXT",        1, &E_GL_EXT_shadow_samplers);
             symbolTable.setFunctionExtensions("shadow2DProjEXT",    1, &E_GL_EXT_shadow_samplers);
         }
+
+        // E_GL_EXT_texture_array
+        if (profile != EEsProfile && spvVersion.spv == 0) {
+            symbolTable.setFunctionExtensions("texture1DArray", 1, &E_GL_EXT_texture_array);
+            symbolTable.setFunctionExtensions("texture2DArray", 1, &E_GL_EXT_texture_array);
+            symbolTable.setFunctionExtensions("shadow1DArray", 1, &E_GL_EXT_texture_array);
+            symbolTable.setFunctionExtensions("shadow2DArray", 1, &E_GL_EXT_texture_array);
+
+            symbolTable.setFunctionExtensions("texture1DArrayLod", 1, &E_GL_EXT_texture_array);
+            symbolTable.setFunctionExtensions("texture2DArrayLod", 1, &E_GL_EXT_texture_array);
+            symbolTable.setFunctionExtensions("shadow1DArrayLod", 1, &E_GL_EXT_texture_array);
+        }
         // Fall through
 
     case EShLangTessControl:
@@ -9967,6 +9983,17 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
             symbolTable.relateToOperator("textureBlockMatchSADQCOM", EOpImageBlockMatchSADQCOM);
             symbolTable.relateToOperator("textureBlockMatchSSDQCOM", EOpImageBlockMatchSSDQCOM);
         }
+
+        if (profile != EEsProfile && spvVersion.spv == 0) {
+            symbolTable.relateToOperator("texture1DArray", EOpTexture);
+            symbolTable.relateToOperator("texture2DArray", EOpTexture);
+            symbolTable.relateToOperator("shadow1DArray", EOpTexture);
+            symbolTable.relateToOperator("shadow2DArray", EOpTexture);
+
+            symbolTable.relateToOperator("texture1DArrayLod", EOpTextureLod);
+            symbolTable.relateToOperator("texture2DArrayLod", EOpTextureLod);
+            symbolTable.relateToOperator("shadow1DArrayLod", EOpTextureLod);
+        }
     }
 
     switch(language) {

+ 36 - 3
3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp

@@ -2317,6 +2317,40 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r
     return aggNode;
 }
 
+TIntermAggregate* TIntermediate::mergeAggregate(TIntermNode* left, TIntermNode* right)
+{
+    if (left == nullptr && right == nullptr)
+        return nullptr;
+
+    TIntermAggregate* aggNode = nullptr;
+    if (left != nullptr)
+        aggNode = left->getAsAggregate();
+    if (aggNode == nullptr || aggNode->getOp() != EOpNull) {
+        aggNode = new TIntermAggregate;
+        if (left != nullptr)
+            aggNode->getSequence().push_back(left);
+    }
+
+    TIntermAggregate* rhsagg = right->getAsAggregate();
+    if (rhsagg == nullptr || rhsagg->getOp() != EOpNull)
+        aggNode->getSequence().push_back(right);
+    else
+        aggNode->getSequence().insert(aggNode->getSequence().end(),
+                                      rhsagg->getSequence().begin(),
+                                      rhsagg->getSequence().end());
+
+    return aggNode;
+}
+
+TIntermAggregate* TIntermediate::mergeAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc& loc)
+{
+    TIntermAggregate* aggNode = mergeAggregate(left, right);
+    if (aggNode)
+        aggNode->setLoc(loc);
+
+    return aggNode;
+}
+
 //
 // Turn an existing node into an aggregate.
 //
@@ -2821,10 +2855,9 @@ void TIntermediate::addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguag
     //}
 
     if (language == EShLangVertex) {
-        // the names won't be found in the symbol table unless the versions are right,
-        // so version logic does not need to be repeated here
         addSymbolLinkageNode(linkage, symbolTable, "gl_VertexID");
-        addSymbolLinkageNode(linkage, symbolTable, "gl_InstanceID");
+        if ((version < 140 && requestedExtensions.find(E_GL_EXT_draw_instanced) != requestedExtensions.end()) || version >= 140)
+            addSymbolLinkageNode(linkage, symbolTable, "gl_InstanceID");
     }
 
     // Add a child to the root node for the linker objects

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

@@ -722,6 +722,24 @@ void TParseContextBase::finish()
     if (parsingBuiltins)
         return;
 
+    for (const TString& relaxedSymbol : relaxedSymbols)
+    {
+        TSymbol* symbol = symbolTable.find(relaxedSymbol);
+        TType& type = symbol->getWritableType();
+        for (const TTypeLoc& typeLoc : *type.getStruct())
+        {
+            if (typeLoc.type->isOpaque())
+            {
+                typeLoc.type->getSampler() = TSampler{};
+                typeLoc.type->setBasicType(EbtInt);
+                TString fieldName("/*");
+                fieldName.append(typeLoc.type->getFieldName());
+                fieldName.append("*/");
+                typeLoc.type->setFieldName(fieldName);
+            }
+        }
+    }
+
     // Transfer the linkage symbols to AST nodes, preserving order.
     TIntermAggregate* linkage = new TIntermAggregate;
     for (auto i = linkageSymbols.begin(); i != linkageSymbols.end(); ++i)

+ 269 - 12
3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp

@@ -993,17 +993,25 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
                 break;
             }
         }
+
         if (fieldFound) {
-            if (base->getType().getQualifier().isFrontEndConstant())
-                result = intermediate.foldDereference(base, member, loc);
-            else {
-                blockMemberExtensionCheck(loc, base, member, field);
-                TIntermTyped* index = intermediate.addConstantUnion(member, loc);
-                result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc);
-                result->setType(*(*fields)[member].type);
-                if ((*fields)[member].type->getQualifier().isIo())
-                    intermediate.addIoAccessed(field);
+            if (spvVersion.vulkan != 0 && spvVersion.vulkanRelaxed)
+                result = vkRelaxedRemapDotDereference(loc, *base, *(*fields)[member].type, field);
+
+            if (result == base)
+            {
+                if (base->getType().getQualifier().isFrontEndConstant())
+                    result = intermediate.foldDereference(base, member, loc);
+                else {
+                    blockMemberExtensionCheck(loc, base, member, field);
+                    TIntermTyped* index = intermediate.addConstantUnion(member, loc);
+                    result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc);
+                    result->setType(*(*fields)[member].type);
+                    if ((*fields)[member].type->getQualifier().isIo())
+                        intermediate.addIoAccessed(field);
+                }
             }
+
             inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier());
         } else {
             auto baseSymbol = base;
@@ -1655,7 +1663,9 @@ TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermType
         }
     } else {
         if (value->getType().isTexture() || value->getType().isImage()) {
-            if (!extensionTurnedOn(E_GL_ARB_bindless_texture))
+            if (spvVersion.spv != 0)
+                error(loc, "sampler or image cannot be used as return type when generating SPIR-V", "return", "");
+            else if (!extensionTurnedOn(E_GL_ARB_bindless_texture))
                 error(loc, "sampler or image can be used as return type only when the extension GL_ARB_bindless_texture enabled", "return", "");
         }
         branch = intermediate.addBranch(EOpReturn, value, loc);
@@ -7357,12 +7367,14 @@ void TParseContext::coopMatTypeParametersCheck(const TSourceLoc& loc, const TPub
     }
 }
 
-bool TParseContext::vkRelaxedRemapUniformVariable(const TSourceLoc& loc, TString& identifier, const TPublicType&,
+bool TParseContext::vkRelaxedRemapUniformVariable(const TSourceLoc& loc, TString& identifier, const TPublicType& publicType,
     TArraySizes*, TIntermTyped* initializer, TType& type)
 {
+    vkRelaxedRemapUniformMembers(loc, publicType, type, identifier);
+
     if (parsingBuiltins || symbolTable.atBuiltInLevel() || !symbolTable.atGlobalLevel() ||
         type.getQualifier().storage != EvqUniform ||
-        !(type.containsNonOpaque()|| type.getBasicType() == EbtAtomicUint)) {
+        !(type.containsNonOpaque() || type.getBasicType() == EbtAtomicUint || (type.containsSampler() && type.isStruct()))) {
         return false;
     }
 
@@ -7436,6 +7448,251 @@ bool TParseContext::vkRelaxedRemapUniformVariable(const TSourceLoc& loc, TString
     return true;
 }
 
+template <typename Function>
+static void ForEachOpaque(const TType& type, const TString& path, Function callback)
+{
+    auto recursion = [&callback](const TType& type, const TString& path, bool skipArray, auto& recursion) -> void {
+        if (!skipArray && type.isArray())
+        {
+            std::vector<int> indices(type.getArraySizes()->getNumDims());
+            for (int flatIndex = 0;
+                 flatIndex < type.getArraySizes()->getCumulativeSize();
+                 ++flatIndex)
+            {
+                TString subscriptPath = path;
+                for (size_t dimIndex = 0; dimIndex < indices.size(); ++dimIndex)
+                {
+                    int index = indices[dimIndex];
+                    subscriptPath.append("[");
+                    subscriptPath.append(String(index));
+                    subscriptPath.append("]");
+                }
+
+                recursion(type, subscriptPath, true, recursion);
+
+                for (size_t dimIndex = 0; dimIndex < indices.size(); ++dimIndex)
+                {
+                    ++indices[dimIndex];
+                    if (indices[dimIndex] < type.getArraySizes()->getDimSize(dimIndex))
+                        break;
+                    else
+                        indices[dimIndex] = 0;
+                }
+            }
+        }
+
+        else if (type.isStruct() && type.containsOpaque())
+        {
+            const TTypeList& types = *type.getStruct();
+            for (const TTypeLoc& typeLoc : types)
+            {
+                TString nextPath = path;
+                nextPath.append(".");
+                nextPath.append(typeLoc.type->getFieldName());
+
+                recursion(*(typeLoc.type), nextPath, false, recursion);
+            }
+        }
+
+        else if (type.isOpaque())
+        {
+            callback(type, path);
+        }
+    };
+
+    recursion(type, path, false, recursion);
+}
+
+void TParseContext::vkRelaxedRemapUniformMembers(const TSourceLoc& loc, const TPublicType& publicType, const TType& type,
+    const TString& identifier)
+{
+    if (!type.isStruct() || !type.containsOpaque())
+        return;
+
+    ForEachOpaque(type, identifier,
+                  [&publicType, &loc, this](const TType& type, const TString& path) {
+                      TArraySizes arraySizes = {};
+                      if (type.getArraySizes()) arraySizes = *type.getArraySizes();
+                      TTypeParameters typeParameters = {};
+                      if (type.getTypeParameters()) typeParameters = *type.getTypeParameters();
+
+                      TPublicType memberType{};
+                      memberType.basicType = type.getBasicType();
+                      memberType.sampler = type.getSampler();
+                      memberType.qualifier = type.getQualifier();
+                      memberType.vectorSize = type.getVectorSize();
+                      memberType.matrixCols = type.getMatrixCols();
+                      memberType.matrixRows = type.getMatrixRows();
+                      memberType.coopmatNV = type.isCoopMatNV();
+                      memberType.coopmatKHR = type.isCoopMatKHR();
+                      memberType.arraySizes = nullptr;
+                      memberType.userDef = nullptr;
+                      memberType.loc = loc;
+                      memberType.typeParameters = (type.getTypeParameters() ? &typeParameters : nullptr);
+                      memberType.spirvType = nullptr;
+
+                      memberType.qualifier.storage = publicType.qualifier.storage;
+                      memberType.shaderQualifiers = publicType.shaderQualifiers;
+
+                      TString& structMemberName = *NewPoolTString(path.c_str()); // A copy is required due to declareVariable() signature.
+                      declareVariable(loc, structMemberName, memberType, nullptr, nullptr);
+                  });
+}
+
+void TParseContext::vkRelaxedRemapFunctionParameter(TFunction* function, TParameter& param, std::vector<int>* newParams)
+{
+    function->addParameter(param);
+
+    if (!param.type->isStruct() || !param.type->containsOpaque())
+        return;
+
+    ForEachOpaque(*param.type, (param.name ? *param.name : param.type->getFieldName()),
+                  [function, param, newParams](const TType& type, const TString& path) {
+                      TString* memberName = NewPoolTString(path.c_str());
+
+                      TType* memberType = new TType();
+                      memberType->shallowCopy(type);
+                      memberType->getQualifier().storage = param.type->getQualifier().storage;
+                      memberType->clearArraySizes();
+
+                      TParameter memberParam = {};
+                      memberParam.name = memberName;
+                      memberParam.type = memberType;
+                      memberParam.defaultValue = nullptr;
+                      function->addParameter(memberParam);
+                      if (newParams)
+                          newParams->push_back(function->getParamCount()-1);
+                  });
+}
+
+//
+// Generates a valid GLSL dereferencing string for the input TIntermNode
+//
+struct AccessChainTraverser : public TIntermTraverser {
+    AccessChainTraverser() : TIntermTraverser(false, false, true)
+    {}
+
+    TString path = "";
+
+    bool visitBinary(TVisit, TIntermBinary* binary) override {
+        if (binary->getOp() == EOpIndexDirectStruct)
+        {
+            const TTypeList& members = *binary->getLeft()->getType().getStruct();
+            const TTypeLoc& member =
+                members[binary->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()];
+            TString memberName = member.type->getFieldName();
+
+            if (path != "")
+                path.append(".");
+
+            path.append(memberName);
+        }
+
+        if (binary->getOp() == EOpIndexDirect)
+        {
+            const TConstUnionArray& indices = binary->getRight()->getAsConstantUnion()->getConstArray();
+            for (int index = 0; index < indices.size(); ++index)
+            {
+                path.append("[");
+                path.append(String(indices[index].getIConst()));
+                path.append("]");
+            }
+        }
+
+        return true;
+    }
+
+    void visitSymbol(TIntermSymbol* symbol) override {
+        if (!IsAnonymous(symbol->getName()))
+            path.append(symbol->getName());
+    }
+};
+
+TIntermNode* TParseContext::vkRelaxedRemapFunctionArgument(const TSourceLoc& loc, TFunction* function, TIntermTyped* intermTyped)
+{
+    AccessChainTraverser accessChainTraverser{};
+    intermTyped->traverse(&accessChainTraverser);
+
+    TParameter param = { NewPoolTString(accessChainTraverser.path.c_str()), new TType };
+    param.type->shallowCopy(intermTyped->getType());
+
+    std::vector<int> newParams = {};
+    vkRelaxedRemapFunctionParameter(function, param, &newParams);
+
+    if (intermTyped->getType().isOpaque())
+    {
+        TIntermNode* remappedArgument = intermTyped;
+        {
+            TIntermSymbol* intermSymbol = nullptr;
+            TSymbol* symbol = symbolTable.find(*param.name);
+            if (symbol && symbol->getAsVariable())
+                intermSymbol = intermediate.addSymbol(*symbol->getAsVariable(), loc);
+            else
+            {
+                TVariable* variable = new TVariable(param.name, *param.type);
+                intermSymbol = intermediate.addSymbol(*variable, loc);
+            }
+
+            remappedArgument = intermSymbol;
+        }
+
+        return remappedArgument;
+    }
+    else if (!(intermTyped->isStruct() && intermTyped->getType().containsOpaque()))
+        return intermTyped;
+    else
+    {
+        TIntermNode* remappedArgument = intermTyped;
+        {
+            TSymbol* symbol = symbolTable.find(*param.name);
+            if (symbol && symbol->getAsVariable())
+                remappedArgument = intermediate.addSymbol(*symbol->getAsVariable(), loc);
+        }
+
+        if (!newParams.empty())
+            remappedArgument = intermediate.makeAggregate(remappedArgument, loc);
+
+        for (int paramIndex : newParams)
+        {
+            TParameter& newParam = function->operator[](paramIndex);
+            TIntermSymbol* intermSymbol = nullptr;
+            TSymbol* symbol = symbolTable.find(*newParam.name);
+            if (symbol && symbol->getAsVariable())
+                intermSymbol = intermediate.addSymbol(*symbol->getAsVariable(), loc);
+            else
+            {
+                TVariable* variable = new TVariable(newParam.name, *newParam.type);
+                intermSymbol = intermediate.addSymbol(*variable, loc);
+            }
+
+            remappedArgument = intermediate.growAggregate(remappedArgument, intermSymbol);
+        }
+
+        return remappedArgument;
+    }
+}
+
+TIntermTyped* TParseContext::vkRelaxedRemapDotDereference(const TSourceLoc&, TIntermTyped& base, const TType& member,
+    const TString& identifier)
+{
+    if (!member.isOpaque())
+        return &base;
+
+    AccessChainTraverser traverser{};
+    base.traverse(&traverser);
+    if (!traverser.path.empty())
+        traverser.path.append(".");
+    traverser.path.append(identifier);
+
+    const TSymbol* symbol = symbolTable.find(traverser.path);
+    if (!symbol)
+        return &base;
+
+    TIntermTyped* result = intermediate.addSymbol(*symbol->getAsVariable());
+    result->setType(symbol->getType());
+    return result;
+}
+
 //
 // Do everything necessary to handle a variable (non-block) declaration.
 // Either redeclaring a variable, or making a new one, updating the symbol

+ 5 - 0
3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h

@@ -180,6 +180,7 @@ public:
     // Basic parsing state, easily accessible to the grammar
 
     TSymbolTable& symbolTable;        // symbol table that goes with the current language, version, and profile
+    TVector<TString> relaxedSymbols;
     int statementNestingLevel;        // 0 if outside all flow control or compound statements
     int loopNestingLevel;             // 0 if outside all loops
     int structNestingLevel;           // 0 if outside structures
@@ -367,6 +368,10 @@ public:
     TIntermTyped* vkRelaxedRemapFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
     // returns true if the variable was remapped to something else
     bool vkRelaxedRemapUniformVariable(const TSourceLoc&, TString&, const TPublicType&, TArraySizes*, TIntermTyped*, TType&);
+    void vkRelaxedRemapUniformMembers(const TSourceLoc&, const TPublicType&, const TType&, const TString&);
+    void vkRelaxedRemapFunctionParameter(TFunction*, TParameter&, std::vector<int>* newParams = nullptr);
+    TIntermNode* vkRelaxedRemapFunctionArgument(const TSourceLoc&, TFunction*, TIntermTyped*);
+    TIntermTyped* vkRelaxedRemapDotDereference(const TSourceLoc&, TIntermTyped&, const TType&, const TString&);
 
     void assignError(const TSourceLoc&, const char* op, TString left, TString right);
     void unaryOpError(const TSourceLoc&, const char* op, TString operand);

+ 15 - 1
3rdparty/glslang/glslang/MachineIndependent/Scan.cpp

@@ -1496,6 +1496,12 @@ int TScanContext::tokenizeIdentifier()
     case USAMPLERCUBE:
     case USAMPLER2DARRAY:
         afterType = true;
+        if (keyword == SAMPLER2DARRAY || keyword == SAMPLER2DARRAYSHADOW) {
+            if (!parseContext.isEsProfile() &&
+                (parseContext.extensionTurnedOn(E_GL_EXT_texture_array) || parseContext.symbolTable.atBuiltInLevel())) {
+                return keyword;
+            }
+        }
         return nonreservedKeyword(300, 130);
 
     case SAMPLER3D:
@@ -1539,6 +1545,12 @@ int TScanContext::tokenizeIdentifier()
     case USAMPLER1D:
     case USAMPLER1DARRAY:
         afterType = true;
+        if (keyword == SAMPLER1DARRAYSHADOW) {
+            if (!parseContext.isEsProfile() &&
+                (parseContext.extensionTurnedOn(E_GL_EXT_texture_array) || parseContext.symbolTable.atBuiltInLevel())) {
+                return keyword;
+            }
+        }
         return es30ReservedFromGLSL(130);
     case ISAMPLER2DRECT:
     case USAMPLER2DRECT:
@@ -1608,7 +1620,9 @@ int TScanContext::tokenizeIdentifier()
         if (parseContext.isEsProfile() && parseContext.version == 300)
             reservedWord();
         else if ((parseContext.isEsProfile() && parseContext.version < 300) ||
-                 (!parseContext.isEsProfile() && parseContext.version < 130))
+                 ((!parseContext.isEsProfile() && parseContext.version < 130) &&
+                   !parseContext.symbolTable.atBuiltInLevel() &&
+                   !parseContext.extensionTurnedOn(E_GL_EXT_texture_array)))
             return identifierOrType();
         return keyword;
 

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

@@ -58,7 +58,6 @@
 #endif
 
 #include "../Include/ShHandle.h"
-#include "../../OGLCompilersDLL/InitializeDll.h"
 
 #include "preprocessor/PpContext.h"
 
@@ -1311,9 +1310,6 @@ bool CompileDeferred(
 //
 int ShInitialize()
 {
-    if (! InitProcess())
-        return 0;
-
     const std::lock_guard<std::mutex> lock(init_lock);
     ++NumberOfClients;
 
@@ -1335,9 +1331,6 @@ int ShInitialize()
 
 ShHandle ShConstructCompiler(const EShLanguage language, int /*debugOptions unused*/)
 {
-    if (!InitThread())
-        return nullptr;
-
     TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(language, 0));
 
     return reinterpret_cast<void*>(base);
@@ -1345,9 +1338,6 @@ ShHandle ShConstructCompiler(const EShLanguage language, int /*debugOptions unus
 
 ShHandle ShConstructLinker(const EShExecutable executable, int /*debugOptions unused*/)
 {
-    if (!InitThread())
-        return nullptr;
-
     TShHandleBase* base = static_cast<TShHandleBase*>(ConstructLinker(executable, 0));
 
     return reinterpret_cast<void*>(base);
@@ -1355,9 +1345,6 @@ ShHandle ShConstructLinker(const EShExecutable executable, int /*debugOptions un
 
 ShHandle ShConstructUniformMap()
 {
-    if (!InitThread())
-        return nullptr;
-
     TShHandleBase* base = static_cast<TShHandleBase*>(ConstructUniformMap());
 
     return reinterpret_cast<void*>(base);
@@ -1871,8 +1858,6 @@ void TShader::setFlattenUniformArrays(bool flatten)     { intermediate->setFlatt
 bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
                     bool forwardCompatible, EShMessages messages, Includer& includer)
 {
-    if (! InitThread())
-        return false;
     SetThreadPoolAllocator(pool);
 
     if (! preamble)
@@ -1897,8 +1882,6 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources,
                          std::string* output_string,
                          Includer& includer)
 {
-    if (! InitThread())
-        return false;
     SetThreadPoolAllocator(pool);
 
     if (! preamble)

+ 8 - 1
3rdparty/glslang/glslang/MachineIndependent/Versions.cpp

@@ -359,6 +359,8 @@ void TParseVersions::initializeExtensionBehavior()
     extensionBehavior[E_GL_EXT_ray_tracing_position_fetch]  = EBhDisable;
     extensionBehavior[E_GL_EXT_shader_tile_image]           = EBhDisable;
     extensionBehavior[E_GL_EXT_texture_shadow_lod]          = EBhDisable;
+    extensionBehavior[E_GL_EXT_draw_instanced]              = EBhDisable;
+    extensionBehavior[E_GL_EXT_texture_array]               = EBhDisable;
 
     // OVR extensions
     extensionBehavior[E_GL_OVR_multiview]                = EBhDisable;
@@ -487,7 +489,7 @@ void TParseVersions::getPreamble(std::string& preamble)
             "#define GL_ARB_vertex_attrib_64bit 1\n"
             "#define GL_ARB_draw_instanced 1\n"
             "#define GL_ARB_fragment_coord_conventions 1\n"
-            "#define GL_ARB_bindless_texture 1\n"
+
             "#define GL_EXT_shader_non_constant_global_initializers 1\n"
             "#define GL_EXT_shader_image_load_formatted 1\n"
             "#define GL_EXT_post_depth_coverage 1\n"
@@ -580,8 +582,13 @@ void TParseVersions::getPreamble(std::string& preamble)
             "#define GL_EXT_shader_atomic_float2 1\n"
 
             "#define GL_EXT_fragment_shader_barycentric 1\n"
+            "#define GL_EXT_texture_array 1\n"
             ;
 
+        if (spvVersion.spv == 0) {
+            preamble += "#define GL_ARB_bindless_texture 1\n";
+        }
+
         if (version >= 150) {
             // define GL_core_profile and GL_compatibility_profile
             preamble += "#define GL_core_profile 1\n";

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

@@ -215,6 +215,8 @@ const char* const E_GL_EXT_spirv_intrinsics                 = "GL_EXT_spirv_intr
 const char* const E_GL_EXT_fragment_shader_barycentric      = "GL_EXT_fragment_shader_barycentric";
 const char* const E_GL_EXT_mesh_shader                      = "GL_EXT_mesh_shader";
 const char* const E_GL_EXT_opacity_micromap                 = "GL_EXT_opacity_micromap";
+const char* const E_GL_EXT_draw_instanced                   = "GL_EXT_draw_instanced";
+const char* const E_GL_EXT_texture_array                    = "GL_EXT_texture_array";
 
 // Arrays of extensions for the above viewportEXTs duplications
 

+ 49 - 19
3rdparty/glslang/glslang/MachineIndependent/glslang.y

@@ -110,13 +110,6 @@ using namespace glslang;
 
 %{
 
-/* windows only pragma */
-#ifdef _MSC_VER
-    #pragma warning(disable : 4065)
-    #pragma warning(disable : 4127)
-    #pragma warning(disable : 4244)
-#endif
-
 #define parseContext (*pParseContext)
 #define yyerror(context, msg) context->parserError(msg)
 
@@ -492,18 +485,41 @@ function_call_header_no_parameters
 
 function_call_header_with_parameters
     : function_call_header assignment_expression {
-        TParameter param = { 0, new TType };
-        param.type->shallowCopy($2->getType());
-        $1.function->addParameter(param);
-        $$.function = $1.function;
-        $$.intermNode = $2;
+        if (parseContext.spvVersion.vulkan > 0
+            && parseContext.spvVersion.vulkanRelaxed
+            && $2->getType().containsOpaque())
+        {
+            $$.intermNode = parseContext.vkRelaxedRemapFunctionArgument($$.loc, $1.function, $2);
+            $$.function = $1.function;
+        }
+        else
+        {
+            TParameter param = { 0, new TType };
+            param.type->shallowCopy($2->getType());
+
+            $1.function->addParameter(param);
+            $$.function = $1.function;
+            $$.intermNode = $2;
+        }
     }
     | function_call_header_with_parameters COMMA assignment_expression {
-        TParameter param = { 0, new TType };
-        param.type->shallowCopy($3->getType());
-        $1.function->addParameter(param);
-        $$.function = $1.function;
-        $$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.loc);
+        if (parseContext.spvVersion.vulkan > 0
+            && parseContext.spvVersion.vulkanRelaxed
+            && $3->getType().containsOpaque())
+        {
+            TIntermNode* remappedNode = parseContext.vkRelaxedRemapFunctionArgument($2.loc, $1.function, $3);
+            $$.intermNode = parseContext.intermediate.mergeAggregate($1.intermNode, remappedNode, $2.loc);
+            $$.function = $1.function;
+        }
+        else
+        {
+            TParameter param = { 0, new TType };
+            param.type->shallowCopy($3->getType());
+
+            $1.function->addParameter(param);
+            $$.function = $1.function;
+            $$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.loc);
+        }
     }
     ;
 
@@ -980,7 +996,12 @@ function_header_with_parameters
         // Add the parameter
         $$ = $1;
         if ($2.param.type->getBasicType() != EbtVoid)
-            $1->addParameter($2.param);
+        {
+            if (!(parseContext.spvVersion.vulkan > 0 && parseContext.spvVersion.vulkanRelaxed))
+                $1->addParameter($2.param);
+            else
+                parseContext.vkRelaxedRemapFunctionParameter($1, $2.param);
+        }
         else
             delete $2.param.type;
     }
@@ -998,7 +1019,10 @@ function_header_with_parameters
         } else {
             // Add the parameter
             $$ = $1;
-            $1->addParameter($3.param);
+            if (!(parseContext.spvVersion.vulkan > 0 && parseContext.spvVersion.vulkanRelaxed))
+                $1->addParameter($3.param);
+            else
+                parseContext.vkRelaxedRemapFunctionParameter($1, $3.param);
         }
     }
     ;
@@ -3549,11 +3573,17 @@ 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);
+
         TVariable* userTypeDef = new TVariable($2.string, *structure, true);
         if (! parseContext.symbolTable.insert(*userTypeDef))
             parseContext.error($2.loc, "redefinition", $2.string->c_str(), "struct");
+        else if (parseContext.spvVersion.vulkanRelaxed
+                 && structure->containsOpaque())
+            parseContext.relaxedSymbols.push_back(structure->getTypeName());
+
         $$.init($1.loc);
         $$.basicType = EbtStruct;
         $$.userDef = structure;

File diff suppressed because it is too large
+ 256 - 240
3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp


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

@@ -528,6 +528,8 @@ public:
     TOperator mapTypeToConstructorOp(const TType&) const;
     TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right);
     TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&);
+    TIntermAggregate* mergeAggregate(TIntermNode* left, TIntermNode* right);
+    TIntermAggregate* mergeAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&);
     TIntermAggregate* makeAggregate(TIntermNode* node);
     TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&);
     TIntermAggregate* makeAggregate(const TSourceLoc&);

+ 29 - 8
3rdparty/glslang/glslang/MachineIndependent/preprocessor/PpContext.h

@@ -86,11 +86,6 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "../ParseHelper.h"
 #include "PpTokens.h"
 
-/* windows only pragma */
-#ifdef _MSC_VER
-    #pragma warning(disable : 4127)
-#endif
-
 namespace glslang {
 
 class TPpToken {
@@ -220,6 +215,7 @@ public:
         virtual bool peekContinuedPasting(int) { return false; } // true when non-spaced tokens can paste
         virtual bool endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define)
         virtual bool isMacroInput() { return false; }
+        virtual bool isStringInput() { return false; }
 
         // Will be called when we start reading tokens from this instance
         virtual void notifyActivated() {}
@@ -360,7 +356,8 @@ protected:
     // Scanner data:
     int previous_token;
     TParseContextBase& parseContext;
-
+    std::vector<int> lastLineTokens;
+    std::vector<TSourceLoc> lastLineTokenLocs;
     // Get the next token from *stack* of input sources, popping input sources
     // that are out of tokens, down until an input source is found that has a token.
     // Return EndOfInput when there are no more tokens to be found by doing this.
@@ -374,7 +371,31 @@ protected:
                 break;
             popInput();
         }
-
+        if (!inputStack.empty() && inputStack.back()->isStringInput()) {
+            if (token == '\n') {
+                bool seenNumSign = false;
+                for (int i = 0; i < (int)lastLineTokens.size() - 1;) {
+                    int curPos = i;
+                    int curToken = lastLineTokens[i++];
+                    if (curToken == '#' && lastLineTokens[i] == '#') {
+                        curToken = PpAtomPaste;
+                        i++;
+                    }
+                    if (curToken == '#') {
+                        if (seenNumSign) {
+                            parseContext.ppError(lastLineTokenLocs[curPos], "(#) can be preceded in its line only by spaces or horizontal tabs", "#", "");
+                        } else {
+                            seenNumSign = true;
+                        }
+                    }
+                }
+                lastLineTokens.clear();
+                lastLineTokenLocs.clear();
+            } else {
+                lastLineTokens.push_back(token);
+                lastLineTokenLocs.push_back(ppToken->loc);
+            }
+        }
         return token;
     }
     int  getChar() { return inputStack.back()->getch(); }
@@ -527,7 +548,7 @@ protected:
     public:
         tStringInput(TPpContext* pp, TInputScanner& i) : tInput(pp), input(&i) { }
         virtual int scan(TPpToken*) override;
-
+        bool isStringInput() override { return true; }
         // Scanner used to get source stream characters.
         //  - Escaped newlines are handled here, invisibly to the caller.
         //  - All forms of newline are handled, and turned into just a '\n'.

+ 92 - 0
3rdparty/glslang/glslang/MachineIndependent/span.h

@@ -0,0 +1,92 @@
+#pragma once
+
+//
+// Copyright (C) 2023 LunarG, Inc.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//    Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//
+//    Redistributions in binary form must reproduce the above
+//    copyright notice, this list of conditions and the following
+//    disclaimer in the documentation and/or other materials provided
+//    with the distribution.
+//
+//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+
+// Partial implementation of std::span for C++11
+// Replace with std::span if repo standard is bumped to C++20
+//
+// This code was copied from https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/main/layers/containers/custom_containers.h
+template <typename T>
+class span {
+  public:
+    using pointer = T *;
+    using const_pointer = T const *;
+    using iterator = pointer;
+    using const_iterator = const_pointer;
+
+    span() = default;
+    span(pointer start, size_t n) : data_(start), count_(n) {}
+    template <typename Iterator>
+    span(Iterator start, Iterator end) : data_(&(*start)), count_(end - start) {}
+    template <typename Container>
+    span(Container &c) : data_(c.data()), count_(c.size()) {}
+
+    iterator begin() { return data_; }
+    const_iterator begin() const { return data_; }
+
+    iterator end() { return data_ + count_; }
+    const_iterator end() const { return data_ + count_; }
+
+    T &operator[](int i) { return data_[i]; }
+    const T &operator[](int i) const { return data_[i]; }
+
+    T &front() { return *data_; }
+    const T &front() const { return *data_; }
+
+    T &back() { return *(data_ + (count_ - 1)); }
+    const T &back() const { return *(data_ + (count_ - 1)); }
+
+    size_t size() const { return count_; }
+    bool empty() const { return count_ == 0; }
+
+    pointer data() { return data_; }
+    const_pointer data() const { return data_; }
+
+  private:
+    pointer data_ = {};
+    size_t count_ = 0;
+};
+
+//
+// Allow type inference that using the constructor doesn't allow in C++11
+template <typename T>
+span<T> make_span(T *begin, size_t count) {
+    return span<T>(begin, count);
+}
+template <typename T>
+span<T> make_span(T *begin, T *end) {
+    return make_span<T>(begin, end);
+}

+ 1 - 15
3rdparty/glslang/glslang/ResourceLimits/resource_limits_c.cpp

@@ -42,28 +42,14 @@ const glslang_resource_t* glslang_default_resource(void)
     return reinterpret_cast<const glslang_resource_t*>(GetDefaultResources());
 }
 
-#if defined(__clang__) || defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#elif defined(_MSC_VER)
-#pragma warning(push)
-#pragma warning(disable : 4996)
-#endif
-
 const char* glslang_default_resource_string()
 {
     std::string cpp_str = GetDefaultTBuiltInResourceString();
     char* c_str = (char*)malloc(cpp_str.length() + 1);
-    strcpy(c_str, cpp_str.c_str());
+    strncpy(c_str, cpp_str.c_str(), cpp_str.length() + 1);
     return c_str;
 }
 
-#if defined(__clang__) || defined(__GNUC__)
-#pragma GCC diagnostic pop
-#elif defined(_MSC_VER)
-#pragma warning(pop)
-#endif
-
 void glslang_decode_resource_limits(glslang_resource_t* resources, char* config)
 {
     DecodeResourceLimits(reinterpret_cast<TBuiltInResource*>(resources), config);

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