Browse Source

Updated glslang.

Бранимир Караџић 4 years ago
parent
commit
e6636b8b5f

+ 11 - 0
3rdparty/glslang/CHANGES.md

@@ -3,6 +3,17 @@
 All notable changes to this project will be documented in this file.
 This project adheres to [Semantic Versioning](https://semver.org/).
 
+## 11.6.0 2021-08-25
+
+### Other changes
+* Atomic memory function only for shader storage block member or shared variable
+* Add support for gl_MaxVaryingVectors for ogl
+* Fix loading bool arrays from interface blocks
+* Generate separate stores for partially swizzled memory stores
+* Allow layout(std430) uniform with GL_EXT_scalar_block_layout
+* Support for pragma STDGL invariant(all)
+* Support for GL_NV_ray_tracing_motion_blur
+
 ## 11.5.0 2021-06-23
 
 ### Other changes

+ 12 - 6
3rdparty/glslang/SPIRV/GlslangToSpv.cpp

@@ -3384,7 +3384,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
         const auto& spirvInst = node->getSpirvInstruction();
         if (spirvInst.set == "") {
             std::vector<spv::IdImmediate> idImmOps;
-            for (int i = 0; i < glslangOperands.size(); ++i) {
+            for (unsigned int i = 0; i < glslangOperands.size(); ++i) {
                 if (glslangOperands[i]->getAsTyped()->getQualifier().isSpirvLiteral()) {
                     // Translate the constant to a literal value
                     std::vector<unsigned> literals;
@@ -3940,12 +3940,14 @@ spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler)
             builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float_fetch);
             builder.addCapability(spv::CapabilityFloat16ImageAMD);
             return builder.makeFloatType(16);
-        case glslang::EbtInt64:      return builder.makeIntType(64);
+        case glslang::EbtInt64:
             builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
-            builder.addCapability(spv::CapabilityFloat16ImageAMD);
-        case glslang::EbtUint64:     return builder.makeUintType(64);
+            builder.addCapability(spv::CapabilityInt64ImageEXT);
+            return builder.makeIntType(64);
+        case glslang::EbtUint64:
             builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
-            builder.addCapability(spv::CapabilityFloat16ImageAMD);
+            builder.addCapability(spv::CapabilityInt64ImageEXT);
+            return builder.makeUintType(64);
 #endif
         default:
             assert(0);
@@ -7506,6 +7508,8 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op
         break;
     case glslang::EOpReadFirstInvocation:
         opCode = spv::OpSubgroupFirstInvocationKHR;
+        if (builder.isVectorType(typeId))
+            return CreateInvocationsVectorOperation(opCode, groupOperation, typeId, operands);
         break;
     case glslang::EOpBallot:
     {
@@ -7630,7 +7634,7 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv
     assert(op == spv::OpGroupFMin || op == spv::OpGroupUMin || op == spv::OpGroupSMin ||
            op == spv::OpGroupFMax || op == spv::OpGroupUMax || op == spv::OpGroupSMax ||
            op == spv::OpGroupFAdd || op == spv::OpGroupIAdd || op == spv::OpGroupBroadcast ||
-           op == spv::OpSubgroupReadInvocationKHR ||
+           op == spv::OpSubgroupReadInvocationKHR || op == spv::OpSubgroupFirstInvocationKHR ||
            op == spv::OpGroupFMinNonUniformAMD || op == spv::OpGroupUMinNonUniformAMD ||
            op == spv::OpGroupSMinNonUniformAMD ||
            op == spv::OpGroupFMaxNonUniformAMD || op == spv::OpGroupUMaxNonUniformAMD ||
@@ -7659,6 +7663,8 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv
             spvGroupOperands.push_back(scalar);
             spv::IdImmediate operand = { true, operands[1] };
             spvGroupOperands.push_back(operand);
+        } else if (op == spv::OpSubgroupFirstInvocationKHR) {
+            spvGroupOperands.push_back(scalar);
         } else if (op == spv::OpGroupBroadcast) {
             spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) };
             spvGroupOperands.push_back(scope);

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

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

+ 3 - 3
3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp

@@ -4017,12 +4017,12 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
             txsample->getSequence().push_back(txcombine);
             txsample->getSequence().push_back(argCoord);
 
-            if (argBias != nullptr)
-                txsample->getSequence().push_back(argBias);
-
             if (argOffset != nullptr)
                 txsample->getSequence().push_back(argOffset);
 
+            if (argBias != nullptr)
+              txsample->getSequence().push_back(argBias);
+
             node = convertReturn(txsample, sampler);
 
             break;

+ 2 - 2
3rdparty/glslang/glslang/HLSL/hlslParseables.cpp

@@ -665,8 +665,8 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
         { "Sample",             /*!O*/        "V4",    nullptr,   "%@,S,V",         "FIU,S,F",        EShLangPS,    true },
         { "Sample",             /* O*/        "V4",    nullptr,   "%@,S,V,",        "FIU,S,F,I",      EShLangPS,    true },
 
-        { "SampleBias",         /*!O*/        "V4",    nullptr,   "%@,S,V,S",       "FIU,S,F,",       EShLangPS,    true },
-        { "SampleBias",         /* O*/        "V4",    nullptr,   "%@,S,V,S,V",     "FIU,S,F,,I",     EShLangPS,    true },
+        { "SampleBias",         /*!O*/        "V4",    nullptr,   "%@,S,V,S",       "FIU,S,F,F",      EShLangPS,    true },
+        { "SampleBias",         /* O*/        "V4",    nullptr,   "%@,S,V,S,V",     "FIU,S,F,F,I",    EShLangPS,    true },
 
         // TODO: FXC accepts int/uint samplers here.  unclear what that means.
         { "SampleCmp",          /*!O*/        "S",     "F",       "%@,S,V,S",       "FIU,s,F,",       EShLangPS,    true },

+ 2 - 2
3rdparty/glslang/glslang/Include/Common.h

@@ -62,7 +62,7 @@ std::string to_string(const T& val) {
 }
 #endif
 
-#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || defined MINGW_HAS_SECURE_API
+#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || MINGW_HAS_SECURE_API
     #include <basetsd.h>
     #ifndef snprintf
     #define snprintf sprintf_s
@@ -214,7 +214,7 @@ template <class T> T Max(const T a, const T b) { return a > b ? a : b; }
 //
 // Create a TString object from an integer.
 //
-#if defined _MSC_VER || defined MINGW_HAS_SECURE_API
+#if defined _MSC_VER || MINGW_HAS_SECURE_API
 inline const TString String(const int i, const int base = 10)
 {
     char text[16];     // 32 bit ints are at most 10 digits in base 10

+ 10 - 0
3rdparty/glslang/glslang/Include/Types.h

@@ -741,6 +741,16 @@ public:
         }
     }
 
+    bool isUniform() const
+    {
+        switch (storage) {
+        case EvqUniform:
+            return true;
+        default:
+            return false;
+        }
+    }
+
     bool isIo() const
     {
         switch (storage) {

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

@@ -1643,6 +1643,7 @@ public:
     ~TIntermAggregate() { delete pragmaTable; }
     virtual       TIntermAggregate* getAsAggregate()       { return this; }
     virtual const TIntermAggregate* getAsAggregate() const { return this; }
+    virtual void updatePrecision();
     virtual void setOperator(TOperator o) { op = o; }
     virtual       TIntermSequence& getSequence()       { return sequence; }
     virtual const TIntermSequence& getSequence() const { return sequence; }

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

@@ -531,7 +531,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
             case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
             // Note: avoid UBSAN error regarding negating 0x80000000
             case EbtInt:   newConstArray[i].setIConst(
-                                unionArray[i].getIConst() == 0x80000000
+                                static_cast<unsigned int>(unionArray[i].getIConst()) == 0x80000000
                                     ? -0x7FFFFFFF - 1
                                     : -unionArray[i].getIConst());
                            break;

+ 7 - 2
3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp

@@ -7701,6 +7701,11 @@ static void BuiltInVariable(const char* name, TBuiltInVariable builtIn, TSymbolT
     symQualifier.builtIn = builtIn;
 }
 
+static void RetargetVariable(const char* from, const char* to, TSymbolTable& symbolTable)
+{
+    symbolTable.retargetSymbol(from, to);
+}
+
 //
 // For built-in variables inside a named block.
 // SpecialQualifier() won't ever go inside a block; their member's qualifier come
@@ -7768,8 +7773,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
 
         if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) {
             // treat these built-ins as aliases of VertexIndex and InstanceIndex
-            BuiltInVariable("gl_VertexID", EbvVertexIndex, symbolTable);
-            BuiltInVariable("gl_InstanceID", EbvInstanceIndex, symbolTable);
+            RetargetVariable("gl_InstanceID", "gl_InstanceIndex", symbolTable);
+            RetargetVariable("gl_VertexID", "gl_VertexIndex", symbolTable);
         }
 
         if (profile != EEsProfile) {

+ 40 - 14
3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp

@@ -416,20 +416,24 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child,
     // TODO: but, did this bypass constant folding?
     //
     switch (op) {
-    case EOpConstructInt8:
-    case EOpConstructUint8:
-    case EOpConstructInt16:
-    case EOpConstructUint16:
-    case EOpConstructInt:
-    case EOpConstructUint:
-    case EOpConstructInt64:
-    case EOpConstructUint64:
-    case EOpConstructBool:
-    case EOpConstructFloat:
-    case EOpConstructDouble:
-    case EOpConstructFloat16:
-        return child;
-    default: break; // some compilers want this
+        case EOpConstructInt8:
+        case EOpConstructUint8:
+        case EOpConstructInt16:
+        case EOpConstructUint16:
+        case EOpConstructInt:
+        case EOpConstructUint:
+        case EOpConstructInt64:
+        case EOpConstructUint64:
+        case EOpConstructBool:
+        case EOpConstructFloat:
+        case EOpConstructDouble:
+        case EOpConstructFloat16: {
+            TIntermUnary* unary_node = child->getAsUnaryNode();
+            if (unary_node != nullptr)
+                unary_node->updatePrecision();
+            return child;
+        }
+        default: break; // some compilers want this
     }
 
     //
@@ -3776,6 +3780,28 @@ bool TIntermediate::promoteAggregate(TIntermAggregate& node)
     return false;
 }
 
+// Propagate precision qualifiers *up* from children to parent, and then
+// back *down* again to the children's subtrees.
+void TIntermAggregate::updatePrecision()
+{
+    if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
+        getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
+        TPrecisionQualifier maxPrecision = EpqNone;
+        TIntermSequence operands = getSequence();
+        for (unsigned int i = 0; i < operands.size(); ++i) {
+            TIntermTyped* typedNode = operands[i]->getAsTyped();
+            assert(typedNode);
+            maxPrecision = std::max(maxPrecision, typedNode->getQualifier().precision);
+        }
+        getQualifier().precision = maxPrecision;
+        for (unsigned int i = 0; i < operands.size(); ++i) {
+          TIntermTyped* typedNode = operands[i]->getAsTyped();
+          assert(typedNode);
+          typedNode->propagatePrecision(maxPrecision);
+        }
+    }
+}
+
 // Propagate precision qualifiers *up* from children to parent, and then
 // back *down* again to the children's subtrees.
 void TIntermBinary::updatePrecision()

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

@@ -622,6 +622,19 @@ void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& mem
     globalUniformBlock->getWritableType().getQualifier().layoutBinding = globalUniformBinding;
     globalUniformBlock->getWritableType().getQualifier().layoutSet = globalUniformSet;
 
+    // Check for declarations of this default uniform that already exist due to other compilation units.
+    TSymbol* symbol = symbolTable.find(memberName);
+    if (symbol) {
+        if (memberType != symbol->getType()) {
+            TString err;
+            err += "\"" + memberType.getCompleteString() + "\"";
+            err += " versus ";
+            err += "\"" + symbol->getType().getCompleteString() + "\"";
+            error(loc, "Types must match:", memberType.getFieldName().c_str(), err.c_str());
+        }
+        return;
+    }
+
     // Add the requested member as a member to the global block.
     TType* type = new TType;
     type->shallowCopy(memberType);

+ 7 - 1
3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp

@@ -7691,7 +7691,13 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
             return nullptr;
     }
 
-    return intermediate.setAggregateOperator(aggrNode, op, type, loc);
+    TIntermTyped *ret_node = intermediate.setAggregateOperator(aggrNode, op, type, loc);
+
+    TIntermAggregate *agg_node = ret_node->getAsAggregate();
+    if (agg_node && (agg_node->isVector() || agg_node->isArray() || agg_node->isMatrix()))
+        agg_node->updatePrecision();
+
+    return ret_node;
 }
 
 // Function for constructor implementation. Calls addUnaryMath with appropriate EOp value

