Browse Source

Updated glslang.

Бранимир Караџић 2 years ago
parent
commit
bf5fda9ae7

+ 47 - 16
3rdparty/glslang/SPIRV/GlslangToSpv.cpp

@@ -2004,6 +2004,10 @@ void TGlslangToSpvTraverser::dumpSpv(std::vector<unsigned int>& out)
 //
 void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
 {
+    // We update the line information even though no code might be generated here
+    // This is helpful to yield correct lines for control flow instructions
+    builder.setLine(symbol->getLoc().line, symbol->getLoc().getFilename());
+
     SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
     if (symbol->getType().isStruct())
         glslangTypeToIdMap[symbol->getType().getStruct()] = symbol->getId();
@@ -2155,6 +2159,9 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
             node->getRight()->traverse(this);
             spv::Id rValue = accessChainLoad(node->getRight()->getType());
 
+            // reset line number for assignment
+            builder.setLine(node->getLoc().line, node->getLoc().getFilename());
+
             if (node->getOp() != glslang::EOpAssign) {
                 // the left is also an r-value
                 builder.setAccessChain(lValue);
@@ -3782,10 +3789,11 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
     // Find a way of executing both sides and selecting the right result.
     const auto executeBothSides = [&]() -> void {
         // execute both sides
+        spv::Id resultType = convertGlslangToSpvType(node->getType());
         node->getTrueBlock()->traverse(this);
         spv::Id trueValue = accessChainLoad(node->getTrueBlock()->getAsTyped()->getType());
         node->getFalseBlock()->traverse(this);
-        spv::Id falseValue = accessChainLoad(node->getTrueBlock()->getAsTyped()->getType());
+        spv::Id falseValue = accessChainLoad(node->getFalseBlock()->getAsTyped()->getType());
 
         builder.setLine(node->getLoc().line, node->getLoc().getFilename());
 
@@ -3794,8 +3802,8 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
             return;
 
         // emit code to select between trueValue and falseValue
-
-        // see if OpSelect can handle it
+        // see if OpSelect can handle the result type, and that the SPIR-V types
+        // of the inputs match the result type.
         if (isOpSelectable()) {
             // Emit OpSelect for this selection.
 
@@ -3807,10 +3815,18 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
                                                                        builder.getNumComponents(trueValue)));
             }
 
+            // If the types do not match, it is because of mismatched decorations on aggregates.
+            // Since isOpSelectable only lets us get here for SPIR-V >= 1.4, we can use OpCopyObject
+            // to get matching types.
+            if (builder.getTypeId(trueValue) != resultType) {
+                trueValue = builder.createUnaryOp(spv::OpCopyLogical, resultType, trueValue);
+            }
+            if (builder.getTypeId(falseValue) != resultType) {
+                falseValue = builder.createUnaryOp(spv::OpCopyLogical, resultType, falseValue);
+            }
+
             // OpSelect
-            result = builder.createTriOp(spv::OpSelect,
-                                         convertGlslangToSpvType(node->getType()), condition,
-                                                                 trueValue, falseValue);
+            result = builder.createTriOp(spv::OpSelect, resultType, condition, trueValue, falseValue);
 
             builder.clearAccessChain();
             builder.setAccessChainRValue(result);
@@ -3818,7 +3834,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
             // We need control flow to select the result.
             // TODO: Once SPIR-V OpSelect allows arbitrary types, eliminate this path.
             result = builder.createVariable(TranslatePrecisionDecoration(node->getType()),
-                spv::StorageClassFunction, convertGlslangToSpvType(node->getType()));
+                spv::StorageClassFunction, resultType);
 
             // Selection control:
             const spv::SelectionControlMask control = TranslateSelectionControl(*node);
@@ -3827,10 +3843,15 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
             spv::Builder::If ifBuilder(condition, control, builder);
 
             // emit the "then" statement
-            builder.createStore(trueValue, result);
+            builder.clearAccessChain();
+            builder.setAccessChainLValue(result);
+            multiTypeStore(node->getType(), trueValue);
+
             ifBuilder.makeBeginElse();
             // emit the "else" statement
-            builder.createStore(falseValue, result);
+            builder.clearAccessChain();
+            builder.setAccessChainLValue(result);
+            multiTypeStore(node->getType(), falseValue);
 
             // finish off the control flow
             ifBuilder.makeEndIf();
@@ -3857,16 +3878,26 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
         // emit the "then" statement
         if (node->getTrueBlock() != nullptr) {
             node->getTrueBlock()->traverse(this);
-            if (result != spv::NoResult)
-                builder.createStore(accessChainLoad(node->getTrueBlock()->getAsTyped()->getType()), result);
+            if (result != spv::NoResult) {
+                spv::Id load = accessChainLoad(node->getTrueBlock()->getAsTyped()->getType());
+
+                builder.clearAccessChain();
+                builder.setAccessChainLValue(result);
+                multiTypeStore(node->getType(), load);
+            }
         }
 
         if (node->getFalseBlock() != nullptr) {
             ifBuilder.makeBeginElse();
             // emit the "else" statement
             node->getFalseBlock()->traverse(this);
-            if (result != spv::NoResult)
-                builder.createStore(accessChainLoad(node->getFalseBlock()->getAsTyped()->getType()), result);
+            if (result != spv::NoResult) {
+                spv::Id load = accessChainLoad(node->getFalseBlock()->getAsTyped()->getType());
+
+                builder.clearAccessChain();
+                builder.setAccessChainLValue(result);
+                multiTypeStore(node->getType(), load);
+            }
         }
 
         // finish off the control flow
@@ -9418,10 +9449,10 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
             std::vector<spv::Id> operandIds;
             assert(!decorateId.second.empty());
             for (auto extraOperand : decorateId.second) {
-                if (extraOperand->getQualifier().isSpecConstant())
-                    operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode()));
-                else
+                if (extraOperand->getQualifier().isFrontEndConstant())
                     operandIds.push_back(createSpvConstant(*extraOperand));
+                else
+                    operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode()));
             }
             builder.addDecorationId(id, static_cast<spv::Decoration>(decorateId.first), operandIds);
         }

+ 34 - 27
3rdparty/glslang/SPIRV/SpvBuilder.cpp

