Updated glslang.
This commit is contained in:
parent
ddfae2f915
commit
bf5fda9ae7
63
3rdparty/glslang/SPIRV/GlslangToSpv.cpp
vendored
63
3rdparty/glslang/SPIRV/GlslangToSpv.cpp
vendored
@ -2004,6 +2004,10 @@ void TGlslangToSpvTraverser::dumpSpv(std::vector<unsigned int>& out)
|
||||
//
|
||||
void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
|
||||
{
|
||||
// We update the line information even though no code might be generated here
|
||||
// This is helpful to yield correct lines for control flow instructions
|
||||
builder.setLine(symbol->getLoc().line, symbol->getLoc().getFilename());
|
||||
|
||||
SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder);
|
||||
if (symbol->getType().isStruct())
|
||||
glslangTypeToIdMap[symbol->getType().getStruct()] = symbol->getId();
|
||||
@ -2155,6 +2159,9 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
||||
node->getRight()->traverse(this);
|
||||
spv::Id rValue = accessChainLoad(node->getRight()->getType());
|
||||
|
||||
// reset line number for assignment
|
||||
builder.setLine(node->getLoc().line, node->getLoc().getFilename());
|
||||
|
||||
if (node->getOp() != glslang::EOpAssign) {
|
||||
// the left is also an r-value
|
||||
builder.setAccessChain(lValue);
|
||||
@ -3782,10 +3789,11 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
|
||||
// Find a way of executing both sides and selecting the right result.
|
||||
const auto executeBothSides = [&]() -> void {
|
||||
// execute both sides
|
||||
spv::Id resultType = convertGlslangToSpvType(node->getType());
|
||||
node->getTrueBlock()->traverse(this);
|
||||
spv::Id trueValue = accessChainLoad(node->getTrueBlock()->getAsTyped()->getType());
|
||||
node->getFalseBlock()->traverse(this);
|
||||
spv::Id falseValue = accessChainLoad(node->getTrueBlock()->getAsTyped()->getType());
|
||||
spv::Id falseValue = accessChainLoad(node->getFalseBlock()->getAsTyped()->getType());
|
||||
|
||||
builder.setLine(node->getLoc().line, node->getLoc().getFilename());
|
||||
|
||||
@ -3794,8 +3802,8 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
|
||||
return;
|
||||
|
||||
// emit code to select between trueValue and falseValue
|
||||
|
||||
// see if OpSelect can handle it
|
||||
// see if OpSelect can handle the result type, and that the SPIR-V types
|
||||
// of the inputs match the result type.
|
||||
if (isOpSelectable()) {
|
||||
// Emit OpSelect for this selection.
|
||||
|
||||
@ -3807,10 +3815,18 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
|
||||
builder.getNumComponents(trueValue)));
|
||||
}
|
||||
|
||||
// If the types do not match, it is because of mismatched decorations on aggregates.
|
||||
// Since isOpSelectable only lets us get here for SPIR-V >= 1.4, we can use OpCopyObject
|
||||
// to get matching types.
|
||||
if (builder.getTypeId(trueValue) != resultType) {
|
||||
trueValue = builder.createUnaryOp(spv::OpCopyLogical, resultType, trueValue);
|
||||
}
|
||||
if (builder.getTypeId(falseValue) != resultType) {
|
||||
falseValue = builder.createUnaryOp(spv::OpCopyLogical, resultType, falseValue);
|
||||
}
|
||||
|
||||
// OpSelect
|
||||
result = builder.createTriOp(spv::OpSelect,
|
||||
convertGlslangToSpvType(node->getType()), condition,
|
||||
trueValue, falseValue);
|
||||
result = builder.createTriOp(spv::OpSelect, resultType, condition, trueValue, falseValue);
|
||||
|
||||
builder.clearAccessChain();
|
||||
builder.setAccessChainRValue(result);
|
||||
@ -3818,7 +3834,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
|
||||
// We need control flow to select the result.
|
||||
// TODO: Once SPIR-V OpSelect allows arbitrary types, eliminate this path.
|
||||
result = builder.createVariable(TranslatePrecisionDecoration(node->getType()),
|
||||
spv::StorageClassFunction, convertGlslangToSpvType(node->getType()));
|
||||
spv::StorageClassFunction, resultType);
|
||||
|
||||
// Selection control:
|
||||
const spv::SelectionControlMask control = TranslateSelectionControl(*node);
|
||||
@ -3827,10 +3843,15 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
|
||||
spv::Builder::If ifBuilder(condition, control, builder);
|
||||
|
||||
// emit the "then" statement
|
||||
builder.createStore(trueValue, result);
|
||||
builder.clearAccessChain();
|
||||
builder.setAccessChainLValue(result);
|
||||
multiTypeStore(node->getType(), trueValue);
|
||||
|
||||
ifBuilder.makeBeginElse();
|
||||
// emit the "else" statement
|
||||
builder.createStore(falseValue, result);
|
||||
builder.clearAccessChain();
|
||||
builder.setAccessChainLValue(result);
|
||||
multiTypeStore(node->getType(), falseValue);
|
||||
|
||||
// finish off the control flow
|
||||
ifBuilder.makeEndIf();
|
||||
@ -3857,16 +3878,26 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
|
||||
// emit the "then" statement
|
||||
if (node->getTrueBlock() != nullptr) {
|
||||
node->getTrueBlock()->traverse(this);
|
||||
if (result != spv::NoResult)
|
||||
builder.createStore(accessChainLoad(node->getTrueBlock()->getAsTyped()->getType()), result);
|
||||
if (result != spv::NoResult) {
|
||||
spv::Id load = accessChainLoad(node->getTrueBlock()->getAsTyped()->getType());
|
||||
|
||||
builder.clearAccessChain();
|
||||
builder.setAccessChainLValue(result);
|
||||
multiTypeStore(node->getType(), load);
|
||||
}
|
||||
}
|
||||
|
||||
if (node->getFalseBlock() != nullptr) {
|
||||
ifBuilder.makeBeginElse();
|
||||
// emit the "else" statement
|
||||
node->getFalseBlock()->traverse(this);
|
||||
if (result != spv::NoResult)
|
||||
builder.createStore(accessChainLoad(node->getFalseBlock()->getAsTyped()->getType()), result);
|
||||
if (result != spv::NoResult) {
|
||||
spv::Id load = accessChainLoad(node->getFalseBlock()->getAsTyped()->getType());
|
||||
|
||||
builder.clearAccessChain();
|
||||
builder.setAccessChainLValue(result);
|
||||
multiTypeStore(node->getType(), load);
|
||||
}
|
||||
}
|
||||
|
||||
// finish off the control flow
|
||||
@ -9418,10 +9449,10 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
||||
std::vector<spv::Id> operandIds;
|
||||
assert(!decorateId.second.empty());
|
||||
for (auto extraOperand : decorateId.second) {
|
||||
if (extraOperand->getQualifier().isSpecConstant())
|
||||
operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode()));
|
||||
else
|
||||
if (extraOperand->getQualifier().isFrontEndConstant())
|
||||
operandIds.push_back(createSpvConstant(*extraOperand));
|
||||
else
|
||||
operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode()));
|
||||
}
|
||||
builder.addDecorationId(id, static_cast<spv::Decoration>(decorateId.first), operandIds);
|
||||
}
|
||||
|
61
3rdparty/glslang/SPIRV/SpvBuilder.cpp
vendored
61
3rdparty/glslang/SPIRV/SpvBuilder.cpp
vendored
@ -144,6 +144,7 @@ void Builder::addLine(Id fileName, int lineNum, int column)
|
||||
|
||||
void Builder::addDebugScopeAndLine(Id fileName, int lineNum, int column)
|
||||
{
|
||||
assert(!currentDebugScopeId.empty());
|
||||
if (currentDebugScopeId.top() != lastDebugScopeId) {
|
||||
spv::Id resultId = getUniqueId();
|
||||
Instruction* scopeInst = new Instruction(resultId, makeVoidType(), OpExtInst);
|
||||
@ -1071,6 +1072,12 @@ Id Builder::makeDebugCompilationUnit() {
|
||||
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(sourceInst));
|
||||
module.mapInstruction(sourceInst);
|
||||
nonSemanticShaderCompilationUnitId = resultId;
|
||||
|
||||
// We can reasonably assume that makeDebugCompilationUnit will be called before any of
|
||||
// debug-scope stack. Function scopes and lexical scopes will occur afterward.
|
||||
assert(currentDebugScopeId.empty());
|
||||
currentDebugScopeId.push(nonSemanticShaderCompilationUnitId);
|
||||
|
||||
return resultId;
|
||||
}
|
||||
|
||||
@ -1100,6 +1107,8 @@ Id Builder::createDebugGlobalVariable(Id const type, char const*const name, Id c
|
||||
Id Builder::createDebugLocalVariable(Id type, char const*const name, size_t const argNumber)
|
||||
{
|
||||
assert(name != nullptr);
|
||||
assert(!currentDebugScopeId.empty());
|
||||
|
||||
Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
|
||||
inst->addIdOperand(nonSemanticShaderDebugInfo);
|
||||
inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugLocalVariable);
|
||||
@ -2119,6 +2128,8 @@ Id Builder::makeDebugFunction(Function* function, Id nameId, Id funcTypeId) {
|
||||
}
|
||||
|
||||
Id Builder::makeDebugLexicalBlock(uint32_t line) {
|
||||
assert(!currentDebugScopeId.empty());
|
||||
|
||||
Id lexId = getUniqueId();
|
||||
auto lex = new Instruction(lexId, makeVoidType(), OpExtInst);
|
||||
lex->addIdOperand(nonSemanticShaderDebugInfo);
|
||||
@ -2758,52 +2769,49 @@ Id Builder::createBuiltinCall(Id resultType, Id builtins, int entryPoint, const
|
||||
Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather,
|
||||
bool noImplicitLod, const TextureParameters& parameters, ImageOperandsMask signExtensionMask)
|
||||
{
|
||||
static const int maxTextureArgs = 10;
|
||||
Id texArgs[maxTextureArgs] = {};
|
||||
std::vector<Id> texArgs;
|
||||
|
||||
//
|
||||
// Set up the fixed arguments
|
||||
//
|
||||
int numArgs = 0;
|
||||
bool explicitLod = false;
|
||||
texArgs[numArgs++] = parameters.sampler;
|
||||
texArgs[numArgs++] = parameters.coords;
|
||||
texArgs.push_back(parameters.sampler);
|
||||
texArgs.push_back(parameters.coords);
|
||||
if (parameters.Dref != NoResult)
|
||||
texArgs[numArgs++] = parameters.Dref;
|
||||
texArgs.push_back(parameters.Dref);
|
||||
if (parameters.component != NoResult)
|
||||
texArgs[numArgs++] = parameters.component;
|
||||
texArgs.push_back(parameters.component);
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
if (parameters.granularity != NoResult)
|
||||
texArgs[numArgs++] = parameters.granularity;
|
||||
texArgs.push_back(parameters.granularity);
|
||||
if (parameters.coarse != NoResult)
|
||||
texArgs[numArgs++] = parameters.coarse;
|
||||
texArgs.push_back(parameters.coarse);
|
||||
#endif
|
||||
|
||||
//
|
||||
// Set up the optional arguments
|
||||
//
|
||||
int optArgNum = numArgs; // track which operand, if it exists, is the mask of optional arguments
|
||||
++numArgs; // speculatively make room for the mask operand
|
||||
size_t optArgNum = texArgs.size(); // the position of the mask for the optional arguments, if any.
|
||||
ImageOperandsMask mask = ImageOperandsMaskNone; // the mask operand
|
||||
if (parameters.bias) {
|
||||
mask = (ImageOperandsMask)(mask | ImageOperandsBiasMask);
|
||||
texArgs[numArgs++] = parameters.bias;
|
||||
texArgs.push_back(parameters.bias);
|
||||
}
|
||||
if (parameters.lod) {
|
||||
mask = (ImageOperandsMask)(mask | ImageOperandsLodMask);
|
||||
texArgs[numArgs++] = parameters.lod;
|
||||
texArgs.push_back(parameters.lod);
|
||||
explicitLod = true;
|
||||
} else if (parameters.gradX) {
|
||||
mask = (ImageOperandsMask)(mask | ImageOperandsGradMask);
|
||||
texArgs[numArgs++] = parameters.gradX;
|
||||
texArgs[numArgs++] = parameters.gradY;
|
||||
texArgs.push_back(parameters.gradX);
|
||||
texArgs.push_back(parameters.gradY);
|
||||
explicitLod = true;
|
||||
} else if (noImplicitLod && ! fetch && ! gather) {
|
||||
// have to explicitly use lod of 0 if not allowed to have them be implicit, and
|
||||
// we would otherwise be about to issue an implicit instruction
|
||||
mask = (ImageOperandsMask)(mask | ImageOperandsLodMask);
|
||||
texArgs[numArgs++] = makeFloatConstant(0.0);
|
||||
texArgs.push_back(makeFloatConstant(0.0));
|
||||
explicitLod = true;
|
||||
}
|
||||
if (parameters.offset) {
|
||||
@ -2813,24 +2821,24 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||
addCapability(CapabilityImageGatherExtended);
|
||||
mask = (ImageOperandsMask)(mask | ImageOperandsOffsetMask);
|
||||
}
|
||||
texArgs[numArgs++] = parameters.offset;
|
||||
texArgs.push_back(parameters.offset);
|
||||
}
|
||||
if (parameters.offsets) {
|
||||
addCapability(CapabilityImageGatherExtended);
|
||||
mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask);
|
||||
texArgs[numArgs++] = parameters.offsets;
|
||||
texArgs.push_back(parameters.offsets);
|
||||
}
|
||||
#ifndef GLSLANG_WEB
|
||||
if (parameters.sample) {
|
||||
mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask);
|
||||
texArgs[numArgs++] = parameters.sample;
|
||||
texArgs.push_back(parameters.sample);
|
||||
}
|
||||
if (parameters.lodClamp) {
|
||||
// capability if this bit is used
|
||||
addCapability(CapabilityMinLod);
|
||||
|
||||
mask = (ImageOperandsMask)(mask | ImageOperandsMinLodMask);
|
||||
texArgs[numArgs++] = parameters.lodClamp;
|
||||
texArgs.push_back(parameters.lodClamp);
|
||||
}
|
||||
if (parameters.nonprivate) {
|
||||
mask = mask | ImageOperandsNonPrivateTexelKHRMask;
|
||||
@ -2840,10 +2848,9 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||
}
|
||||
#endif
|
||||
mask = mask | signExtensionMask;
|
||||
if (mask == ImageOperandsMaskNone)
|
||||
--numArgs; // undo speculative reservation for the mask argument
|
||||
else
|
||||
texArgs[optArgNum] = mask;
|
||||
// insert the operand for the mask, if any bits were set.
|
||||
if (mask != ImageOperandsMaskNone)
|
||||
texArgs.insert(texArgs.begin() + optArgNum, mask);
|
||||
|
||||
//
|
||||
// Set up the instruction
|
||||
@ -2947,11 +2954,11 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||
|
||||
// Build the SPIR-V instruction
|
||||
Instruction* textureInst = new Instruction(getUniqueId(), resultType, opCode);
|
||||
for (int op = 0; op < optArgNum; ++op)
|
||||
for (size_t op = 0; op < optArgNum; ++op)
|
||||
textureInst->addIdOperand(texArgs[op]);
|
||||
if (optArgNum < numArgs)
|
||||
if (optArgNum < texArgs.size())
|
||||
textureInst->addImmediateOperand(texArgs[optArgNum]);
|
||||
for (int op = optArgNum + 1; op < numArgs; ++op)
|
||||
for (size_t op = optArgNum + 1; op < texArgs.size(); ++op)
|
||||
textureInst->addIdOperand(texArgs[op]);
|
||||
setPrecision(textureInst->getResultId(), precision);
|
||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(textureInst));
|
||||
|
26
3rdparty/glslang/StandAlone/StandAlone.cpp
vendored
26
3rdparty/glslang/StandAlone/StandAlone.cpp
vendored
@ -258,6 +258,17 @@ public:
|
||||
text.append("\n");
|
||||
}
|
||||
|
||||
void addText(std::string preambleText)
|
||||
{
|
||||
fixLine(preambleText);
|
||||
|
||||
Processes.push_back("preamble-text");
|
||||
Processes.back().append(preambleText);
|
||||
|
||||
text.append(preambleText);
|
||||
text.append("\n");
|
||||
}
|
||||
|
||||
protected:
|
||||
void fixLine(std::string& line)
|
||||
{
|
||||
@ -727,6 +738,13 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
|
||||
} else if (lowerword == "no-storage-format" || // synonyms
|
||||
lowerword == "nsf") {
|
||||
Options |= EOptionNoStorageFormat;
|
||||
} else if (lowerword == "preamble-text" ||
|
||||
lowerword == "p") {
|
||||
if (argc > 1)
|
||||
UserPreamble.addText(argv[1]);
|
||||
else
|
||||
Error("expects <text>", argv[0]);
|
||||
bumpArg();
|
||||
} else if (lowerword == "relaxed-errors") {
|
||||
Options |= EOptionRelaxedErrors;
|
||||
} else if (lowerword == "reflect-strict-array-suffix") {
|
||||
@ -926,6 +944,9 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
|
||||
else
|
||||
Error("unknown -O option");
|
||||
break;
|
||||
case 'P':
|
||||
UserPreamble.addText(getStringOperand("-P<text>"));
|
||||
break;
|
||||
case 'R':
|
||||
VulkanRulesRelaxed = true;
|
||||
break;
|
||||
@ -1832,7 +1853,7 @@ void CompileFile(const char* fileName, ShHandle compiler)
|
||||
SetMessageOptions(messages);
|
||||
|
||||
if (UserPreamble.isSet())
|
||||
Error("-D and -U options require -l (linking)\n");
|
||||
Error("-D, -U and -P options require -l (linking)\n");
|
||||
|
||||
for (int i = 0; i < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++i) {
|
||||
for (int j = 0; j < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++j) {
|
||||
@ -1902,6 +1923,9 @@ void usage()
|
||||
" is searched first, followed by left-to-right order of -I\n"
|
||||
" -Od disables optimization; may cause illegal SPIR-V for HLSL\n"
|
||||
" -Os optimizes SPIR-V to minimize size\n"
|
||||
" -P<text> | --preamble-text <text> | --P <text>\n"
|
||||
" inject custom preamble text, which is treated as if it\n"
|
||||
" appeared immediately after the version declaration (if any).\n"
|
||||
" -R use relaxed verification rules for generating Vulkan SPIR-V,\n"
|
||||
" allowing the use of default uniforms, atomic_uints, and\n"
|
||||
" gl_VertexID and gl_InstanceID keywords.\n"
|
||||
|
@ -1177,10 +1177,13 @@ void HlslParseContext::flatten(const TVariable& variable, bool linkage, bool arr
|
||||
if (type.isBuiltIn() && !type.isStruct())
|
||||
return;
|
||||
|
||||
|
||||
auto entry = flattenMap.insert(std::make_pair(variable.getUniqueId(),
|
||||
TFlattenData(type.getQualifier().layoutBinding,
|
||||
type.getQualifier().layoutLocation)));
|
||||
|
||||
if (type.isStruct() && type.getStruct()->size()==0)
|
||||
return;
|
||||
// if flattening arrayed io struct, array each member of dereferenced type
|
||||
if (arrayed) {
|
||||
const TType dereferencedType(type, 0);
|
||||
@ -7565,7 +7568,6 @@ const TFunction* HlslParseContext::findFunction(const TSourceLoc& loc, TFunction
|
||||
candidateList[0]->getBuiltInOp() == EOpMethodRestartStrip ||
|
||||
candidateList[0]->getBuiltInOp() == EOpMethodIncrementCounter ||
|
||||
candidateList[0]->getBuiltInOp() == EOpMethodDecrementCounter ||
|
||||
candidateList[0]->getBuiltInOp() == EOpMethodAppend ||
|
||||
candidateList[0]->getBuiltInOp() == EOpMethodConsume)) {
|
||||
return candidateList[0];
|
||||
}
|
||||
@ -9046,7 +9048,8 @@ void HlslParseContext::fixBlockUniformOffsets(const TQualifier& qualifier, TType
|
||||
// "The specified offset must be a multiple
|
||||
// of the base alignment of the type of the block member it qualifies, or a compile-time error results."
|
||||
if (! IsMultipleOfPow2(memberQualifier.layoutOffset, memberAlignment))
|
||||
error(memberLoc, "must be a multiple of the member's alignment", "offset", "");
|
||||
error(memberLoc, "must be a multiple of the member's alignment", "offset",
|
||||
"(layout offset = %d | member alignment = %d)", memberQualifier.layoutOffset, memberAlignment);
|
||||
|
||||
// "The offset qualifier forces the qualified member to start at or after the specified
|
||||
// integral-constant expression, which will be its byte offset from the beginning of the buffer.
|
||||
|
@ -4013,7 +4013,7 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
|
||||
switch (language) {
|
||||
case EShLangVertex:
|
||||
if (publicType.basicType == EbtStruct) {
|
||||
error(loc, "cannot be a structure or array", GetStorageQualifierString(qualifier.storage), "");
|
||||
error(loc, "cannot be a structure", GetStorageQualifierString(qualifier.storage), "");
|
||||
return;
|
||||
}
|
||||
if (publicType.arraySizes) {
|
||||
@ -4228,7 +4228,7 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
|
||||
if (dstSpirvDecorate.decorates.find(decorateString.first) != dstSpirvDecorate.decorates.end())
|
||||
error(loc, "too many SPIR-V decorate qualifiers", "spirv_decorate_string", "(decoration=%u)", decorateString.first);
|
||||
else
|
||||
dstSpirvDecorate.decorates.insert(decorateString);
|
||||
dstSpirvDecorate.decorateStrings.insert(decorateString);
|
||||
}
|
||||
} else {
|
||||
dst.spirvDecorate = src.spirvDecorate;
|
||||
@ -9029,7 +9029,8 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ
|
||||
// "The specified offset must be a multiple
|
||||
// of the base alignment of the type of the block member it qualifies, or a compile-time error results."
|
||||
if (! IsMultipleOfPow2(memberQualifier.layoutOffset, memberAlignment))
|
||||
error(memberLoc, "must be a multiple of the member's alignment", "offset", "");
|
||||
error(memberLoc, "must be a multiple of the member's alignment", "offset",
|
||||
"(layout offset = %d | member alignment = %d)", memberQualifier.layoutOffset, memberAlignment);
|
||||
|
||||
// GLSL: "It is a compile-time error to specify an offset that is smaller than the offset of the previous
|
||||
// member in the block or that lies within the previous member of the block"
|
||||
|
@ -168,7 +168,7 @@ void TQualifier::setSpirvDecorateId(int decoration, const TIntermAggregate* args
|
||||
TVector<const TIntermTyped*> extraOperands;
|
||||
for (auto arg : args->getSequence()) {
|
||||
auto extraOperand = arg->getAsTyped();
|
||||
assert(extraOperand != nullptr && extraOperand->getQualifier().isConstant());
|
||||
assert(extraOperand != nullptr);
|
||||
extraOperands.push_back(extraOperand);
|
||||
}
|
||||
spirvDecorate->decorateIds[decoration] = extraOperands;
|
||||
@ -202,30 +202,29 @@ TString TQualifier::getSpirvDecorateQualifierString() const
|
||||
const auto appendStr = [&](const char* s) { qualifierString.append(s); };
|
||||
|
||||
const auto appendDecorate = [&](const TIntermTyped* constant) {
|
||||
auto& constArray = constant->getAsConstantUnion() != nullptr ? constant->getAsConstantUnion()->getConstArray()
|
||||
: constant->getAsSymbolNode()->getConstArray();
|
||||
if (constant->getBasicType() == EbtFloat) {
|
||||
float value = static_cast<float>(constArray[0].getDConst());
|
||||
appendFloat(value);
|
||||
if (constant->getAsConstantUnion()) {
|
||||
auto& constArray = constant->getAsConstantUnion()->getConstArray();
|
||||
if (constant->getBasicType() == EbtFloat) {
|
||||
float value = static_cast<float>(constArray[0].getDConst());
|
||||
appendFloat(value);
|
||||
} else if (constant->getBasicType() == EbtInt) {
|
||||
int value = constArray[0].getIConst();
|
||||
appendInt(value);
|
||||
} else if (constant->getBasicType() == EbtUint) {
|
||||
unsigned value = constArray[0].getUConst();
|
||||
appendUint(value);
|
||||
} else if (constant->getBasicType() == EbtBool) {
|
||||
bool value = constArray[0].getBConst();
|
||||
appendBool(value);
|
||||
} else if (constant->getBasicType() == EbtString) {
|
||||
const TString* value = constArray[0].getSConst();
|
||||
appendStr(value->c_str());
|
||||
} else
|
||||
assert(0);
|
||||
} else {
|
||||
assert(constant->getAsSymbolNode());
|
||||
appendStr(constant->getAsSymbolNode()->getName().c_str());
|
||||
}
|
||||
else if (constant->getBasicType() == EbtInt) {
|
||||
int value = constArray[0].getIConst();
|
||||
appendInt(value);
|
||||
}
|
||||
else if (constant->getBasicType() == EbtUint) {
|
||||
unsigned value = constArray[0].getUConst();
|
||||
appendUint(value);
|
||||
}
|
||||
else if (constant->getBasicType() == EbtBool) {
|
||||
bool value = constArray[0].getBConst();
|
||||
appendBool(value);
|
||||
}
|
||||
else if (constant->getBasicType() == EbtString) {
|
||||
const TString* value = constArray[0].getSConst();
|
||||
appendStr(value->c_str());
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
};
|
||||
|
||||
for (auto& decorate : spirvDecorate->decorates) {
|
||||
|
@ -378,7 +378,7 @@ GLSLANG_WEB_EXCLUDE_ON
|
||||
%type <interm.type> spirv_storage_class_qualifier
|
||||
%type <interm.type> spirv_decorate_qualifier
|
||||
%type <interm.intermNode> spirv_decorate_parameter_list spirv_decorate_parameter
|
||||
%type <interm.intermNode> spirv_decorate_id_parameter_list
|
||||
%type <interm.intermNode> spirv_decorate_id_parameter_list spirv_decorate_id_parameter
|
||||
%type <interm.intermNode> spirv_decorate_string_parameter_list
|
||||
%type <interm.type> spirv_type_specifier
|
||||
%type <interm.spirvTypeParams> spirv_type_parameter_list spirv_type_parameter
|
||||
@ -4347,23 +4347,33 @@ spirv_decorate_parameter
|
||||
}
|
||||
|
||||
spirv_decorate_id_parameter_list
|
||||
: constant_expression {
|
||||
if ($1->getBasicType() != EbtFloat &&
|
||||
$1->getBasicType() != EbtInt &&
|
||||
$1->getBasicType() != EbtUint &&
|
||||
$1->getBasicType() != EbtBool)
|
||||
parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), "");
|
||||
: spirv_decorate_id_parameter {
|
||||
$$ = parseContext.intermediate.makeAggregate($1);
|
||||
}
|
||||
| spirv_decorate_id_parameter_list COMMA constant_expression {
|
||||
if ($3->getBasicType() != EbtFloat &&
|
||||
$3->getBasicType() != EbtInt &&
|
||||
$3->getBasicType() != EbtUint &&
|
||||
$3->getBasicType() != EbtBool)
|
||||
parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), "");
|
||||
| spirv_decorate_id_parameter_list COMMA spirv_decorate_id_parameter {
|
||||
$$ = parseContext.intermediate.growAggregate($1, $3);
|
||||
}
|
||||
|
||||
spirv_decorate_id_parameter
|
||||
: variable_identifier {
|
||||
if ($1->getAsConstantUnion() || $1->getAsSymbolNode())
|
||||
$$ = $1;
|
||||
else
|
||||
parseContext.error($1->getLoc(), "only allow constants or variables which are not elements of a composite", "", "");
|
||||
}
|
||||
| FLOATCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true);
|
||||
}
|
||||
| INTCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true);
|
||||
}
|
||||
| UINTCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true);
|
||||
}
|
||||
| BOOLCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
|
||||
}
|
||||
|
||||
spirv_decorate_string_parameter_list
|
||||
: STRING_LITERAL {
|
||||
$$ = parseContext.intermediate.makeAggregate(
|
||||
|
@ -378,7 +378,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
|
||||
%type <interm.type> spirv_storage_class_qualifier
|
||||
%type <interm.type> spirv_decorate_qualifier
|
||||
%type <interm.intermNode> spirv_decorate_parameter_list spirv_decorate_parameter
|
||||
%type <interm.intermNode> spirv_decorate_id_parameter_list
|
||||
%type <interm.intermNode> spirv_decorate_id_parameter_list spirv_decorate_id_parameter
|
||||
%type <interm.intermNode> spirv_decorate_string_parameter_list
|
||||
%type <interm.type> spirv_type_specifier
|
||||
%type <interm.spirvTypeParams> spirv_type_parameter_list spirv_type_parameter
|
||||
@ -4347,23 +4347,33 @@ spirv_decorate_parameter
|
||||
}
|
||||
|
||||
spirv_decorate_id_parameter_list
|
||||
: constant_expression {
|
||||
if ($1->getBasicType() != EbtFloat &&
|
||||
$1->getBasicType() != EbtInt &&
|
||||
$1->getBasicType() != EbtUint &&
|
||||
$1->getBasicType() != EbtBool)
|
||||
parseContext.error($1->getLoc(), "this type not allowed", $1->getType().getBasicString(), "");
|
||||
: spirv_decorate_id_parameter {
|
||||
$$ = parseContext.intermediate.makeAggregate($1);
|
||||
}
|
||||
| spirv_decorate_id_parameter_list COMMA constant_expression {
|
||||
if ($3->getBasicType() != EbtFloat &&
|
||||
$3->getBasicType() != EbtInt &&
|
||||
$3->getBasicType() != EbtUint &&
|
||||
$3->getBasicType() != EbtBool)
|
||||
parseContext.error($3->getLoc(), "this type not allowed", $3->getType().getBasicString(), "");
|
||||
| spirv_decorate_id_parameter_list COMMA spirv_decorate_id_parameter {
|
||||
$$ = parseContext.intermediate.growAggregate($1, $3);
|
||||
}
|
||||
|
||||
spirv_decorate_id_parameter
|
||||
: variable_identifier {
|
||||
if ($1->getAsConstantUnion() || $1->getAsSymbolNode())
|
||||
$$ = $1;
|
||||
else
|
||||
parseContext.error($1->getLoc(), "only allow constants or variables which are not elements of a composite", "", "");
|
||||
}
|
||||
| FLOATCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true);
|
||||
}
|
||||
| INTCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.i, $1.loc, true);
|
||||
}
|
||||
| UINTCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true);
|
||||
}
|
||||
| BOOLCONSTANT {
|
||||
$$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
|
||||
}
|
||||
|
||||
spirv_decorate_string_parameter_list
|
||||
: STRING_LITERAL {
|
||||
$$ = parseContext.intermediate.makeAggregate(
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user