+ 2 - 2
3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h

@@ -241,7 +241,7 @@ protected:
     // override this to set the language-specific name
     virtual const char* getAtomicCounterBlockName() const { return ""; }
     virtual void setAtomicCounterBlockDefaults(TType&) const {}
-    virtual void setInvariant(const TSourceLoc& loc, const char* builtin) {}
+    virtual void setInvariant(const TSourceLoc&, const char*) {}
     virtual void finalizeAtomicCounterBlockLayout(TVariable&) {}
     bool isAtomicCounterBlock(const TSymbol& symbol) {
         const TVariable* var = symbol.getAsVariable();
@@ -472,7 +472,7 @@ public:
     // Determine loop control from attributes
     void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
     // Function attributes
-    void handleFunctionAttributes(const TSourceLoc&, const TAttributes&, TFunction*);
+    void handleFunctionAttributes(const TSourceLoc&, const TAttributes&);
 
     // GL_EXT_spirv_intrinsics
     TSpirvRequirement* makeSpirvRequirement(const TSourceLoc& loc, const TString& name,

+ 35 - 3
3rdparty/glslang/glslang/MachineIndependent/SymbolTable.cpp

@@ -279,8 +279,14 @@ TFunction::~TFunction()
 //
 TSymbolTableLevel::~TSymbolTableLevel()
 {
-    for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
-        delete (*it).second;
+    for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
+        const TString& name = it->first;
+        auto retargetIter = std::find_if(retargetedSymbols.begin(), retargetedSymbols.end(),
+                                      [&name](const std::pair<TString, TString>& i) { return i.first == name; });
+        if (retargetIter == retargetedSymbols.end())
+            delete (*it).second;
+    }
+
 
     delete [] defaultPrecision;
 }
@@ -418,6 +424,15 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
     TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
     symTableLevel->anonId = anonId;
     symTableLevel->thisLevel = thisLevel;
+    symTableLevel->retargetedSymbols.clear();
+    for (auto &s : retargetedSymbols) {
+        // Extra constructions to make sure they use the correct allocator pool
+        TString newFrom;
+        newFrom = s.first;
+        TString newTo;
+        newTo = s.second;
+        symTableLevel->retargetedSymbols.push_back({std::move(newFrom), std::move(newTo)});
+    }
     std::vector<bool> containerCopied(anonId, false);
     tLevel::const_iterator iter;
     for (iter = level.begin(); iter != level.end(); ++iter) {
@@ -433,8 +448,25 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
                 symTableLevel->insert(*container, false);
                 containerCopied[anon->getAnonId()] = true;
             }
-        } else
+        } else {
+            const TString& name = iter->first;
+            auto retargetIter = std::find_if(retargetedSymbols.begin(), retargetedSymbols.end(),
+                                          [&name](const std::pair<TString, TString>& i) { return i.first == name; });
+            if (retargetIter != retargetedSymbols.end())
+                continue;
             symTableLevel->insert(*iter->second->clone(), false);
+        }
+    }
+    // Now point retargeted symbols to the newly created versions of them
+    for (auto &s : retargetedSymbols) {
+        TSymbol* sym = symTableLevel->find(s.second);
+        if (!sym)
+            continue;
+
+        // Need to declare and assign so newS is using the correct pool allocator
+        TString newS;
+        newS = s.first;
+        symTableLevel->insert(newS, sym);
     }
 
     return symTableLevel;

