From df98cc26d583fb443bf82f8eb25f3da2e7c50022 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Thu, 29 Sep 2016 23:58:30 -0600 Subject: [PATCH] Add amend ability for anonymous blocks, so they can grow between function bodies. --- Test/baseResults/hlsl.amend.frag.out | 207 ++++++++++++++++++ Test/hlsl.amend.frag | 28 +++ glslang/Include/revision.h | 2 +- .../MachineIndependent/ParseContextBase.cpp | 29 ++- glslang/MachineIndependent/ParseHelper.h | 3 +- glslang/MachineIndependent/SymbolTable.h | 62 ++++-- gtests/Hlsl.FromFile.cpp | 1 + 7 files changed, 298 insertions(+), 34 deletions(-) create mode 100755 Test/baseResults/hlsl.amend.frag.out create mode 100755 Test/hlsl.amend.frag diff --git a/Test/baseResults/hlsl.amend.frag.out b/Test/baseResults/hlsl.amend.frag.out new file mode 100755 index 000000000..1be59064e --- /dev/null +++ b/Test/baseResults/hlsl.amend.frag.out @@ -0,0 +1,207 @@ +hlsl.amend.frag +Shader version: 450 +gl_FragCoord origin is upper left +0:? Sequence +0:5 Function Definition: f1( (temp void) +0:5 Function Parameters: +0:? Sequence +0:6 vector-scale (temp 4-component vector of float) +0:6 a: direct index for structure (layout(offset=0 ) uniform 4-component vector of float) +0:6 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of float a, layout(offset=16 ) uniform float b, layout(offset=32 ) uniform 3-component vector of float c, layout(offset=44 ) uniform int d, uniform int e}) +0:6 Constant: +0:6 0 (const uint) +0:6 b: direct index for structure (layout(offset=16 ) uniform float) +0:6 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of float a, layout(offset=16 ) uniform float b, layout(offset=32 ) uniform 3-component vector of float c, layout(offset=44 ) uniform int d, uniform int e}) +0:6 Constant: +0:6 1 (const uint) +0:12 Function Definition: f2( (temp void) +0:12 Function Parameters: +0:? Sequence +0:13 add (temp float) +0:13 add (temp float) +0:13 direct index (temp float) +0:13 a: direct index for structure (layout(offset=0 ) uniform 4-component vector of float) +0:13 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of float a, layout(offset=16 ) uniform float b, layout(offset=32 ) uniform 3-component vector of float c, layout(offset=44 ) uniform int d, uniform int e}) +0:13 Constant: +0:13 0 (const uint) +0:13 Constant: +0:13 0 (const int) +0:13 b: direct index for structure (layout(offset=16 ) uniform float) +0:13 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of float a, layout(offset=16 ) uniform float b, layout(offset=32 ) uniform 3-component vector of float c, layout(offset=44 ) uniform int d, uniform int e}) +0:13 Constant: +0:13 1 (const uint) +0:13 direct index (temp float) +0:13 c: direct index for structure (layout(offset=32 ) uniform 3-component vector of float) +0:13 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of float a, layout(offset=16 ) uniform float b, layout(offset=32 ) uniform 3-component vector of float c, layout(offset=44 ) uniform int d, uniform int e}) +0:13 Constant: +0:13 2 (const uint) +0:13 Constant: +0:13 0 (const int) +0:17 Function Definition: f3( (temp void) +0:17 Function Parameters: +0:? Sequence +0:18 c: direct index for structure (layout(offset=32 ) uniform 3-component vector of float) +0:18 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of float a, layout(offset=16 ) uniform float b, layout(offset=32 ) uniform 3-component vector of float c, layout(offset=44 ) uniform int d, uniform int e}) +0:18 Constant: +0:18 2 (const uint) +0:24 Function Definition: f4( (temp void) +0:24 Function Parameters: +0:? Sequence +0:25 vector-scale (temp 4-component vector of float) +0:25 Convert int to float (temp float) +0:25 d: direct index for structure (layout(offset=44 ) uniform int) +0:25 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of float a, layout(offset=16 ) uniform float b, layout(offset=32 ) uniform 3-component vector of float c, layout(offset=44 ) uniform int d, uniform int e}) +0:25 Constant: +0:25 3 (const uint) +0:25 a: direct index for structure (layout(offset=0 ) uniform 4-component vector of float) +0:25 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of float a, layout(offset=16 ) uniform float b, layout(offset=32 ) uniform 3-component vector of float c, layout(offset=44 ) uniform int d, uniform int e}) +0:25 Constant: +0:25 0 (const uint) +0:? Linker Objects +0:? 'anon@0' (uniform block{layout(offset=0 ) uniform 4-component vector of float a, layout(offset=16 ) uniform float b, layout(offset=32 ) uniform 3-component vector of float c, layout(offset=44 ) uniform int d, uniform int e}) + + +Linked fragment stage: + + +Shader version: 450 +gl_FragCoord origin is upper left +0:? Sequence +0:5 Function Definition: f1( (temp void) +0:5 Function Parameters: +0:? Sequence +0:6 vector-scale (temp 4-component vector of float) +0:6 a: direct index for structure (layout(offset=0 ) uniform 4-component vector of float) +0:6 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of float a, layout(offset=16 ) uniform float b, layout(offset=32 ) uniform 3-component vector of float c, layout(offset=44 ) uniform int d, uniform int e}) +0:6 Constant: +0:6 0 (const uint) +0:6 b: direct index for structure (layout(offset=16 ) uniform float) +0:6 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of float a, layout(offset=16 ) uniform float b, layout(offset=32 ) uniform 3-component vector of float c, layout(offset=44 ) uniform int d, uniform int e}) +0:6 Constant: +0:6 1 (const uint) +0:12 Function Definition: f2( (temp void) +0:12 Function Parameters: +0:? Sequence +0:13 add (temp float) +0:13 add (temp float) +0:13 direct index (temp float) +0:13 a: direct index for structure (layout(offset=0 ) uniform 4-component vector of float) +0:13 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of float a, layout(offset=16 ) uniform float b, layout(offset=32 ) uniform 3-component vector of float c, layout(offset=44 ) uniform int d, uniform int e}) +0:13 Constant: +0:13 0 (const uint) +0:13 Constant: +0:13 0 (const int) +0:13 b: direct index for structure (layout(offset=16 ) uniform float) +0:13 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of float a, layout(offset=16 ) uniform float b, layout(offset=32 ) uniform 3-component vector of float c, layout(offset=44 ) uniform int d, uniform int e}) +0:13 Constant: +0:13 1 (const uint) +0:13 direct index (temp float) +0:13 c: direct index for structure (layout(offset=32 ) uniform 3-component vector of float) +0:13 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of float a, layout(offset=16 ) uniform float b, layout(offset=32 ) uniform 3-component vector of float c, layout(offset=44 ) uniform int d, uniform int e}) +0:13 Constant: +0:13 2 (const uint) +0:13 Constant: +0:13 0 (const int) +0:17 Function Definition: f3( (temp void) +0:17 Function Parameters: +0:? Sequence +0:18 c: direct index for structure (layout(offset=32 ) uniform 3-component vector of float) +0:18 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of float a, layout(offset=16 ) uniform float b, layout(offset=32 ) uniform 3-component vector of float c, layout(offset=44 ) uniform int d, uniform int e}) +0:18 Constant: +0:18 2 (const uint) +0:24 Function Definition: f4( (temp void) +0:24 Function Parameters: +0:? Sequence +0:25 vector-scale (temp 4-component vector of float) +0:25 Convert int to float (temp float) +0:25 d: direct index for structure (layout(offset=44 ) uniform int) +0:25 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of float a, layout(offset=16 ) uniform float b, layout(offset=32 ) uniform 3-component vector of float c, layout(offset=44 ) uniform int d, uniform int e}) +0:25 Constant: +0:25 3 (const uint) +0:25 a: direct index for structure (layout(offset=0 ) uniform 4-component vector of float) +0:25 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 4-component vector of float a, layout(offset=16 ) uniform float b, layout(offset=32 ) uniform 3-component vector of float c, layout(offset=44 ) uniform int d, uniform int e}) +0:25 Constant: +0:25 0 (const uint) +0:? Linker Objects +0:? 'anon@0' (uniform block{layout(offset=0 ) uniform 4-component vector of float a, layout(offset=16 ) uniform float b, layout(offset=32 ) uniform 3-component vector of float c, layout(offset=44 ) uniform int d, uniform int e}) + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 47 + + Capability Shader + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Fragment 4 "f1" + ExecutionMode 4 OriginUpperLeft + Name 4 "f1" + Name 6 "f2(" + Name 8 "f3(" + Name 10 "f4(" + Name 16 "$Global" + MemberName 16($Global) 0 "a" + MemberName 16($Global) 1 "b" + MemberName 16($Global) 2 "c" + MemberName 16($Global) 3 "d" + MemberName 16($Global) 4 "e" + Name 18 "" + MemberDecorate 16($Global) 0 Offset 0 + MemberDecorate 16($Global) 1 Offset 16 + MemberDecorate 16($Global) 2 Offset 32 + MemberDecorate 16($Global) 3 Offset 44 + MemberDecorate 16($Global) 4 Offset 48 + Decorate 16($Global) Block + Decorate 18 DescriptorSet 0 + 2: TypeVoid + 3: TypeFunction 2 + 12: TypeFloat 32 + 13: TypeVector 12(float) 4 + 14: TypeVector 12(float) 3 + 15: TypeInt 32 1 + 16($Global): TypeStruct 13(fvec4) 12(float) 14(fvec3) 15(int) 15(int) + 17: TypePointer Uniform 16($Global) + 18: 17(ptr) Variable Uniform + 19: 15(int) Constant 0 + 20: TypePointer Uniform 13(fvec4) + 23: 15(int) Constant 1 + 24: TypePointer Uniform 12(float) + 28: TypeInt 32 0 + 29: 28(int) Constant 0 + 35: 15(int) Constant 2 + 39: 15(int) Constant 3 + 40: TypePointer Uniform 15(int) + 4(f1): 2 Function None 3 + 5: Label + 21: 20(ptr) AccessChain 18 19 + 22: 13(fvec4) Load 21 + 25: 24(ptr) AccessChain 18 23 + 26: 12(float) Load 25 + 27: 13(fvec4) VectorTimesScalar 22 26 + Return + FunctionEnd + 6(f2(): 2 Function None 3 + 7: Label + 30: 24(ptr) AccessChain 18 19 29 + 31: 12(float) Load 30 + 32: 24(ptr) AccessChain 18 23 + 33: 12(float) Load 32 + 34: 12(float) FAdd 31 33 + 36: 24(ptr) AccessChain 18 35 29 + 37: 12(float) Load 36 + 38: 12(float) FAdd 34 37 + Return + FunctionEnd + 8(f3(): 2 Function None 3 + 9: Label + Return + FunctionEnd + 10(f4(): 2 Function None 3 + 11: Label + 41: 40(ptr) AccessChain 18 39 + 42: 15(int) Load 41 + 43: 12(float) ConvertSToF 42 + 44: 20(ptr) AccessChain 18 19 + 45: 13(fvec4) Load 44 + 46: 13(fvec4) VectorTimesScalar 45 43 + Return + FunctionEnd diff --git a/Test/hlsl.amend.frag b/Test/hlsl.amend.frag new file mode 100755 index 000000000..c9fd69bd3 --- /dev/null +++ b/Test/hlsl.amend.frag @@ -0,0 +1,28 @@ +float4 a; +float b; + +void f1() +{ + a * b; +} + +float3 c; + +void f2() +{ + a.x + b + c.x; +} + +void f3() +{ + c; +} + +int d; + +void f4() +{ + d * a; +} + +int e; \ No newline at end of file diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h index 240025501..2d79b4249 100644 --- a/glslang/Include/revision.h +++ b/glslang/Include/revision.h @@ -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.1527" +#define GLSLANG_REVISION "Overload400-PrecQual.1528" #define GLSLANG_DATE "29-Sep-2016" diff --git a/glslang/MachineIndependent/ParseContextBase.cpp b/glslang/MachineIndependent/ParseContextBase.cpp index 54715ce18..a8e83d014 100644 --- a/glslang/MachineIndependent/ParseContextBase.cpp +++ b/glslang/MachineIndependent/ParseContextBase.cpp @@ -196,7 +196,7 @@ void TParseContextBase::growGlobalUniformBlock(TSourceLoc& loc, TType& memberTyp TType blockType(new TTypeList, blockName, blockQualifier); TString* instanceName = NewPoolTString(""); globalUniformBlock = new TVariable(instanceName, blockType, true); - globalUniformBlockAdded = false; + firstNewMember = 0; } // add the requested member as a member to the block @@ -205,7 +205,6 @@ void TParseContextBase::growGlobalUniformBlock(TSourceLoc& loc, TType& memberTyp type->setFieldName(memberName); TTypeLoc typeLoc = {type, loc}; globalUniformBlock->getType().getWritableStruct()->push_back(typeLoc); - globalUniformBlockChanged = true; } // @@ -218,17 +217,25 @@ bool TParseContextBase::insertGlobalUniformBlock() if (globalUniformBlock == nullptr) return true; - if (globalUniformBlockAdded) - return ! globalUniformBlockChanged; - - globalUniformBlockChanged = false; - globalUniformBlockAdded = symbolTable.insert(*globalUniformBlock); - if (globalUniformBlockAdded) { - intermediate.addSymbolLinkageNode(linkage, *globalUniformBlock); - finalizeGlobalUniformBlockLayout(*globalUniformBlock); + int numMembers = globalUniformBlock->getType().getStruct()->size(); + bool inserted; + if (firstNewMember == 0) { + // This is the first request; we need a normal symbol table insert + inserted = symbolTable.insert(*globalUniformBlock); + if (inserted) + intermediate.addSymbolLinkageNode(linkage, *globalUniformBlock); + } else if (firstNewMember <= numMembers) { + // This is a follow-on request; we need to amend the first insert + inserted = symbolTable.amend(*globalUniformBlock, firstNewMember); } - return globalUniformBlockAdded; + if (inserted) { + finalizeGlobalUniformBlockLayout(*globalUniformBlock); + firstNewMember = numMembers; + } + + return inserted; + } } // end namespace glslang diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index b007ebbb1..e377501de 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -158,8 +158,7 @@ protected: // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL) TVariable* globalUniformBlock; // the actual block, inserted into the symbol table - bool globalUniformBlockAdded; // true once inserted into the symbol table - bool globalUniformBlockChanged; // true if members have changed + 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 void finalizeGlobalUniformBlockLayout(TVariable&) { } diff --git a/glslang/MachineIndependent/SymbolTable.h b/glslang/MachineIndependent/SymbolTable.h index 97c3d6b51..aeec34fc0 100644 --- a/glslang/MachineIndependent/SymbolTable.h +++ b/glslang/MachineIndependent/SymbolTable.h @@ -147,7 +147,8 @@ public: TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), userType(uT), - constSubtree(nullptr) { type.shallowCopy(t); } + constSubtree(nullptr), + anonId(-1) { type.shallowCopy(t); } virtual TVariable* clone() const; virtual ~TVariable() { } @@ -161,6 +162,8 @@ public: virtual void setConstArray(const TConstUnionArray& array) { constArray = array; } virtual void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; } virtual TIntermTyped* getConstSubtree() const { return constSubtree; } + virtual void setAnonId(int i) { anonId = i; } + virtual int getAnonId() const { return anonId; } virtual void dump(TInfoSink &infoSink) const; @@ -178,6 +181,7 @@ protected: // constant, or neither, but never both. TConstUnionArray constArray; // for compile-time constant value TIntermTyped* constSubtree; // for specialization constant computation + int anonId; // the ID used for anonymous blocks: TODO: see if uniqueId could serve a dual purpose }; // @@ -305,27 +309,16 @@ public: // // returning true means symbol was added to the table with no semantic errors // - tInsertResult result; const TString& name = symbol.getName(); if (name == "") { + symbol.getAsVariable()->setAnonId(anonId++); // An empty name means an anonymous container, exposing its members to the external scope. // Give it a name and insert its members in the symbol table, pointing to the container. char buf[20]; - snprintf(buf, 20, "%s%d", AnonymousPrefix, anonId); + snprintf(buf, 20, "%s%d", AnonymousPrefix, symbol.getAsVariable()->getAnonId()); symbol.changeName(NewPoolTString(buf)); - bool isOkay = true; - const TTypeList& types = *symbol.getAsVariable()->getType().getStruct(); - for (unsigned int m = 0; m < types.size(); ++m) { - TAnonMember* member = new TAnonMember(&types[m].type->getFieldName(), m, *symbol.getAsVariable(), anonId); - result = level.insert(tLevelPair(member->getMangledName(), member)); - if (! result.second) - isOkay = false; - } - - ++anonId; - - return isOkay; + return insertAnonymousMembers(symbol, 0); } else { // Check for redefinition errors: // - STL itself will tell us if there is a direct name collision, with name mangling, at this level @@ -340,14 +333,35 @@ public: level.insert(tLevelPair(insertName, &symbol)); return true; - } else { - result = level.insert(tLevelPair(insertName, &symbol)); - - return result.second; - } + } else + return level.insert(tLevelPair(insertName, &symbol)).second; } } + // Add more members to an already inserted aggregate object + bool amend(TSymbol& symbol, int firstNewMember) + { + // See insert() for comments on basic explanation of insert. + // This operates similarly, but more simply. + // Only supporting amend of anonymous blocks so far. + if (IsAnonymous(symbol.getName())) + return insertAnonymousMembers(symbol, firstNewMember); + else + return false; + } + + bool insertAnonymousMembers(TSymbol& symbol, int firstMember) + { + const TTypeList& types = *symbol.getAsVariable()->getType().getStruct(); + for (unsigned int m = firstMember; m < types.size(); ++m) { + TAnonMember* member = new TAnonMember(&types[m].type->getFieldName(), m, *symbol.getAsVariable(), symbol.getAsVariable()->getAnonId()); + if (! level.insert(tLevelPair(member->getMangledName(), member)).second) + return false; + } + + return true; + } + TSymbol* find(const TString& name) const { tLevel::const_iterator it = level.find(name); @@ -546,6 +560,14 @@ public: return table[currentLevel()]->insert(symbol, separateNameSpaces); } + // Add more members to an already inserted aggregate object + bool amend(TSymbol& symbol, int firstNewMember) + { + // See insert() for comments on basic explanation of insert. + // This operates similarly, but more simply. + return table[currentLevel()]->amend(symbol, firstNewMember); + } + // // To allocate an internal temporary, which will need to be uniquely // identified by the consumer of the AST, but never need to diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index 2e191ba26..7467eb79f 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -80,6 +80,7 @@ TEST_P(HlslCompileAndFlattenTest, FromFile) INSTANTIATE_TEST_CASE_P( ToSpirv, HlslCompileTest, ::testing::ValuesIn(std::vector{ + {"hlsl.amend.frag", "f1"}, {"hlsl.array.frag", "PixelShaderFunction"}, {"hlsl.array.implicit-size.frag", "PixelShaderFunction"}, {"hlsl.assoc.frag", "PixelShaderFunction"},