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