+ 27 - 2
3rdparty/glslang/glslang/MachineIndependent/SymbolTable.h

@@ -413,13 +413,20 @@ public:
     TSymbolTableLevel() : defaultPrecision(0), anonId(0), thisLevel(false) { }
     ~TSymbolTableLevel();
 
-    bool insert(TSymbol& symbol, bool separateNameSpaces)
+    bool insert(const TString& name, TSymbol* symbol) {
+        return level.insert(tLevelPair(name, symbol)).second;
+    }
+
+    bool insert(TSymbol& symbol, bool separateNameSpaces, const TString& forcedKeyName = TString())
     {
         //
         // returning true means symbol was added to the table with no semantic errors
         //
         const TString& name = symbol.getName();
-        if (name == "") {
+        if (forcedKeyName.length()) {
+            return level.insert(tLevelPair(forcedKeyName, &symbol)).second;
+        }
+        else if (name == "") {
             symbol.getAsVariable()->setAnonId(anonId++);
             // An empty name means an anonymous container, exposing its members to the external scope.
             // Give it a name and insert its members in the symbol table, pointing to the container.
@@ -471,6 +478,16 @@ public:
         return true;
     }
 
+    void retargetSymbol(const TString& from, const TString& to) {
+        tLevel::const_iterator fromIt = level.find(from);
+        tLevel::const_iterator toIt = level.find(to);
+        if (fromIt == level.end() || toIt == level.end())
+            return;
+        delete fromIt->second;
+        level[from] = toIt->second;
+        retargetedSymbols.push_back({from, to});
+    }
+
     TSymbol* find(const TString& name) const
     {
         tLevel::const_iterator it = level.find(name);
@@ -583,6 +600,8 @@ protected:
 
     tLevel level;  // named mappings
     TPrecisionQualifier *defaultPrecision;
+    // pair<FromName, ToName>
+    TVector<std::pair<TString, TString>> retargetedSymbols;
     int anonId;
     bool thisLevel;  // True if this level of the symbol table is a structure scope containing member function
                      // that are supposed to see anonymous access to member variables.
@@ -788,6 +807,12 @@ public:
         return symbol;
     }
 
+    void retargetSymbol(const TString& from, const TString& to) {
+        int level = currentLevel();
+        table[level]->retargetSymbol(from, to);
+    }
+
+
     // Find of a symbol that returns how many layers deep of nested
     // structures-with-member-functions ('this' scopes) deep the symbol was
     // found in.

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

@@ -347,7 +347,7 @@ void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermN
 //
 // Function attributes
 //
-void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttributes& attributes, TFunction* function)
+void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttributes& attributes)
 {
     for (auto it = attributes.begin(); it != attributes.end(); ++it) {
         if (it->size() > 0) {

+ 6 - 4
3rdparty/glslang/glslang/MachineIndependent/glslang.m4

@@ -983,20 +983,20 @@ function_prototype
         $$.function = $1;
         $$.loc = $2.loc;
         parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
-        parseContext.handleFunctionAttributes($2.loc, *$3, $$.function);
+        parseContext.handleFunctionAttributes($2.loc, *$3);
     }
     | attribute function_declarator RIGHT_PAREN {
         $$.function = $2;
         $$.loc = $3.loc;
         parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
-        parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
+        parseContext.handleFunctionAttributes($3.loc, *$1);
     }
     | attribute function_declarator RIGHT_PAREN attribute {
         $$.function = $2;
         $$.loc = $3.loc;
         parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
-        parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
-        parseContext.handleFunctionAttributes($3.loc, *$4, $$.function);
+        parseContext.handleFunctionAttributes($3.loc, *$1);
+        parseContext.handleFunctionAttributes($3.loc, *$4);
     }
     ;
 
@@ -3926,6 +3926,7 @@ iteration_statement_nonattributed
         --parseContext.controlFlowNestingLevel;
     }
     | DO {
+        parseContext.symbolTable.push();
         ++parseContext.loopNestingLevel;
         ++parseContext.statementNestingLevel;
         ++parseContext.controlFlowNestingLevel;
@@ -3937,6 +3938,7 @@ iteration_statement_nonattributed
         parseContext.boolCheck($8.loc, $6);
 
         $$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc);
+        parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
         --parseContext.loopNestingLevel;
         --parseContext.statementNestingLevel;
         --parseContext.controlFlowNestingLevel;

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

@@ -983,20 +983,20 @@ function_prototype
         $$.function = $1;
         $$.loc = $2.loc;
         parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
-        parseContext.handleFunctionAttributes($2.loc, *$3, $$.function);
+        parseContext.handleFunctionAttributes($2.loc, *$3);
     }
     | attribute function_declarator RIGHT_PAREN {
         $$.function = $2;
         $$.loc = $3.loc;
         parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
-        parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
+        parseContext.handleFunctionAttributes($3.loc, *$1);
     }
     | attribute function_declarator RIGHT_PAREN attribute {
         $$.function = $2;
         $$.loc = $3.loc;
         parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
-        parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
-        parseContext.handleFunctionAttributes($3.loc, *$4, $$.function);
+        parseContext.handleFunctionAttributes($3.loc, *$1);
+        parseContext.handleFunctionAttributes($3.loc, *$4);
     }
     ;
 
