Merge pull request #2625 from amdrexu/feature

Implement the extension GL_EXT_spirv_intrinsics
This commit is contained in:
Greg Fischer 2021-06-16 14:52:35 -06:00 committed by GitHub
commit 71612a7e5d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 7337 additions and 3967 deletions

View file

@ -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(), "");

View file

@ -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);

View file

@ -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:

View 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

View file

@ -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

View file

@ -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
};
//

View file

@ -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
}
//

View file

@ -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

View file

@ -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
%%

View file

@ -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

View file

@ -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;

View file

@ -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");
}

View file

@ -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;

View file

@ -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 '\'':