@@ -144,6 +144,7 @@ void Builder::addLine(Id fileName, int lineNum, int column)
 
 void Builder::addDebugScopeAndLine(Id fileName, int lineNum, int column)
 {
+    assert(!currentDebugScopeId.empty());
     if (currentDebugScopeId.top() != lastDebugScopeId) {
         spv::Id resultId = getUniqueId();
         Instruction* scopeInst = new Instruction(resultId, makeVoidType(), OpExtInst);
@@ -1071,6 +1072,12 @@ Id Builder::makeDebugCompilationUnit() {
     constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(sourceInst));
     module.mapInstruction(sourceInst);
     nonSemanticShaderCompilationUnitId = resultId;
+
+    // We can reasonably assume that makeDebugCompilationUnit will be called before any of
+    // debug-scope stack. Function scopes and lexical scopes will occur afterward.
+    assert(currentDebugScopeId.empty());
+    currentDebugScopeId.push(nonSemanticShaderCompilationUnitId);
+
     return resultId;
 }
 
@@ -1100,6 +1107,8 @@ Id Builder::createDebugGlobalVariable(Id const type, char const*const name, Id c
 Id Builder::createDebugLocalVariable(Id type, char const*const name, size_t const argNumber)
 {
     assert(name != nullptr);
+    assert(!currentDebugScopeId.empty());
+
     Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
     inst->addIdOperand(nonSemanticShaderDebugInfo);
     inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugLocalVariable);
@@ -2119,6 +2128,8 @@ Id Builder::makeDebugFunction(Function* function, Id nameId, Id funcTypeId) {
 }
 
 Id Builder::makeDebugLexicalBlock(uint32_t line) {
+    assert(!currentDebugScopeId.empty());
+
     Id lexId = getUniqueId();
     auto lex = new Instruction(lexId, makeVoidType(), OpExtInst);
     lex->addIdOperand(nonSemanticShaderDebugInfo);
@@ -2758,52 +2769,49 @@ Id Builder::createBuiltinCall(Id resultType, Id builtins, int entryPoint, const
 Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather,
     bool noImplicitLod, const TextureParameters& parameters, ImageOperandsMask signExtensionMask)
 {
-    static const int maxTextureArgs = 10;
-    Id texArgs[maxTextureArgs] = {};
+    std::vector<Id> texArgs;
 
     //
     // Set up the fixed arguments
     //
-    int numArgs = 0;
     bool explicitLod = false;
-    texArgs[numArgs++] = parameters.sampler;
-    texArgs[numArgs++] = parameters.coords;
+    texArgs.push_back(parameters.sampler);
+    texArgs.push_back(parameters.coords);
     if (parameters.Dref != NoResult)
-        texArgs[numArgs++] = parameters.Dref;
+        texArgs.push_back(parameters.Dref);
     if (parameters.component != NoResult)
-        texArgs[numArgs++] = parameters.component;
+        texArgs.push_back(parameters.component);
 
 #ifndef GLSLANG_WEB
     if (parameters.granularity != NoResult)
-        texArgs[numArgs++] = parameters.granularity;
+        texArgs.push_back(parameters.granularity);
     if (parameters.coarse != NoResult)
-        texArgs[numArgs++] = parameters.coarse;
+        texArgs.push_back(parameters.coarse);
 #endif
 
     //
     // Set up the optional arguments
     //
-    int optArgNum = numArgs;    // track which operand, if it exists, is the mask of optional arguments
-    ++numArgs;                  // speculatively make room for the mask operand
+    size_t optArgNum = texArgs.size(); // the position of the mask for the optional arguments, if any.
     ImageOperandsMask mask = ImageOperandsMaskNone; // the mask operand
     if (parameters.bias) {
         mask = (ImageOperandsMask)(mask | ImageOperandsBiasMask);
-        texArgs[numArgs++] = parameters.bias;
+        texArgs.push_back(parameters.bias);
     }
     if (parameters.lod) {
         mask = (ImageOperandsMask)(mask | ImageOperandsLodMask);
-        texArgs[numArgs++] = parameters.lod;
+        texArgs.push_back(parameters.lod);
         explicitLod = true;
     } else if (parameters.gradX) {
         mask = (ImageOperandsMask)(mask | ImageOperandsGradMask);
-        texArgs[numArgs++] = parameters.gradX;
-        texArgs[numArgs++] = parameters.gradY;
+        texArgs.push_back(parameters.gradX);
+        texArgs.push_back(parameters.gradY);
         explicitLod = true;
     } else if (noImplicitLod && ! fetch && ! gather) {
         // have to explicitly use lod of 0 if not allowed to have them be implicit, and
         // we would otherwise be about to issue an implicit instruction
         mask = (ImageOperandsMask)(mask | ImageOperandsLodMask);
-        texArgs[numArgs++] = makeFloatConstant(0.0);
+        texArgs.push_back(makeFloatConstant(0.0));
         explicitLod = true;
     }
     if (parameters.offset) {
@@ -2813,24 +2821,24 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
             addCapability(CapabilityImageGatherExtended);
             mask = (ImageOperandsMask)(mask | ImageOperandsOffsetMask);
         }
-        texArgs[numArgs++] = parameters.offset;
+        texArgs.push_back(parameters.offset);
     }
     if (parameters.offsets) {
         addCapability(CapabilityImageGatherExtended);
         mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask);
-        texArgs[numArgs++] = parameters.offsets;
+        texArgs.push_back(parameters.offsets);
     }
 #ifndef GLSLANG_WEB
     if (parameters.sample) {
         mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask);
-        texArgs[numArgs++] = parameters.sample;
+        texArgs.push_back(parameters.sample);
     }
     if (parameters.lodClamp) {
         // capability if this bit is used
         addCapability(CapabilityMinLod);
 
         mask = (ImageOperandsMask)(mask | ImageOperandsMinLodMask);
-        texArgs[numArgs++] = parameters.lodClamp;
+        texArgs.push_back(parameters.lodClamp);
     }
     if (parameters.nonprivate) {
         mask = mask | ImageOperandsNonPrivateTexelKHRMask;
@@ -2840,10 +2848,9 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
     }
 #endif
     mask = mask | signExtensionMask;
-    if (mask == ImageOperandsMaskNone)
-        --numArgs;  // undo speculative reservation for the mask argument
-    else
-        texArgs[optArgNum] = mask;
+    // insert the operand for the mask, if any bits were set.
+    if (mask != ImageOperandsMaskNone)
+        texArgs.insert(texArgs.begin() + optArgNum, mask);
 
     //
     // Set up the instruction
@@ -2947,11 +2954,11 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
 
     // Build the SPIR-V instruction
     Instruction* textureInst = new Instruction(getUniqueId(), resultType, opCode);
-    for (int op = 0; op < optArgNum; ++op)
+    for (size_t op = 0; op < optArgNum; ++op)
         textureInst->addIdOperand(texArgs[op]);
-    if (optArgNum < numArgs)
+    if (optArgNum < texArgs.size())
         textureInst->addImmediateOperand(texArgs[optArgNum]);
-    for (int op = optArgNum + 1; op < numArgs; ++op)
+    for (size_t op = optArgNum + 1; op < texArgs.size(); ++op)
         textureInst->addIdOperand(texArgs[op]);
     setPrecision(textureInst->getResultId(), precision);
     buildPoint->addInstruction(std::unique_ptr<Instruction>(textureInst));

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

@@ -258,6 +258,17 @@ public:
         text.append("\n");
     }
 
