Implement the extension GL_EXT_spirv_intrinsics

- Add support of SPIR-V execution mode qualifiers.
- Add support of SPIR-V storage class qualifier.
- Add support of SPIR-V decorate qualifiers.
- Add support of SPIR-V type specifier.
- Add support of SPIR-V intruction qualifiers.
- Add support of spirv_by_reference/spirv_literal parameter qualifier.
- Add shader stage macros introduced by this extension.
This commit is contained in:
Rex Xu 2021-04-25 16:52:35 +08:00
parent 3d935ea224
commit 65a7fb7054
40 changed files with 7337 additions and 3967 deletions

View File

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

View File

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

View File

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

View File

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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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);
}

View 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;
}

View 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;
}

View 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);
}

View 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);
}

View 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);
}

View 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);
}

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

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 ||
@ -3582,6 +3648,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);
@ -3843,6 +3917,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", "", "");
}
@ -4806,6 +4915,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);
}
@ -5873,6 +5993,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)))
@ -5934,6 +6057,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
@ -7940,6 +8068,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 '\'':

View File

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