@@ -3926,6 +3926,7 @@ iteration_statement_nonattributed
         --parseContext.controlFlowNestingLevel;
     }
     | DO {
+        parseContext.symbolTable.push();
         ++parseContext.loopNestingLevel;
         ++parseContext.statementNestingLevel;
         ++parseContext.controlFlowNestingLevel;
@@ -3937,6 +3938,7 @@ iteration_statement_nonattributed
         parseContext.boolCheck($8.loc, $6);
 
         $$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc);
+        parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
         --parseContext.loopNestingLevel;
         --parseContext.statementNestingLevel;
         --parseContext.controlFlowNestingLevel;

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


+ 31 - 0
3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp

@@ -1633,6 +1633,37 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) {
             return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
         });
         resolver->endResolve(EShLangCount);
+        if (autoPushConstantBlockName.length()) {
+            bool upgraded = false;
+            for (size_t stage = 0; stage < EShLangCount; stage++) {
+                if (intermediates[stage] != nullptr) {
+                    TVarLiveMap** pUniformVarMap = uniformResolve.uniformVarMap;
+                    auto at = pUniformVarMap[stage]->find(autoPushConstantBlockName);
+                    if (at == pUniformVarMap[stage]->end())
+                        continue;
+                    TQualifier& qualifier = at->second.symbol->getQualifier();
+                    if (!qualifier.isUniform())
+                        continue;
+                    TType& t = at->second.symbol->getWritableType();
+                    int size, stride;
+                    TIntermediate::getBaseAlignment(t, size, stride, autoPushConstantBlockPacking,
+                                                    qualifier.layoutMatrix == ElmRowMajor);
+                    if (size <= int(autoPushConstantMaxSize)) {
+                        qualifier.setBlockStorage(EbsPushConstant);
+                        qualifier.layoutPacking = autoPushConstantBlockPacking;
+                        upgraded = true;
+                    }
+                }
+            }
+            // If it's been upgraded to push_constant, then remove it from the uniformVector
+            // so it doesn't get a set/binding assigned to it.
+            if (upgraded) {
+                auto at = std::find_if(uniformVector.begin(), uniformVector.end(),
+                                       [this](const TVarLivePair& p) { return p.first == autoPushConstantBlockName; });
+                if (at != uniformVector.end())
+                    uniformVector.erase(at);
+            }
+        }
         for (size_t stage = 0; stage < EShLangCount; stage++) {
             if (intermediates[stage] != nullptr) {
                 // traverse each stage, set new location to each input/output and unifom symbol, set new binding to

+ 15 - 1
3rdparty/glslang/glslang/MachineIndependent/iomapper.h

@@ -291,7 +291,7 @@ public:
     bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; }
 };
 
