HLSL: Allow use of $Global members in between function calls.
This allows global initializers to use $Global members.
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
// For the version, it uses the latest git tag followed by the number of commits.
|
||||
// For the date, it uses the current date (when then script is run).
|
||||
|
||||
#define GLSLANG_REVISION "Overload400-PrecQual.1930"
|
||||
#define GLSLANG_REVISION "Overload400-PrecQual.1931"
|
||||
#define GLSLANG_DATE "22-Mar-2017"
|
||||
|
||||
@@ -226,7 +226,8 @@ void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op,
|
||||
// Add 'symbol' to the list of deferred linkage symbols, which
|
||||
// are later processed in finish(), at which point the symbol
|
||||
// must still be valid.
|
||||
// It is okay if the symbol's type will be subsequently edited.
|
||||
// It is okay if the symbol's type will be subsequently edited;
|
||||
// the modifications will be tracked.
|
||||
void TParseContextBase::trackLinkage(TSymbol& symbol)
|
||||
{
|
||||
if (!parsingBuiltins)
|
||||
@@ -532,19 +533,18 @@ void TParseContextBase::parseSwizzleSelector(const TSourceLoc& loc, const TStrin
|
||||
//
|
||||
void TParseContextBase::growGlobalUniformBlock(TSourceLoc& loc, TType& memberType, TString& memberName, TTypeList* typeList)
|
||||
{
|
||||
// make the global block, if not yet made
|
||||
// Make the global block, if not yet made.
|
||||
if (globalUniformBlock == nullptr) {
|
||||
TString& blockName = *NewPoolTString(getGlobalUniformBlockName());
|
||||
TQualifier blockQualifier;
|
||||
blockQualifier.clear();
|
||||
blockQualifier.storage = EvqUniform;
|
||||
TType blockType(new TTypeList, blockName, blockQualifier);
|
||||
TString* instanceName = NewPoolTString("");
|
||||
globalUniformBlock = new TVariable(instanceName, blockType, true);
|
||||
TType blockType(new TTypeList, *NewPoolTString(getGlobalUniformBlockName()), blockQualifier);
|
||||
setUniformBlockDefaults(blockType);
|
||||
globalUniformBlock = new TVariable(NewPoolTString(""), blockType, true);
|
||||
firstNewMember = 0;
|
||||
}
|
||||
|
||||
// add the requested member as a member to the block
|
||||
// Add the requested member as a member to the global block.
|
||||
TType* type = new TType;
|
||||
type->shallowCopy(memberType);
|
||||
type->setFieldName(memberName);
|
||||
@@ -552,36 +552,20 @@ void TParseContextBase::growGlobalUniformBlock(TSourceLoc& loc, TType& memberTyp
|
||||
type->setStruct(typeList);
|
||||
TTypeLoc typeLoc = {type, loc};
|
||||
globalUniformBlock->getType().getWritableStruct()->push_back(typeLoc);
|
||||
}
|
||||
|
||||
//
|
||||
// Insert into the symbol table the global uniform block created in
|
||||
// growGlobalUniformBlock(). The variables added as members won't be
|
||||
// found unless this is done.
|
||||
//
|
||||
bool TParseContextBase::insertGlobalUniformBlock()
|
||||
{
|
||||
if (globalUniformBlock == nullptr)
|
||||
return true;
|
||||
|
||||
int numMembers = (int)globalUniformBlock->getType().getStruct()->size();
|
||||
bool inserted = false;
|
||||
// Insert into the symbol table.
|
||||
if (firstNewMember == 0) {
|
||||
// This is the first request; we need a normal symbol table insert
|
||||
inserted = symbolTable.insert(*globalUniformBlock);
|
||||
if (inserted)
|
||||
if (symbolTable.insert(*globalUniformBlock))
|
||||
trackLinkage(*globalUniformBlock);
|
||||
} else if (firstNewMember <= numMembers) {
|
||||
else
|
||||
error(loc, "failed to insert the global constant buffer", "uniform", "");
|
||||
} else {
|
||||
// This is a follow-on request; we need to amend the first insert
|
||||
inserted = symbolTable.amend(*globalUniformBlock, firstNewMember);
|
||||
symbolTable.amend(*globalUniformBlock, firstNewMember);
|
||||
}
|
||||
|
||||
if (inserted) {
|
||||
finalizeGlobalUniformBlockLayout(*globalUniformBlock);
|
||||
firstNewMember = numMembers;
|
||||
}
|
||||
|
||||
return inserted;
|
||||
++firstNewMember;
|
||||
}
|
||||
|
||||
void TParseContextBase::finish()
|
||||
|
||||
@@ -136,11 +136,7 @@ public:
|
||||
TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile
|
||||
|
||||
// Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
|
||||
// TODO: This could perhaps get its own object, but the current design doesn't work
|
||||
// yet when new uniform variables are declared between function definitions, so
|
||||
// this is pending getting a fully functional design.
|
||||
virtual void growGlobalUniformBlock(TSourceLoc&, TType&, TString& memberName, TTypeList* typeList = nullptr);
|
||||
virtual bool insertGlobalUniformBlock();
|
||||
|
||||
virtual bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
|
||||
virtual void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
|
||||
@@ -177,7 +173,8 @@ protected:
|
||||
TVariable* globalUniformBlock; // the actual block, inserted into the symbol table
|
||||
int firstNewMember; // the index of the first member not yet inserted into the symbol table
|
||||
// override this to set the language-specific name
|
||||
virtual const char* getGlobalUniformBlockName() { return ""; }
|
||||
virtual const char* getGlobalUniformBlockName() const { return ""; }
|
||||
virtual void setUniformBlockDefaults(TType& block) const { }
|
||||
virtual void finalizeGlobalUniformBlockLayout(TVariable&) { }
|
||||
virtual void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||
const char* szExtraInfoFormat, TPrefixType prefix,
|
||||
|
||||
Reference in New Issue
Block a user