WIP: HLSL: support global const initializers from non-constant rvalues
Semantic test left over from other source languages is removed, since this is permitted by HLSL.
Also, to support the functionality, a targeted test is performed for this case and it is
turned into a EvqGlobal qualifier to create an AST initialization segment when needed.
Constness is now propagated up aggregate chains during initializer construction. This
handles hierarchical cases such as the distinction between:
static const float2 a[2] = { { 1, 2 }, { 3, 4} };
vs
static const float2 a[2] = { { 1, 2 }, { cbuffer_member, 4} };
The first of which can use a first class constant initalization, and the second cannot.
This commit is contained in:
@@ -7165,6 +7165,21 @@ TIntermNode* HlslParseContext::declareVariable(const TSourceLoc& loc, const TStr
|
||||
if (voidErrorCheck(loc, identifier, type.getBasicType()))
|
||||
return nullptr;
|
||||
|
||||
// Global consts with initializers that are non-const act like EvqGlobal in HLSL.
|
||||
// This test is implicitly recursive, because initializers propagate constness
|
||||
// up the aggregate node tree during creation. E.g, for:
|
||||
// { { 1, 2 }, { 3, 4 } }
|
||||
// the initializer list is marked EvqConst at the top node, and remains so here. However:
|
||||
// { 1, { myvar, 2 }, 3 }
|
||||
// is not a const intializer, and still becomes EvqGlobal here.
|
||||
|
||||
const bool nonConstInitializer = (initializer != nullptr && initializer->getQualifier().storage != EvqConst);
|
||||
|
||||
if (type.getQualifier().storage == EvqConst && symbolTable.atGlobalLevel() && nonConstInitializer) {
|
||||
// Force to global
|
||||
type.getQualifier().storage = EvqGlobal;
|
||||
}
|
||||
|
||||
// make const and initialization consistent
|
||||
fixConstInit(loc, identifier, type, initializer);
|
||||
|
||||
@@ -7345,11 +7360,6 @@ TIntermNode* HlslParseContext::executeInitializer(const TSourceLoc& loc, TInterm
|
||||
variable->getWritableType().getQualifier().storage = EvqTemporary;
|
||||
return nullptr;
|
||||
}
|
||||
if (qualifier == EvqConst && symbolTable.atGlobalLevel() && initializer->getType().getQualifier().storage != EvqConst) {
|
||||
error(loc, "global const initializers must be constant", "=", "'%s'", variable->getType().getCompleteString().c_str());
|
||||
variable->getWritableType().getQualifier().storage = EvqTemporary;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Const variables require a constant initializer
|
||||
if (qualifier == EvqConst) {
|
||||
|
||||
Reference in New Issue
Block a user