-// I/O mapper for OpenGL
+// I/O mapper for GLSL
 class TGlslIoMapper : public TIoMapper {
 public:
     TGlslIoMapper() {
@@ -301,6 +301,8 @@ public:
         memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1));
         profile = ENoProfile;
         version = 0;
+        autoPushConstantMaxSize = 128;
+        autoPushConstantBlockPacking = ElpStd430;
     }
     virtual ~TGlslIoMapper() {
         for (size_t stage = 0; stage < EShLangCount; stage++) {
@@ -319,6 +321,13 @@ public:
             if (intermediates[stage] != nullptr)
                 intermediates[stage] = nullptr;
         }
+    }
+	// If set, the uniform block with the given name will be changed to be backed by
+	// push_constant if it's size is <= maxSize
+    void setAutoPushConstantBlock(const char* name, unsigned int maxSize, TLayoutPacking packing) {
+        autoPushConstantBlockName = name;
+        autoPushConstantMaxSize = maxSize;
+        autoPushConstantBlockPacking = packing;
     }
     // grow the reflection stage by stage
     bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override;
@@ -329,6 +338,11 @@ public:
     bool hadError = false;
     EProfile profile;
     int version;
+
+private:
+    TString autoPushConstantBlockName;
+    unsigned int autoPushConstantMaxSize;
+    TLayoutPacking autoPushConstantBlockPacking;
 };
 
 } // end namespace glslang

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

@@ -1934,7 +1934,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, T
     }
 
     // rule 9
-    if (type.getBasicType() == EbtStruct) {
+    if (type.getBasicType() == EbtStruct || type.getBasicType() == EbtBlock) {
         const TTypeList& memberList = *type.getStruct();
 
         size = 0;
@@ -2159,8 +2159,9 @@ int TIntermediate::computeBufferReferenceTypeSize(const TType& type)
 bool TIntermediate::isIoResizeArray(const TType& type, EShLanguage language) {
     return type.isArray() &&
             ((language == EShLangGeometry    && type.getQualifier().storage == EvqVaryingIn) ||
-            (language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut &&
+            (language == EShLangTessControl && (type.getQualifier().storage == EvqVaryingIn || type.getQualifier().storage == EvqVaryingOut) &&
                 ! type.getQualifier().patch) ||
+            (language == EShLangTessEvaluation && type.getQualifier().storage == EvqVaryingIn) ||
             (language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn &&
                 type.getQualifier().pervertexNV) ||
             (language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut &&

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