Merge pull request #2625 from amdrexu/feature
Implement the extension GL_EXT_spirv_intrinsics
This commit is contained in:
		
						commit
						71612a7e5d
					
				
							
								
								
									
										2
									
								
								BUILD.gn
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								BUILD.gn
									
									
									
									
									
								
							@ -131,6 +131,7 @@ template("glslang_sources_common") {
 | 
			
		||||
      "glslang/Include/PoolAlloc.h",
 | 
			
		||||
      "glslang/Include/ResourceLimits.h",
 | 
			
		||||
      "glslang/Include/ShHandle.h",
 | 
			
		||||
      "glslang/Include/SpirvIntrinsics.h",
 | 
			
		||||
      "glslang/Include/Types.h",
 | 
			
		||||
      "glslang/Include/arrays.h",
 | 
			
		||||
      "glslang/Include/intermediate.h",
 | 
			
		||||
@ -151,6 +152,7 @@ template("glslang_sources_common") {
 | 
			
		||||
      "glslang/MachineIndependent/Scan.h",
 | 
			
		||||
      "glslang/MachineIndependent/ScanContext.h",
 | 
			
		||||
      "glslang/MachineIndependent/ShaderLang.cpp",
 | 
			
		||||
      "glslang/MachineIndependent/SpirvIntrinsics.cpp",
 | 
			
		||||
      "glslang/MachineIndependent/SymbolTable.cpp",
 | 
			
		||||
      "glslang/MachineIndependent/SymbolTable.h",
 | 
			
		||||
      "glslang/MachineIndependent/Versions.cpp",
 | 
			
		||||
 | 
			
		||||
@ -160,6 +160,7 @@ protected:
 | 
			
		||||
    spv::SelectionControlMask TranslateSwitchControl(const glslang::TIntermSwitch&) const;
 | 
			
		||||
    spv::LoopControlMask TranslateLoopControl(const glslang::TIntermLoop&, std::vector<unsigned int>& operands) const;
 | 
			
		||||
    spv::StorageClass TranslateStorageClass(const glslang::TType&);
 | 
			
		||||
    void TranslateLiterals(const glslang::TVector<const glslang::TIntermConstantUnion*>&, std::vector<unsigned>&) const;
 | 
			
		||||
    void addIndirectionIndexCapabilities(const glslang::TType& baseType, const glslang::TType& indexType);
 | 
			
		||||
    spv::Id createSpvVariable(const glslang::TIntermSymbol*, spv::Id forcedType);
 | 
			
		||||
    spv::Id getSampledType(const glslang::TSampler&);
 | 
			
		||||
@ -1249,6 +1250,10 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
 | 
			
		||||
{
 | 
			
		||||
    if (type.getBasicType() == glslang::EbtRayQuery)
 | 
			
		||||
        return spv::StorageClassPrivate;
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    if (type.getQualifier().isSpirvByReference())
 | 
			
		||||
        return spv::StorageClassFunction;
 | 
			
		||||
#endif
 | 
			
		||||
    if (type.getQualifier().isPipeInput())
 | 
			
		||||
        return spv::StorageClassInput;
 | 
			
		||||
    if (type.getQualifier().isPipeOutput())
 | 
			
		||||
@ -1297,6 +1302,7 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
 | 
			
		||||
    case glslang::EvqHitAttr:        return spv::StorageClassHitAttributeKHR;
 | 
			
		||||
    case glslang::EvqCallableData:   return spv::StorageClassCallableDataKHR;
 | 
			
		||||
    case glslang::EvqCallableDataIn: return spv::StorageClassIncomingCallableDataKHR;
 | 
			
		||||
    case glslang::EvqSpirvStorageClass: return static_cast<spv::StorageClass>(type.getQualifier().spirvStorageClass);
 | 
			
		||||
#endif
 | 
			
		||||
    default:
 | 
			
		||||
        assert(0);
 | 
			
		||||
@ -1306,6 +1312,52 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
 | 
			
		||||
    return spv::StorageClassFunction;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Translate glslang constants to SPIR-V literals
 | 
			
		||||
void TGlslangToSpvTraverser::TranslateLiterals(const glslang::TVector<const glslang::TIntermConstantUnion*>& constants,
 | 
			
		||||
                                               std::vector<unsigned>& literals) const
 | 
			
		||||
{
 | 
			
		||||
    for (auto constant : constants) {
 | 
			
		||||
        if (constant->getBasicType() == glslang::EbtFloat) {
 | 
			
		||||
            float floatValue = static_cast<float>(constant->getConstArray()[0].getDConst());
 | 
			
		||||
            unsigned literal = *reinterpret_cast<unsigned*>(&floatValue);
 | 
			
		||||
            literals.push_back(literal);
 | 
			
		||||
        } else if (constant->getBasicType() == glslang::EbtInt) {
 | 
			
		||||
            unsigned literal = constant->getConstArray()[0].getIConst();
 | 
			
		||||
            literals.push_back(literal);
 | 
			
		||||
        } else if (constant->getBasicType() == glslang::EbtUint) {
 | 
			
		||||
            unsigned literal = constant->getConstArray()[0].getUConst();
 | 
			
		||||
            literals.push_back(literal);
 | 
			
		||||
        } else if (constant->getBasicType() == glslang::EbtBool) {
 | 
			
		||||
            unsigned literal = constant->getConstArray()[0].getBConst();
 | 
			
		||||
            literals.push_back(literal);
 | 
			
		||||
        } else if (constant->getBasicType() == glslang::EbtString) {
 | 
			
		||||
            auto str = constant->getConstArray()[0].getSConst()->c_str();
 | 
			
		||||
            unsigned literal = 0;
 | 
			
		||||
            char* literalPtr = reinterpret_cast<char*>(&literal);
 | 
			
		||||
            unsigned charCount = 0;
 | 
			
		||||
            char ch = 0;
 | 
			
		||||
            do {
 | 
			
		||||
                ch = *(str++);
 | 
			
		||||
                *(literalPtr++) = ch;
 | 
			
		||||
                ++charCount;
 | 
			
		||||
                if (charCount == 4) {
 | 
			
		||||
                    literals.push_back(literal);
 | 
			
		||||
                    literalPtr = reinterpret_cast<char*>(&literal);
 | 
			
		||||
                    charCount = 0;
 | 
			
		||||
                }
 | 
			
		||||
            } while (ch != 0);
 | 
			
		||||
 | 
			
		||||
            // Partial literal is padded with 0
 | 
			
		||||
            if (charCount > 0) {
 | 
			
		||||
                for (; charCount < 4; ++charCount)
 | 
			
		||||
                    *(literalPtr++) = 0;
 | 
			
		||||
                literals.push_back(literal);
 | 
			
		||||
            }
 | 
			
		||||
        } else
 | 
			
		||||
            assert(0); // Unexpected type
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Add capabilities pertaining to how an array is indexed.
 | 
			
		||||
void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TType& baseType,
 | 
			
		||||
                                                             const glslang::TType& indexType)
 | 
			
		||||
@ -1735,6 +1787,53 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    //
 | 
			
		||||
    // Add SPIR-V requirements (GL_EXT_spirv_intrinsics)
 | 
			
		||||
    //
 | 
			
		||||
    if (glslangIntermediate->hasSpirvRequirement()) {
 | 
			
		||||
        const glslang::TSpirvRequirement& spirvRequirement = glslangIntermediate->getSpirvRequirement();
 | 
			
		||||
 | 
			
		||||
        // Add SPIR-V extension requirement
 | 
			
		||||
        for (auto& extension : spirvRequirement.extensions)
 | 
			
		||||
            builder.addExtension(extension.c_str());
 | 
			
		||||
 | 
			
		||||
        // Add SPIR-V capability requirement
 | 
			
		||||
        for (auto capability : spirvRequirement.capabilities)
 | 
			
		||||
            builder.addCapability(static_cast<spv::Capability>(capability));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // Add SPIR-V execution mode qualifiers (GL_EXT_spirv_intrinsics)
 | 
			
		||||
    //
 | 
			
		||||
    if (glslangIntermediate->hasSpirvExecutionMode()) {
 | 
			
		||||
        const glslang::TSpirvExecutionMode spirvExecutionMode = glslangIntermediate->getSpirvExecutionMode();
 | 
			
		||||
 | 
			
		||||
        // Add spirv_execution_mode
 | 
			
		||||
        for (auto& mode : spirvExecutionMode.modes) {
 | 
			
		||||
            if (!mode.second.empty()) {
 | 
			
		||||
                std::vector<unsigned> literals;
 | 
			
		||||
                TranslateLiterals(mode.second, literals);
 | 
			
		||||
                builder.addExecutionMode(shaderEntry, static_cast<spv::ExecutionMode>(mode.first), literals);
 | 
			
		||||
            } else
 | 
			
		||||
                builder.addExecutionMode(shaderEntry, static_cast<spv::ExecutionMode>(mode.first));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Add spirv_execution_mode_id
 | 
			
		||||
        for (auto& modeId : spirvExecutionMode.modeIds) {
 | 
			
		||||
            std::vector<spv::Id> operandIds;
 | 
			
		||||
            assert(!modeId.second.empty());
 | 
			
		||||
            for (auto extraOperand : modeId.second) {
 | 
			
		||||
                int nextConst = 0;
 | 
			
		||||
                spv::Id operandId = createSpvConstantFromConstUnionArray(
 | 
			
		||||
                    extraOperand->getType(), extraOperand->getConstArray(), nextConst, false);
 | 
			
		||||
                operandIds.push_back(operandId);
 | 
			
		||||
            }
 | 
			
		||||
            builder.addExecutionModeId(shaderEntry, static_cast<spv::ExecutionMode>(modeId.first), operandIds);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Finish creating SPV, after the traversal is complete.
 | 
			
		||||
@ -2317,10 +2416,14 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
 | 
			
		||||
        node->getOp() == glslang::EOpRayQueryGetWorldRayDirection ||
 | 
			
		||||
        node->getOp() == glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque ||
 | 
			
		||||
        node->getOp() == glslang::EOpRayQueryTerminate ||
 | 
			
		||||
        node->getOp() == glslang::EOpRayQueryConfirmIntersection) {
 | 
			
		||||
        node->getOp() == glslang::EOpRayQueryConfirmIntersection ||
 | 
			
		||||
        (node->getOp() == glslang::EOpSpirvInst && operandNode->getAsTyped()->getQualifier().isSpirvByReference())) {
 | 
			
		||||
        operand = builder.accessChainGetLValue(); // Special case l-value operands
 | 
			
		||||
        lvalueCoherentFlags = builder.getAccessChain().coherentFlags;
 | 
			
		||||
        lvalueCoherentFlags |= TranslateCoherent(operandNode->getAsTyped()->getType());
 | 
			
		||||
    } else if (operandNode->getAsTyped()->getQualifier().isSpirvLiteral()) {
 | 
			
		||||
        // Will be translated to a literal value, make a placeholder here
 | 
			
		||||
        operand = spv::NoResult;
 | 
			
		||||
    } else
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
@ -2341,6 +2444,38 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
 | 
			
		||||
        result = createUnaryOperation(node->getOp(), decorations, resultType(), operand,
 | 
			
		||||
            node->getOperand()->getBasicType(), lvalueCoherentFlags);
 | 
			
		||||
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    // it could be attached to a SPIR-V intruction
 | 
			
		||||
    if (!result) {
 | 
			
		||||
        if (node->getOp() == glslang::EOpSpirvInst) {
 | 
			
		||||
            const auto& spirvInst = node->getSpirvInstruction();
 | 
			
		||||
            if (spirvInst.set == "") {
 | 
			
		||||
                spv::IdImmediate idImmOp = {true, operand};
 | 
			
		||||
                if (operandNode->getAsTyped()->getQualifier().isSpirvLiteral()) {
 | 
			
		||||
                    // Translate the constant to a literal value
 | 
			
		||||
                    std::vector<unsigned> literals;
 | 
			
		||||
                    glslang::TVector<const glslang::TIntermConstantUnion*> constants;
 | 
			
		||||
                    constants.push_back(operandNode->getAsConstantUnion());
 | 
			
		||||
                    TranslateLiterals(constants, literals);
 | 
			
		||||
                    idImmOp = {false, literals[0]};
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (node->getBasicType() == glslang::EbtVoid)
 | 
			
		||||
                    builder.createNoResultOp(static_cast<spv::Op>(spirvInst.id), {idImmOp});
 | 
			
		||||
                else
 | 
			
		||||
                    result = builder.createOp(static_cast<spv::Op>(spirvInst.id), resultType(), {idImmOp});
 | 
			
		||||
            } else {
 | 
			
		||||
                result = builder.createBuiltinCall(
 | 
			
		||||
                    resultType(), spirvInst.set == "GLSL.std.450" ? stdBuiltins : getExtBuiltins(spirvInst.set.c_str()),
 | 
			
		||||
                    spirvInst.id, {operand});
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (node->getBasicType() == glslang::EbtVoid)
 | 
			
		||||
                return false; // done with this node
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (result) {
 | 
			
		||||
        if (invertedType) {
 | 
			
		||||
            result = createInvertedSwizzle(decorations.precision, *node->getOperand(), result);
 | 
			
		||||
@ -3037,6 +3172,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
 | 
			
		||||
            if (arg == 1)
 | 
			
		||||
                lvalue = true;
 | 
			
		||||
            break;
 | 
			
		||||
        case glslang::EOpSpirvInst:
 | 
			
		||||
            if (glslangOperands[arg]->getAsTyped()->getQualifier().isSpirvByReference())
 | 
			
		||||
                lvalue = true;
 | 
			
		||||
            break;
 | 
			
		||||
#endif
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
@ -3142,7 +3281,12 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
 | 
			
		||||
                 visitSymbol(itNode->second);
 | 
			
		||||
                 spv::Id symId = getSymbolId(itNode->second);
 | 
			
		||||
                 operands.push_back(symId);
 | 
			
		||||
             } else {
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
             } else if (glslangOperands[arg]->getAsTyped()->getQualifier().isSpirvLiteral()) {
 | 
			
		||||
                 // Will be translated to a literal value, make a placeholder here
 | 
			
		||||
                 operands.push_back(spv::NoResult);
 | 
			
		||||
#endif
 | 
			
		||||
             } else  {
 | 
			
		||||
                operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType()));
 | 
			
		||||
             }
 | 
			
		||||
        }
 | 
			
		||||
@ -3184,6 +3328,34 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
 | 
			
		||||
            ? node->getSequence()[0]->getAsTyped()->getBasicType() : node->getBasicType();
 | 
			
		||||
        result = createAtomicOperation(node->getOp(), precision, resultType(), operands, typeProxy,
 | 
			
		||||
            lvalueCoherentFlags);
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    } else if (node->getOp() == glslang::EOpSpirvInst) {
 | 
			
		||||
        const auto& spirvInst = node->getSpirvInstruction();
 | 
			
		||||
        if (spirvInst.set == "") {
 | 
			
		||||
            std::vector<spv::IdImmediate> idImmOps;
 | 
			
		||||
            for (int i = 0; i < glslangOperands.size(); ++i) {
 | 
			
		||||
                if (glslangOperands[i]->getAsTyped()->getQualifier().isSpirvLiteral()) {
 | 
			
		||||
                    // Translate the constant to a literal value
 | 
			
		||||
                    std::vector<unsigned> literals;
 | 
			
		||||
                    glslang::TVector<const glslang::TIntermConstantUnion*> constants;
 | 
			
		||||
                    constants.push_back(glslangOperands[i]->getAsConstantUnion());
 | 
			
		||||
                    TranslateLiterals(constants, literals);
 | 
			
		||||
                    idImmOps.push_back({false, literals[0]});
 | 
			
		||||
                } else
 | 
			
		||||
                    idImmOps.push_back({true, operands[i]});
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (node->getBasicType() == glslang::EbtVoid)
 | 
			
		||||
                builder.createNoResultOp(static_cast<spv::Op>(spirvInst.id), idImmOps);
 | 
			
		||||
            else
 | 
			
		||||
                result = builder.createOp(static_cast<spv::Op>(spirvInst.id), resultType(), idImmOps);
 | 
			
		||||
        } else {
 | 
			
		||||
            result = builder.createBuiltinCall(
 | 
			
		||||
                resultType(), spirvInst.set == "GLSL.std.450" ? stdBuiltins : getExtBuiltins(spirvInst.set.c_str()),
 | 
			
		||||
                spirvInst.id, operands);
 | 
			
		||||
        }
 | 
			
		||||
        noReturnValue = node->getBasicType() == glslang::EbtVoid;
 | 
			
		||||
#endif
 | 
			
		||||
    } else if (node->getOp() == glslang::EOpDebugPrintf) {
 | 
			
		||||
        if (!nonSemanticDebugPrintf) {
 | 
			
		||||
            nonSemanticDebugPrintf = builder.import("NonSemantic.DebugPrintf");
 | 
			
		||||
@ -3464,6 +3636,11 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T
 | 
			
		||||
 | 
			
		||||
void TGlslangToSpvTraverser::visitConstantUnion(glslang::TIntermConstantUnion* node)
 | 
			
		||||
{
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    if (node->getQualifier().isSpirvLiteral())
 | 
			
		||||
        return; // Translated to a literal value, skip further processing
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    int nextConst = 0;
 | 
			
		||||
    spv::Id constant = createSpvConstantFromConstUnionArray(node->getType(), node->getConstArray(), nextConst, false);
 | 
			
		||||
 | 
			
		||||
@ -3912,6 +4089,77 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
 | 
			
		||||
    case glslang::EbtString:
 | 
			
		||||
        // no type used for OpString
 | 
			
		||||
        return 0;
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    case glslang::EbtSpirvType: {
 | 
			
		||||
        // GL_EXT_spirv_intrinsics
 | 
			
		||||
        const auto& spirvType = type.getSpirvType();
 | 
			
		||||
        const auto& spirvInst = spirvType.spirvInst;
 | 
			
		||||
 | 
			
		||||
        std::vector<spv::Id> operands;
 | 
			
		||||
        for (const auto& typeParam : spirvType.typeParams) {
 | 
			
		||||
            if (typeParam.isConstant) {
 | 
			
		||||
                // Constant expression
 | 
			
		||||
                if (typeParam.constant->isLiteral()) {
 | 
			
		||||
                    if (typeParam.constant->getBasicType() == glslang::EbtFloat) {
 | 
			
		||||
                        float floatValue = static_cast<float>(typeParam.constant->getConstArray()[0].getDConst());
 | 
			
		||||
                        unsigned literal = *reinterpret_cast<unsigned*>(&floatValue);
 | 
			
		||||
                        operands.push_back(literal);
 | 
			
		||||
                    } else if (typeParam.constant->getBasicType() == glslang::EbtInt) {
 | 
			
		||||
                        unsigned literal = typeParam.constant->getConstArray()[0].getIConst();
 | 
			
		||||
                        operands.push_back(literal);
 | 
			
		||||
                    } else if (typeParam.constant->getBasicType() == glslang::EbtUint) {
 | 
			
		||||
                        unsigned literal = typeParam.constant->getConstArray()[0].getUConst();
 | 
			
		||||
                        operands.push_back(literal);
 | 
			
		||||
                    } else if (typeParam.constant->getBasicType() == glslang::EbtBool) {
 | 
			
		||||
                        unsigned literal = typeParam.constant->getConstArray()[0].getBConst();
 | 
			
		||||
                        operands.push_back(literal);
 | 
			
		||||
                    } else if (typeParam.constant->getBasicType() == glslang::EbtString) {
 | 
			
		||||
                        auto str = typeParam.constant->getConstArray()[0].getSConst()->c_str();
 | 
			
		||||
                        unsigned literal = 0;
 | 
			
		||||
                        char* literalPtr = reinterpret_cast<char*>(&literal);
 | 
			
		||||
                        unsigned charCount = 0;
 | 
			
		||||
                        char ch = 0;
 | 
			
		||||
                        do {
 | 
			
		||||
                            ch = *(str++);
 | 
			
		||||
                            *(literalPtr++) = ch;
 | 
			
		||||
                            ++charCount;
 | 
			
		||||
                            if (charCount == 4) {
 | 
			
		||||
                                operands.push_back(literal);
 | 
			
		||||
                                literalPtr = reinterpret_cast<char*>(&literal);
 | 
			
		||||
                                charCount = 0;
 | 
			
		||||
                            }
 | 
			
		||||
                        } while (ch != 0);
 | 
			
		||||
 | 
			
		||||
                        // Partial literal is padded with 0
 | 
			
		||||
                        if (charCount > 0) {
 | 
			
		||||
                            for (; charCount < 4; ++charCount)
 | 
			
		||||
                                *(literalPtr++) = 0;
 | 
			
		||||
                            operands.push_back(literal);
 | 
			
		||||
                        }
 | 
			
		||||
                    } else
 | 
			
		||||
                        assert(0); // Unexpected type
 | 
			
		||||
                } else {
 | 
			
		||||
                    int nextConst = 0;
 | 
			
		||||
                    spv::Id constant = createSpvConstantFromConstUnionArray(
 | 
			
		||||
                        typeParam.constant->getType(), typeParam.constant->getConstArray(), nextConst, false);
 | 
			
		||||
                    operands.push_back(constant);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                // Type specifier
 | 
			
		||||
                spv::Id typeId = convertGlslangToSpvType(*typeParam.type);
 | 
			
		||||
                operands.push_back(typeId);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (spirvInst.set == "")
 | 
			
		||||
            spvType = builder.createOp(static_cast<spv::Op>(spirvInst.id), spv::NoType, operands);
 | 
			
		||||
        else {
 | 
			
		||||
            spvType = builder.createBuiltinCall(
 | 
			
		||||
                spv::NoType, getExtBuiltins(spirvInst.set.c_str()), spirvInst.id, operands);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    default:
 | 
			
		||||
        assert(0);
 | 
			
		||||
        break;
 | 
			
		||||
@ -4225,6 +4473,38 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
 | 
			
		||||
            builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV);
 | 
			
		||||
            builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //
 | 
			
		||||
        // Add SPIR-V decorations for members (GL_EXT_spirv_intrinsics)
 | 
			
		||||
        //
 | 
			
		||||
        if (glslangMember.getQualifier().hasSprivDecorate()) {
 | 
			
		||||
            const glslang::TSpirvDecorate& spirvDecorate = glslangMember.getQualifier().getSpirvDecorate();
 | 
			
		||||
 | 
			
		||||
            // Add spirv_decorate
 | 
			
		||||
            for (auto& decorate : spirvDecorate.decorates) {
 | 
			
		||||
                if (!decorate.second.empty()) {
 | 
			
		||||
                    std::vector<unsigned> literals;
 | 
			
		||||
                    TranslateLiterals(decorate.second, literals);
 | 
			
		||||
                    builder.addMemberDecoration(spvType, member, static_cast<spv::Decoration>(decorate.first), literals);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    builder.addMemberDecoration(spvType, member, static_cast<spv::Decoration>(decorate.first));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // spirv_decorate_id not applied to members
 | 
			
		||||
            assert(spirvDecorate.decorateIds.empty());
 | 
			
		||||
 | 
			
		||||
            // Add spirv_decorate_string
 | 
			
		||||
            for (auto& decorateString : spirvDecorate.decorateStrings) {
 | 
			
		||||
                std::vector<const char*> strings;
 | 
			
		||||
                assert(!decorateString.second.empty());
 | 
			
		||||
                for (auto extraOperand : decorateString.second) {
 | 
			
		||||
                    const char* string = extraOperand->getConstArray()[0].getSConst()->c_str();
 | 
			
		||||
                    strings.push_back(string);
 | 
			
		||||
                }
 | 
			
		||||
                builder.addDecoration(spvType, static_cast<spv::Decoration>(decorateString.first), strings);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -4614,6 +4894,9 @@ bool TGlslangToSpvTraverser::originalParam(glslang::TStorageQualifier qualifier,
 | 
			
		||||
    if (glslangIntermediate->getSource() == glslang::EShSourceHlsl)
 | 
			
		||||
        return paramType.getBasicType() == glslang::EbtBlock;
 | 
			
		||||
    return paramType.containsOpaque() ||                                                       // sampler, etc.
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
           paramType.getQualifier().isSpirvByReference() ||                                    // spirv_by_reference
 | 
			
		||||
#endif
 | 
			
		||||
           (paramType.getBasicType() == glslang::EbtBlock && qualifier == glslang::EvqBuffer); // SSBO
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -8465,6 +8748,48 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
 | 
			
		||||
        builder.addDecoration(id, symbol->getType().getQualifier().restrict ?
 | 
			
		||||
            spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // Add SPIR-V decorations for structure (GL_EXT_spirv_intrinsics)
 | 
			
		||||
    //
 | 
			
		||||
    if (symbol->getType().getQualifier().hasSprivDecorate()) {
 | 
			
		||||
        const glslang::TSpirvDecorate& spirvDecorate = symbol->getType().getQualifier().getSpirvDecorate();
 | 
			
		||||
 | 
			
		||||
        // Add spirv_decorate
 | 
			
		||||
        for (auto& decorate : spirvDecorate.decorates) {
 | 
			
		||||
            if (!decorate.second.empty()) {
 | 
			
		||||
                std::vector<unsigned> literals;
 | 
			
		||||
                TranslateLiterals(decorate.second, literals);
 | 
			
		||||
                builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first), literals);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
                builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Add spirv_decorate_id
 | 
			
		||||
        for (auto& decorateId : spirvDecorate.decorateIds) {
 | 
			
		||||
            std::vector<spv::Id> operandIds;
 | 
			
		||||
            assert(!decorateId.second.empty());
 | 
			
		||||
            for (auto extraOperand : decorateId.second) {
 | 
			
		||||
                int nextConst = 0;
 | 
			
		||||
                spv::Id operandId = createSpvConstantFromConstUnionArray(
 | 
			
		||||
                    extraOperand->getType(), extraOperand->getConstArray(), nextConst, false);
 | 
			
		||||
                operandIds.push_back(operandId);
 | 
			
		||||
            }
 | 
			
		||||
            builder.addDecoration(id, static_cast<spv::Decoration>(decorateId.first), operandIds);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Add spirv_decorate_string
 | 
			
		||||
        for (auto& decorateString : spirvDecorate.decorateStrings) {
 | 
			
		||||
            std::vector<const char*> strings;
 | 
			
		||||
            assert(!decorateString.second.empty());
 | 
			
		||||
            for (auto extraOperand : decorateString.second) {
 | 
			
		||||
                const char* string = extraOperand->getConstArray()[0].getSConst()->c_str();
 | 
			
		||||
                strings.push_back(string);
 | 
			
		||||
            }
 | 
			
		||||
            builder.addDecoration(id, static_cast<spv::Decoration>(decorateString.first), strings);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return id;
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,9 @@ WARNING: 0:1: '#define' : missing space after macro name
 | 
			
		||||
ERROR: 0:3: 'preprocessor evaluation' : bad expression 
 | 
			
		||||
ERROR: 0:3: '#if' : unexpected tokens following directive 
 | 
			
		||||
ERROR: 0:6: 'string' : End of line in string 
 | 
			
		||||
ERROR: 0:6: 'string literal' : required extension not requested: GL_EXT_debug_printf
 | 
			
		||||
ERROR: 0:6: 'string literal' : required extension not requested: Possible extensions include:
 | 
			
		||||
GL_EXT_debug_printf
 | 
			
		||||
GL_EXT_spirv_intrinsics
 | 
			
		||||
ERROR: 0:6: '' :  syntax error, unexpected INT, expecting COMMA or SEMICOLON
 | 
			
		||||
ERROR: 5 compilation errors.  No code generated.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -18,8 +18,12 @@ ERROR: 0:117: '#error' : bad5
 | 
			
		||||
ERROR: 0:120: '#if' : unexpected tokens following directive 
 | 
			
		||||
ERROR: 0:121: '#error' : bad6  
 | 
			
		||||
ERROR: 0:122: '#endif' : unexpected tokens following directive 
 | 
			
		||||
ERROR: 0:135: 'string literal' : required extension not requested: GL_EXT_debug_printf
 | 
			
		||||
ERROR: 0:136: 'string literal' : required extension not requested: GL_EXT_debug_printf
 | 
			
		||||
ERROR: 0:135: 'string literal' : required extension not requested: Possible extensions include:
 | 
			
		||||
GL_EXT_debug_printf
 | 
			
		||||
GL_EXT_spirv_intrinsics
 | 
			
		||||
ERROR: 0:136: 'string literal' : required extension not requested: Possible extensions include:
 | 
			
		||||
GL_EXT_debug_printf
 | 
			
		||||
GL_EXT_spirv_intrinsics
 | 
			
		||||
ERROR: 0:136: 'length' : no matching overloaded function found 
 | 
			
		||||
ERROR: 0:136: '=' :  cannot convert from ' const float' to ' global int'
 | 
			
		||||
ERROR: 0:138: ''' : character literals not supported 
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										56
									
								
								Test/baseResults/spv.intrinsicsSpirvByReference.vert.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								Test/baseResults/spv.intrinsicsSpirvByReference.vert.out
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
			
		||||
spv.intrinsicsSpirvByReference.vert
 | 
			
		||||
// Module Version 10000
 | 
			
		||||
// Generated by (magic number): 8000a
 | 
			
		||||
// Id's are bound by 30
 | 
			
		||||
 | 
			
		||||
                              Capability Shader
 | 
			
		||||
               1:             ExtInstImport  "GLSL.std.450"
 | 
			
		||||
                              MemoryModel Logical GLSL450
 | 
			
		||||
                              EntryPoint Vertex 4  "main" 15 17 26
 | 
			
		||||
                              Source GLSL 450
 | 
			
		||||
                              SourceExtension  "GL_EXT_spirv_intrinsics"
 | 
			
		||||
                              Name 4  "main"
 | 
			
		||||
                              Name 10  "func(f1;"
 | 
			
		||||
                              Name 9  "f"
 | 
			
		||||
                              Name 15  "vec2Out"
 | 
			
		||||
                              Name 17  "floatIn"
 | 
			
		||||
                              Name 26  "floatOut"
 | 
			
		||||
                              Name 27  "param"
 | 
			
		||||
                              Decorate 15(vec2Out) Location 0
 | 
			
		||||
                              Decorate 17(floatIn) Location 0
 | 
			
		||||
                              Decorate 26(floatOut) Location 1
 | 
			
		||||
               2:             TypeVoid
 | 
			
		||||
               3:             TypeFunction 2
 | 
			
		||||
               6:             TypeFloat 32
 | 
			
		||||
               7:             TypePointer Function 6(float)
 | 
			
		||||
               8:             TypeFunction 2 7(ptr)
 | 
			
		||||
              12:    6(float) Constant 1056964608
 | 
			
		||||
              13:             TypeVector 6(float) 2
 | 
			
		||||
              14:             TypePointer Output 13(fvec2)
 | 
			
		||||
     15(vec2Out):     14(ptr) Variable Output
 | 
			
		||||
              16:             TypePointer Input 6(float)
 | 
			
		||||
     17(floatIn):     16(ptr) Variable Input
 | 
			
		||||
              19:             TypeInt 32 0
 | 
			
		||||
              20:     19(int) Constant 1
 | 
			
		||||
              21:             TypePointer Output 6(float)
 | 
			
		||||
              24:     19(int) Constant 0
 | 
			
		||||
    26(floatOut):     21(ptr) Variable Output
 | 
			
		||||
         4(main):           2 Function None 3
 | 
			
		||||
               5:             Label
 | 
			
		||||
       27(param):      7(ptr) Variable Function
 | 
			
		||||
              18:    6(float) Load 17(floatIn)
 | 
			
		||||
              22:     21(ptr) AccessChain 15(vec2Out) 20
 | 
			
		||||
              23:    6(float) ExtInst 1(GLSL.std.450) 35(Modf) 18 22
 | 
			
		||||
              25:     21(ptr) AccessChain 15(vec2Out) 24
 | 
			
		||||
                              Store 25 23
 | 
			
		||||
              28:    6(float) Load 26(floatOut)
 | 
			
		||||
                              Store 27(param) 28
 | 
			
		||||
              29:           2 FunctionCall 10(func(f1;) 27(param)
 | 
			
		||||
                              Return
 | 
			
		||||
                              FunctionEnd
 | 
			
		||||
    10(func(f1;):           2 Function None 8
 | 
			
		||||
            9(f):      7(ptr) FunctionParameter
 | 
			
		||||
              11:             Label
 | 
			
		||||
                              Store 9(f) 12
 | 
			
		||||
                              Return
 | 
			
		||||
                              FunctionEnd
 | 
			
		||||
							
								
								
									
										88
									
								
								Test/baseResults/spv.intrinsicsSpirvDecorate.frag.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								Test/baseResults/spv.intrinsicsSpirvDecorate.frag.out
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,88 @@
 | 
			
		||||
spv.intrinsicsSpirvDecorate.frag
 | 
			
		||||
Validation failed
 | 
			
		||||
// Module Version 10000
 | 
			
		||||
// Generated by (magic number): 8000a
 | 
			
		||||
// Id's are bound by 43
 | 
			
		||||
 | 
			
		||||
                              Capability Shader
 | 
			
		||||
                              Extension  "SPV_AMD_shader_explicit_vertex_parameter"
 | 
			
		||||
               1:             ExtInstImport  "GLSL.std.450"
 | 
			
		||||
              14:             ExtInstImport  "SPV_AMD_shader_explicit_vertex_parameter"
 | 
			
		||||
                              MemoryModel Logical GLSL450
 | 
			
		||||
                              EntryPoint Fragment 4  "main" 8 10 18 20 22 25 28 31 34 39
 | 
			
		||||
                              ExecutionMode 4 OriginUpperLeft
 | 
			
		||||
                              Source GLSL 450
 | 
			
		||||
                              SourceExtension  "GL_EXT_spirv_intrinsics"
 | 
			
		||||
                              Name 4  "main"
 | 
			
		||||
                              Name 8  "floatOut"
 | 
			
		||||
                              Name 10  "floatIn"
 | 
			
		||||
                              Name 18  "vec2Out"
 | 
			
		||||
                              Name 20  "gl_BaryCoordNoPerspAMD"
 | 
			
		||||
                              Name 22  "gl_BaryCoordNoPerspCentroidAMD"
 | 
			
		||||
                              Name 25  "gl_BaryCoordNoPerspSampleAMD"
 | 
			
		||||
                              Name 28  "gl_BaryCoordSmoothAMD"
 | 
			
		||||
                              Name 31  "gl_BaryCoordSmoothCentroidAMD"
 | 
			
		||||
                              Name 34  "gl_BaryCoordSmoothSampleAMD"
 | 
			
		||||
                              Name 39  "gl_BaryCoordPullModelAMD"
 | 
			
		||||
                              Decorate 8(floatOut) Location 0
 | 
			
		||||
                              Decorate 10(floatIn) Location 0
 | 
			
		||||
                              Decorate 10(floatIn) ExplicitInterpAMD
 | 
			
		||||
                              Decorate 18(vec2Out) Location 1
 | 
			
		||||
                              Decorate 20(gl_BaryCoordNoPerspAMD) Location 0
 | 
			
		||||
                              Decorate 20(gl_BaryCoordNoPerspAMD) BuiltIn BaryCoordNoPerspAMD
 | 
			
		||||
                              Decorate 22(gl_BaryCoordNoPerspCentroidAMD) Location 1
 | 
			
		||||
                              Decorate 22(gl_BaryCoordNoPerspCentroidAMD) BuiltIn BaryCoordNoPerspCentroidAMD
 | 
			
		||||
                              Decorate 25(gl_BaryCoordNoPerspSampleAMD) Location 2
 | 
			
		||||
                              Decorate 25(gl_BaryCoordNoPerspSampleAMD) BuiltIn BaryCoordNoPerspSampleAMD
 | 
			
		||||
                              Decorate 28(gl_BaryCoordSmoothAMD) Location 3
 | 
			
		||||
                              Decorate 28(gl_BaryCoordSmoothAMD) BuiltIn BaryCoordSmoothAMD
 | 
			
		||||
                              Decorate 31(gl_BaryCoordSmoothCentroidAMD) Location 4
 | 
			
		||||
                              Decorate 31(gl_BaryCoordSmoothCentroidAMD) BuiltIn BaryCoordSmoothCentroidAMD
 | 
			
		||||
                              Decorate 34(gl_BaryCoordSmoothSampleAMD) Location 5
 | 
			
		||||
                              Decorate 34(gl_BaryCoordSmoothSampleAMD) BuiltIn BaryCoordSmoothSampleAMD
 | 
			
		||||
                              Decorate 39(gl_BaryCoordPullModelAMD) Location 6
 | 
			
		||||
                              Decorate 39(gl_BaryCoordPullModelAMD) BuiltIn BaryCoordPullModelAMD
 | 
			
		||||
               2:             TypeVoid
 | 
			
		||||
               3:             TypeFunction 2
 | 
			
		||||
               6:             TypeFloat 32
 | 
			
		||||
               7:             TypePointer Output 6(float)
 | 
			
		||||
     8(floatOut):      7(ptr) Variable Output
 | 
			
		||||
               9:             TypePointer Input 6(float)
 | 
			
		||||
     10(floatIn):      9(ptr) Variable Input
 | 
			
		||||
              12:             TypeInt 32 0
 | 
			
		||||
              13:     12(int) Constant 1
 | 
			
		||||
              16:             TypeVector 6(float) 2
 | 
			
		||||
              17:             TypePointer Output 16(fvec2)
 | 
			
		||||
     18(vec2Out):     17(ptr) Variable Output
 | 
			
		||||
              19:             TypePointer Input 16(fvec2)
 | 
			
		||||
20(gl_BaryCoordNoPerspAMD):     19(ptr) Variable Input
 | 
			
		||||
22(gl_BaryCoordNoPerspCentroidAMD):     19(ptr) Variable Input
 | 
			
		||||
25(gl_BaryCoordNoPerspSampleAMD):     19(ptr) Variable Input
 | 
			
		||||
28(gl_BaryCoordSmoothAMD):     19(ptr) Variable Input
 | 
			
		||||
31(gl_BaryCoordSmoothCentroidAMD):     19(ptr) Variable Input
 | 
			
		||||
34(gl_BaryCoordSmoothSampleAMD):     19(ptr) Variable Input
 | 
			
		||||
              37:             TypeVector 6(float) 3
 | 
			
		||||
              38:             TypePointer Input 37(fvec3)
 | 
			
		||||
39(gl_BaryCoordPullModelAMD):     38(ptr) Variable Input
 | 
			
		||||
         4(main):           2 Function None 3
 | 
			
		||||
               5:             Label
 | 
			
		||||
              11:    6(float) Load 10(floatIn)
 | 
			
		||||
              15:    6(float) ExtInst 14(SPV_AMD_shader_explicit_vertex_parameter) 1(InterpolateAtVertexAMD) 11 13
 | 
			
		||||
                              Store 8(floatOut) 15
 | 
			
		||||
              21:   16(fvec2) Load 20(gl_BaryCoordNoPerspAMD)
 | 
			
		||||
              23:   16(fvec2) Load 22(gl_BaryCoordNoPerspCentroidAMD)
 | 
			
		||||
              24:   16(fvec2) FAdd 21 23
 | 
			
		||||
              26:   16(fvec2) Load 25(gl_BaryCoordNoPerspSampleAMD)
 | 
			
		||||
              27:   16(fvec2) FAdd 24 26
 | 
			
		||||
              29:   16(fvec2) Load 28(gl_BaryCoordSmoothAMD)
 | 
			
		||||
              30:   16(fvec2) FAdd 27 29
 | 
			
		||||
              32:   16(fvec2) Load 31(gl_BaryCoordSmoothCentroidAMD)
 | 
			
		||||
              33:   16(fvec2) FAdd 30 32
 | 
			
		||||
              35:   16(fvec2) Load 34(gl_BaryCoordSmoothSampleAMD)
 | 
			
		||||
              36:   16(fvec2) FAdd 33 35
 | 
			
		||||
              40:   37(fvec3) Load 39(gl_BaryCoordPullModelAMD)
 | 
			
		||||
              41:   16(fvec2) VectorShuffle 40 40 0 1
 | 
			
		||||
              42:   16(fvec2) FAdd 36 41
 | 
			
		||||
                              Store 18(vec2Out) 42
 | 
			
		||||
                              Return
 | 
			
		||||
                              FunctionEnd
 | 
			
		||||
							
								
								
									
										36
									
								
								Test/baseResults/spv.intrinsicsSpirvExecutionMode.frag.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								Test/baseResults/spv.intrinsicsSpirvExecutionMode.frag.out
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
			
		||||
spv.intrinsicsSpirvExecutionMode.frag
 | 
			
		||||
Validation failed
 | 
			
		||||
// Module Version 10000
 | 
			
		||||
// Generated by (magic number): 8000a
 | 
			
		||||
// Id's are bound by 12
 | 
			
		||||
 | 
			
		||||
                              Capability Shader
 | 
			
		||||
                              Capability StencilExportEXT
 | 
			
		||||
                              Extension  "SPV_EXT_shader_stencil_export"
 | 
			
		||||
               1:             ExtInstImport  "GLSL.std.450"
 | 
			
		||||
                              MemoryModel Logical GLSL450
 | 
			
		||||
                              EntryPoint Fragment 4  "main" 8 10
 | 
			
		||||
                              ExecutionMode 4 OriginUpperLeft
 | 
			
		||||
                              ExecutionMode 4 StencilRefReplacingEXT
 | 
			
		||||
                              Source GLSL 450
 | 
			
		||||
                              SourceExtension  "GL_EXT_spirv_intrinsics"
 | 
			
		||||
                              Name 4  "main"
 | 
			
		||||
                              Name 8  "gl_FragStencilRef"
 | 
			
		||||
                              Name 10  "color"
 | 
			
		||||
                              Decorate 8(gl_FragStencilRef) Location 0
 | 
			
		||||
                              Decorate 8(gl_FragStencilRef) BuiltIn FragStencilRefEXT
 | 
			
		||||
                              Decorate 10(color) Flat
 | 
			
		||||
                              Decorate 10(color) Location 0
 | 
			
		||||
               2:             TypeVoid
 | 
			
		||||
               3:             TypeFunction 2
 | 
			
		||||
               6:             TypeInt 32 1
 | 
			
		||||
               7:             TypePointer Output 6(int)
 | 
			
		||||
8(gl_FragStencilRef):      7(ptr) Variable Output
 | 
			
		||||
               9:             TypePointer Input 6(int)
 | 
			
		||||
       10(color):      9(ptr) Variable Input
 | 
			
		||||
         4(main):           2 Function None 3
 | 
			
		||||
               5:             Label
 | 
			
		||||
              11:      6(int) Load 10(color)
 | 
			
		||||
                              Store 8(gl_FragStencilRef) 11
 | 
			
		||||
                              Return
 | 
			
		||||
                              FunctionEnd
 | 
			
		||||
							
								
								
									
										59
									
								
								Test/baseResults/spv.intrinsicsSpirvInstruction.vert.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								Test/baseResults/spv.intrinsicsSpirvInstruction.vert.out
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,59 @@
 | 
			
		||||
spv.intrinsicsSpirvInstruction.vert
 | 
			
		||||
Validation failed
 | 
			
		||||
// Module Version 10000
 | 
			
		||||
// Generated by (magic number): 8000a
 | 
			
		||||
// Id's are bound by 30
 | 
			
		||||
 | 
			
		||||
                              Capability Shader
 | 
			
		||||
                              Capability Int64
 | 
			
		||||
                              Capability ShaderClockKHR
 | 
			
		||||
                              Extension  "SPV_AMD_shader_trinary_minmax"
 | 
			
		||||
                              Extension  "SPV_KHR_shader_clock"
 | 
			
		||||
               1:             ExtInstImport  "GLSL.std.450"
 | 
			
		||||
              28:             ExtInstImport  "SPV_AMD_shader_trinary_minmax"
 | 
			
		||||
                              MemoryModel Logical GLSL450
 | 
			
		||||
                              EntryPoint Vertex 4  "main" 9 13 18 21
 | 
			
		||||
                              Source GLSL 450
 | 
			
		||||
                              SourceExtension  "GL_ARB_gpu_shader_int64"
 | 
			
		||||
                              SourceExtension  "GL_EXT_spirv_intrinsics"
 | 
			
		||||
                              Name 4  "main"
 | 
			
		||||
                              Name 9  "uvec2Out"
 | 
			
		||||
                              Name 13  "i64Out"
 | 
			
		||||
                              Name 18  "vec2Out"
 | 
			
		||||
                              Name 21  "vec3In"
 | 
			
		||||
                              Decorate 9(uvec2Out) Location 0
 | 
			
		||||
                              Decorate 13(i64Out) Location 1
 | 
			
		||||
                              Decorate 18(vec2Out) Location 2
 | 
			
		||||
                              Decorate 21(vec3In) Location 0
 | 
			
		||||
               2:             TypeVoid
 | 
			
		||||
               3:             TypeFunction 2
 | 
			
		||||
               6:             TypeInt 32 0
 | 
			
		||||
               7:             TypeVector 6(int) 2
 | 
			
		||||
               8:             TypePointer Output 7(ivec2)
 | 
			
		||||
     9(uvec2Out):      8(ptr) Variable Output
 | 
			
		||||
              11:             TypeInt 64 1
 | 
			
		||||
              12:             TypePointer Output 11(int64_t)
 | 
			
		||||
      13(i64Out):     12(ptr) Variable Output
 | 
			
		||||
              15:             TypeFloat 32
 | 
			
		||||
              16:             TypeVector 15(float) 2
 | 
			
		||||
              17:             TypePointer Output 16(fvec2)
 | 
			
		||||
     18(vec2Out):     17(ptr) Variable Output
 | 
			
		||||
              19:             TypeVector 15(float) 3
 | 
			
		||||
              20:             TypePointer Input 19(fvec3)
 | 
			
		||||
      21(vec3In):     20(ptr) Variable Input
 | 
			
		||||
         4(main):           2 Function None 3
 | 
			
		||||
               5:             Label
 | 
			
		||||
              10:    7(ivec2) ReadClockKHR
 | 
			
		||||
                              Store 9(uvec2Out) 10
 | 
			
		||||
              14: 11(int64_t) ReadClockKHR
 | 
			
		||||
                              Store 13(i64Out) 14
 | 
			
		||||
              22:   19(fvec3) Load 21(vec3In)
 | 
			
		||||
              23:   16(fvec2) VectorShuffle 22 22 0 1
 | 
			
		||||
              24:   19(fvec3) Load 21(vec3In)
 | 
			
		||||
              25:   16(fvec2) VectorShuffle 24 24 1 2
 | 
			
		||||
              26:   19(fvec3) Load 21(vec3In)
 | 
			
		||||
              27:   16(fvec2) VectorShuffle 26 26 2 0
 | 
			
		||||
              29:   16(fvec2) ExtInst 28(SPV_AMD_shader_trinary_minmax) 1(FMin3AMD) 23 25 27
 | 
			
		||||
                              Store 18(vec2Out) 29
 | 
			
		||||
                              Return
 | 
			
		||||
                              FunctionEnd
 | 
			
		||||
							
								
								
									
										29
									
								
								Test/baseResults/spv.intrinsicsSpirvLiteral.vert.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								Test/baseResults/spv.intrinsicsSpirvLiteral.vert.out
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
			
		||||
spv.intrinsicsSpirvLiteral.vert
 | 
			
		||||
// Module Version 10000
 | 
			
		||||
// Generated by (magic number): 8000a
 | 
			
		||||
// Id's are bound by 12
 | 
			
		||||
 | 
			
		||||
                              Capability Shader
 | 
			
		||||
               1:             ExtInstImport  "GLSL.std.450"
 | 
			
		||||
                              MemoryModel Logical GLSL450
 | 
			
		||||
                              EntryPoint Vertex 4  "main"
 | 
			
		||||
                              Source GLSL 450
 | 
			
		||||
                              SourceExtension  "GL_EXT_spirv_intrinsics"
 | 
			
		||||
                              Name 4  "main"
 | 
			
		||||
                              Name 9  "vec4Out"
 | 
			
		||||
                              Name 10  "vec4In"
 | 
			
		||||
                              Decorate 9(vec4Out) Location 1
 | 
			
		||||
                              Decorate 10(vec4In) Location 0
 | 
			
		||||
               2:             TypeVoid
 | 
			
		||||
               3:             TypeFunction 2
 | 
			
		||||
               6:             TypeFloat 32
 | 
			
		||||
               7:             TypeVector 6(float) 4
 | 
			
		||||
               8:             TypePointer Function 7(fvec4)
 | 
			
		||||
         4(main):           2 Function None 3
 | 
			
		||||
               5:             Label
 | 
			
		||||
      9(vec4Out):      8(ptr) Variable Function
 | 
			
		||||
      10(vec4In):      8(ptr) Variable Function
 | 
			
		||||
              11:    7(fvec4) Load 10(vec4In) None
 | 
			
		||||
                              Store 9(vec4Out) 11 Volatile 
 | 
			
		||||
                              Return
 | 
			
		||||
                              FunctionEnd
 | 
			
		||||
							
								
								
									
										30
									
								
								Test/baseResults/spv.intrinsicsSpirvStorageClass.rchit.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Test/baseResults/spv.intrinsicsSpirvStorageClass.rchit.out
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
			
		||||
spv.intrinsicsSpirvStorageClass.rchit
 | 
			
		||||
// Module Version 10000
 | 
			
		||||
// Generated by (magic number): 8000a
 | 
			
		||||
// Id's are bound by 13
 | 
			
		||||
 | 
			
		||||
                              Capability RayTracingKHR
 | 
			
		||||
                              Capability RayTracingProvisionalKHR
 | 
			
		||||
                              Extension  "SPV_KHR_ray_tracing"
 | 
			
		||||
               1:             ExtInstImport  "GLSL.std.450"
 | 
			
		||||
                              MemoryModel Logical GLSL450
 | 
			
		||||
                              EntryPoint ClosestHitKHR 4  "main"
 | 
			
		||||
                              Source GLSL 460
 | 
			
		||||
                              SourceExtension  "GL_EXT_spirv_intrinsics"
 | 
			
		||||
                              Name 4  "main"
 | 
			
		||||
                              Name 9  "payload"
 | 
			
		||||
                              Decorate 9(payload) Location 1
 | 
			
		||||
               2:             TypeVoid
 | 
			
		||||
               3:             TypeFunction 2
 | 
			
		||||
               6:             TypeFloat 32
 | 
			
		||||
               7:             TypeVector 6(float) 4
 | 
			
		||||
               8:             TypePointer RayPayloadKHR 7(fvec4)
 | 
			
		||||
      9(payload):      8(ptr) Variable RayPayloadKHR
 | 
			
		||||
              10:    6(float) Constant 0
 | 
			
		||||
              11:    6(float) Constant 1065353216
 | 
			
		||||
              12:    7(fvec4) ConstantComposite 10 11 10 11
 | 
			
		||||
         4(main):           2 Function None 3
 | 
			
		||||
               5:             Label
 | 
			
		||||
                              Store 9(payload) 12
 | 
			
		||||
                              Return
 | 
			
		||||
                              FunctionEnd
 | 
			
		||||
							
								
								
									
										45
									
								
								Test/baseResults/spv.intrinsicsSpirvType.rgen.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								Test/baseResults/spv.intrinsicsSpirvType.rgen.out
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
			
		||||
spv.intrinsicsSpirvType.rgen
 | 
			
		||||
Validation failed
 | 
			
		||||
// Module Version 10000
 | 
			
		||||
// Generated by (magic number): 8000a
 | 
			
		||||
// Id's are bound by 21
 | 
			
		||||
 | 
			
		||||
                              Capability RayQueryKHR
 | 
			
		||||
                              Capability RayTraversalPrimitiveCullingKHR
 | 
			
		||||
                              Capability RayTracingKHR
 | 
			
		||||
                              Extension  "SPV_KHR_ray_query"
 | 
			
		||||
                              Extension  "SPV_KHR_ray_tracing"
 | 
			
		||||
               1:             ExtInstImport  "GLSL.std.450"
 | 
			
		||||
                              MemoryModel Logical GLSL450
 | 
			
		||||
                              EntryPoint RayGenerationKHR 4  "main"
 | 
			
		||||
                              Source GLSL 460
 | 
			
		||||
                              SourceExtension  "GL_EXT_spirv_intrinsics"
 | 
			
		||||
                              Name 4  "main"
 | 
			
		||||
                              Name 8  "rq"
 | 
			
		||||
                              Name 11  "as"
 | 
			
		||||
                              Decorate 11(as) Location 0
 | 
			
		||||
                              Decorate 11(as) DescriptorSet 0
 | 
			
		||||
                              Decorate 11(as) Binding 0
 | 
			
		||||
               2:             TypeVoid
 | 
			
		||||
               3:             TypeFunction 2
 | 
			
		||||
               7:             TypePointer Function 6
 | 
			
		||||
              10:             TypePointer UniformConstant 9
 | 
			
		||||
          11(as):     10(ptr) Variable UniformConstant
 | 
			
		||||
              13:             TypeInt 32 0
 | 
			
		||||
              14:     13(int) Constant 0
 | 
			
		||||
              15:             TypeFloat 32
 | 
			
		||||
              16:             TypeVector 15(float) 3
 | 
			
		||||
              17:   15(float) Constant 0
 | 
			
		||||
              18:   16(fvec3) ConstantComposite 17 17 17
 | 
			
		||||
              19:   15(float) Constant 1065353216
 | 
			
		||||
              20:   16(fvec3) ConstantComposite 19 19 19
 | 
			
		||||
         4(main):           2 Function None 3
 | 
			
		||||
               5:             Label
 | 
			
		||||
           8(rq):      7(ptr) Variable Function
 | 
			
		||||
               6:             TypeRayQueryKHR
 | 
			
		||||
               9:             TypeAccelerationStructureKHR
 | 
			
		||||
              12:           9 Load 11(as)
 | 
			
		||||
                              RayQueryInitializeKHR 8(rq) 12 14 14 18 17 20 19
 | 
			
		||||
                              RayQueryTerminateKHR 8(rq)
 | 
			
		||||
                              Return
 | 
			
		||||
                              FunctionEnd
 | 
			
		||||
							
								
								
									
										21
									
								
								Test/spv.intrinsicsSpirvByReference.vert
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Test/spv.intrinsicsSpirvByReference.vert
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
			
		||||
#version 450 core
 | 
			
		||||
 | 
			
		||||
#extension GL_EXT_spirv_intrinsics: enable
 | 
			
		||||
 | 
			
		||||
spirv_instruction (set = "GLSL.std.450", id = 35) // modf
 | 
			
		||||
float modf(float x, spirv_by_reference float i);
 | 
			
		||||
 | 
			
		||||
layout(location = 0) in float floatIn;
 | 
			
		||||
layout(location = 0) out vec2 vec2Out;
 | 
			
		||||
layout(location = 1) out float floatOut;
 | 
			
		||||
 | 
			
		||||
void func(spirv_by_reference float f)
 | 
			
		||||
{
 | 
			
		||||
    f = 0.5;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
    vec2Out.x = modf(floatIn, vec2Out.y);
 | 
			
		||||
    func(floatOut);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										37
									
								
								Test/spv.intrinsicsSpirvDecorate.frag
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								Test/spv.intrinsicsSpirvDecorate.frag
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
			
		||||
#version 450 core
 | 
			
		||||
 | 
			
		||||
#extension GL_EXT_spirv_intrinsics: enable
 | 
			
		||||
 | 
			
		||||
#define GL_AMD_shader_explicit_vertex_parameter 1
 | 
			
		||||
 | 
			
		||||
spirv_decorate (extensions = ["SPV_AMD_shader_explicit_vertex_parameter"], 11, 4992)
 | 
			
		||||
in vec2 gl_BaryCoordNoPerspAMD;
 | 
			
		||||
spirv_decorate (extensions = ["SPV_AMD_shader_explicit_vertex_parameter"], 11, 4993)
 | 
			
		||||
in vec2 gl_BaryCoordNoPerspCentroidAMD;
 | 
			
		||||
spirv_decorate (extensions = ["SPV_AMD_shader_explicit_vertex_parameter"], 11, 4994)
 | 
			
		||||
in vec2 gl_BaryCoordNoPerspSampleAMD;
 | 
			
		||||
spirv_decorate (extensions = ["SPV_AMD_shader_explicit_vertex_parameter"], 11, 4995)
 | 
			
		||||
in vec2 gl_BaryCoordSmoothAMD;
 | 
			
		||||
spirv_decorate (extensions = ["SPV_AMD_shader_explicit_vertex_parameter"], 11, 4996)
 | 
			
		||||
in vec2 gl_BaryCoordSmoothCentroidAMD;
 | 
			
		||||
spirv_decorate (extensions = ["SPV_AMD_shader_explicit_vertex_parameter"], 11, 4997)
 | 
			
		||||
in vec2 gl_BaryCoordSmoothSampleAMD;
 | 
			
		||||
spirv_decorate (extensions = ["SPV_AMD_shader_explicit_vertex_parameter"], 11, 4998)
 | 
			
		||||
in vec3 gl_BaryCoordPullModelAMD;
 | 
			
		||||
 | 
			
		||||
#define __explicitInterpAMD spirv_decorate(extensions = ["SPV_AMD_shader_explicit_vertex_parameter"], 4999)
 | 
			
		||||
 | 
			
		||||
spirv_instruction(extensions = ["SPV_AMD_shader_explicit_vertex_parameter"], set = "SPV_AMD_shader_explicit_vertex_parameter", id = 1)
 | 
			
		||||
float interpolateAtVertexAMD(float interpolant, uint vertexIdx);
 | 
			
		||||
 | 
			
		||||
layout(location = 0) in __explicitInterpAMD float floatIn;
 | 
			
		||||
layout(location = 0) out float floatOut;
 | 
			
		||||
layout(location = 1) out vec2 vec2Out;
 | 
			
		||||
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
    floatOut = interpolateAtVertexAMD(floatIn, 1);
 | 
			
		||||
    vec2Out = gl_BaryCoordNoPerspAMD + gl_BaryCoordNoPerspCentroidAMD + gl_BaryCoordNoPerspSampleAMD +
 | 
			
		||||
              gl_BaryCoordSmoothAMD + gl_BaryCoordSmoothCentroidAMD + gl_BaryCoordSmoothSampleAMD +
 | 
			
		||||
              gl_BaryCoordPullModelAMD.xy;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								Test/spv.intrinsicsSpirvExecutionMode.frag
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Test/spv.intrinsicsSpirvExecutionMode.frag
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
#version 450 core
 | 
			
		||||
 | 
			
		||||
#extension GL_EXT_spirv_intrinsics: enable
 | 
			
		||||
 | 
			
		||||
#define GL_ARB_shader_stencil_export 1
 | 
			
		||||
 | 
			
		||||
spirv_execution_mode(5027); // StencilRefReplacingEXT
 | 
			
		||||
 | 
			
		||||
spirv_decorate(extensions = ["SPV_EXT_shader_stencil_export"], capabilities = [5013], 11, 5014)
 | 
			
		||||
out int gl_FragStencilRef;
 | 
			
		||||
 | 
			
		||||
layout(location = 0) in flat int color;
 | 
			
		||||
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
    gl_FragStencilRef = color;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								Test/spv.intrinsicsSpirvInstruction.vert
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								Test/spv.intrinsicsSpirvInstruction.vert
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
			
		||||
#version 450 core
 | 
			
		||||
 | 
			
		||||
#extension GL_EXT_spirv_intrinsics: enable
 | 
			
		||||
#extension GL_ARB_gpu_shader_int64: enable
 | 
			
		||||
 | 
			
		||||
spirv_instruction (extensions = ["SPV_KHR_shader_clock"], capabilities = [5055], id = 5056)
 | 
			
		||||
uvec2 clockRealtime2x32EXT(void);
 | 
			
		||||
 | 
			
		||||
spirv_instruction (extensions = ["SPV_KHR_shader_clock"], capabilities = [5055], id = 5056)
 | 
			
		||||
int64_t clockRealtimeEXT(void);
 | 
			
		||||
 | 
			
		||||
spirv_instruction (extensions = ["SPV_AMD_shader_trinary_minmax"], set = "SPV_AMD_shader_trinary_minmax", id = 1)
 | 
			
		||||
vec2 min3(vec2 x, vec2 y, vec2 z);
 | 
			
		||||
 | 
			
		||||
layout(location = 0) in vec3 vec3In;
 | 
			
		||||
 | 
			
		||||
layout(location = 0) out uvec2 uvec2Out;
 | 
			
		||||
layout(location = 1) out int64_t i64Out;
 | 
			
		||||
layout(location = 2) out vec2 vec2Out;
 | 
			
		||||
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
    uvec2Out = clockRealtime2x32EXT();
 | 
			
		||||
    i64Out = clockRealtimeEXT();
 | 
			
		||||
    vec2Out = min3(vec3In.xy, vec3In.yz, vec3In.zx); 
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								Test/spv.intrinsicsSpirvLiteral.vert
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Test/spv.intrinsicsSpirvLiteral.vert
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
#version 450 core
 | 
			
		||||
 | 
			
		||||
#extension GL_EXT_spirv_intrinsics: enable
 | 
			
		||||
 | 
			
		||||
spirv_instruction(id = 61)
 | 
			
		||||
vec4 load(spirv_by_reference vec4 pointer, spirv_literal int memoryOperands);
 | 
			
		||||
 | 
			
		||||
spirv_instruction(id = 62)
 | 
			
		||||
void store(spirv_by_reference vec4 pointer, vec4 object, spirv_literal int memoryOperands);
 | 
			
		||||
 | 
			
		||||
layout(location = 0) in vec4 vec4In;
 | 
			
		||||
layout(location = 1) out vec4 vec4Out;
 | 
			
		||||
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
    store(vec4Out, load(vec4In, /*None=*/0x0), /*Volatile=*/0x1);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								Test/spv.intrinsicsSpirvStorageClass.rchit
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								Test/spv.intrinsicsSpirvStorageClass.rchit
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
#version 460
 | 
			
		||||
 | 
			
		||||
#extension GL_EXT_spirv_intrinsics: enable
 | 
			
		||||
 | 
			
		||||
#define rayPayloadEXT spirv_storage_class(extensions = ["SPV_KHR_ray_tracing"], capabilities = [5353], 5338)
 | 
			
		||||
 | 
			
		||||
layout(location = 1) rayPayloadEXT vec4 payload;
 | 
			
		||||
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
    payload = vec4(0.0, 1.0, 0.0, 1.0);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								Test/spv.intrinsicsSpirvType.rgen
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								Test/spv.intrinsicsSpirvType.rgen
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
#version 460 core
 | 
			
		||||
 | 
			
		||||
#extension GL_EXT_spirv_intrinsics: enable
 | 
			
		||||
 | 
			
		||||
#define rayQueryEXT spirv_type (extensions = ["SPV_KHR_ray_query"], capabilities = [4472], id = 4472)
 | 
			
		||||
#define accelerationStructureEXT spirv_type (extensions = ["SPV_KHR_ray_query"], capabilities = [4472], id = 5341)
 | 
			
		||||
 | 
			
		||||
spirv_instruction (extensions = ["SPV_KHR_ray_query"], capabilities = [4472, 4478], id = 4473)
 | 
			
		||||
void rayQueryInitializeEXT(spirv_by_reference rayQueryEXT rayQuery, accelerationStructureEXT topLevel, uint rayFlags, uint cullMask, vec3 origin, float tMin, vec3 direction, float tMax);
 | 
			
		||||
 | 
			
		||||
spirv_instruction (extensions = ["SPV_KHR_ray_query"], capabilities = [4478], id = 4474)
 | 
			
		||||
void rayQueryTerminateEXT(spirv_by_reference rayQueryEXT rayQuery);
 | 
			
		||||
 | 
			
		||||
layout(binding = 0) uniform accelerationStructureEXT as;
 | 
			
		||||
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
    rayQueryEXT rq;
 | 
			
		||||
 | 
			
		||||
    rayQueryInitializeEXT(rq, as, 0, 0, vec3(0.0), 0.0, vec3(1.0), 1.0);
 | 
			
		||||
    rayQueryTerminateEXT(rq);
 | 
			
		||||
}
 | 
			
		||||
@ -73,6 +73,7 @@ set(MACHINEINDEPENDENT_SOURCES
 | 
			
		||||
    MachineIndependent/RemoveTree.cpp
 | 
			
		||||
    MachineIndependent/Scan.cpp
 | 
			
		||||
    MachineIndependent/ShaderLang.cpp
 | 
			
		||||
    MachineIndependent/SpirvIntrinsics.cpp
 | 
			
		||||
    MachineIndependent/SymbolTable.cpp
 | 
			
		||||
    MachineIndependent/Versions.cpp
 | 
			
		||||
    MachineIndependent/intermOut.cpp
 | 
			
		||||
@ -160,6 +161,7 @@ set(GLSLANG_HEADERS
 | 
			
		||||
    Include/PoolAlloc.h
 | 
			
		||||
    Include/ResourceLimits.h
 | 
			
		||||
    Include/ShHandle.h
 | 
			
		||||
    Include/SpirvIntrinsics.h
 | 
			
		||||
    Include/Types.h)
 | 
			
		||||
 | 
			
		||||
add_library(glslang ${LIB_TYPE} ${BISON_GLSLParser_OUTPUT_SOURCE} ${GLSLANG_SOURCES} ${GLSLANG_HEADERS})
 | 
			
		||||
 | 
			
		||||
@ -65,6 +65,10 @@ enum TBasicType {
 | 
			
		||||
    EbtAccStruct,
 | 
			
		||||
    EbtReference,
 | 
			
		||||
    EbtRayQuery,
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    // SPIR-V type defined by spirv_type
 | 
			
		||||
    EbtSpirvType,
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // HLSL types that live only temporarily.
 | 
			
		||||
    EbtString,
 | 
			
		||||
@ -91,6 +95,9 @@ enum TStorageQualifier {
 | 
			
		||||
    EvqUniform,       // read only, shared with app
 | 
			
		||||
    EvqBuffer,        // read/write, shared with app
 | 
			
		||||
    EvqShared,        // compute shader's read/write 'shared' qualifier
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    EvqSpirvStorageClass, // spirv_storage_class
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    EvqPayload,
 | 
			
		||||
    EvqPayloadIn,
 | 
			
		||||
@ -321,6 +328,9 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q)
 | 
			
		||||
    case EvqGlobal:         return "global";         break;
 | 
			
		||||
    case EvqConst:          return "const";          break;
 | 
			
		||||
    case EvqConstReadOnly:  return "const (read only)"; break;
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    case EvqSpirvStorageClass: return "spirv_storage_class"; break;
 | 
			
		||||
#endif
 | 
			
		||||
    case EvqVaryingIn:      return "in";             break;
 | 
			
		||||
    case EvqVaryingOut:     return "out";            break;
 | 
			
		||||
    case EvqUniform:        return "uniform";        break;
 | 
			
		||||
 | 
			
		||||
@ -194,6 +194,10 @@ template <class K, class D, class HASH = std::hash<K>, class PRED = std::equal_t
 | 
			
		||||
class TUnorderedMap : public std::unordered_map<K, D, HASH, PRED, pool_allocator<std::pair<K const, D> > > {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class K, class CMP = std::less<K> >
 | 
			
		||||
class TSet : public std::set<K, CMP, pool_allocator<K> > {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Persistent string memory.  Should only be used for strings that survive
 | 
			
		||||
// across compiles/links.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										136
									
								
								glslang/Include/SpirvIntrinsics.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								glslang/Include/SpirvIntrinsics.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,136 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright(C) 2021 Advanced Micro Devices, Inc.
 | 
			
		||||
//
 | 
			
		||||
// All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Redistribution and use in source and binary forms, with or without
 | 
			
		||||
// modification, are permitted provided that the following conditions
 | 
			
		||||
// are met:
 | 
			
		||||
//
 | 
			
		||||
//    Redistributions of source code must retain the above copyright
 | 
			
		||||
//    notice, this list of conditions and the following disclaimer.
 | 
			
		||||
//
 | 
			
		||||
//    Redistributions in binary form must reproduce the above
 | 
			
		||||
//    copyright notice, this list of conditions and the following
 | 
			
		||||
//    disclaimer in the documentation and/or other materials provided
 | 
			
		||||
//    with the distribution.
 | 
			
		||||
//
 | 
			
		||||
//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
 | 
			
		||||
//    contributors may be used to endorse or promote products derived
 | 
			
		||||
//    from this software without specific prior written permission.
 | 
			
		||||
//
 | 
			
		||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 | 
			
		||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 | 
			
		||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 | 
			
		||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
			
		||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
			
		||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
// POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// GL_EXT_spirv_intrinsics
 | 
			
		||||
//
 | 
			
		||||
#include "Common.h"
 | 
			
		||||
 | 
			
		||||
namespace glslang {
 | 
			
		||||
 | 
			
		||||
class TIntermTyped;
 | 
			
		||||
class TIntermConstantUnion;
 | 
			
		||||
class TType;
 | 
			
		||||
 | 
			
		||||
// SPIR-V requirements
 | 
			
		||||
struct TSpirvRequirement {
 | 
			
		||||
    POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
 | 
			
		||||
 | 
			
		||||
    // capability = [..]
 | 
			
		||||
    TSet<TString> extensions;
 | 
			
		||||
    // extension = [..]
 | 
			
		||||
    TSet<int> capabilities;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// SPIR-V execution modes
 | 
			
		||||
struct TSpirvExecutionMode {
 | 
			
		||||
    POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
 | 
			
		||||
 | 
			
		||||
    // spirv_execution_mode
 | 
			
		||||
    TMap<int, TVector<const TIntermConstantUnion*>> modes;
 | 
			
		||||
    // spirv_execution_mode_id
 | 
			
		||||
    TMap<int, TVector<const TIntermConstantUnion*> > modeIds;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// SPIR-V decorations
 | 
			
		||||
struct TSpirvDecorate {
 | 
			
		||||
    POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
 | 
			
		||||
 | 
			
		||||
    // spirv_decorate
 | 
			
		||||
    TMap<int, TVector<const TIntermConstantUnion*> > decorates;
 | 
			
		||||
    // spirv_decorate_id
 | 
			
		||||
    TMap<int, TVector<const TIntermConstantUnion*> > decorateIds;
 | 
			
		||||
    // spirv_decorate_string
 | 
			
		||||
    TMap<int, TVector<const TIntermConstantUnion*> > decorateStrings;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// SPIR-V instruction
 | 
			
		||||
struct TSpirvInstruction {
 | 
			
		||||
    POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
 | 
			
		||||
 | 
			
		||||
    TSpirvInstruction() { set = ""; id = -1; }
 | 
			
		||||
 | 
			
		||||
    bool operator==(const TSpirvInstruction& rhs) const { return set == rhs.set && id == rhs.id; }
 | 
			
		||||
    bool operator!=(const TSpirvInstruction& rhs) const { return !operator==(rhs); }
 | 
			
		||||
 | 
			
		||||
    // spirv_instruction
 | 
			
		||||
    TString set;
 | 
			
		||||
    int     id;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// SPIR-V type parameter
 | 
			
		||||
struct TSpirvTypeParameter {
 | 
			
		||||
    POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
 | 
			
		||||
 | 
			
		||||
    TSpirvTypeParameter(const TIntermConstantUnion* arg) { isConstant = true; constant = arg; }
 | 
			
		||||
    TSpirvTypeParameter(const TType* arg) { isConstant = false; type = arg; }
 | 
			
		||||
 | 
			
		||||
    bool operator==(const TSpirvTypeParameter& rhs) const
 | 
			
		||||
    {
 | 
			
		||||
        return isConstant == rhs.isConstant && ((isConstant && constant == rhs.constant) || (!isConstant && type == rhs.type));
 | 
			
		||||
    }
 | 
			
		||||
    bool operator!=(const TSpirvTypeParameter& rhs) const { return !operator==(rhs); }
 | 
			
		||||
 | 
			
		||||
    bool isConstant;
 | 
			
		||||
    union {
 | 
			
		||||
        const TIntermConstantUnion* constant;
 | 
			
		||||
        const TType* type;
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef TVector<TSpirvTypeParameter> TSpirvTypeParameters;
 | 
			
		||||
 | 
			
		||||
// SPIR-V type
 | 
			
		||||
struct TSpirvType {
 | 
			
		||||
    POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
 | 
			
		||||
 | 
			
		||||
    bool operator==(const TSpirvType& rhs) const
 | 
			
		||||
    {
 | 
			
		||||
        return spirvInst == rhs.spirvInst && typeParams == rhs.typeParams;
 | 
			
		||||
    }
 | 
			
		||||
    bool operator!=(const TSpirvType& rhs) const { return !operator==(rhs); }
 | 
			
		||||
 | 
			
		||||
    // spirv_type
 | 
			
		||||
    TSpirvInstruction spirvInst;
 | 
			
		||||
    TSpirvTypeParameters typeParams;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // end namespace glslang
 | 
			
		||||
 | 
			
		||||
#endif // GLSLANG_WEB
 | 
			
		||||
@ -44,11 +44,14 @@
 | 
			
		||||
#include "../Include/BaseTypes.h"
 | 
			
		||||
#include "../Public/ShaderLang.h"
 | 
			
		||||
#include "arrays.h"
 | 
			
		||||
#include "SpirvIntrinsics.h"
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
namespace glslang {
 | 
			
		||||
 | 
			
		||||
class TIntermAggregate;
 | 
			
		||||
 | 
			
		||||
const int GlslangMaxTypeLength = 200;  // TODO: need to print block/struct one member per line, so this can stay bounded
 | 
			
		||||
 | 
			
		||||
const char* const AnonymousPrefix = "anon@"; // for something like a block whose members can be directly accessed
 | 
			
		||||
@ -487,7 +490,6 @@ enum TShaderInterface
 | 
			
		||||
    EsiCount
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TQualifier {
 | 
			
		||||
public:
 | 
			
		||||
    static const int layoutNotSet = -1;
 | 
			
		||||
@ -501,6 +503,8 @@ public:
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
        noContraction = false;
 | 
			
		||||
        nullInit = false;
 | 
			
		||||
        spirvByReference = false;
 | 
			
		||||
        spirvLiteral = false;
 | 
			
		||||
#endif
 | 
			
		||||
        defaultBlock = false;
 | 
			
		||||
    }
 | 
			
		||||
@ -518,6 +522,12 @@ public:
 | 
			
		||||
        nullInit = false;
 | 
			
		||||
        defaultBlock = false;
 | 
			
		||||
        clearLayout();
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
        spirvStorageClass = -1;
 | 
			
		||||
        spirvDecorate = nullptr;
 | 
			
		||||
        spirvByReference = false;
 | 
			
		||||
        spirvLiteral = false;
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void clearInterstage()
 | 
			
		||||
@ -596,6 +606,10 @@ public:
 | 
			
		||||
    bool isPervertexNV() const { return false; }
 | 
			
		||||
    void setNullInit() { }
 | 
			
		||||
    bool isNullInit() const { return false; }
 | 
			
		||||
    void setSpirvByReference() { }
 | 
			
		||||
    bool isSpirvByReference() { return false; }
 | 
			
		||||
    void setSpirvLiteral() { }
 | 
			
		||||
    bool isSpirvLiteral() { return false; }
 | 
			
		||||
#else
 | 
			
		||||
    bool noContraction: 1; // prevent contraction and reassociation, e.g., for 'precise' keyword, and expressions it affects
 | 
			
		||||
    bool nopersp      : 1;
 | 
			
		||||
@ -618,6 +632,8 @@ public:
 | 
			
		||||
    bool shadercallcoherent : 1;
 | 
			
		||||
    bool nonprivate   : 1;
 | 
			
		||||
    bool nullInit : 1;
 | 
			
		||||
    bool spirvByReference : 1;
 | 
			
		||||
    bool spirvLiteral : 1;
 | 
			
		||||
    bool isWriteOnly() const { return writeonly; }
 | 
			
		||||
    bool isReadOnly() const { return readonly; }
 | 
			
		||||
    bool isRestrict() const { return restrict; }
 | 
			
		||||
@ -655,6 +671,10 @@ public:
 | 
			
		||||
    bool isPervertexNV() const { return pervertexNV; }
 | 
			
		||||
    void setNullInit() { nullInit = true; }
 | 
			
		||||
    bool isNullInit() const { return nullInit; }
 | 
			
		||||
    void setSpirvByReference() { spirvByReference = true; }
 | 
			
		||||
    bool isSpirvByReference() const { return spirvByReference; }
 | 
			
		||||
    void setSpirvLiteral() { spirvLiteral = true; }
 | 
			
		||||
    bool isSpirvLiteral() const { return spirvLiteral; }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    bool isPipeInput() const
 | 
			
		||||
@ -948,6 +968,10 @@ public:
 | 
			
		||||
    bool layoutViewportRelative;
 | 
			
		||||
    int layoutSecondaryViewportRelativeOffset;
 | 
			
		||||
    bool layoutShaderRecord;
 | 
			
		||||
 | 
			
		||||
    // GL_EXT_spirv_intrinsics
 | 
			
		||||
    int spirvStorageClass;
 | 
			
		||||
    TSpirvDecorate* spirvDecorate;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    bool hasUniformLayout() const
 | 
			
		||||
@ -1079,6 +1103,15 @@ public:
 | 
			
		||||
    {
 | 
			
		||||
        return nonUniform;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // GL_EXT_spirv_intrinsics
 | 
			
		||||
    bool hasSprivDecorate() const { return spirvDecorate != nullptr; }
 | 
			
		||||
    void setSpirvDecorate(int decoration, const TIntermAggregate* args = nullptr);
 | 
			
		||||
    void setSpirvDecorateId(int decoration, const TIntermAggregate* args);
 | 
			
		||||
    void setSpirvDecorateString(int decoration, const TIntermAggregate* args);
 | 
			
		||||
    const TSpirvDecorate& getSpirvDecorate() const { assert(spirvDecorate); return *spirvDecorate; }
 | 
			
		||||
    TSpirvDecorate& getSpirvDecorate() { assert(spirvDecorate); return *spirvDecorate; }
 | 
			
		||||
    TString getSpirvDecorateQualifierString() const;
 | 
			
		||||
#endif
 | 
			
		||||
    bool hasSpecConstantId() const
 | 
			
		||||
    {
 | 
			
		||||
@ -1423,6 +1456,10 @@ public:
 | 
			
		||||
    const TType* userDef;
 | 
			
		||||
    TSourceLoc loc;
 | 
			
		||||
    TArraySizes* typeParameters;
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    // SPIR-V type defined by spirv_type directive
 | 
			
		||||
    TSpirvType* spirvType;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GLSLANG_WEB
 | 
			
		||||
    bool isCoopmat() const { return false; }
 | 
			
		||||
@ -1441,6 +1478,9 @@ public:
 | 
			
		||||
        loc = l;
 | 
			
		||||
        typeParameters = nullptr;
 | 
			
		||||
        coopmat = false;
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
        spirvType = nullptr;
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void initQualifiers(bool global = false)
 | 
			
		||||
@ -1477,6 +1517,11 @@ public:
 | 
			
		||||
        return matrixCols == 0 && vectorSize == 1 && arraySizes == nullptr && userDef == nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    // GL_EXT_spirv_intrinsics
 | 
			
		||||
    void setSpirvType(const TSpirvInstruction& spirvInst, const TSpirvTypeParameters* typeParams = nullptr);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // "Image" is a superset of "Subpass"
 | 
			
		||||
    bool isImage()   const { return basicType == EbtSampler && sampler.isImage(); }
 | 
			
		||||
    bool isSubpass() const { return basicType == EbtSampler && sampler.isSubpass(); }
 | 
			
		||||
@ -1494,6 +1539,9 @@ public:
 | 
			
		||||
                   bool isVector = false) :
 | 
			
		||||
                            basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmat(false),
 | 
			
		||||
                            arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr)
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
                            , spirvType(nullptr)
 | 
			
		||||
#endif
 | 
			
		||||
                            {
 | 
			
		||||
                                sampler.clear();
 | 
			
		||||
                                qualifier.clear();
 | 
			
		||||
@ -1505,6 +1553,9 @@ public:
 | 
			
		||||
          bool isVector = false) :
 | 
			
		||||
                            basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmat(false),
 | 
			
		||||
                            arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr)
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
                            , spirvType(nullptr)
 | 
			
		||||
#endif
 | 
			
		||||
                            {
 | 
			
		||||
                                sampler.clear();
 | 
			
		||||
                                qualifier.clear();
 | 
			
		||||
@ -1518,6 +1569,9 @@ public:
 | 
			
		||||
                            basicType(p.basicType),
 | 
			
		||||
                            vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmat(p.coopmat),
 | 
			
		||||
                            arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(p.typeParameters)
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
                            , spirvType(p.spirvType)
 | 
			
		||||
#endif
 | 
			
		||||
                            {
 | 
			
		||||
                                if (basicType == EbtSampler)
 | 
			
		||||
                                    sampler = p.sampler;
 | 
			
		||||
@ -1552,6 +1606,9 @@ public:
 | 
			
		||||
        basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false),
 | 
			
		||||
        arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr),
 | 
			
		||||
        sampler(sampler), typeParameters(nullptr)
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
        , spirvType(nullptr)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        qualifier.clear();
 | 
			
		||||
        qualifier.storage = q;
 | 
			
		||||
@ -1602,6 +1659,9 @@ public:
 | 
			
		||||
    TType(TTypeList* userDef, const TString& n) :
 | 
			
		||||
                            basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false),
 | 
			
		||||
                            arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr)
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
                            , spirvType(nullptr)
 | 
			
		||||
#endif
 | 
			
		||||
                            {
 | 
			
		||||
                                sampler.clear();
 | 
			
		||||
                                qualifier.clear();
 | 
			
		||||
@ -1611,6 +1671,9 @@ public:
 | 
			
		||||
    TType(TTypeList* userDef, const TString& n, const TQualifier& q) :
 | 
			
		||||
                            basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false),
 | 
			
		||||
                            qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr)
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
                            , spirvType(nullptr)
 | 
			
		||||
#endif
 | 
			
		||||
                            {
 | 
			
		||||
                                sampler.clear();
 | 
			
		||||
                                typeName = NewPoolTString(n.c_str());
 | 
			
		||||
@ -1619,6 +1682,9 @@ public:
 | 
			
		||||
    explicit TType(TBasicType t, const TType &p, const TString& n) :
 | 
			
		||||
                            basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false),
 | 
			
		||||
                            arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr)
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
                            , spirvType(nullptr)
 | 
			
		||||
#endif
 | 
			
		||||
                            {
 | 
			
		||||
                                assert(t == EbtReference);
 | 
			
		||||
                                typeName = NewPoolTString(n.c_str());
 | 
			
		||||
@ -1649,6 +1715,9 @@ public:
 | 
			
		||||
            referentType = copyOf.referentType;
 | 
			
		||||
        }
 | 
			
		||||
        typeParameters = copyOf.typeParameters;
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
        spirvType = copyOf.spirvType;
 | 
			
		||||
#endif
 | 
			
		||||
        coopmat = copyOf.isCoopMat();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1770,7 +1839,7 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
    virtual bool isOpaque() const { return basicType == EbtSampler
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
         || basicType == EbtAtomicUint || basicType == EbtAccStruct || basicType == EbtRayQuery
 | 
			
		||||
            || basicType == EbtAtomicUint || basicType == EbtAccStruct || basicType == EbtRayQuery
 | 
			
		||||
#endif
 | 
			
		||||
        ; }
 | 
			
		||||
    virtual bool isBuiltIn() const { return getQualifier().builtIn != EbvNone; }
 | 
			
		||||
@ -2018,8 +2087,6 @@ public:
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    const char* getBasicString() const
 | 
			
		||||
    {
 | 
			
		||||
        return TType::getBasicString(basicType);
 | 
			
		||||
@ -2050,6 +2117,7 @@ public:
 | 
			
		||||
        case EbtRayQuery:          return "rayQueryEXT";
 | 
			
		||||
        case EbtReference:         return "reference";
 | 
			
		||||
        case EbtString:            return "string";
 | 
			
		||||
        case EbtSpirvType:         return "spirv_type";
 | 
			
		||||
#endif
 | 
			
		||||
        default:                   return "unknown type";
 | 
			
		||||
        }
 | 
			
		||||
@ -2070,6 +2138,9 @@ public:
 | 
			
		||||
        const auto appendUint = [&](unsigned int u) { typeString.append(std::to_string(u).c_str()); };
 | 
			
		||||
        const auto appendInt  = [&](int i)          { typeString.append(std::to_string(i).c_str()); };
 | 
			
		||||
 | 
			
		||||
        if (qualifier.hasSprivDecorate())
 | 
			
		||||
            appendStr(qualifier.getSpirvDecorateQualifierString().c_str());
 | 
			
		||||
 | 
			
		||||
        if (qualifier.hasLayout()) {
 | 
			
		||||
            // To reduce noise, skip this if the only layout is an xfb_buffer
 | 
			
		||||
            // with no triggering xfb_offset.
 | 
			
		||||
@ -2219,6 +2290,10 @@ public:
 | 
			
		||||
            appendStr(" nonuniform");
 | 
			
		||||
        if (qualifier.isNullInit())
 | 
			
		||||
            appendStr(" null-init");
 | 
			
		||||
        if (qualifier.isSpirvByReference())
 | 
			
		||||
            appendStr(" spirv_by_reference");
 | 
			
		||||
        if (qualifier.isSpirvLiteral())
 | 
			
		||||
            appendStr(" spirv_literal");
 | 
			
		||||
        appendStr(" ");
 | 
			
		||||
        appendStr(getStorageQualifierString());
 | 
			
		||||
        if (isArray()) {
 | 
			
		||||
@ -2455,6 +2530,15 @@ public:
 | 
			
		||||
                (typeParameters != nullptr && right.typeParameters != nullptr && *typeParameters == *right.typeParameters));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    // See if two type's SPIR-V type contents match
 | 
			
		||||
    bool sameSpirvType(const TType& right) const
 | 
			
		||||
    {
 | 
			
		||||
        return ((spirvType == nullptr && right.spirvType == nullptr) ||
 | 
			
		||||
                (spirvType != nullptr && right.spirvType != nullptr && *spirvType == *right.spirvType));
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // See if two type's elements match in all ways except basic type
 | 
			
		||||
    bool sameElementShape(const TType& right) const
 | 
			
		||||
    {
 | 
			
		||||
@ -2493,7 +2577,11 @@ public:
 | 
			
		||||
    // See if two types match in all ways (just the actual type, not qualification)
 | 
			
		||||
    bool operator==(const TType& right) const
 | 
			
		||||
    {
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
        return sameElementType(right) && sameArrayness(right) && sameTypeParameters(right) && sameSpirvType(right);
 | 
			
		||||
#else
 | 
			
		||||
        return sameElementType(right) && sameArrayness(right) && sameTypeParameters(right);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool operator!=(const TType& right) const
 | 
			
		||||
@ -2512,6 +2600,10 @@ public:
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    const TSpirvType& getSpirvType() const { assert(spirvType); return *spirvType; }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    // Require consumer to pick between deep copy and shallow copy.
 | 
			
		||||
    TType(const TType& type);
 | 
			
		||||
@ -2524,6 +2616,19 @@ protected:
 | 
			
		||||
    {
 | 
			
		||||
        shallowCopy(copyOf);
 | 
			
		||||
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
        // GL_EXT_spirv_intrinsics
 | 
			
		||||
        if (copyOf.qualifier.spirvDecorate) {
 | 
			
		||||
            qualifier.spirvDecorate = new TSpirvDecorate;
 | 
			
		||||
            *qualifier.spirvDecorate = *copyOf.qualifier.spirvDecorate;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (copyOf.spirvType) {
 | 
			
		||||
            spirvType = new TSpirvType;
 | 
			
		||||
            *spirvType = *copyOf.spirvType;
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        if (copyOf.arraySizes) {
 | 
			
		||||
            arraySizes = new TArraySizes;
 | 
			
		||||
            *arraySizes = *copyOf.arraySizes;
 | 
			
		||||
@ -2583,6 +2688,9 @@ protected:
 | 
			
		||||
    TString *typeName;          // for structure type name
 | 
			
		||||
    TSampler sampler;
 | 
			
		||||
    TArraySizes* typeParameters;// nullptr unless a parameterized type; can be shared across types
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    TSpirvType* spirvType;  // SPIR-V type defined by spirv_type directive
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // end namespace glslang
 | 
			
		||||
 | 
			
		||||
@ -71,6 +71,9 @@ enum TOperator {
 | 
			
		||||
    EOpFunctionCall,
 | 
			
		||||
    EOpFunction,        // For function definition
 | 
			
		||||
    EOpParameters,      // an aggregate listing the parameters to a function
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    EOpSpirvInst,
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // Unary operators
 | 
			
		||||
@ -1616,8 +1619,15 @@ public:
 | 
			
		||||
    virtual       TIntermUnary* getAsUnaryNode()       { return this; }
 | 
			
		||||
    virtual const TIntermUnary* getAsUnaryNode() const { return this; }
 | 
			
		||||
    virtual void updatePrecision();
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
 | 
			
		||||
    const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
 | 
			
		||||
#endif
 | 
			
		||||
protected:
 | 
			
		||||
    TIntermTyped* operand;
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    TSpirvInstruction spirvInst;
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef TVector<TIntermNode*> TIntermSequence;
 | 
			
		||||
@ -1648,6 +1658,10 @@ public:
 | 
			
		||||
    bool getDebug() const { return debug; }
 | 
			
		||||
    void setPragmaTable(const TPragmaTable& pTable);
 | 
			
		||||
    const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
 | 
			
		||||
    const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
 | 
			
		||||
#endif
 | 
			
		||||
protected:
 | 
			
		||||
    TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
 | 
			
		||||
    TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
 | 
			
		||||
@ -1658,6 +1672,9 @@ protected:
 | 
			
		||||
    bool optimize;
 | 
			
		||||
    bool debug;
 | 
			
		||||
    TPragmaTable* pragmaTable;
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    TSpirvInstruction spirvInst;
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
@ -1092,12 +1092,31 @@ TFunction* TParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFunct
 | 
			
		||||
    TSymbol* symbol = symbolTable.find(function.getMangledName(), &builtIn);
 | 
			
		||||
    if (symbol && symbol->getAsFunction() && builtIn)
 | 
			
		||||
        requireProfile(loc, ~EEsProfile, "redefinition of built-in function");
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    // Check the validity of using spirv_literal qualifier
 | 
			
		||||
    for (int i = 0; i < function.getParamCount(); ++i) {
 | 
			
		||||
        if (function[i].type->getQualifier().isSpirvLiteral() && function.getBuiltInOp() != EOpSpirvInst)
 | 
			
		||||
            error(loc, "'spirv_literal' can only be used on functions defined with 'spirv_instruction' for argument",
 | 
			
		||||
                  function.getName().c_str(), "%d", i + 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // For function declaration with SPIR-V instruction qualifier, always ignore the built-in function and
 | 
			
		||||
    // respect this redeclared one.
 | 
			
		||||
    if (symbol && builtIn && function.getBuiltInOp() == EOpSpirvInst)
 | 
			
		||||
        symbol = nullptr;
 | 
			
		||||
#endif
 | 
			
		||||
    const TFunction* prevDec = symbol ? symbol->getAsFunction() : 0;
 | 
			
		||||
    if (prevDec) {
 | 
			
		||||
        if (prevDec->isPrototyped() && prototype)
 | 
			
		||||
            profileRequires(loc, EEsProfile, 300, nullptr, "multiple prototypes for same function");
 | 
			
		||||
        if (prevDec->getType() != function.getType())
 | 
			
		||||
            error(loc, "overloaded functions must have the same return type", function.getName().c_str(), "");
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
        if (prevDec->getSpirvInstruction() != function.getSpirvInstruction()) {
 | 
			
		||||
            error(loc, "overloaded functions must have the same qualifiers", function.getName().c_str(),
 | 
			
		||||
                  "spirv_instruction");
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        for (int i = 0; i < prevDec->getParamCount(); ++i) {
 | 
			
		||||
            if ((*prevDec)[i].type->getQualifier().storage != function[i].type->getQualifier().storage)
 | 
			
		||||
                error(loc, "overloaded functions must have the same parameter storage qualifiers for argument", function[i].type->getStorageQualifierString(), "%d", i+1);
 | 
			
		||||
@ -1299,6 +1318,15 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
 | 
			
		||||
                        if (lValueErrorCheck(arguments->getLoc(), "assign", arg->getAsTyped()))
 | 
			
		||||
                            error(arguments->getLoc(), "Non-L-value cannot be passed for 'out' or 'inout' parameters.", "out", "");
 | 
			
		||||
                    }
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
                    if (formalQualifier.isSpirvLiteral()) {
 | 
			
		||||
                        if (!arg->getAsTyped()->getQualifier().isFrontEndConstant()) {
 | 
			
		||||
                            error(arguments->getLoc(),
 | 
			
		||||
                                  "Non front-end constant expressions cannot be passed for 'spirv_literal' parameters.",
 | 
			
		||||
                                  "spirv_literal", "");
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
#endif
 | 
			
		||||
                    const TType& argType = arg->getAsTyped()->getType();
 | 
			
		||||
                    const TQualifier& argQualifier = argType.getQualifier();
 | 
			
		||||
                    if (argQualifier.isMemory() && (argType.containsOpaque() || argType.isReference())) {
 | 
			
		||||
@ -1353,6 +1381,11 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
 | 
			
		||||
            if (builtIn && fnCandidate->getBuiltInOp() != EOpNull) {
 | 
			
		||||
                // A function call mapped to a built-in operation.
 | 
			
		||||
                result = handleBuiltInFunctionCall(loc, arguments, *fnCandidate);
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
            } else if (fnCandidate->getBuiltInOp() == EOpSpirvInst) {
 | 
			
		||||
                // When SPIR-V instruction qualifier is specified, the function call is still mapped to a built-in operation.
 | 
			
		||||
                result = handleBuiltInFunctionCall(loc, arguments, *fnCandidate);
 | 
			
		||||
#endif
 | 
			
		||||
            } else {
 | 
			
		||||
                // This is a function call not mapped to built-in operator.
 | 
			
		||||
                // It could still be a built-in function, but only if PureOperatorBuiltins == false.
 | 
			
		||||
@ -1430,6 +1463,35 @@ TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNo
 | 
			
		||||
    } else if (result->getAsOperator())
 | 
			
		||||
        builtInOpCheck(loc, function, *result->getAsOperator());
 | 
			
		||||
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    // Special handling for function call with SPIR-V instruction qualifier specified
 | 
			
		||||
    if (function.getBuiltInOp() == EOpSpirvInst) {
 | 
			
		||||
        if (auto agg = result->getAsAggregate()) {
 | 
			
		||||
            // Propogate spirv_by_reference/spirv_literal from parameters to arguments
 | 
			
		||||
            auto& sequence = agg->getSequence();
 | 
			
		||||
            for (unsigned i = 0; i < sequence.size(); ++i) {
 | 
			
		||||
                if (function[i].type->getQualifier().isSpirvByReference())
 | 
			
		||||
                    sequence[i]->getAsTyped()->getQualifier().setSpirvByReference();
 | 
			
		||||
                if (function[i].type->getQualifier().isSpirvLiteral())
 | 
			
		||||
                    sequence[i]->getAsTyped()->getQualifier().setSpirvLiteral();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Attach the function call to SPIR-V intruction
 | 
			
		||||
            agg->setSpirvInstruction(function.getSpirvInstruction());
 | 
			
		||||
        } else if (auto unaryNode = result->getAsUnaryNode()) {
 | 
			
		||||
            // Propogate spirv_by_reference/spirv_literal from parameters to arguments
 | 
			
		||||
            if (function[0].type->getQualifier().isSpirvByReference())
 | 
			
		||||
                unaryNode->getOperand()->getQualifier().setSpirvByReference();
 | 
			
		||||
            if (function[0].type->getQualifier().isSpirvLiteral())
 | 
			
		||||
                unaryNode->getOperand()->getQualifier().setSpirvLiteral();
 | 
			
		||||
 | 
			
		||||
            // Attach the function call to SPIR-V intruction
 | 
			
		||||
            unaryNode->setSpirvInstruction(function.getSpirvInstruction());
 | 
			
		||||
        } else
 | 
			
		||||
            assert(0);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2931,7 +2993,8 @@ void TParseContext::reservedErrorCheck(const TSourceLoc& loc, const TString& ide
 | 
			
		||||
    // "Identifiers starting with "gl_" are reserved for use by OpenGL, and may not be
 | 
			
		||||
    // declared in a shader; this results in a compile-time error."
 | 
			
		||||
    if (! symbolTable.atBuiltInLevel()) {
 | 
			
		||||
        if (builtInName(identifier))
 | 
			
		||||
        if (builtInName(identifier) && !extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
 | 
			
		||||
            // The extension GL_EXT_spirv_intrinsics allows us to declare identifiers starting with "gl_".
 | 
			
		||||
            error(loc, "identifiers starting with \"gl_\" are reserved", identifier.c_str(), "");
 | 
			
		||||
 | 
			
		||||
        // "__" are not supposed to be an error.  ES 300 (and desktop) added the clarification:
 | 
			
		||||
@ -2939,7 +3002,8 @@ void TParseContext::reservedErrorCheck(const TSourceLoc& loc, const TString& ide
 | 
			
		||||
        // reserved; using such a name does not itself result in an error, but may result
 | 
			
		||||
        // in undefined behavior."
 | 
			
		||||
        // however, before that, ES tests required an error.
 | 
			
		||||
        if (identifier.find("__") != TString::npos) {
 | 
			
		||||
        if (identifier.find("__") != TString::npos && !extensionTurnedOn(E_GL_EXT_spirv_intrinsics)) {
 | 
			
		||||
            // The extension GL_EXT_spirv_intrinsics allows us to declare identifiers starting with "__".
 | 
			
		||||
            if (isEsProfile() && version < 300)
 | 
			
		||||
                error(loc, "identifiers containing consecutive underscores (\"__\") are reserved, and an error if version < 300", identifier.c_str(), "");
 | 
			
		||||
            else
 | 
			
		||||
@ -2960,14 +3024,16 @@ void TParseContext::reservedPpErrorCheck(const TSourceLoc& loc, const char* iden
 | 
			
		||||
    // single underscore) are also reserved, and defining such a name results in a
 | 
			
		||||
    // compile-time error."
 | 
			
		||||
    // however, before that, ES tests required an error.
 | 
			
		||||
    if (strncmp(identifier, "GL_", 3) == 0)
 | 
			
		||||
    if (strncmp(identifier, "GL_", 3) == 0 && !extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
 | 
			
		||||
        // The extension GL_EXT_spirv_intrinsics allows us to declare macros prefixed with "GL_".
 | 
			
		||||
        ppError(loc, "names beginning with \"GL_\" can't be (un)defined:", op,  identifier);
 | 
			
		||||
    else if (strncmp(identifier, "defined", 8) == 0)
 | 
			
		||||
        if (relaxedErrors())
 | 
			
		||||
            ppWarn(loc, "\"defined\" is (un)defined:", op,  identifier);
 | 
			
		||||
        else
 | 
			
		||||
            ppError(loc, "\"defined\" can't be (un)defined:", op,  identifier);
 | 
			
		||||
    else if (strstr(identifier, "__") != 0) {
 | 
			
		||||
    else if (strstr(identifier, "__") != 0 && !extensionTurnedOn(E_GL_EXT_spirv_intrinsics)) {
 | 
			
		||||
        // The extension GL_EXT_spirv_intrinsics allows us to declare macros prefixed with "__".
 | 
			
		||||
        if (isEsProfile() && version >= 300 &&
 | 
			
		||||
            (strcmp(identifier, "__LINE__") == 0 ||
 | 
			
		||||
             strcmp(identifier, "__FILE__") == 0 ||
 | 
			
		||||
@ -3594,6 +3660,14 @@ void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& q
 | 
			
		||||
    if (!nonuniformOkay && qualifier.isNonUniform())
 | 
			
		||||
        error(loc, "for non-parameter, can only apply to 'in' or no storage qualifier", "nonuniformEXT", "");
 | 
			
		||||
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    if (qualifier.isSpirvByReference())
 | 
			
		||||
        error(loc, "can only apply to parameter", "spirv_by_reference", "");
 | 
			
		||||
 | 
			
		||||
    if (qualifier.isSpirvLiteral())
 | 
			
		||||
        error(loc, "can only apply to parameter", "spirv_literal", "");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // Storage qualifier isn't ready for memberQualifierCheck, we should skip invariantCheck for it.
 | 
			
		||||
    if (!isMemberCheck || structNestingLevel > 0)
 | 
			
		||||
        invariantCheck(loc, qualifier);
 | 
			
		||||
@ -3855,6 +3929,41 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
 | 
			
		||||
    MERGE_SINGLETON(nonUniform);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    // SPIR-V storage class qualifier (GL_EXT_spirv_intrinsics)
 | 
			
		||||
    dst.spirvStorageClass = src.spirvStorageClass;
 | 
			
		||||
 | 
			
		||||
    // SPIR-V decorate qualifiers (GL_EXT_spirv_intrinsics)
 | 
			
		||||
    if (src.hasSprivDecorate()) {
 | 
			
		||||
        if (dst.hasSprivDecorate()) {
 | 
			
		||||
            const TSpirvDecorate& srcSpirvDecorate = src.getSpirvDecorate();
 | 
			
		||||
            TSpirvDecorate& dstSpirvDecorate = dst.getSpirvDecorate();
 | 
			
		||||
            for (auto& decorate : srcSpirvDecorate.decorates) {
 | 
			
		||||
                if (dstSpirvDecorate.decorates.find(decorate.first) != dstSpirvDecorate.decorates.end())
 | 
			
		||||
                    error(loc, "too many SPIR-V decorate qualifiers", "spirv_decorate", "(decoration=%u)", decorate.first);
 | 
			
		||||
                else
 | 
			
		||||
                    dstSpirvDecorate.decorates.insert(decorate);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (auto& decorateId : srcSpirvDecorate.decorateIds) {
 | 
			
		||||
                if (dstSpirvDecorate.decorateIds.find(decorateId.first) != dstSpirvDecorate.decorateIds.end())
 | 
			
		||||
                    error(loc, "too many SPIR-V decorate qualifiers", "spirv_decorate_id", "(decoration=%u)", decorateId.first);
 | 
			
		||||
                else
 | 
			
		||||
                    dstSpirvDecorate.decorateIds.insert(decorateId);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (auto& decorateString : srcSpirvDecorate.decorateStrings) {
 | 
			
		||||
                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);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            dst.spirvDecorate = src.spirvDecorate;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (repeated)
 | 
			
		||||
        error(loc, "replicated qualifiers", "", "");
 | 
			
		||||
}
 | 
			
		||||
@ -4818,6 +4927,17 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali
 | 
			
		||||
    }
 | 
			
		||||
    if (qualifier.isNonUniform())
 | 
			
		||||
        type.getQualifier().nonUniform = qualifier.nonUniform;
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    if (qualifier.isSpirvByReference())
 | 
			
		||||
        type.getQualifier().setSpirvByReference();
 | 
			
		||||
    if (qualifier.isSpirvLiteral()) {
 | 
			
		||||
        if (type.getBasicType() == EbtFloat || type.getBasicType() == EbtInt || type.getBasicType() == EbtUint ||
 | 
			
		||||
            type.getBasicType() == EbtBool)
 | 
			
		||||
            type.getQualifier().setSpirvLiteral();
 | 
			
		||||
        else
 | 
			
		||||
            error(loc, "cannot use spirv_literal qualifier", type.getBasicTypeString().c_str(), "");
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    paramCheckFixStorage(loc, qualifier.storage, type);
 | 
			
		||||
}
 | 
			
		||||
@ -5885,6 +6005,9 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb
 | 
			
		||||
        case EvqVaryingIn:
 | 
			
		||||
        case EvqVaryingOut:
 | 
			
		||||
            if (!type.getQualifier().isTaskMemory() &&
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
                !type.getQualifier().hasSprivDecorate() &&
 | 
			
		||||
#endif
 | 
			
		||||
                (type.getBasicType() != EbtBlock ||
 | 
			
		||||
                 (!(*type.getStruct())[0].type->getQualifier().hasLocation() &&
 | 
			
		||||
                   (*type.getStruct())[0].type->getQualifier().builtIn == EbvNone)))
 | 
			
		||||
@ -5946,6 +6069,11 @@ void TParseContext::layoutMemberLocationArrayCheck(const TSourceLoc& loc, bool m
 | 
			
		||||
// Do layout error checking with respect to a type.
 | 
			
		||||
void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
 | 
			
		||||
{
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    if (extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
 | 
			
		||||
        return; // Skip any check if GL_EXT_spirv_intrinsics is turned on
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    const TQualifier& qualifier = type.getQualifier();
 | 
			
		||||
 | 
			
		||||
    // first, intra-layout qualifier-only error checking
 | 
			
		||||
@ -7952,6 +8080,10 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
 | 
			
		||||
            memberQualifier.perViewNV = currentBlockQualifier.perViewNV;
 | 
			
		||||
        if (currentBlockQualifier.perTaskNV)
 | 
			
		||||
            memberQualifier.perTaskNV = currentBlockQualifier.perTaskNV;
 | 
			
		||||
        if (memberQualifier.storage == EvqSpirvStorageClass)
 | 
			
		||||
            error(memberLoc, "member cannot have a spirv_storage_class qualifier", memberType.getFieldName().c_str(), "");
 | 
			
		||||
        if (memberQualifier.hasSprivDecorate() && !memberQualifier.getSpirvDecorate().decorateIds.empty())
 | 
			
		||||
            error(memberLoc, "member cannot have a spirv_decorate_id qualifier", memberType.getFieldName().c_str(), "");
 | 
			
		||||
#endif
 | 
			
		||||
        if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()))
 | 
			
		||||
            error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");
 | 
			
		||||
 | 
			
		||||
@ -472,6 +472,20 @@ public:
 | 
			
		||||
    void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
 | 
			
		||||
    // Function attributes
 | 
			
		||||
    void handleFunctionAttributes(const TSourceLoc&, const TAttributes&, TFunction*);
 | 
			
		||||
 | 
			
		||||
    // GL_EXT_spirv_intrinsics
 | 
			
		||||
    TSpirvRequirement* makeSpirvRequirement(const TSourceLoc& loc, const TString& name,
 | 
			
		||||
                                            const TIntermAggregate* extensions, const TIntermAggregate* capabilities);
 | 
			
		||||
    TSpirvRequirement* mergeSpirvRequirements(const TSourceLoc& loc, TSpirvRequirement* spirvReq1,
 | 
			
		||||
                                                TSpirvRequirement* spirvReq2);
 | 
			
		||||
    TSpirvTypeParameters* makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant);
 | 
			
		||||
    TSpirvTypeParameters* makeSpirvTypeParameters(const TPublicType& type);
 | 
			
		||||
    TSpirvTypeParameters* mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1,
 | 
			
		||||
                                                   TSpirvTypeParameters* spirvTypeParams2);
 | 
			
		||||
    TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, const TString& value);
 | 
			
		||||
    TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, int value);
 | 
			
		||||
    TSpirvInstruction* mergeSpirvInstruction(const TSourceLoc& loc, TSpirvInstruction* spirvInst1,
 | 
			
		||||
                                             TSpirvInstruction* spirvInst2);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    void checkAndResizeMeshViewDim(const TSourceLoc&, TType&, bool isBlockMember);
 | 
			
		||||
 | 
			
		||||
@ -586,6 +586,18 @@ void TScanContext::fillInKeywordMap()
 | 
			
		||||
    (*KeywordMap)["f64mat4x2"] =               F64MAT4X2;
 | 
			
		||||
    (*KeywordMap)["f64mat4x3"] =               F64MAT4X3;
 | 
			
		||||
    (*KeywordMap)["f64mat4x4"] =               F64MAT4X4;
 | 
			
		||||
 | 
			
		||||
    // GL_EXT_spirv_intrinsics
 | 
			
		||||
    (*KeywordMap)["spirv_instruction"] =       SPIRV_INSTRUCTION;
 | 
			
		||||
    (*KeywordMap)["spirv_execution_mode"] =    SPIRV_EXECUTION_MODE;
 | 
			
		||||
    (*KeywordMap)["spirv_execution_mode_id"] = SPIRV_EXECUTION_MODE_ID;
 | 
			
		||||
    (*KeywordMap)["spirv_decorate"] =          SPIRV_DECORATE;
 | 
			
		||||
    (*KeywordMap)["spirv_decorate_id"] =       SPIRV_DECORATE_ID;
 | 
			
		||||
    (*KeywordMap)["spirv_decorate_string"] =   SPIRV_DECORATE_STRING;
 | 
			
		||||
    (*KeywordMap)["spirv_type"] =              SPIRV_TYPE;
 | 
			
		||||
    (*KeywordMap)["spirv_storage_class"] =     SPIRV_STORAGE_CLASS;
 | 
			
		||||
    (*KeywordMap)["spirv_by_reference"] =      SPIRV_BY_REFERENCE;
 | 
			
		||||
    (*KeywordMap)["spirv_literal"] =           SPIRV_LITERAL;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    (*KeywordMap)["sampler2D"] =               SAMPLER2D;
 | 
			
		||||
@ -1747,6 +1759,21 @@ int TScanContext::tokenizeIdentifier()
 | 
			
		||||
            return keyword;
 | 
			
		||||
        else
 | 
			
		||||
            return identifierOrType();
 | 
			
		||||
 | 
			
		||||
    case SPIRV_INSTRUCTION:
 | 
			
		||||
    case SPIRV_EXECUTION_MODE:
 | 
			
		||||
    case SPIRV_EXECUTION_MODE_ID:
 | 
			
		||||
    case SPIRV_DECORATE:
 | 
			
		||||
    case SPIRV_DECORATE_ID:
 | 
			
		||||
    case SPIRV_DECORATE_STRING:
 | 
			
		||||
    case SPIRV_TYPE:
 | 
			
		||||
    case SPIRV_STORAGE_CLASS:
 | 
			
		||||
    case SPIRV_BY_REFERENCE:
 | 
			
		||||
    case SPIRV_LITERAL:
 | 
			
		||||
        if (parseContext.symbolTable.atBuiltInLevel() ||
 | 
			
		||||
            parseContext.extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
 | 
			
		||||
            return keyword;
 | 
			
		||||
        return identifierOrType();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										355
									
								
								glslang/MachineIndependent/SpirvIntrinsics.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										355
									
								
								glslang/MachineIndependent/SpirvIntrinsics.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,355 @@
 | 
			
		||||
//
 | 
			
		||||
// Copyright(C) 2021 Advanced Micro Devices, Inc.
 | 
			
		||||
//
 | 
			
		||||
// All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Redistribution and use in source and binary forms, with or without
 | 
			
		||||
// modification, are permitted provided that the following conditions
 | 
			
		||||
// are met:
 | 
			
		||||
//
 | 
			
		||||
//    Redistributions of source code must retain the above copyright
 | 
			
		||||
//    notice, this list of conditions and the following disclaimer.
 | 
			
		||||
//
 | 
			
		||||
//    Redistributions in binary form must reproduce the above
 | 
			
		||||
//    copyright notice, this list of conditions and the following
 | 
			
		||||
//    disclaimer in the documentation and/or other materials provided
 | 
			
		||||
//    with the distribution.
 | 
			
		||||
//
 | 
			
		||||
//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
 | 
			
		||||
//    contributors may be used to endorse or promote products derived
 | 
			
		||||
//    from this software without specific prior written permission.
 | 
			
		||||
//
 | 
			
		||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 | 
			
		||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 | 
			
		||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 | 
			
		||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
			
		||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | 
			
		||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
			
		||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
			
		||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
// POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// GL_EXT_spirv_intrinsics
 | 
			
		||||
//
 | 
			
		||||
#include "../Include/intermediate.h"
 | 
			
		||||
#include "../Include/SpirvIntrinsics.h"
 | 
			
		||||
#include "../Include/Types.h"
 | 
			
		||||
#include "ParseHelper.h"
 | 
			
		||||
 | 
			
		||||
namespace glslang {
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Handle SPIR-V requirements
 | 
			
		||||
//
 | 
			
		||||
TSpirvRequirement* TParseContext::makeSpirvRequirement(const TSourceLoc& loc, const TString& name,
 | 
			
		||||
                                                       const TIntermAggregate* extensions,
 | 
			
		||||
                                                       const TIntermAggregate* capabilities)
 | 
			
		||||
{
 | 
			
		||||
    TSpirvRequirement* spirvReq = new TSpirvRequirement;
 | 
			
		||||
 | 
			
		||||
    if (name == "extensions") {
 | 
			
		||||
        assert(extensions);
 | 
			
		||||
        for (auto extension : extensions->getSequence()) {
 | 
			
		||||
            assert(extension->getAsConstantUnion());
 | 
			
		||||
            spirvReq->extensions.insert(*extension->getAsConstantUnion()->getConstArray()[0].getSConst());
 | 
			
		||||
        }
 | 
			
		||||
    } else if (name == "capabilities") {
 | 
			
		||||
        assert(capabilities);
 | 
			
		||||
        for (auto capability : capabilities->getSequence()) {
 | 
			
		||||
            assert(capability->getAsConstantUnion());
 | 
			
		||||
            spirvReq->capabilities.insert(capability->getAsConstantUnion()->getConstArray()[0].getIConst());
 | 
			
		||||
        }
 | 
			
		||||
    } else
 | 
			
		||||
        error(loc, "unknow SPIR-V requirement", name.c_str(), "");
 | 
			
		||||
 | 
			
		||||
    return spirvReq;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TSpirvRequirement* TParseContext::mergeSpirvRequirements(const TSourceLoc& loc, TSpirvRequirement* spirvReq1,
 | 
			
		||||
                                                         TSpirvRequirement* spirvReq2)
 | 
			
		||||
{
 | 
			
		||||
    // Merge the second SPIR-V requirement to the first one
 | 
			
		||||
    if (!spirvReq2->extensions.empty()) {
 | 
			
		||||
        if (spirvReq1->extensions.empty())
 | 
			
		||||
            spirvReq1->extensions = spirvReq2->extensions;
 | 
			
		||||
        else
 | 
			
		||||
            error(loc, "too many SPIR-V requirements", "extensions", "");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!spirvReq2->capabilities.empty()) {
 | 
			
		||||
        if (spirvReq1->capabilities.empty())
 | 
			
		||||
            spirvReq1->capabilities = spirvReq2->capabilities;
 | 
			
		||||
        else
 | 
			
		||||
            error(loc, "too many SPIR-V requirements", "capabilities", "");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return spirvReq1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TIntermediate::insertSpirvRequirement(const TSpirvRequirement* spirvReq)
 | 
			
		||||
{
 | 
			
		||||
    if (!spirvRequirement)
 | 
			
		||||
        spirvRequirement = new TSpirvRequirement;
 | 
			
		||||
 | 
			
		||||
    for (auto extension : spirvReq->extensions)
 | 
			
		||||
        spirvRequirement->extensions.insert(extension);
 | 
			
		||||
 | 
			
		||||
    for (auto capability : spirvReq->capabilities)
 | 
			
		||||
        spirvRequirement->capabilities.insert(capability);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Handle SPIR-V execution modes
 | 
			
		||||
//
 | 
			
		||||
void TIntermediate::insertSpirvExecutionMode(int executionMode, const TIntermAggregate* args)
 | 
			
		||||
{
 | 
			
		||||
    if (!spirvExecutionMode)
 | 
			
		||||
        spirvExecutionMode = new TSpirvExecutionMode;
 | 
			
		||||
 | 
			
		||||
    TVector<const TIntermConstantUnion*> extraOperands;
 | 
			
		||||
    if (args) {
 | 
			
		||||
        for (auto arg : args->getSequence()) {
 | 
			
		||||
            auto extraOperand = arg->getAsConstantUnion();
 | 
			
		||||
            assert(extraOperand != nullptr);
 | 
			
		||||
            extraOperands.push_back(extraOperand);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    spirvExecutionMode->modes[executionMode] = extraOperands;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TIntermediate::insertSpirvExecutionModeId(int executionMode, const TIntermAggregate* args)
 | 
			
		||||
{
 | 
			
		||||
    if (!spirvExecutionMode)
 | 
			
		||||
        spirvExecutionMode = new TSpirvExecutionMode;
 | 
			
		||||
 | 
			
		||||
    assert(args);
 | 
			
		||||
    TVector<const TIntermConstantUnion*> extraOperands;
 | 
			
		||||
 | 
			
		||||
    for (auto arg : args->getSequence()) {
 | 
			
		||||
        auto extraOperand = arg->getAsConstantUnion();
 | 
			
		||||
        assert(extraOperand != nullptr);
 | 
			
		||||
        extraOperands.push_back(extraOperand);
 | 
			
		||||
    }
 | 
			
		||||
    spirvExecutionMode->modeIds[executionMode] = extraOperands;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Handle SPIR-V decorate qualifiers
 | 
			
		||||
//
 | 
			
		||||
void TQualifier::setSpirvDecorate(int decoration, const TIntermAggregate* args)
 | 
			
		||||
{
 | 
			
		||||
    if (!spirvDecorate)
 | 
			
		||||
        spirvDecorate = new TSpirvDecorate;
 | 
			
		||||
 | 
			
		||||
    TVector<const TIntermConstantUnion*> extraOperands;
 | 
			
		||||
    if (args) {
 | 
			
		||||
        for (auto arg : args->getSequence()) {
 | 
			
		||||
            auto extraOperand = arg->getAsConstantUnion();
 | 
			
		||||
            assert(extraOperand != nullptr);
 | 
			
		||||
            extraOperands.push_back(extraOperand);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    spirvDecorate->decorates[decoration] = extraOperands;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TQualifier::setSpirvDecorateId(int decoration, const TIntermAggregate* args)
 | 
			
		||||
{
 | 
			
		||||
    if (!spirvDecorate)
 | 
			
		||||
        spirvDecorate = new TSpirvDecorate;
 | 
			
		||||
 | 
			
		||||
    assert(args);
 | 
			
		||||
    TVector<const TIntermConstantUnion*> extraOperands;
 | 
			
		||||
    for (auto arg : args->getSequence()) {
 | 
			
		||||
        auto extraOperand = arg->getAsConstantUnion();
 | 
			
		||||
        assert(extraOperand != nullptr);
 | 
			
		||||
        extraOperands.push_back(extraOperand);
 | 
			
		||||
    }
 | 
			
		||||
    spirvDecorate->decorateIds[decoration] = extraOperands;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TQualifier::setSpirvDecorateString(int decoration, const TIntermAggregate* args)
 | 
			
		||||
{
 | 
			
		||||
    if (!spirvDecorate)
 | 
			
		||||
        spirvDecorate = new TSpirvDecorate;
 | 
			
		||||
 | 
			
		||||
    assert(args);
 | 
			
		||||
    TVector<const TIntermConstantUnion*> extraOperands;
 | 
			
		||||
    for (auto arg : args->getSequence()) {
 | 
			
		||||
        auto extraOperand = arg->getAsConstantUnion();
 | 
			
		||||
        assert(extraOperand != nullptr);
 | 
			
		||||
        extraOperands.push_back(extraOperand);
 | 
			
		||||
    }
 | 
			
		||||
    spirvDecorate->decorateStrings[decoration] = extraOperands;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TString TQualifier::getSpirvDecorateQualifierString() const
 | 
			
		||||
{
 | 
			
		||||
    assert(spirvDecorate);
 | 
			
		||||
 | 
			
		||||
    TString qualifierString;
 | 
			
		||||
 | 
			
		||||
    const auto appendFloat = [&](float f) { qualifierString.append(std::to_string(f).c_str()); };
 | 
			
		||||
    const auto appendInt = [&](int i) { qualifierString.append(std::to_string(i).c_str()); };
 | 
			
		||||
    const auto appendUint = [&](unsigned int u) { qualifierString.append(std::to_string(u).c_str()); };
 | 
			
		||||
    const auto appendBool = [&](bool b) { qualifierString.append(std::to_string(b).c_str()); };
 | 
			
		||||
    const auto appendStr = [&](const char* s) { qualifierString.append(s); };
 | 
			
		||||
 | 
			
		||||
    const auto appendDecorate = [&](const TIntermConstantUnion* constant) {
 | 
			
		||||
        if (constant->getBasicType() == EbtFloat) {
 | 
			
		||||
            float value = static_cast<float>(constant->getConstArray()[0].getDConst());
 | 
			
		||||
            appendFloat(value);
 | 
			
		||||
        }
 | 
			
		||||
        else if (constant->getBasicType() == EbtInt) {
 | 
			
		||||
            int value = constant->getConstArray()[0].getIConst();
 | 
			
		||||
            appendInt(value);
 | 
			
		||||
        }
 | 
			
		||||
        else if (constant->getBasicType() == EbtUint) {
 | 
			
		||||
            unsigned value = constant->getConstArray()[0].getUConst();
 | 
			
		||||
            appendUint(value);
 | 
			
		||||
        }
 | 
			
		||||
        else if (constant->getBasicType() == EbtBool) {
 | 
			
		||||
            bool value = constant->getConstArray()[0].getBConst();
 | 
			
		||||
            appendBool(value);
 | 
			
		||||
        }
 | 
			
		||||
        else if (constant->getBasicType() == EbtString) {
 | 
			
		||||
            const TString* value = constant->getConstArray()[0].getSConst();
 | 
			
		||||
            appendStr(value->c_str());
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            assert(0);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    for (auto& decorate : spirvDecorate->decorates) {
 | 
			
		||||
        appendStr("spirv_decorate(");
 | 
			
		||||
        appendInt(decorate.first);
 | 
			
		||||
        for (auto extraOperand : decorate.second) {
 | 
			
		||||
            appendStr(", ");
 | 
			
		||||
            appendDecorate(extraOperand);
 | 
			
		||||
        }
 | 
			
		||||
        appendStr(") ");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (auto& decorateId : spirvDecorate->decorateIds) {
 | 
			
		||||
        appendStr("spirv_decorate_id(");
 | 
			
		||||
        appendInt(decorateId.first);
 | 
			
		||||
        for (auto extraOperand : decorateId.second) {
 | 
			
		||||
            appendStr(", ");
 | 
			
		||||
            appendDecorate(extraOperand);
 | 
			
		||||
        }
 | 
			
		||||
        appendStr(") ");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (auto& decorateString : spirvDecorate->decorateStrings) {
 | 
			
		||||
        appendStr("spirv_decorate_string(");
 | 
			
		||||
        appendInt(decorateString.first);
 | 
			
		||||
        for (auto extraOperand : decorateString.second) {
 | 
			
		||||
            appendStr(", ");
 | 
			
		||||
            appendDecorate(extraOperand);
 | 
			
		||||
        }
 | 
			
		||||
        appendStr(") ");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return qualifierString;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Handle SPIR-V type specifiers
 | 
			
		||||
//
 | 
			
		||||
void TPublicType::setSpirvType(const TSpirvInstruction& spirvInst, const TSpirvTypeParameters* typeParams)
 | 
			
		||||
{
 | 
			
		||||
    if (!spirvType)
 | 
			
		||||
        spirvType = new TSpirvType;
 | 
			
		||||
 | 
			
		||||
    basicType = EbtSpirvType;
 | 
			
		||||
    spirvType->spirvInst = spirvInst;
 | 
			
		||||
    if (typeParams)
 | 
			
		||||
        spirvType->typeParams = *typeParams;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant)
 | 
			
		||||
{
 | 
			
		||||
    TSpirvTypeParameters* spirvTypeParams = new TSpirvTypeParameters;
 | 
			
		||||
    if (constant->getBasicType() != EbtFloat &&
 | 
			
		||||
        constant->getBasicType() != EbtInt &&
 | 
			
		||||
        constant->getBasicType() != EbtUint &&
 | 
			
		||||
        constant->getBasicType() != EbtBool &&
 | 
			
		||||
        constant->getBasicType() != EbtString)
 | 
			
		||||
        error(loc, "this type not allowed", constant->getType().getBasicString(), "");
 | 
			
		||||
    else {
 | 
			
		||||
        assert(constant);
 | 
			
		||||
        spirvTypeParams->push_back(TSpirvTypeParameter(constant));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return spirvTypeParams;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TPublicType& type)
 | 
			
		||||
{
 | 
			
		||||
    TSpirvTypeParameters* spirvTypeParams = new TSpirvTypeParameters;
 | 
			
		||||
    spirvTypeParams->push_back(TSpirvTypeParameter(new TType(type)));
 | 
			
		||||
    return spirvTypeParams;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TSpirvTypeParameters* TParseContext::mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1, TSpirvTypeParameters* spirvTypeParams2)
 | 
			
		||||
{
 | 
			
		||||
    // Merge SPIR-V type parameters of the second one to the first one
 | 
			
		||||
    for (const auto& spirvTypeParam : *spirvTypeParams2)
 | 
			
		||||
        spirvTypeParams1->push_back(spirvTypeParam);
 | 
			
		||||
    return spirvTypeParams1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Handle SPIR-V instruction qualifiers
 | 
			
		||||
//
 | 
			
		||||
TSpirvInstruction* TParseContext::makeSpirvInstruction(const TSourceLoc& loc, const TString& name, const TString& value)
 | 
			
		||||
{
 | 
			
		||||
    TSpirvInstruction* spirvInst = new TSpirvInstruction;
 | 
			
		||||
    if (name == "set")
 | 
			
		||||
        spirvInst->set = value;
 | 
			
		||||
    else
 | 
			
		||||
        error(loc, "unknown SPIR-V instruction qualifier", name.c_str(), "");
 | 
			
		||||
 | 
			
		||||
    return spirvInst;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TSpirvInstruction* TParseContext::makeSpirvInstruction(const TSourceLoc& loc, const TString& name, int value)
 | 
			
		||||
{
 | 
			
		||||
    TSpirvInstruction* spirvInstuction = new TSpirvInstruction;
 | 
			
		||||
    if (name == "id")
 | 
			
		||||
        spirvInstuction->id = value;
 | 
			
		||||
    else
 | 
			
		||||
        error(loc, "unknown SPIR-V instruction qualifier", name.c_str(), "");
 | 
			
		||||
 | 
			
		||||
    return spirvInstuction;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TSpirvInstruction* TParseContext::mergeSpirvInstruction(const TSourceLoc& loc, TSpirvInstruction* spirvInst1, TSpirvInstruction* spirvInst2)
 | 
			
		||||
{
 | 
			
		||||
    // Merge qualifiers of the second SPIR-V instruction to those of the first one
 | 
			
		||||
    if (!spirvInst2->set.empty()) {
 | 
			
		||||
        if (spirvInst1->set.empty())
 | 
			
		||||
            spirvInst1->set = spirvInst2->set;
 | 
			
		||||
        else
 | 
			
		||||
            error(loc, "too many SPIR-V instruction qualifiers", "spirv_instruction", "(set)");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (spirvInst2->id != -1) {
 | 
			
		||||
        if (spirvInst1->id == -1)
 | 
			
		||||
            spirvInst1->id = spirvInst2->id;
 | 
			
		||||
        else
 | 
			
		||||
            error(loc, "too many SPIR-V instruction qualifiers", "spirv_instruction", "(id)");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return spirvInst1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // end namespace glslang
 | 
			
		||||
 | 
			
		||||
#endif // GLSLANG_WEB
 | 
			
		||||
@ -77,6 +77,7 @@ void TType::buildMangledName(TString& mangledName) const
 | 
			
		||||
    case EbtAtomicUint:         mangledName += "au";     break;
 | 
			
		||||
    case EbtAccStruct:          mangledName += "as";     break;
 | 
			
		||||
    case EbtRayQuery:           mangledName += "rq";     break;
 | 
			
		||||
    case EbtSpirvType:          mangledName += "spv-t";  break;
 | 
			
		||||
#endif
 | 
			
		||||
    case EbtSampler:
 | 
			
		||||
        switch (sampler.type) {
 | 
			
		||||
@ -390,6 +391,9 @@ TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf)
 | 
			
		||||
    implicitThis = copyOf.implicitThis;
 | 
			
		||||
    illegalImplicitThis = copyOf.illegalImplicitThis;
 | 
			
		||||
    defaultParamCount = copyOf.defaultParamCount;
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    spirvInst = copyOf.spirvInst;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TFunction* TFunction::clone() const
 | 
			
		||||
 | 
			
		||||
@ -319,6 +319,15 @@ public:
 | 
			
		||||
    virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
 | 
			
		||||
    virtual const TParameter& operator[](int i) const { return parameters[i]; }
 | 
			
		||||
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    virtual void setSpirvInstruction(const TSpirvInstruction& inst)
 | 
			
		||||
    {
 | 
			
		||||
        relateToOperator(EOpSpirvInst);
 | 
			
		||||
        spirvInst = inst;
 | 
			
		||||
    }
 | 
			
		||||
    virtual const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
 | 
			
		||||
    virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
 | 
			
		||||
#endif
 | 
			
		||||
@ -342,6 +351,10 @@ protected:
 | 
			
		||||
                               // This is important for a static member function that has member variables in scope,
 | 
			
		||||
                               // but is not allowed to use them, or see hidden symbols instead.
 | 
			
		||||
    int  defaultParamCount;
 | 
			
		||||
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    TSpirvInstruction spirvInst; // SPIR-V instruction qualifiers
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
@ -333,6 +333,7 @@ void TParseVersions::initializeExtensionBehavior()
 | 
			
		||||
    extensionBehavior[E_GL_EXT_shader_image_int64]   = EBhDisable;
 | 
			
		||||
    extensionBehavior[E_GL_EXT_terminate_invocation]        = EBhDisable;
 | 
			
		||||
    extensionBehavior[E_GL_EXT_shared_memory_block]         = EBhDisable;
 | 
			
		||||
    extensionBehavior[E_GL_EXT_spirv_intrinsics]            = EBhDisable;
 | 
			
		||||
 | 
			
		||||
    // OVR extensions
 | 
			
		||||
    extensionBehavior[E_GL_OVR_multiview]                = EBhDisable;
 | 
			
		||||
@ -493,6 +494,7 @@ void TParseVersions::getPreamble(std::string& preamble)
 | 
			
		||||
            "#define GL_EXT_ray_tracing 1\n"
 | 
			
		||||
            "#define GL_EXT_ray_query 1\n"
 | 
			
		||||
            "#define GL_EXT_ray_flags_primitive_culling 1\n"
 | 
			
		||||
            "#define GL_EXT_spirv_intrinsics 1\n"
 | 
			
		||||
 | 
			
		||||
            "#define GL_AMD_shader_ballot 1\n"
 | 
			
		||||
            "#define GL_AMD_shader_trinary_minmax 1\n"
 | 
			
		||||
@ -602,6 +604,29 @@ void TParseVersions::getPreamble(std::string& preamble)
 | 
			
		||||
        preamble += "\n";
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    // GL_EXT_spirv_intrinsics
 | 
			
		||||
    if (!isEsProfile()) {
 | 
			
		||||
        switch (language) {
 | 
			
		||||
        case EShLangVertex:         preamble += "#define GL_VERTEX_SHADER 1 \n";                    break;
 | 
			
		||||
        case EShLangTessControl:    preamble += "#define GL_TESSELLATION_CONTROL_SHADER 1 \n";      break;
 | 
			
		||||
        case EShLangTessEvaluation: preamble += "#define GL_TESSELLATION_EVALUATION_SHADER 1 \n";   break;
 | 
			
		||||
        case EShLangGeometry:       preamble += "#define GL_GEOMETRY_SHADER 1 \n";                  break;
 | 
			
		||||
        case EShLangFragment:       preamble += "#define GL_FRAGMENT_SHADER 1 \n";                  break;
 | 
			
		||||
        case EShLangCompute:        preamble += "#define GL_COMPUTE_SHADER 1 \n";                   break;
 | 
			
		||||
        case EShLangRayGen:         preamble += "#define GL_RAY_GENERATION_SHADER_EXT 1 \n";        break;
 | 
			
		||||
        case EShLangIntersect:      preamble += "#define GL_INTERSECTION_SHADER_EXT 1 \n";          break;
 | 
			
		||||
        case EShLangAnyHit:         preamble += "#define GL_ANY_HIT_SHADER_EXT 1 \n";               break;
 | 
			
		||||
        case EShLangClosestHit:     preamble += "#define GL_CLOSEST_HIT_SHADER_EXT 1 \n";           break;
 | 
			
		||||
        case EShLangMiss:           preamble += "#define GL_MISS_SHADER_EXT 1 \n";                  break;
 | 
			
		||||
        case EShLangCallable:       preamble += "#define GL_CALLABLE_SHADER_EXT 1 \n";              break;
 | 
			
		||||
        case EShLangTaskNV:         preamble += "#define GL_TASK_SHADER_NV 1 \n";                   break;
 | 
			
		||||
        case EShLangMeshNV:         preamble += "#define GL_MESH_SHADER_NV 1 \n";                   break;
 | 
			
		||||
        default:                                                                                    break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
@ -205,6 +205,7 @@ const char* const E_GL_EXT_shader_image_int64               = "GL_EXT_shader_ima
 | 
			
		||||
const char* const E_GL_EXT_null_initializer                 = "GL_EXT_null_initializer";
 | 
			
		||||
const char* const E_GL_EXT_shared_memory_block              = "GL_EXT_shared_memory_block";
 | 
			
		||||
const char* const E_GL_EXT_subgroup_uniform_control_flow    = "GL_EXT_subgroup_uniform_control_flow";
 | 
			
		||||
const char* const E_GL_EXT_spirv_intrinsics                 = "GL_EXT_spirv_intrinsics";
 | 
			
		||||
 | 
			
		||||
// Arrays of extensions for the above viewportEXTs duplications
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -116,6 +116,9 @@ using namespace glslang;
 | 
			
		||||
            glslang::TIntermNodePair nodePair;
 | 
			
		||||
            glslang::TIntermTyped* intermTypedNode;
 | 
			
		||||
            glslang::TAttributes* attributes;
 | 
			
		||||
            glslang::TSpirvRequirement* spirvReq;
 | 
			
		||||
            glslang::TSpirvInstruction* spirvInst;
 | 
			
		||||
            glslang::TSpirvTypeParameters* spirvTypeParams;
 | 
			
		||||
        };
 | 
			
		||||
        union {
 | 
			
		||||
            glslang::TPublicType type;
 | 
			
		||||
@ -271,6 +274,11 @@ GLSLANG_WEB_EXCLUDE_ON
 | 
			
		||||
%token <lex> SUBPASSINPUT SUBPASSINPUTMS ISUBPASSINPUT ISUBPASSINPUTMS USUBPASSINPUT USUBPASSINPUTMS
 | 
			
		||||
%token <lex> F16SUBPASSINPUT F16SUBPASSINPUTMS
 | 
			
		||||
 | 
			
		||||
// spirv intrinsics
 | 
			
		||||
%token <lex> SPIRV_INSTRUCTION SPIRV_EXECUTION_MODE SPIRV_EXECUTION_MODE_ID
 | 
			
		||||
%token <lex> SPIRV_DECORATE SPIRV_DECORATE_ID SPIRV_DECORATE_STRING
 | 
			
		||||
%token <lex> SPIRV_TYPE SPIRV_STORAGE_CLASS SPIRV_BY_REFERENCE SPIRV_LITERAL
 | 
			
		||||
 | 
			
		||||
GLSLANG_WEB_EXCLUDE_OFF
 | 
			
		||||
 | 
			
		||||
%token <lex> LEFT_OP RIGHT_OP
 | 
			
		||||
@ -362,6 +370,19 @@ GLSLANG_WEB_EXCLUDE_ON
 | 
			
		||||
%type <interm.attributes> attribute attribute_list single_attribute
 | 
			
		||||
%type <interm.intermNode> demote_statement
 | 
			
		||||
%type <interm.intermTypedNode> initializer_list
 | 
			
		||||
%type <interm.spirvReq> spirv_requirements_list spirv_requirements_parameter
 | 
			
		||||
%type <interm.intermNode> spirv_extension_list spirv_capability_list
 | 
			
		||||
%type <interm.intermNode> spirv_execution_mode_qualifier
 | 
			
		||||
%type <interm.intermNode> spirv_execution_mode_parameter_list spirv_execution_mode_parameter spirv_execution_mode_id_parameter_list
 | 
			
		||||
%type <interm.type> spirv_storage_class_qualifier
 | 
			
		||||
%type <interm.type> spirv_decorate_qualifier
 | 
			
		||||
%type <interm.intermNode> spirv_decorate_parameter_list spirv_decorate_parameter
 | 
			
		||||
%type <interm.intermNode> spirv_decorate_id_parameter_list
 | 
			
		||||
%type <interm.intermNode> spirv_decorate_string_parameter_list
 | 
			
		||||
%type <interm.type> spirv_type_specifier
 | 
			
		||||
%type <interm.spirvTypeParams> spirv_type_parameter_list spirv_type_parameter
 | 
			
		||||
%type <interm.spirvInst> spirv_instruction_qualifier
 | 
			
		||||
%type <interm.spirvInst> spirv_instruction_qualifier_list spirv_instruction_qualifier_id
 | 
			
		||||
GLSLANG_WEB_EXCLUDE_OFF
 | 
			
		||||
 | 
			
		||||
%start translation_unit
 | 
			
		||||
@ -875,6 +896,20 @@ declaration
 | 
			
		||||
        $$ = 0;
 | 
			
		||||
        // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature
 | 
			
		||||
    }
 | 
			
		||||
GLSLANG_WEB_EXCLUDE_ON
 | 
			
		||||
    | spirv_instruction_qualifier function_prototype SEMICOLON {
 | 
			
		||||
        parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V instruction qualifier");
 | 
			
		||||
        $2.function->setSpirvInstruction(*$1); // Attach SPIR-V intruction qualifier
 | 
			
		||||
        parseContext.handleFunctionDeclarator($2.loc, *$2.function, true /* prototype */);
 | 
			
		||||
        $$ = 0;
 | 
			
		||||
        // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_execution_mode_qualifier SEMICOLON {
 | 
			
		||||
        parseContext.globalCheck($2.loc, "SPIR-V execution mode qualifier");
 | 
			
		||||
        parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V execution mode qualifier");
 | 
			
		||||
        $$ = 0;
 | 
			
		||||
    }
 | 
			
		||||
GLSLANG_WEB_EXCLUDE_OFF
 | 
			
		||||
    | init_declarator_list SEMICOLON {
 | 
			
		||||
        if ($1.intermNode && $1.intermNode->getAsAggregate())
 | 
			
		||||
            $1.intermNode->getAsAggregate()->setOperator(EOpSequence);
 | 
			
		||||
@ -1366,6 +1401,25 @@ GLSLANG_WEB_EXCLUDE_ON
 | 
			
		||||
    | non_uniform_qualifier {
 | 
			
		||||
        $$ = $1;
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_storage_class_qualifier {
 | 
			
		||||
        parseContext.globalCheck($1.loc, "spirv_storage_class");
 | 
			
		||||
        parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V storage class qualifier");
 | 
			
		||||
        $$ = $1;
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_decorate_qualifier {
 | 
			
		||||
        parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V decorate qualifier");
 | 
			
		||||
        $$ = $1;
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_BY_REFERENCE {
 | 
			
		||||
        parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_reference");
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        $$.qualifier.setSpirvByReference();
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_LITERAL {
 | 
			
		||||
        parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_literal");
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        $$.qualifier.setSpirvLiteral();
 | 
			
		||||
    }
 | 
			
		||||
GLSLANG_WEB_EXCLUDE_OFF
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
@ -3426,6 +3480,10 @@ GLSLANG_WEB_EXCLUDE_ON
 | 
			
		||||
        $$.basicType = EbtUint;
 | 
			
		||||
        $$.coopmat = true;
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_type_specifier {
 | 
			
		||||
        parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V type specifier");
 | 
			
		||||
        $$ = $1;
 | 
			
		||||
    }
 | 
			
		||||
GLSLANG_WEB_EXCLUDE_OFF
 | 
			
		||||
    | struct_specifier {
 | 
			
		||||
        $$ = $1;
 | 
			
		||||
@ -4068,4 +4126,273 @@ single_attribute
 | 
			
		||||
    }
 | 
			
		||||
GLSLANG_WEB_EXCLUDE_OFF
 | 
			
		||||
 | 
			
		||||
GLSLANG_WEB_EXCLUDE_ON
 | 
			
		||||
spirv_requirements_list
 | 
			
		||||
    : spirv_requirements_parameter {
 | 
			
		||||
        $$ = $1;
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_requirements_list COMMA spirv_requirements_parameter {
 | 
			
		||||
        $$ = parseContext.mergeSpirvRequirements($2.loc, $1, $3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_requirements_parameter
 | 
			
		||||
    : IDENTIFIER EQUAL LEFT_BRACKET spirv_extension_list RIGHT_BRACKET {
 | 
			
		||||
        $$ = parseContext.makeSpirvRequirement($2.loc, *$1.string, $4->getAsAggregate(), nullptr);
 | 
			
		||||
    }
 | 
			
		||||
    | IDENTIFIER EQUAL LEFT_BRACKET spirv_capability_list RIGHT_BRACKET {
 | 
			
		||||
        $$ = parseContext.makeSpirvRequirement($2.loc, *$1.string, nullptr, $4->getAsAggregate());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_extension_list
 | 
			
		||||
    : STRING_LITERAL {
 | 
			
		||||
        $$ = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion($1.string, $1.loc, true));
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_extension_list COMMA STRING_LITERAL {
 | 
			
		||||
        $$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.string, $3.loc, true));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_capability_list
 | 
			
		||||
    : INTCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion($1.i, $1.loc, true));
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_capability_list COMMA INTCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.i, $3.loc, true));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_execution_mode_qualifier
 | 
			
		||||
    : SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT RIGHT_PAREN {
 | 
			
		||||
        parseContext.intermediate.insertSpirvExecutionMode($3.i);
 | 
			
		||||
        $$ = 0;
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN {
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        parseContext.intermediate.insertSpirvExecutionMode($5.i);
 | 
			
		||||
        $$ = 0;
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN {
 | 
			
		||||
        parseContext.intermediate.insertSpirvExecutionMode($3.i, $5->getAsAggregate());
 | 
			
		||||
        $$ = 0;
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN {
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        parseContext.intermediate.insertSpirvExecutionMode($5.i, $7->getAsAggregate());
 | 
			
		||||
        $$ = 0;
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_EXECUTION_MODE_ID LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN {
 | 
			
		||||
        parseContext.intermediate.insertSpirvExecutionModeId($3.i, $5->getAsAggregate());
 | 
			
		||||
        $$ = 0;
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_EXECUTION_MODE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN {
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        parseContext.intermediate.insertSpirvExecutionModeId($5.i, $7->getAsAggregate());
 | 
			
		||||
        $$ = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_execution_mode_parameter_list
 | 
			
		||||
    : spirv_execution_mode_parameter {
 | 
			
		||||
        $$ = parseContext.intermediate.makeAggregate($1);
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_execution_mode_parameter_list COMMA spirv_execution_mode_parameter {
 | 
			
		||||
        $$ = parseContext.intermediate.growAggregate($1, $3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_execution_mode_parameter
 | 
			
		||||
    : FLOATCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true);
 | 
			
		||||
    }
 | 
			
		||||
    | INTCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true);
 | 
			
		||||
    }
 | 
			
		||||
    | UINTCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true);
 | 
			
		||||
    }
 | 
			
		||||
    | BOOLCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
 | 
			
		||||
    }
 | 
			
		||||
    | STRING_LITERAL {
 | 
			
		||||
        $$ = parseContext.intermediate.addConstantUnion($1.string, $1.loc, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_execution_mode_id_parameter_list
 | 
			
		||||
    : constant_expression {
 | 
			
		||||
        if ($1->getBasicType() != EbtFloat &&
 | 
			
		||||
            $1->getBasicType() != EbtInt &&
 | 
			
		||||
            $1->getBasicType() != EbtUint &&
 | 
			
		||||
            $1->getBasicType() != EbtBool &&
 | 
			
		||||
            $1->getBasicType() != EbtString)
 | 
			
		||||
            parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), "");
 | 
			
		||||
        $$ = parseContext.intermediate.makeAggregate($1);
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_execution_mode_id_parameter_list COMMA constant_expression {
 | 
			
		||||
        if ($3->getBasicType() != EbtFloat &&
 | 
			
		||||
            $3->getBasicType() != EbtInt &&
 | 
			
		||||
            $3->getBasicType() != EbtUint &&
 | 
			
		||||
            $3->getBasicType() != EbtBool &&
 | 
			
		||||
            $3->getBasicType() != EbtString)
 | 
			
		||||
            parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), "");
 | 
			
		||||
        $$ = parseContext.intermediate.growAggregate($1, $3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_storage_class_qualifier
 | 
			
		||||
    : SPIRV_STORAGE_CLASS LEFT_PAREN INTCONSTANT RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        $$.qualifier.storage = EvqSpirvStorageClass;
 | 
			
		||||
        $$.qualifier.spirvStorageClass = $3.i;
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_STORAGE_CLASS LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        $$.qualifier.storage = EvqSpirvStorageClass;
 | 
			
		||||
        $$.qualifier.spirvStorageClass = $5.i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_decorate_qualifier
 | 
			
		||||
    : SPIRV_DECORATE LEFT_PAREN INTCONSTANT RIGHT_PAREN{
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        $$.qualifier.setSpirvDecorate($3.i);
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN{
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        $$.qualifier.setSpirvDecorate($5.i);
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_DECORATE LEFT_PAREN INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        $$.qualifier.setSpirvDecorate($3.i, $5->getAsAggregate());
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        $$.qualifier.setSpirvDecorate($5.i, $7->getAsAggregate());
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_DECORATE_ID LEFT_PAREN INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        $$.qualifier.setSpirvDecorateId($3.i, $5->getAsAggregate());
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_DECORATE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        $$.qualifier.setSpirvDecorateId($5.i, $7->getAsAggregate());
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_DECORATE_STRING LEFT_PAREN INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        $$.qualifier.setSpirvDecorateString($3.i, $5->getAsAggregate());
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_DECORATE_STRING LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        $$.qualifier.setSpirvDecorateString($5.i, $7->getAsAggregate());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_decorate_parameter_list
 | 
			
		||||
    : spirv_decorate_parameter {
 | 
			
		||||
        $$ = parseContext.intermediate.makeAggregate($1);
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_decorate_parameter_list COMMA spirv_decorate_parameter {
 | 
			
		||||
        $$ = parseContext.intermediate.growAggregate($1, $3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_decorate_parameter
 | 
			
		||||
    : FLOATCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true);
 | 
			
		||||
    }
 | 
			
		||||
    | INTCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true);
 | 
			
		||||
    }
 | 
			
		||||
    | UINTCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true);
 | 
			
		||||
    }
 | 
			
		||||
    | BOOLCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_decorate_id_parameter_list
 | 
			
		||||
    : constant_expression {
 | 
			
		||||
        if ($1->getBasicType() != EbtFloat &&
 | 
			
		||||
            $1->getBasicType() != EbtInt &&
 | 
			
		||||
            $1->getBasicType() != EbtUint &&
 | 
			
		||||
            $1->getBasicType() != EbtBool)
 | 
			
		||||
            parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), "");
 | 
			
		||||
        $$ = parseContext.intermediate.makeAggregate($1);
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_decorate_id_parameter_list COMMA constant_expression {
 | 
			
		||||
        if ($3->getBasicType() != EbtFloat &&
 | 
			
		||||
            $3->getBasicType() != EbtInt &&
 | 
			
		||||
            $3->getBasicType() != EbtUint &&
 | 
			
		||||
            $3->getBasicType() != EbtBool)
 | 
			
		||||
            parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), "");
 | 
			
		||||
        $$ = parseContext.intermediate.growAggregate($1, $3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_decorate_string_parameter_list
 | 
			
		||||
    : STRING_LITERAL {
 | 
			
		||||
        $$ = parseContext.intermediate.makeAggregate(
 | 
			
		||||
            parseContext.intermediate.addConstantUnion($1.string, $1.loc, true));
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_decorate_string_parameter_list COMMA STRING_LITERAL {
 | 
			
		||||
        $$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.string, $3.loc, true));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_type_specifier
 | 
			
		||||
    : SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
 | 
			
		||||
        $$.setSpirvType(*$3, $5);
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        $$.setSpirvType(*$5, $7);
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
 | 
			
		||||
        $$.setSpirvType(*$3);
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        $$.setSpirvType(*$5);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_type_parameter_list
 | 
			
		||||
    : spirv_type_parameter {
 | 
			
		||||
        $$ = $1;
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_type_parameter_list COMMA spirv_type_parameter {
 | 
			
		||||
        $$ = parseContext.mergeSpirvTypeParameters($1, $3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_type_parameter
 | 
			
		||||
    : constant_expression {
 | 
			
		||||
        $$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1->getAsConstantUnion());
 | 
			
		||||
    }
 | 
			
		||||
    | type_specifier {
 | 
			
		||||
        $$ = parseContext.makeSpirvTypeParameters($1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_instruction_qualifier
 | 
			
		||||
    : SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {
 | 
			
		||||
        $$ = $3;
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_INSTRUCTION LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN {
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        $$ = $5;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_instruction_qualifier_list
 | 
			
		||||
    : spirv_instruction_qualifier_id {
 | 
			
		||||
        $$ = $1;
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_instruction_qualifier_list COMMA spirv_instruction_qualifier_id {
 | 
			
		||||
        $$ = parseContext.mergeSpirvInstruction($2.loc, $1, $3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_instruction_qualifier_id
 | 
			
		||||
    : IDENTIFIER EQUAL STRING_LITERAL {
 | 
			
		||||
        $$ = parseContext.makeSpirvInstruction($2.loc, *$1.string, *$3.string);
 | 
			
		||||
    }
 | 
			
		||||
    | IDENTIFIER EQUAL INTCONSTANT {
 | 
			
		||||
        $$ = parseContext.makeSpirvInstruction($2.loc, *$1.string, $3.i);
 | 
			
		||||
    }
 | 
			
		||||
GLSLANG_WEB_EXCLUDE_OFF
 | 
			
		||||
 | 
			
		||||
%%
 | 
			
		||||
 | 
			
		||||
@ -116,6 +116,9 @@ using namespace glslang;
 | 
			
		||||
            glslang::TIntermNodePair nodePair;
 | 
			
		||||
            glslang::TIntermTyped* intermTypedNode;
 | 
			
		||||
            glslang::TAttributes* attributes;
 | 
			
		||||
            glslang::TSpirvRequirement* spirvReq;
 | 
			
		||||
            glslang::TSpirvInstruction* spirvInst;
 | 
			
		||||
            glslang::TSpirvTypeParameters* spirvTypeParams;
 | 
			
		||||
        };
 | 
			
		||||
        union {
 | 
			
		||||
            glslang::TPublicType type;
 | 
			
		||||
@ -271,6 +274,11 @@ extern int yylex(YYSTYPE*, TParseContext&);
 | 
			
		||||
%token <lex> SUBPASSINPUT SUBPASSINPUTMS ISUBPASSINPUT ISUBPASSINPUTMS USUBPASSINPUT USUBPASSINPUTMS
 | 
			
		||||
%token <lex> F16SUBPASSINPUT F16SUBPASSINPUTMS
 | 
			
		||||
 | 
			
		||||
// spirv intrinsics
 | 
			
		||||
%token <lex> SPIRV_INSTRUCTION SPIRV_EXECUTION_MODE SPIRV_EXECUTION_MODE_ID
 | 
			
		||||
%token <lex> SPIRV_DECORATE SPIRV_DECORATE_ID SPIRV_DECORATE_STRING
 | 
			
		||||
%token <lex> SPIRV_TYPE SPIRV_STORAGE_CLASS SPIRV_BY_REFERENCE SPIRV_LITERAL
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
%token <lex> LEFT_OP RIGHT_OP
 | 
			
		||||
@ -362,6 +370,19 @@ extern int yylex(YYSTYPE*, TParseContext&);
 | 
			
		||||
%type <interm.attributes> attribute attribute_list single_attribute
 | 
			
		||||
%type <interm.intermNode> demote_statement
 | 
			
		||||
%type <interm.intermTypedNode> initializer_list
 | 
			
		||||
%type <interm.spirvReq> spirv_requirements_list spirv_requirements_parameter
 | 
			
		||||
%type <interm.intermNode> spirv_extension_list spirv_capability_list
 | 
			
		||||
%type <interm.intermNode> spirv_execution_mode_qualifier
 | 
			
		||||
%type <interm.intermNode> spirv_execution_mode_parameter_list spirv_execution_mode_parameter spirv_execution_mode_id_parameter_list
 | 
			
		||||
%type <interm.type> spirv_storage_class_qualifier
 | 
			
		||||
%type <interm.type> spirv_decorate_qualifier
 | 
			
		||||
%type <interm.intermNode> spirv_decorate_parameter_list spirv_decorate_parameter
 | 
			
		||||
%type <interm.intermNode> spirv_decorate_id_parameter_list
 | 
			
		||||
%type <interm.intermNode> spirv_decorate_string_parameter_list
 | 
			
		||||
%type <interm.type> spirv_type_specifier
 | 
			
		||||
%type <interm.spirvTypeParams> spirv_type_parameter_list spirv_type_parameter
 | 
			
		||||
%type <interm.spirvInst> spirv_instruction_qualifier
 | 
			
		||||
%type <interm.spirvInst> spirv_instruction_qualifier_list spirv_instruction_qualifier_id
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
%start translation_unit
 | 
			
		||||
@ -875,6 +896,20 @@ declaration
 | 
			
		||||
        $$ = 0;
 | 
			
		||||
        // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    | spirv_instruction_qualifier function_prototype SEMICOLON {
 | 
			
		||||
        parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V instruction qualifier");
 | 
			
		||||
        $2.function->setSpirvInstruction(*$1); // Attach SPIR-V intruction qualifier
 | 
			
		||||
        parseContext.handleFunctionDeclarator($2.loc, *$2.function, true /* prototype */);
 | 
			
		||||
        $$ = 0;
 | 
			
		||||
        // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_execution_mode_qualifier SEMICOLON {
 | 
			
		||||
        parseContext.globalCheck($2.loc, "SPIR-V execution mode qualifier");
 | 
			
		||||
        parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V execution mode qualifier");
 | 
			
		||||
        $$ = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    | init_declarator_list SEMICOLON {
 | 
			
		||||
        if ($1.intermNode && $1.intermNode->getAsAggregate())
 | 
			
		||||
            $1.intermNode->getAsAggregate()->setOperator(EOpSequence);
 | 
			
		||||
@ -1366,6 +1401,25 @@ single_type_qualifier
 | 
			
		||||
    | non_uniform_qualifier {
 | 
			
		||||
        $$ = $1;
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_storage_class_qualifier {
 | 
			
		||||
        parseContext.globalCheck($1.loc, "spirv_storage_class");
 | 
			
		||||
        parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V storage class qualifier");
 | 
			
		||||
        $$ = $1;
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_decorate_qualifier {
 | 
			
		||||
        parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V decorate qualifier");
 | 
			
		||||
        $$ = $1;
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_BY_REFERENCE {
 | 
			
		||||
        parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_reference");
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        $$.qualifier.setSpirvByReference();
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_LITERAL {
 | 
			
		||||
        parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_literal");
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        $$.qualifier.setSpirvLiteral();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
@ -3426,6 +3480,10 @@ type_specifier_nonarray
 | 
			
		||||
        $$.basicType = EbtUint;
 | 
			
		||||
        $$.coopmat = true;
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_type_specifier {
 | 
			
		||||
        parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V type specifier");
 | 
			
		||||
        $$ = $1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    | struct_specifier {
 | 
			
		||||
        $$ = $1;
 | 
			
		||||
@ -4068,4 +4126,273 @@ single_attribute
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
spirv_requirements_list
 | 
			
		||||
    : spirv_requirements_parameter {
 | 
			
		||||
        $$ = $1;
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_requirements_list COMMA spirv_requirements_parameter {
 | 
			
		||||
        $$ = parseContext.mergeSpirvRequirements($2.loc, $1, $3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_requirements_parameter
 | 
			
		||||
    : IDENTIFIER EQUAL LEFT_BRACKET spirv_extension_list RIGHT_BRACKET {
 | 
			
		||||
        $$ = parseContext.makeSpirvRequirement($2.loc, *$1.string, $4->getAsAggregate(), nullptr);
 | 
			
		||||
    }
 | 
			
		||||
    | IDENTIFIER EQUAL LEFT_BRACKET spirv_capability_list RIGHT_BRACKET {
 | 
			
		||||
        $$ = parseContext.makeSpirvRequirement($2.loc, *$1.string, nullptr, $4->getAsAggregate());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_extension_list
 | 
			
		||||
    : STRING_LITERAL {
 | 
			
		||||
        $$ = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion($1.string, $1.loc, true));
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_extension_list COMMA STRING_LITERAL {
 | 
			
		||||
        $$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.string, $3.loc, true));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_capability_list
 | 
			
		||||
    : INTCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion($1.i, $1.loc, true));
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_capability_list COMMA INTCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.i, $3.loc, true));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_execution_mode_qualifier
 | 
			
		||||
    : SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT RIGHT_PAREN {
 | 
			
		||||
        parseContext.intermediate.insertSpirvExecutionMode($3.i);
 | 
			
		||||
        $$ = 0;
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN {
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        parseContext.intermediate.insertSpirvExecutionMode($5.i);
 | 
			
		||||
        $$ = 0;
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN {
 | 
			
		||||
        parseContext.intermediate.insertSpirvExecutionMode($3.i, $5->getAsAggregate());
 | 
			
		||||
        $$ = 0;
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN {
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        parseContext.intermediate.insertSpirvExecutionMode($5.i, $7->getAsAggregate());
 | 
			
		||||
        $$ = 0;
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_EXECUTION_MODE_ID LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN {
 | 
			
		||||
        parseContext.intermediate.insertSpirvExecutionModeId($3.i, $5->getAsAggregate());
 | 
			
		||||
        $$ = 0;
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_EXECUTION_MODE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN {
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        parseContext.intermediate.insertSpirvExecutionModeId($5.i, $7->getAsAggregate());
 | 
			
		||||
        $$ = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_execution_mode_parameter_list
 | 
			
		||||
    : spirv_execution_mode_parameter {
 | 
			
		||||
        $$ = parseContext.intermediate.makeAggregate($1);
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_execution_mode_parameter_list COMMA spirv_execution_mode_parameter {
 | 
			
		||||
        $$ = parseContext.intermediate.growAggregate($1, $3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_execution_mode_parameter
 | 
			
		||||
    : FLOATCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true);
 | 
			
		||||
    }
 | 
			
		||||
    | INTCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true);
 | 
			
		||||
    }
 | 
			
		||||
    | UINTCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true);
 | 
			
		||||
    }
 | 
			
		||||
    | BOOLCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
 | 
			
		||||
    }
 | 
			
		||||
    | STRING_LITERAL {
 | 
			
		||||
        $$ = parseContext.intermediate.addConstantUnion($1.string, $1.loc, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_execution_mode_id_parameter_list
 | 
			
		||||
    : constant_expression {
 | 
			
		||||
        if ($1->getBasicType() != EbtFloat &&
 | 
			
		||||
            $1->getBasicType() != EbtInt &&
 | 
			
		||||
            $1->getBasicType() != EbtUint &&
 | 
			
		||||
            $1->getBasicType() != EbtBool &&
 | 
			
		||||
            $1->getBasicType() != EbtString)
 | 
			
		||||
            parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), "");
 | 
			
		||||
        $$ = parseContext.intermediate.makeAggregate($1);
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_execution_mode_id_parameter_list COMMA constant_expression {
 | 
			
		||||
        if ($3->getBasicType() != EbtFloat &&
 | 
			
		||||
            $3->getBasicType() != EbtInt &&
 | 
			
		||||
            $3->getBasicType() != EbtUint &&
 | 
			
		||||
            $3->getBasicType() != EbtBool &&
 | 
			
		||||
            $3->getBasicType() != EbtString)
 | 
			
		||||
            parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), "");
 | 
			
		||||
        $$ = parseContext.intermediate.growAggregate($1, $3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_storage_class_qualifier
 | 
			
		||||
    : SPIRV_STORAGE_CLASS LEFT_PAREN INTCONSTANT RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        $$.qualifier.storage = EvqSpirvStorageClass;
 | 
			
		||||
        $$.qualifier.spirvStorageClass = $3.i;
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_STORAGE_CLASS LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        $$.qualifier.storage = EvqSpirvStorageClass;
 | 
			
		||||
        $$.qualifier.spirvStorageClass = $5.i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_decorate_qualifier
 | 
			
		||||
    : SPIRV_DECORATE LEFT_PAREN INTCONSTANT RIGHT_PAREN{
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        $$.qualifier.setSpirvDecorate($3.i);
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN{
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        $$.qualifier.setSpirvDecorate($5.i);
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_DECORATE LEFT_PAREN INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        $$.qualifier.setSpirvDecorate($3.i, $5->getAsAggregate());
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        $$.qualifier.setSpirvDecorate($5.i, $7->getAsAggregate());
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_DECORATE_ID LEFT_PAREN INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        $$.qualifier.setSpirvDecorateId($3.i, $5->getAsAggregate());
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_DECORATE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        $$.qualifier.setSpirvDecorateId($5.i, $7->getAsAggregate());
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_DECORATE_STRING LEFT_PAREN INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        $$.qualifier.setSpirvDecorateString($3.i, $5->getAsAggregate());
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_DECORATE_STRING LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc);
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        $$.qualifier.setSpirvDecorateString($5.i, $7->getAsAggregate());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_decorate_parameter_list
 | 
			
		||||
    : spirv_decorate_parameter {
 | 
			
		||||
        $$ = parseContext.intermediate.makeAggregate($1);
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_decorate_parameter_list COMMA spirv_decorate_parameter {
 | 
			
		||||
        $$ = parseContext.intermediate.growAggregate($1, $3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_decorate_parameter
 | 
			
		||||
    : FLOATCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true);
 | 
			
		||||
    }
 | 
			
		||||
    | INTCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true);
 | 
			
		||||
    }
 | 
			
		||||
    | UINTCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true);
 | 
			
		||||
    }
 | 
			
		||||
    | BOOLCONSTANT {
 | 
			
		||||
        $$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_decorate_id_parameter_list
 | 
			
		||||
    : constant_expression {
 | 
			
		||||
        if ($1->getBasicType() != EbtFloat &&
 | 
			
		||||
            $1->getBasicType() != EbtInt &&
 | 
			
		||||
            $1->getBasicType() != EbtUint &&
 | 
			
		||||
            $1->getBasicType() != EbtBool)
 | 
			
		||||
            parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), "");
 | 
			
		||||
        $$ = parseContext.intermediate.makeAggregate($1);
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_decorate_id_parameter_list COMMA constant_expression {
 | 
			
		||||
        if ($3->getBasicType() != EbtFloat &&
 | 
			
		||||
            $3->getBasicType() != EbtInt &&
 | 
			
		||||
            $3->getBasicType() != EbtUint &&
 | 
			
		||||
            $3->getBasicType() != EbtBool)
 | 
			
		||||
            parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), "");
 | 
			
		||||
        $$ = parseContext.intermediate.growAggregate($1, $3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_decorate_string_parameter_list
 | 
			
		||||
    : STRING_LITERAL {
 | 
			
		||||
        $$ = parseContext.intermediate.makeAggregate(
 | 
			
		||||
            parseContext.intermediate.addConstantUnion($1.string, $1.loc, true));
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_decorate_string_parameter_list COMMA STRING_LITERAL {
 | 
			
		||||
        $$ = parseContext.intermediate.growAggregate($1, parseContext.intermediate.addConstantUnion($3.string, $3.loc, true));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_type_specifier
 | 
			
		||||
    : SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
 | 
			
		||||
        $$.setSpirvType(*$3, $5);
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        $$.setSpirvType(*$5, $7);
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
 | 
			
		||||
        $$.setSpirvType(*$3);
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN {
 | 
			
		||||
        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        $$.setSpirvType(*$5);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_type_parameter_list
 | 
			
		||||
    : spirv_type_parameter {
 | 
			
		||||
        $$ = $1;
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_type_parameter_list COMMA spirv_type_parameter {
 | 
			
		||||
        $$ = parseContext.mergeSpirvTypeParameters($1, $3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_type_parameter
 | 
			
		||||
    : constant_expression {
 | 
			
		||||
        $$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1->getAsConstantUnion());
 | 
			
		||||
    }
 | 
			
		||||
    | type_specifier {
 | 
			
		||||
        $$ = parseContext.makeSpirvTypeParameters($1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_instruction_qualifier
 | 
			
		||||
    : SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN {
 | 
			
		||||
        $$ = $3;
 | 
			
		||||
    }
 | 
			
		||||
    | SPIRV_INSTRUCTION LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN {
 | 
			
		||||
        parseContext.intermediate.insertSpirvRequirement($3);
 | 
			
		||||
        $$ = $5;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_instruction_qualifier_list
 | 
			
		||||
    : spirv_instruction_qualifier_id {
 | 
			
		||||
        $$ = $1;
 | 
			
		||||
    }
 | 
			
		||||
    | spirv_instruction_qualifier_list COMMA spirv_instruction_qualifier_id {
 | 
			
		||||
        $$ = parseContext.mergeSpirvInstruction($2.loc, $1, $3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
spirv_instruction_qualifier_id
 | 
			
		||||
    : IDENTIFIER EQUAL STRING_LITERAL {
 | 
			
		||||
        $$ = parseContext.makeSpirvInstruction($2.loc, *$1.string, *$3.string);
 | 
			
		||||
    }
 | 
			
		||||
    | IDENTIFIER EQUAL INTCONSTANT {
 | 
			
		||||
        $$ = parseContext.makeSpirvInstruction($2.loc, *$1.string, $3.i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
%%
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,8 +1,8 @@
 | 
			
		||||
/* A Bison parser, made by GNU Bison 3.7.5.  */
 | 
			
		||||
/* A Bison parser, made by GNU Bison 3.7.4.  */
 | 
			
		||||
 | 
			
		||||
/* Bison interface for Yacc-like parsers in C
 | 
			
		||||
 | 
			
		||||
   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
 | 
			
		||||
   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
 | 
			
		||||
   Inc.
 | 
			
		||||
 | 
			
		||||
   This program is free software: you can redistribute it and/or modify
 | 
			
		||||
@ -368,134 +368,144 @@ extern int yydebug;
 | 
			
		||||
    USUBPASSINPUTMS = 569,         /* USUBPASSINPUTMS  */
 | 
			
		||||
    F16SUBPASSINPUT = 570,         /* F16SUBPASSINPUT  */
 | 
			
		||||
    F16SUBPASSINPUTMS = 571,       /* F16SUBPASSINPUTMS  */
 | 
			
		||||
    LEFT_OP = 572,                 /* LEFT_OP  */
 | 
			
		||||
    RIGHT_OP = 573,                /* RIGHT_OP  */
 | 
			
		||||
    INC_OP = 574,                  /* INC_OP  */
 | 
			
		||||
    DEC_OP = 575,                  /* DEC_OP  */
 | 
			
		||||
    LE_OP = 576,                   /* LE_OP  */
 | 
			
		||||
    GE_OP = 577,                   /* GE_OP  */
 | 
			
		||||
    EQ_OP = 578,                   /* EQ_OP  */
 | 
			
		||||
    NE_OP = 579,                   /* NE_OP  */
 | 
			
		||||
    AND_OP = 580,                  /* AND_OP  */
 | 
			
		||||
    OR_OP = 581,                   /* OR_OP  */
 | 
			
		||||
    XOR_OP = 582,                  /* XOR_OP  */
 | 
			
		||||
    MUL_ASSIGN = 583,              /* MUL_ASSIGN  */
 | 
			
		||||
    DIV_ASSIGN = 584,              /* DIV_ASSIGN  */
 | 
			
		||||
    ADD_ASSIGN = 585,              /* ADD_ASSIGN  */
 | 
			
		||||
    MOD_ASSIGN = 586,              /* MOD_ASSIGN  */
 | 
			
		||||
    LEFT_ASSIGN = 587,             /* LEFT_ASSIGN  */
 | 
			
		||||
    RIGHT_ASSIGN = 588,            /* RIGHT_ASSIGN  */
 | 
			
		||||
    AND_ASSIGN = 589,              /* AND_ASSIGN  */
 | 
			
		||||
    XOR_ASSIGN = 590,              /* XOR_ASSIGN  */
 | 
			
		||||
    OR_ASSIGN = 591,               /* OR_ASSIGN  */
 | 
			
		||||
    SUB_ASSIGN = 592,              /* SUB_ASSIGN  */
 | 
			
		||||
    STRING_LITERAL = 593,          /* STRING_LITERAL  */
 | 
			
		||||
    LEFT_PAREN = 594,              /* LEFT_PAREN  */
 | 
			
		||||
    RIGHT_PAREN = 595,             /* RIGHT_PAREN  */
 | 
			
		||||
    LEFT_BRACKET = 596,            /* LEFT_BRACKET  */
 | 
			
		||||
    RIGHT_BRACKET = 597,           /* RIGHT_BRACKET  */
 | 
			
		||||
    LEFT_BRACE = 598,              /* LEFT_BRACE  */
 | 
			
		||||
    RIGHT_BRACE = 599,             /* RIGHT_BRACE  */
 | 
			
		||||
    DOT = 600,                     /* DOT  */
 | 
			
		||||
    COMMA = 601,                   /* COMMA  */
 | 
			
		||||
    COLON = 602,                   /* COLON  */
 | 
			
		||||
    EQUAL = 603,                   /* EQUAL  */
 | 
			
		||||
    SEMICOLON = 604,               /* SEMICOLON  */
 | 
			
		||||
    BANG = 605,                    /* BANG  */
 | 
			
		||||
    DASH = 606,                    /* DASH  */
 | 
			
		||||
    TILDE = 607,                   /* TILDE  */
 | 
			
		||||
    PLUS = 608,                    /* PLUS  */
 | 
			
		||||
    STAR = 609,                    /* STAR  */
 | 
			
		||||
    SLASH = 610,                   /* SLASH  */
 | 
			
		||||
    PERCENT = 611,                 /* PERCENT  */
 | 
			
		||||
    LEFT_ANGLE = 612,              /* LEFT_ANGLE  */
 | 
			
		||||
    RIGHT_ANGLE = 613,             /* RIGHT_ANGLE  */
 | 
			
		||||
    VERTICAL_BAR = 614,            /* VERTICAL_BAR  */
 | 
			
		||||
    CARET = 615,                   /* CARET  */
 | 
			
		||||
    AMPERSAND = 616,               /* AMPERSAND  */
 | 
			
		||||
    QUESTION = 617,                /* QUESTION  */
 | 
			
		||||
    INVARIANT = 618,               /* INVARIANT  */
 | 
			
		||||
    HIGH_PRECISION = 619,          /* HIGH_PRECISION  */
 | 
			
		||||
    MEDIUM_PRECISION = 620,        /* MEDIUM_PRECISION  */
 | 
			
		||||
    LOW_PRECISION = 621,           /* LOW_PRECISION  */
 | 
			
		||||
    PRECISION = 622,               /* PRECISION  */
 | 
			
		||||
    PACKED = 623,                  /* PACKED  */
 | 
			
		||||
    RESOURCE = 624,                /* RESOURCE  */
 | 
			
		||||
    SUPERP = 625,                  /* SUPERP  */
 | 
			
		||||
    FLOATCONSTANT = 626,           /* FLOATCONSTANT  */
 | 
			
		||||
    INTCONSTANT = 627,             /* INTCONSTANT  */
 | 
			
		||||
    UINTCONSTANT = 628,            /* UINTCONSTANT  */
 | 
			
		||||
    BOOLCONSTANT = 629,            /* BOOLCONSTANT  */
 | 
			
		||||
    IDENTIFIER = 630,              /* IDENTIFIER  */
 | 
			
		||||
    TYPE_NAME = 631,               /* TYPE_NAME  */
 | 
			
		||||
    CENTROID = 632,                /* CENTROID  */
 | 
			
		||||
    IN = 633,                      /* IN  */
 | 
			
		||||
    OUT = 634,                     /* OUT  */
 | 
			
		||||
    INOUT = 635,                   /* INOUT  */
 | 
			
		||||
    STRUCT = 636,                  /* STRUCT  */
 | 
			
		||||
    VOID = 637,                    /* VOID  */
 | 
			
		||||
    WHILE = 638,                   /* WHILE  */
 | 
			
		||||
    BREAK = 639,                   /* BREAK  */
 | 
			
		||||
    CONTINUE = 640,                /* CONTINUE  */
 | 
			
		||||
    DO = 641,                      /* DO  */
 | 
			
		||||
    ELSE = 642,                    /* ELSE  */
 | 
			
		||||
    FOR = 643,                     /* FOR  */
 | 
			
		||||
    IF = 644,                      /* IF  */
 | 
			
		||||
    DISCARD = 645,                 /* DISCARD  */
 | 
			
		||||
    RETURN = 646,                  /* RETURN  */
 | 
			
		||||
    SWITCH = 647,                  /* SWITCH  */
 | 
			
		||||
    CASE = 648,                    /* CASE  */
 | 
			
		||||
    DEFAULT = 649,                 /* DEFAULT  */
 | 
			
		||||
    TERMINATE_INVOCATION = 650,    /* TERMINATE_INVOCATION  */
 | 
			
		||||
    TERMINATE_RAY = 651,           /* TERMINATE_RAY  */
 | 
			
		||||
    IGNORE_INTERSECTION = 652,     /* IGNORE_INTERSECTION  */
 | 
			
		||||
    UNIFORM = 653,                 /* UNIFORM  */
 | 
			
		||||
    SHARED = 654,                  /* SHARED  */
 | 
			
		||||
    BUFFER = 655,                  /* BUFFER  */
 | 
			
		||||
    FLAT = 656,                    /* FLAT  */
 | 
			
		||||
    SMOOTH = 657,                  /* SMOOTH  */
 | 
			
		||||
    LAYOUT = 658,                  /* LAYOUT  */
 | 
			
		||||
    DOUBLECONSTANT = 659,          /* DOUBLECONSTANT  */
 | 
			
		||||
    INT16CONSTANT = 660,           /* INT16CONSTANT  */
 | 
			
		||||
    UINT16CONSTANT = 661,          /* UINT16CONSTANT  */
 | 
			
		||||
    FLOAT16CONSTANT = 662,         /* FLOAT16CONSTANT  */
 | 
			
		||||
    INT32CONSTANT = 663,           /* INT32CONSTANT  */
 | 
			
		||||
    UINT32CONSTANT = 664,          /* UINT32CONSTANT  */
 | 
			
		||||
    INT64CONSTANT = 665,           /* INT64CONSTANT  */
 | 
			
		||||
    UINT64CONSTANT = 666,          /* UINT64CONSTANT  */
 | 
			
		||||
    SUBROUTINE = 667,              /* SUBROUTINE  */
 | 
			
		||||
    DEMOTE = 668,                  /* DEMOTE  */
 | 
			
		||||
    PAYLOADNV = 669,               /* PAYLOADNV  */
 | 
			
		||||
    PAYLOADINNV = 670,             /* PAYLOADINNV  */
 | 
			
		||||
    HITATTRNV = 671,               /* HITATTRNV  */
 | 
			
		||||
    CALLDATANV = 672,              /* CALLDATANV  */
 | 
			
		||||
    CALLDATAINNV = 673,            /* CALLDATAINNV  */
 | 
			
		||||
    PAYLOADEXT = 674,              /* PAYLOADEXT  */
 | 
			
		||||
    PAYLOADINEXT = 675,            /* PAYLOADINEXT  */
 | 
			
		||||
    HITATTREXT = 676,              /* HITATTREXT  */
 | 
			
		||||
    CALLDATAEXT = 677,             /* CALLDATAEXT  */
 | 
			
		||||
    CALLDATAINEXT = 678,           /* CALLDATAINEXT  */
 | 
			
		||||
    PATCH = 679,                   /* PATCH  */
 | 
			
		||||
    SAMPLE = 680,                  /* SAMPLE  */
 | 
			
		||||
    NONUNIFORM = 681,              /* NONUNIFORM  */
 | 
			
		||||
    COHERENT = 682,                /* COHERENT  */
 | 
			
		||||
    VOLATILE = 683,                /* VOLATILE  */
 | 
			
		||||
    RESTRICT = 684,                /* RESTRICT  */
 | 
			
		||||
    READONLY = 685,                /* READONLY  */
 | 
			
		||||
    WRITEONLY = 686,               /* WRITEONLY  */
 | 
			
		||||
    DEVICECOHERENT = 687,          /* DEVICECOHERENT  */
 | 
			
		||||
    QUEUEFAMILYCOHERENT = 688,     /* QUEUEFAMILYCOHERENT  */
 | 
			
		||||
    WORKGROUPCOHERENT = 689,       /* WORKGROUPCOHERENT  */
 | 
			
		||||
    SUBGROUPCOHERENT = 690,        /* SUBGROUPCOHERENT  */
 | 
			
		||||
    NONPRIVATE = 691,              /* NONPRIVATE  */
 | 
			
		||||
    SHADERCALLCOHERENT = 692,      /* SHADERCALLCOHERENT  */
 | 
			
		||||
    NOPERSPECTIVE = 693,           /* NOPERSPECTIVE  */
 | 
			
		||||
    EXPLICITINTERPAMD = 694,       /* EXPLICITINTERPAMD  */
 | 
			
		||||
    PERVERTEXNV = 695,             /* PERVERTEXNV  */
 | 
			
		||||
    PERPRIMITIVENV = 696,          /* PERPRIMITIVENV  */
 | 
			
		||||
    PERVIEWNV = 697,               /* PERVIEWNV  */
 | 
			
		||||
    PERTASKNV = 698,               /* PERTASKNV  */
 | 
			
		||||
    PRECISE = 699                  /* PRECISE  */
 | 
			
		||||
    SPIRV_INSTRUCTION = 572,       /* SPIRV_INSTRUCTION  */
 | 
			
		||||
    SPIRV_EXECUTION_MODE = 573,    /* SPIRV_EXECUTION_MODE  */
 | 
			
		||||
    SPIRV_EXECUTION_MODE_ID = 574, /* SPIRV_EXECUTION_MODE_ID  */
 | 
			
		||||
    SPIRV_DECORATE = 575,          /* SPIRV_DECORATE  */
 | 
			
		||||
    SPIRV_DECORATE_ID = 576,       /* SPIRV_DECORATE_ID  */
 | 
			
		||||
    SPIRV_DECORATE_STRING = 577,   /* SPIRV_DECORATE_STRING  */
 | 
			
		||||
    SPIRV_TYPE = 578,              /* SPIRV_TYPE  */
 | 
			
		||||
    SPIRV_STORAGE_CLASS = 579,     /* SPIRV_STORAGE_CLASS  */
 | 
			
		||||
    SPIRV_BY_REFERENCE = 580,      /* SPIRV_BY_REFERENCE  */
 | 
			
		||||
    SPIRV_LITERAL = 581,           /* SPIRV_LITERAL  */
 | 
			
		||||
    LEFT_OP = 582,                 /* LEFT_OP  */
 | 
			
		||||
    RIGHT_OP = 583,                /* RIGHT_OP  */
 | 
			
		||||
    INC_OP = 584,                  /* INC_OP  */
 | 
			
		||||
    DEC_OP = 585,                  /* DEC_OP  */
 | 
			
		||||
    LE_OP = 586,                   /* LE_OP  */
 | 
			
		||||
    GE_OP = 587,                   /* GE_OP  */
 | 
			
		||||
    EQ_OP = 588,                   /* EQ_OP  */
 | 
			
		||||
    NE_OP = 589,                   /* NE_OP  */
 | 
			
		||||
    AND_OP = 590,                  /* AND_OP  */
 | 
			
		||||
    OR_OP = 591,                   /* OR_OP  */
 | 
			
		||||
    XOR_OP = 592,                  /* XOR_OP  */
 | 
			
		||||
    MUL_ASSIGN = 593,              /* MUL_ASSIGN  */
 | 
			
		||||
    DIV_ASSIGN = 594,              /* DIV_ASSIGN  */
 | 
			
		||||
    ADD_ASSIGN = 595,              /* ADD_ASSIGN  */
 | 
			
		||||
    MOD_ASSIGN = 596,              /* MOD_ASSIGN  */
 | 
			
		||||
    LEFT_ASSIGN = 597,             /* LEFT_ASSIGN  */
 | 
			
		||||
    RIGHT_ASSIGN = 598,            /* RIGHT_ASSIGN  */
 | 
			
		||||
    AND_ASSIGN = 599,              /* AND_ASSIGN  */
 | 
			
		||||
    XOR_ASSIGN = 600,              /* XOR_ASSIGN  */
 | 
			
		||||
    OR_ASSIGN = 601,               /* OR_ASSIGN  */
 | 
			
		||||
    SUB_ASSIGN = 602,              /* SUB_ASSIGN  */
 | 
			
		||||
    STRING_LITERAL = 603,          /* STRING_LITERAL  */
 | 
			
		||||
    LEFT_PAREN = 604,              /* LEFT_PAREN  */
 | 
			
		||||
    RIGHT_PAREN = 605,             /* RIGHT_PAREN  */
 | 
			
		||||
    LEFT_BRACKET = 606,            /* LEFT_BRACKET  */
 | 
			
		||||
    RIGHT_BRACKET = 607,           /* RIGHT_BRACKET  */
 | 
			
		||||
    LEFT_BRACE = 608,              /* LEFT_BRACE  */
 | 
			
		||||
    RIGHT_BRACE = 609,             /* RIGHT_BRACE  */
 | 
			
		||||
    DOT = 610,                     /* DOT  */
 | 
			
		||||
    COMMA = 611,                   /* COMMA  */
 | 
			
		||||
    COLON = 612,                   /* COLON  */
 | 
			
		||||
    EQUAL = 613,                   /* EQUAL  */
 | 
			
		||||
    SEMICOLON = 614,               /* SEMICOLON  */
 | 
			
		||||
    BANG = 615,                    /* BANG  */
 | 
			
		||||
    DASH = 616,                    /* DASH  */
 | 
			
		||||
    TILDE = 617,                   /* TILDE  */
 | 
			
		||||
    PLUS = 618,                    /* PLUS  */
 | 
			
		||||
    STAR = 619,                    /* STAR  */
 | 
			
		||||
    SLASH = 620,                   /* SLASH  */
 | 
			
		||||
    PERCENT = 621,                 /* PERCENT  */
 | 
			
		||||
    LEFT_ANGLE = 622,              /* LEFT_ANGLE  */
 | 
			
		||||
    RIGHT_ANGLE = 623,             /* RIGHT_ANGLE  */
 | 
			
		||||
    VERTICAL_BAR = 624,            /* VERTICAL_BAR  */
 | 
			
		||||
    CARET = 625,                   /* CARET  */
 | 
			
		||||
    AMPERSAND = 626,               /* AMPERSAND  */
 | 
			
		||||
    QUESTION = 627,                /* QUESTION  */
 | 
			
		||||
    INVARIANT = 628,               /* INVARIANT  */
 | 
			
		||||
    HIGH_PRECISION = 629,          /* HIGH_PRECISION  */
 | 
			
		||||
    MEDIUM_PRECISION = 630,        /* MEDIUM_PRECISION  */
 | 
			
		||||
    LOW_PRECISION = 631,           /* LOW_PRECISION  */
 | 
			
		||||
    PRECISION = 632,               /* PRECISION  */
 | 
			
		||||
    PACKED = 633,                  /* PACKED  */
 | 
			
		||||
    RESOURCE = 634,                /* RESOURCE  */
 | 
			
		||||
    SUPERP = 635,                  /* SUPERP  */
 | 
			
		||||
    FLOATCONSTANT = 636,           /* FLOATCONSTANT  */
 | 
			
		||||
    INTCONSTANT = 637,             /* INTCONSTANT  */
 | 
			
		||||
    UINTCONSTANT = 638,            /* UINTCONSTANT  */
 | 
			
		||||
    BOOLCONSTANT = 639,            /* BOOLCONSTANT  */
 | 
			
		||||
    IDENTIFIER = 640,              /* IDENTIFIER  */
 | 
			
		||||
    TYPE_NAME = 641,               /* TYPE_NAME  */
 | 
			
		||||
    CENTROID = 642,                /* CENTROID  */
 | 
			
		||||
    IN = 643,                      /* IN  */
 | 
			
		||||
    OUT = 644,                     /* OUT  */
 | 
			
		||||
    INOUT = 645,                   /* INOUT  */
 | 
			
		||||
    STRUCT = 646,                  /* STRUCT  */
 | 
			
		||||
    VOID = 647,                    /* VOID  */
 | 
			
		||||
    WHILE = 648,                   /* WHILE  */
 | 
			
		||||
    BREAK = 649,                   /* BREAK  */
 | 
			
		||||
    CONTINUE = 650,                /* CONTINUE  */
 | 
			
		||||
    DO = 651,                      /* DO  */
 | 
			
		||||
    ELSE = 652,                    /* ELSE  */
 | 
			
		||||
    FOR = 653,                     /* FOR  */
 | 
			
		||||
    IF = 654,                      /* IF  */
 | 
			
		||||
    DISCARD = 655,                 /* DISCARD  */
 | 
			
		||||
    RETURN = 656,                  /* RETURN  */
 | 
			
		||||
    SWITCH = 657,                  /* SWITCH  */
 | 
			
		||||
    CASE = 658,                    /* CASE  */
 | 
			
		||||
    DEFAULT = 659,                 /* DEFAULT  */
 | 
			
		||||
    TERMINATE_INVOCATION = 660,    /* TERMINATE_INVOCATION  */
 | 
			
		||||
    TERMINATE_RAY = 661,           /* TERMINATE_RAY  */
 | 
			
		||||
    IGNORE_INTERSECTION = 662,     /* IGNORE_INTERSECTION  */
 | 
			
		||||
    UNIFORM = 663,                 /* UNIFORM  */
 | 
			
		||||
    SHARED = 664,                  /* SHARED  */
 | 
			
		||||
    BUFFER = 665,                  /* BUFFER  */
 | 
			
		||||
    FLAT = 666,                    /* FLAT  */
 | 
			
		||||
    SMOOTH = 667,                  /* SMOOTH  */
 | 
			
		||||
    LAYOUT = 668,                  /* LAYOUT  */
 | 
			
		||||
    DOUBLECONSTANT = 669,          /* DOUBLECONSTANT  */
 | 
			
		||||
    INT16CONSTANT = 670,           /* INT16CONSTANT  */
 | 
			
		||||
    UINT16CONSTANT = 671,          /* UINT16CONSTANT  */
 | 
			
		||||
    FLOAT16CONSTANT = 672,         /* FLOAT16CONSTANT  */
 | 
			
		||||
    INT32CONSTANT = 673,           /* INT32CONSTANT  */
 | 
			
		||||
    UINT32CONSTANT = 674,          /* UINT32CONSTANT  */
 | 
			
		||||
    INT64CONSTANT = 675,           /* INT64CONSTANT  */
 | 
			
		||||
    UINT64CONSTANT = 676,          /* UINT64CONSTANT  */
 | 
			
		||||
    SUBROUTINE = 677,              /* SUBROUTINE  */
 | 
			
		||||
    DEMOTE = 678,                  /* DEMOTE  */
 | 
			
		||||
    PAYLOADNV = 679,               /* PAYLOADNV  */
 | 
			
		||||
    PAYLOADINNV = 680,             /* PAYLOADINNV  */
 | 
			
		||||
    HITATTRNV = 681,               /* HITATTRNV  */
 | 
			
		||||
    CALLDATANV = 682,              /* CALLDATANV  */
 | 
			
		||||
    CALLDATAINNV = 683,            /* CALLDATAINNV  */
 | 
			
		||||
    PAYLOADEXT = 684,              /* PAYLOADEXT  */
 | 
			
		||||
    PAYLOADINEXT = 685,            /* PAYLOADINEXT  */
 | 
			
		||||
    HITATTREXT = 686,              /* HITATTREXT  */
 | 
			
		||||
    CALLDATAEXT = 687,             /* CALLDATAEXT  */
 | 
			
		||||
    CALLDATAINEXT = 688,           /* CALLDATAINEXT  */
 | 
			
		||||
    PATCH = 689,                   /* PATCH  */
 | 
			
		||||
    SAMPLE = 690,                  /* SAMPLE  */
 | 
			
		||||
    NONUNIFORM = 691,              /* NONUNIFORM  */
 | 
			
		||||
    COHERENT = 692,                /* COHERENT  */
 | 
			
		||||
    VOLATILE = 693,                /* VOLATILE  */
 | 
			
		||||
    RESTRICT = 694,                /* RESTRICT  */
 | 
			
		||||
    READONLY = 695,                /* READONLY  */
 | 
			
		||||
    WRITEONLY = 696,               /* WRITEONLY  */
 | 
			
		||||
    DEVICECOHERENT = 697,          /* DEVICECOHERENT  */
 | 
			
		||||
    QUEUEFAMILYCOHERENT = 698,     /* QUEUEFAMILYCOHERENT  */
 | 
			
		||||
    WORKGROUPCOHERENT = 699,       /* WORKGROUPCOHERENT  */
 | 
			
		||||
    SUBGROUPCOHERENT = 700,        /* SUBGROUPCOHERENT  */
 | 
			
		||||
    NONPRIVATE = 701,              /* NONPRIVATE  */
 | 
			
		||||
    SHADERCALLCOHERENT = 702,      /* SHADERCALLCOHERENT  */
 | 
			
		||||
    NOPERSPECTIVE = 703,           /* NOPERSPECTIVE  */
 | 
			
		||||
    EXPLICITINTERPAMD = 704,       /* EXPLICITINTERPAMD  */
 | 
			
		||||
    PERVERTEXNV = 705,             /* PERVERTEXNV  */
 | 
			
		||||
    PERPRIMITIVENV = 706,          /* PERPRIMITIVENV  */
 | 
			
		||||
    PERVIEWNV = 707,               /* PERVIEWNV  */
 | 
			
		||||
    PERTASKNV = 708,               /* PERTASKNV  */
 | 
			
		||||
    PRECISE = 709                  /* PRECISE  */
 | 
			
		||||
  };
 | 
			
		||||
  typedef enum yytokentype yytoken_kind_t;
 | 
			
		||||
#endif
 | 
			
		||||
@ -527,6 +537,9 @@ union YYSTYPE
 | 
			
		||||
            glslang::TIntermNodePair nodePair;
 | 
			
		||||
            glslang::TIntermTyped* intermTypedNode;
 | 
			
		||||
            glslang::TAttributes* attributes;
 | 
			
		||||
            glslang::TSpirvRequirement* spirvReq;
 | 
			
		||||
            glslang::TSpirvInstruction* spirvInst;
 | 
			
		||||
            glslang::TSpirvTypeParameters* spirvTypeParams;
 | 
			
		||||
        };
 | 
			
		||||
        union {
 | 
			
		||||
            glslang::TPublicType type;
 | 
			
		||||
@ -540,7 +553,7 @@ union YYSTYPE
 | 
			
		||||
        glslang::TArraySizes* typeParameters;
 | 
			
		||||
    } interm;
 | 
			
		||||
 | 
			
		||||
#line 544 "MachineIndependent/glslang_tab.cpp.h"
 | 
			
		||||
#line 557 "MachineIndependent/glslang_tab.cpp.h"
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
typedef union YYSTYPE YYSTYPE;
 | 
			
		||||
 | 
			
		||||
@ -696,6 +696,10 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
 | 
			
		||||
 | 
			
		||||
    case EOpConstructReference: out.debug << "Construct reference type"; break;
 | 
			
		||||
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    case EOpSpirvInst: out.debug << "spirv_instruction"; break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    default: out.debug.message(EPrefixError, "Bad unary op");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1126,6 +1130,10 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
 | 
			
		||||
    case EOpIsHelperInvocation: out.debug << "IsHelperInvocation"; break;
 | 
			
		||||
    case EOpDebugPrintf:  out.debug << "Debug printf";  break;
 | 
			
		||||
 | 
			
		||||
#ifndef GLSLANG_WEB
 | 
			
		||||
    case EOpSpirvInst: out.debug << "spirv_instruction"; break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    default: out.debug.message(EPrefixError, "Bad aggregation op");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -330,6 +330,8 @@ public:
 | 
			
		||||
        binaryDoubleOutput(false),
 | 
			
		||||
        subgroupUniformControlFlow(false),
 | 
			
		||||
        usePhysicalStorageBuffer(false),
 | 
			
		||||
        spirvRequirement(nullptr),
 | 
			
		||||
        spirvExecutionMode(nullptr),
 | 
			
		||||
        uniformLocationBase(0)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
@ -868,6 +870,15 @@ public:
 | 
			
		||||
 | 
			
		||||
    void setSubgroupUniformControlFlow() { subgroupUniformControlFlow = true; }
 | 
			
		||||
    bool getSubgroupUniformControlFlow() const { return subgroupUniformControlFlow; }
 | 
			
		||||
 | 
			
		||||
    // GL_EXT_spirv_intrinsics
 | 
			
		||||
    void insertSpirvRequirement(const TSpirvRequirement* spirvReq);
 | 
			
		||||
    bool hasSpirvRequirement() const { return spirvRequirement != nullptr; }
 | 
			
		||||
    const TSpirvRequirement& getSpirvRequirement() const { return *spirvRequirement; }
 | 
			
		||||
    void insertSpirvExecutionMode(int executionMode, const TIntermAggregate* args = nullptr);
 | 
			
		||||
    void insertSpirvExecutionModeId(int executionMode, const TIntermAggregate* args);
 | 
			
		||||
    bool hasSpirvExecutionMode() const { return spirvExecutionMode != nullptr; }
 | 
			
		||||
    const TSpirvExecutionMode& getSpirvExecutionMode() const { return *spirvExecutionMode; }
 | 
			
		||||
#endif // GLSLANG_WEB
 | 
			
		||||
 | 
			
		||||
    void addBlockStorageOverride(const char* nameStr, TBlockStorageClass backing)
 | 
			
		||||
@ -1122,6 +1133,9 @@ protected:
 | 
			
		||||
    bool subgroupUniformControlFlow;
 | 
			
		||||
    bool usePhysicalStorageBuffer;
 | 
			
		||||
 | 
			
		||||
    TSpirvRequirement* spirvRequirement;
 | 
			
		||||
    TSpirvExecutionMode* spirvExecutionMode;
 | 
			
		||||
 | 
			
		||||
    std::unordered_map<std::string, int> uniformLocationOverrides;
 | 
			
		||||
    int uniformLocationBase;
 | 
			
		||||
    TNumericFeatures numericFeatures;
 | 
			
		||||
 | 
			
		||||
@ -1191,9 +1191,12 @@ int TPpContext::tokenize(TPpToken& ppToken)
 | 
			
		||||
            // HLSL allows string literals.
 | 
			
		||||
            // GLSL allows string literals with GL_EXT_debug_printf.
 | 
			
		||||
            if (ifdepth == 0 && parseContext.intermediate.getSource() != EShSourceHlsl) {
 | 
			
		||||
                parseContext.requireExtensions(ppToken.loc, 1, &E_GL_EXT_debug_printf, "string literal");
 | 
			
		||||
                if (!parseContext.extensionTurnedOn(E_GL_EXT_debug_printf))
 | 
			
		||||
                    continue;
 | 
			
		||||
              const char* const string_literal_EXTs[] = { E_GL_EXT_debug_printf, E_GL_EXT_spirv_intrinsics };
 | 
			
		||||
              const int Num_string_literal_EXTs = sizeof(string_literal_EXTs) / sizeof(string_literal_EXTs[0]);
 | 
			
		||||
              parseContext.requireExtensions(ppToken.loc, 2, string_literal_EXTs, "string literal");
 | 
			
		||||
              if (!parseContext.extensionTurnedOn(E_GL_EXT_debug_printf) &&
 | 
			
		||||
                  !parseContext.extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
 | 
			
		||||
                  continue;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case '\'':
 | 
			
		||||
 | 
			
		||||
@ -356,6 +356,13 @@ INSTANTIATE_TEST_SUITE_P(
 | 
			
		||||
        "spv.int64.frag",
 | 
			
		||||
        "spv.intcoopmat.comp",
 | 
			
		||||
        "spv.intOps.vert",
 | 
			
		||||
        "spv.intrinsicsSpirvByReference.vert",
 | 
			
		||||
        "spv.intrinsicsSpirvDecorate.frag",
 | 
			
		||||
        "spv.intrinsicsSpirvExecutionMode.frag",
 | 
			
		||||
        "spv.intrinsicsSpirvInstruction.vert",
 | 
			
		||||
        "spv.intrinsicsSpirvLiteral.vert",
 | 
			
		||||
        "spv.intrinsicsSpirvStorageClass.rchit",
 | 
			
		||||
        "spv.intrinsicsSpirvType.rgen",
 | 
			
		||||
        "spv.layer.tese",
 | 
			
		||||
        "spv.layoutNested.vert",
 | 
			
		||||
        "spv.length.frag",
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user