+    void addText(std::string preambleText)
+    {
+        fixLine(preambleText);
+
+        Processes.push_back("preamble-text");
+        Processes.back().append(preambleText);
+
+        text.append(preambleText);
+        text.append("\n");
+    }
+
 protected:
     void fixLine(std::string& line)
     {
@@ -727,6 +738,13 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
                     } else if (lowerword == "no-storage-format" || // synonyms
                                lowerword == "nsf") {
                         Options |= EOptionNoStorageFormat;
+                    } else if (lowerword == "preamble-text" ||
+                               lowerword == "p") {
+                        if (argc > 1)
+                            UserPreamble.addText(argv[1]);
+                        else
+                            Error("expects <text>", argv[0]);
+                        bumpArg();
                     } else if (lowerword == "relaxed-errors") {
                         Options |= EOptionRelaxedErrors;
                     } else if (lowerword == "reflect-strict-array-suffix") {
@@ -926,6 +944,9 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
                 else
                     Error("unknown -O option");
                 break;
+            case 'P':
+                UserPreamble.addText(getStringOperand("-P<text>"));
+                break;
             case 'R':
                 VulkanRulesRelaxed = true;
                 break;
@@ -1832,7 +1853,7 @@ void CompileFile(const char* fileName, ShHandle compiler)
     SetMessageOptions(messages);
 
     if (UserPreamble.isSet())
-        Error("-D and -U options require -l (linking)\n");
+        Error("-D, -U and -P options require -l (linking)\n");
 
     for (int i = 0; i < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++i) {
         for (int j = 0; j < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++j) {
@@ -1902,6 +1923,9 @@ void usage()
            "              is searched first, followed by left-to-right order of -I\n"
            "  -Od         disables optimization; may cause illegal SPIR-V for HLSL\n"
            "  -Os         optimizes SPIR-V to minimize size\n"
+           "  -P<text> | --preamble-text <text> | --P <text>\n"
+           "              inject custom preamble text, which is treated as if it\n"
+           "              appeared immediately after the version declaration (if any).\n"
            "  -R          use relaxed verification rules for generating Vulkan SPIR-V,\n"
            "              allowing the use of default uniforms, atomic_uints, and\n"
            "              gl_VertexID and gl_InstanceID keywords.\n"

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

@@ -1177,10 +1177,13 @@ void HlslParseContext::flatten(const TVariable& variable, bool linkage, bool arr
     if (type.isBuiltIn() && !type.isStruct())
         return;
 
+
     auto entry = flattenMap.insert(std::make_pair(variable.getUniqueId(),
                                                   TFlattenData(type.getQualifier().layoutBinding,
                                                                type.getQualifier().layoutLocation)));
 
+    if (type.isStruct() && type.getStruct()->size()==0)
+        return;
     // if flattening arrayed io struct, array each member of dereferenced type
     if (arrayed) {
         const TType dereferencedType(type, 0);
@@ -7565,7 +7568,6 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, TFunction
          candidateList[0]->getBuiltInOp() == EOpMethodRestartStrip ||
          candidateList[0]->getBuiltInOp() == EOpMethodIncrementCounter ||
          candidateList[0]->getBuiltInOp() == EOpMethodDecrementCounter ||
-         candidateList[0]->getBuiltInOp() == EOpMethodAppend ||
          candidateList[0]->getBuiltInOp() == EOpMethodConsume)) {
         return candidateList[0];
     }
@@ -9046,7 +9048,8 @@ void HlslParseContext::fixBlockUniformOffsets(const TQualifier& qualifier, TType
             // "The specified offset must be a multiple
             // of the base alignment of the type of the block member it qualifies, or a compile-time error results."
             if (! IsMultipleOfPow2(memberQualifier.layoutOffset, memberAlignment))
-                error(memberLoc, "must be a multiple of the member's alignment", "offset", "");
+                error(memberLoc, "must be a multiple of the member's alignment", "offset",
+                    "(layout offset = %d | member alignment = %d)", memberQualifier.layoutOffset, memberAlignment);
 
             // "The offset qualifier forces the qualified member to start at or after the specified
             // integral-constant expression, which will be its byte offset from the beginning of the buffer.

+ 4 - 3
3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp

@@ -4013,7 +4013,7 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
         switch (language) {
         case EShLangVertex:
             if (publicType.basicType == EbtStruct) {
-                error(loc, "cannot be a structure or array", GetStorageQualifierString(qualifier.storage), "");
+                error(loc, "cannot be a structure", GetStorageQualifierString(qualifier.storage), "");
                 return;
             }
             if (publicType.arraySizes) {
@@ -4228,7 +4228,7 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
                 if (dstSpirvDecorate.decorates.find(decorateString.first) != dstSpirvDecorate.decorates.end())
                     error(loc, "too many SPIR-V decorate qualifiers", "spirv_decorate_string", "(decoration=%u)", decorateString.first);
                 else
-                    dstSpirvDecorate.decorates.insert(decorateString);
+                    dstSpirvDecorate.decorateStrings.insert(decorateString);
             }
         } else {
             dst.spirvDecorate = src.spirvDecorate;
@@ -9029,7 +9029,8 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ
             // "The specified offset must be a multiple
             // of the base alignment of the type of the block member it qualifies, or a compile-time error results."
             if (! IsMultipleOfPow2(memberQualifier.layoutOffset, memberAlignment))
-                error(memberLoc, "must be a multiple of the member's alignment", "offset", "");
+                error(memberLoc, "must be a multiple of the member's alignment", "offset",
+                    "(layout offset = %d | member alignment = %d)", memberQualifier.layoutOffset, memberAlignment);
 
             // GLSL: "It is a compile-time error to specify an offset that is smaller than the offset of the previous
             // member in the block or that lies within the previous member of the block"

+ 23 - 24
3rdparty/glslang/glslang/MachineIndependent/SpirvIntrinsics.cpp

@@ -168,7 +168,7 @@ void TQualifier::setSpirvDecorateId(int decoration, const TIntermAggregate* args
     TVector<const TIntermTyped*> extraOperands;
     for (auto arg : args->getSequence()) {
         auto extraOperand = arg->getAsTyped();
-        assert(extraOperand != nullptr && extraOperand->getQualifier().isConstant());
+        assert(extraOperand != nullptr);
         extraOperands.push_back(extraOperand);
     }
     spirvDecorate->decorateIds[decoration] = extraOperands;
@@ -202,30 +202,29 @@ TString TQualifier::getSpirvDecorateQualifierString() const
     const auto appendStr = [&](const char* s) { qualifierString.append(s); };
 
     const auto appendDecorate = [&](const TIntermTyped* constant) {
-        auto& constArray = constant->getAsConstantUnion() != nullptr ? constant->getAsConstantUnion()->getConstArray()
-                                                                     : constant->getAsSymbolNode()->getConstArray();
-        if (constant->getBasicType() == EbtFloat) {
-            float value = static_cast<float>(constArray[0].getDConst());
-            appendFloat(value);
-        }
-        else if (constant->getBasicType() == EbtInt) {
-            int value = constArray[0].getIConst();
-            appendInt(value);
-        }
-        else if (constant->getBasicType() == EbtUint) {
-            unsigned value = constArray[0].getUConst();
-            appendUint(value);
+        if (constant->getAsConstantUnion()) {
+            auto& constArray = constant->getAsConstantUnion()->getConstArray();
+            if (constant->getBasicType() == EbtFloat) {
+                float value = static_cast<float>(constArray[0].getDConst());
+                appendFloat(value);
+            } else if (constant->getBasicType() == EbtInt) {
+                int value = constArray[0].getIConst();
+                appendInt(value);
+            } else if (constant->getBasicType() == EbtUint) {
+                unsigned value = constArray[0].getUConst();
+                appendUint(value);
+            } else if (constant->getBasicType() == EbtBool) {
+                bool value = constArray[0].getBConst();
+                appendBool(value);
+            } else if (constant->getBasicType() == EbtString) {
+                const TString* value = constArray[0].getSConst();
+                appendStr(value->c_str());
+            } else
+                assert(0);
+        } else {
+            assert(constant->getAsSymbolNode());
+            appendStr(constant->getAsSymbolNode()->getName().c_str());
         }
-        else if (constant->getBasicType() == EbtBool) {
-            bool value = constArray[0].getBConst();
-            appendBool(value);
-        }
-        else if (constant->getBasicType() == EbtString) {
-            const TString* value = constArray[0].getSConst();
-            appendStr(value->c_str());
-        }
-        else
-            assert(0);
     };
 
     for (auto& decorate : spirvDecorate->decorates) {

+ 23 - 13
3rdparty/glslang/glslang/MachineIndependent/glslang.m4

@@ -378,7 +378,7 @@ GLSLANG_WEB_EXCLUDE_ON
 %type <interm.type> spirv_storage_class_qualifier
 %type <interm.type> spirv_decorate_qualifier
 %type <interm.intermNode> spirv_decorate_parameter_list spirv_decorate_parameter
-%type <interm.intermNode> spirv_decorate_id_parameter_list
+%type <interm.intermNode> spirv_decorate_id_parameter_list spirv_decorate_id_parameter
 %type <interm.intermNode> spirv_decorate_string_parameter_list
 %type <interm.type> spirv_type_specifier
 %type <interm.spirvTypeParams> spirv_type_parameter_list spirv_type_parameter
@@ -4347,23 +4347,33 @@ spirv_decorate_parameter
     }
 
 spirv_decorate_id_parameter_list
-    : constant_expression {
-        if ($1->getBasicType() != EbtFloat &&
-            $1->getBasicType() != EbtInt &&
-            $1->getBasicType() != EbtUint &&
-            $1->getBasicType() != EbtBool)
-            parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), "");
+    : spirv_decorate_id_parameter {
         $$ = parseContext.intermediate.makeAggregate($1);
     }
-    | spirv_decorate_id_parameter_list COMMA constant_expression {
-        if ($3->getBasicType() != EbtFloat &&
-            $3->getBasicType() != EbtInt &&
-            $3->getBasicType() != EbtUint &&
-            $3->getBasicType() != EbtBool)
-            parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), "");
+    | spirv_decorate_id_parameter_list COMMA spirv_decorate_id_parameter {
         $$ = parseContext.intermediate.growAggregate($1, $3);
     }
 
+spirv_decorate_id_parameter
+    : variable_identifier {
+        if ($1->getAsConstantUnion() || $1->getAsSymbolNode())
+            $$ = $1;
+        else
+            parseContext.error($1->getLoc(), "only allow constants or variables which are not elements of a composite", "", "");
+    }
+    | FLOATCONSTANT {
+        $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true);
+    }
+    | INTCONSTANT {
+        $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true);
+    }
+    | UINTCONSTANT {
+        $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true);
+    }
+    | BOOLCONSTANT {
+        $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
+    }
+
 spirv_decorate_string_parameter_list
     : STRING_LITERAL {
         $$ = parseContext.intermediate.makeAggregate(

+ 23 - 13
3rdparty/glslang/glslang/MachineIndependent/glslang.y

@@ -378,7 +378,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
 %type <interm.type> spirv_storage_class_qualifier
 %type <interm.type> spirv_decorate_qualifier
 %type <interm.intermNode> spirv_decorate_parameter_list spirv_decorate_parameter
-%type <interm.intermNode> spirv_decorate_id_parameter_list
+%type <interm.intermNode> spirv_decorate_id_parameter_list spirv_decorate_id_parameter
 %type <interm.intermNode> spirv_decorate_string_parameter_list
 %type <interm.type> spirv_type_specifier
 %type <interm.spirvTypeParams> spirv_type_parameter_list spirv_type_parameter
@@ -4347,23 +4347,33 @@ spirv_decorate_parameter
     }
 
 spirv_decorate_id_parameter_list
-    : constant_expression {
-        if ($1->getBasicType() != EbtFloat &&
-            $1->getBasicType() != EbtInt &&
-            $1->getBasicType() != EbtUint &&
-            $1->getBasicType() != EbtBool)
-            parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), "");
+    : spirv_decorate_id_parameter {
         $$ = parseContext.intermediate.makeAggregate($1);
     }
-    | spirv_decorate_id_parameter_list COMMA constant_expression {
-        if ($3->getBasicType() != EbtFloat &&
-            $3->getBasicType() != EbtInt &&
-            $3->getBasicType() != EbtUint &&
-            $3->getBasicType() != EbtBool)
-            parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), "");
+    | spirv_decorate_id_parameter_list COMMA spirv_decorate_id_parameter {
         $$ = parseContext.intermediate.growAggregate($1, $3);
     }
 
+spirv_decorate_id_parameter
+    : variable_identifier {
+        if ($1->getAsConstantUnion() || $1->getAsSymbolNode())
+            $$ = $1;
+        else
+            parseContext.error($1->getLoc(), "only allow constants or variables which are not elements of a composite", "", "");
+    }
+    | FLOATCONSTANT {
+        $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true);
+    }
+    | INTCONSTANT {
+        $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true);
+    }
+    | UINTCONSTANT {
+        $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true);
+    }
+    | BOOLCONSTANT {
+        $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
+    }
+
 spirv_decorate_string_parameter_list
     : STRING_LITERAL {
         $$ = parseContext.intermediate.makeAggregate(

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


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