Commit aa0298bf by John Kessenich

Merge pull request #220 from Qining/fix-built-in-spec-constants

Handle built-in constants redeclared with a specialization constant id.
parents 1c7e7076 4f4bb81c
...@@ -3744,6 +3744,7 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n ...@@ -3744,6 +3744,7 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n
{ {
assert(node.getQualifier().isConstant()); assert(node.getQualifier().isConstant());
// Handle front-end constants first (non-specialization constants).
if (! node.getQualifier().specConstant) { if (! node.getQualifier().specConstant) {
// hand off to the non-spec-constant path // hand off to the non-spec-constant path
assert(node.getAsConstantUnion() != nullptr || node.getAsSymbolNode() != nullptr); assert(node.getAsConstantUnion() != nullptr || node.getAsSymbolNode() != nullptr);
...@@ -3754,12 +3755,6 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n ...@@ -3754,12 +3755,6 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n
// We now know we have a specialization constant to build // We now know we have a specialization constant to build
if (node.getAsSymbolNode() && node.getQualifier().hasSpecConstantId()) {
// this is a direct literal assigned to a layout(constant_id=) declaration
int nextConst = 0;
return createSpvConstantFromConstUnionArray(node.getType(), node.getAsConstantUnion() ? node.getAsConstantUnion()->getConstArray() : node.getAsSymbolNode()->getConstArray(),
nextConst, true);
} else {
// gl_WorkgroupSize is a special case until the front-end handles hierarchical specialization constants, // gl_WorkgroupSize is a special case until the front-end handles hierarchical specialization constants,
// even then, it's specialization ids are handled by special case syntax in GLSL: layout(local_size_x = ... // even then, it's specialization ids are handled by special case syntax in GLSL: layout(local_size_x = ...
if (node.getType().getQualifier().builtIn == glslang::EbvWorkGroupSize) { if (node.getType().getQualifier().builtIn == glslang::EbvWorkGroupSize) {
...@@ -3771,14 +3766,24 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n ...@@ -3771,14 +3766,24 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n
addDecoration(dimConstId.back(), spv::DecorationSpecId, glslangIntermediate->getLocalSizeSpecId(dim)); addDecoration(dimConstId.back(), spv::DecorationSpecId, glslangIntermediate->getLocalSizeSpecId(dim));
} }
return builder.makeCompositeConstant(builder.makeVectorType(builder.makeUintType(32), 3), dimConstId, true); return builder.makeCompositeConstant(builder.makeVectorType(builder.makeUintType(32), 3), dimConstId, true);
} else if (auto* sn = node.getAsSymbolNode()){ }
return createSpvConstantFromConstSubTree(sn->getConstSubtree());
} else { // An AST node labelled as specialization constant should be a symbol node.
// Its initializer should either be a sub tree with constant nodes, or a constant union array.
if (auto* sn = node.getAsSymbolNode()) {
if (auto* sub_tree = sn->getConstSubtree()) {
return createSpvConstantFromConstSubTree(sub_tree);
} else if (auto* const_union_array = &sn->getConstArray()){
int nextConst = 0;
return createSpvConstantFromConstUnionArray(sn->getType(), *const_union_array, nextConst, true);
}
}
// Neither a front-end constant node, nor a specialization constant node with constant union array or
// constant sub tree as initializer.
spv::MissingFunctionality("Neither a front-end constant nor a spec constant."); spv::MissingFunctionality("Neither a front-end constant nor a spec constant.");
exit(1); exit(1);
return spv::NoResult; return spv::NoResult;
}
}
} }
// Use 'consts' as the flattened glslang source of scalar constants to recursively // Use 'consts' as the flattened glslang source of scalar constants to recursively
......
...@@ -8,6 +8,8 @@ layout(constant_id = 18) const float spFloat = 3.14; ...@@ -8,6 +8,8 @@ layout(constant_id = 18) const float spFloat = 3.14;
layout(constant_id = 19) const double spDouble = 3.1415926535897932384626433832795; layout(constant_id = 19) const double spDouble = 3.1415926535897932384626433832795;
layout(constant_id = 22) const uint scale = 2; layout(constant_id = 22) const uint scale = 2;
layout(constant_id = 24) gl_MaxImageUnits;
out vec4 color; out vec4 color;
out int size; out int size;
...@@ -41,3 +43,9 @@ void foo(vec4 p[arraySize]) ...@@ -41,3 +43,9 @@ void foo(vec4 p[arraySize])
color *= dupScale; color *= dupScale;
color += float(spDupDouble / spDupFloat); color += float(spDupDouble / spDupFloat);
} }
int builtin_spec_constant()
{
int result = gl_MaxImageUnits;
return result;
}
...@@ -5714,6 +5714,10 @@ void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qua ...@@ -5714,6 +5714,10 @@ void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qua
error(loc, "cannot change qualification after use", "invariant", ""); error(loc, "cannot change qualification after use", "invariant", "");
symbol->getWritableType().getQualifier().invariant = true; symbol->getWritableType().getQualifier().invariant = true;
invariantCheck(loc, symbol->getType().getQualifier()); invariantCheck(loc, symbol->getType().getQualifier());
} else if (qualifier.specConstant) {
symbol->getWritableType().getQualifier().makeSpecConstant();
if (qualifier.hasSpecConstantId())
symbol->getWritableType().getQualifier().layoutSpecConstantId = qualifier.layoutSpecConstantId;
} else } else
warn(loc, "unknown requalification", "", ""); warn(loc, "unknown requalification", "", "");
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment