From 93b400f26784ad6ce8714df957a5d1a665232488 Mon Sep 17 00:00:00 2001 From: Chow Date: Thu, 12 Nov 2020 15:54:16 +0800 Subject: Fix issue for new unique id system. Add level bits to help verifying symbols and split symbol tables. For intermediates rebuilding, now need manually amending level bits for redeclaring built-ins. --- SPIRV/GlslangToSpv.cpp | 10 +++--- .../link.vk.multiBlocksValid.1.0.geom.out | 4 +-- Test/baseResults/spv.specConstant.vert.out | 6 ++-- glslang/HLSL/hlslParseHelper.cpp | 6 ++-- glslang/HLSL/hlslParseHelper.h | 22 ++++++------- glslang/Include/intermediate.h | 10 +++--- glslang/MachineIndependent/Intermediate.cpp | 2 +- glslang/MachineIndependent/ParseHelper.cpp | 6 ++-- glslang/MachineIndependent/ParseHelper.h | 4 +-- glslang/MachineIndependent/ShaderLang.cpp | 9 +++++ glslang/MachineIndependent/SymbolTable.cpp | 2 +- glslang/MachineIndependent/SymbolTable.h | 38 ++++++++++++++++------ glslang/MachineIndependent/iomapper.h | 2 +- glslang/MachineIndependent/limits.cpp | 6 ++-- glslang/MachineIndependent/linkValidate.cpp | 35 +++++++++++--------- glslang/MachineIndependent/localintermediate.h | 18 ++++++---- glslang/Public/ShaderLang.h | 1 + 17 files changed, 110 insertions(+), 71 deletions(-) diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index e9c14df3..d061726a 100644 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -255,15 +255,15 @@ protected: spv::Id nonSemanticDebugPrintf; std::unordered_map extBuiltinMap; - std::unordered_map symbolValues; - std::unordered_set rValueParameters; // set of formal function parameters passed as rValues, + std::unordered_map symbolValues; + std::unordered_set rValueParameters; // set of formal function parameters passed as rValues, // rather than a pointer std::unordered_map functionMap; std::unordered_map structMap[glslang::ElpCount][glslang::ElmCount]; // for mapping glslang block indices to spv indices (e.g., due to hidden members): - std::unordered_map> memberRemapper; + std::unordered_map> memberRemapper; // for mapping glslang symbol struct to symbol Id - std::unordered_map glslangTypeToIdMap; + std::unordered_map glslangTypeToIdMap; std::stack breakForLoop; // false means break for switch std::unordered_map counterOriginator; // Map pointee types for EbtReference to their forward pointers @@ -1943,7 +1943,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T { // This may be, e.g., an anonymous block-member selection, which generally need // index remapping due to hidden members in anonymous blocks. - int glslangId = glslangTypeToIdMap[node->getLeft()->getType().getStruct()]; + long long glslangId = glslangTypeToIdMap[node->getLeft()->getType().getStruct()]; if (memberRemapper.find(glslangId) != memberRemapper.end()) { std::vector& remapper = memberRemapper[glslangId]; assert(remapper.size() > 0); diff --git a/Test/baseResults/link.vk.multiBlocksValid.1.0.geom.out b/Test/baseResults/link.vk.multiBlocksValid.1.0.geom.out index c0b33b70..b0456a08 100644 --- a/Test/baseResults/link.vk.multiBlocksValid.1.0.geom.out +++ b/Test/baseResults/link.vk.multiBlocksValid.1.0.geom.out @@ -328,14 +328,14 @@ output primitive = triangle_strip Decorate 59(Vertex) Block Decorate 61(oV) Location 0 Decorate 64(Vertex) Block - Decorate 68(iV) Location 1 + Decorate 68(iV) Location 0 MemberDecorate 95(BufferBlock) 0 ColMajor MemberDecorate 95(BufferBlock) 0 Offset 0 MemberDecorate 95(BufferBlock) 0 MatrixStride 16 Decorate 95(BufferBlock) BufferBlock Decorate 97(uBuf) DescriptorSet 0 Decorate 97(uBuf) Binding 1 - Decorate 100(P) Location 0 + Decorate 100(P) Location 2 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 diff --git a/Test/baseResults/spv.specConstant.vert.out b/Test/baseResults/spv.specConstant.vert.out index 76f3de61..f7d43811 100644 --- a/Test/baseResults/spv.specConstant.vert.out +++ b/Test/baseResults/spv.specConstant.vert.out @@ -11,7 +11,7 @@ spv.specConstant.vert Source GLSL 400 Name 4 "main" Name 9 "arraySize" - Name 14 "foo(vf4[s805310914];" + Name 14 "foo(vf4[s216172782];" Name 13 "p" Name 17 "builtin_spec_constant(" Name 20 "color" @@ -106,10 +106,10 @@ spv.specConstant.vert Store 20(color) 46 48: 10 Load 22(ucol) Store 47(param) 48 - 49: 2 FunctionCall 14(foo(vf4[s805310914];) 47(param) + 49: 2 FunctionCall 14(foo(vf4[s216172782];) 47(param) Return FunctionEnd -14(foo(vf4[s805310914];): 2 Function None 12 +14(foo(vf4[s216172782];): 2 Function None 12 13(p): 11(ptr) FunctionParameter 15: Label 54: 24(ptr) AccessChain 53(dupUcol) 23 diff --git a/glslang/HLSL/hlslParseHelper.cpp b/glslang/HLSL/hlslParseHelper.cpp index ea31837e..ff0f35a7 100644 --- a/glslang/HLSL/hlslParseHelper.cpp +++ b/glslang/HLSL/hlslParseHelper.cpp @@ -1376,7 +1376,7 @@ TIntermTyped* HlslParseContext::flattenAccess(TIntermTyped* base, int member) return flattened ? flattened : base; } -TIntermTyped* HlslParseContext::flattenAccess(int uniqueId, int member, TStorageQualifier outerStorage, +TIntermTyped* HlslParseContext::flattenAccess(long long uniqueId, int member, TStorageQualifier outerStorage, const TType& dereferencedType, int subset) { const auto flattenData = flattenMap.find(uniqueId); @@ -1444,7 +1444,7 @@ int HlslParseContext::findSubtreeOffset(const TType& type, int subset, const TVe }; // Find and return the split IO TVariable for id, or nullptr if none. -TVariable* HlslParseContext::getSplitNonIoVar(int id) const +TVariable* HlslParseContext::getSplitNonIoVar(long long id) const { const auto splitNonIoVar = splitNonIoVars.find(id); if (splitNonIoVar == splitNonIoVars.end()) @@ -3256,7 +3256,7 @@ TIntermAggregate* HlslParseContext::handleSamplerTextureCombine(const TSourceLoc // shadow state. This depends on downstream optimization to // DCE one variant in [shadow, nonshadow] if both are present, // or the SPIR-V module would be invalid. - int newId = texSymbol->getId(); + long long newId = texSymbol->getId(); // Check to see if this texture has been given a shadow mode already. // If so, look up the one we already have. diff --git a/glslang/HLSL/hlslParseHelper.h b/glslang/HLSL/hlslParseHelper.h index b92856a4..2d7165cf 100644 --- a/glslang/HLSL/hlslParseHelper.h +++ b/glslang/HLSL/hlslParseHelper.h @@ -253,12 +253,12 @@ protected: // Array and struct flattening TIntermTyped* flattenAccess(TIntermTyped* base, int member); - TIntermTyped* flattenAccess(int uniqueId, int member, TStorageQualifier outerStorage, const TType&, int subset = -1); + TIntermTyped* flattenAccess(long long uniqueId, int member, TStorageQualifier outerStorage, const TType&, int subset = -1); int findSubtreeOffset(const TIntermNode&) const; int findSubtreeOffset(const TType&, int subset, const TVector& offsets) const; bool shouldFlatten(const TType&, TStorageQualifier, bool topLevel) const; bool wasFlattened(const TIntermTyped* node) const; - bool wasFlattened(int id) const { return flattenMap.find(id) != flattenMap.end(); } + bool wasFlattened(long long id) const { return flattenMap.find(id) != flattenMap.end(); } int addFlattenedMember(const TVariable&, const TType&, TFlattenData&, const TString& name, bool linkage, const TQualifier& outerQualifier, const TArraySizes* builtInArraySizes); @@ -267,8 +267,8 @@ protected: void splitBuiltIn(const TString& baseName, const TType& memberType, const TArraySizes*, const TQualifier&); const TType& split(const TType& type, const TString& name, const TQualifier&); bool wasSplit(const TIntermTyped* node) const; - bool wasSplit(int id) const { return splitNonIoVars.find(id) != splitNonIoVars.end(); } - TVariable* getSplitNonIoVar(int id) const; + bool wasSplit(long long id) const { return splitNonIoVars.find(id) != splitNonIoVars.end(); } + TVariable* getSplitNonIoVar(long long id) const; void addPatchConstantInvocation(); void fixTextureShadowModes(); void finalizeAppendMethods(); @@ -386,7 +386,7 @@ protected: // TVector ioArraySymbolResizeList; - TMap flattenMap; + TMap flattenMap; // IO-type map. Maps a pure symbol-table form of a structure-member list into // each of the (up to) three kinds of IO, as each as different allowed decorations, @@ -399,7 +399,7 @@ protected: TMap ioTypeMap; // Structure splitting data: - TMap splitNonIoVars; // variables with the built-in interstage IO removed, indexed by unique ID. + TMap splitNonIoVars; // variables with the built-in interstage IO removed, indexed by unique ID. // Structuredbuffer shared types. Typically there are only a few. TVector structBufferTypes; @@ -488,18 +488,18 @@ protected: struct tShadowTextureSymbols { tShadowTextureSymbols() { symId.fill(-1); } - void set(bool shadow, int id) { symId[int(shadow)] = id; } - int get(bool shadow) const { return symId[int(shadow)]; } + void set(bool shadow, long long id) { symId[int(shadow)] = id; } + long long get(bool shadow) const { return symId[int(shadow)]; } // True if this texture has been seen with both shadow and non-shadow modes bool overloaded() const { return symId[0] != -1 && symId[1] != -1; } - bool isShadowId(int id) const { return symId[1] == id; } + bool isShadowId(long long id) const { return symId[1] == id; } private: - std::array symId; + std::array symId; }; - TMap textureShadowVariant; + TMap textureShadowVariant; bool parsingEntrypointParameters; }; diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h index f0411ebb..a5874346 100644 --- a/glslang/Include/intermediate.h +++ b/glslang/Include/intermediate.h @@ -1264,15 +1264,15 @@ public: // if symbol is initialized as symbol(sym), the memory comes from the pool allocator of sym. If sym comes from // per process threadPoolAllocator, then it causes increased memory usage per compile // it is essential to use "symbol = sym" to assign to symbol - TIntermSymbol(int i, const TString& n, const TType& t) + TIntermSymbol(long long i, const TString& n, const TType& t) : TIntermTyped(t), id(i), #ifndef GLSLANG_WEB flattenSubset(-1), #endif constSubtree(nullptr) { name = n; } - virtual int getId() const { return id; } - virtual void changeId(int i) { id = i; } + virtual long long getId() const { return id; } + virtual void changeId(long long i) { id = i; } virtual const TString& getName() const { return name; } virtual void traverse(TIntermTraverser*); virtual TIntermSymbol* getAsSymbolNode() { return this; } @@ -1290,10 +1290,10 @@ public: // This is meant for cases where a node has already been constructed, and // later on, it becomes necessary to switch to a different symbol. - virtual void switchId(int newId) { id = newId; } + virtual void switchId(long long newId) { id = newId; } protected: - int id; // the unique id of the symbol this node represents + long long id; // the unique id of the symbol this node represents #ifndef GLSLANG_WEB int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced #endif diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index b8c220d7..2face357 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -65,7 +65,7 @@ namespace glslang { // Returns the added node. // -TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, const TConstUnionArray& constArray, +TIntermSymbol* TIntermediate::addSymbol(long long id, const TString& name, const TType& type, const TConstUnionArray& constArray, TIntermTyped* constSubtree, const TSourceLoc& loc) { TIntermSymbol* node = new TIntermSymbol(id, name, type); diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 63fb957c..e58b8661 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -4274,8 +4274,10 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS // If it wasn't at a built-in level, then it's already been redeclared; // that is, this is a redeclaration of a redeclaration; reuse that initial // redeclaration. Otherwise, make the new one. - if (builtIn) + if (builtIn) { makeEditable(symbol); + symbolTable.amendSymbolIdLevel(*symbol); + } // Now, modify the type of the copy, as per the type of the current redeclaration. @@ -4804,7 +4806,7 @@ void TParseContext::inductiveLoopCheck(const TSourceLoc& loc, TIntermNode* init, } // get the unique id of the loop index - int loopIndex = binaryInit->getLeft()->getAsSymbolNode()->getId(); + long long loopIndex = binaryInit->getLeft()->getAsSymbolNode()->getId(); inductiveLoopIds.insert(loopIndex); // condition's form must be "loop-index relational-operator constant-expression" diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index fe2b6fbb..df53b5eb 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -67,7 +67,7 @@ struct TPragma { class TScanContext; class TPpContext; -typedef std::set TIdSetType; +typedef std::set TIdSetType; typedef std::map> TStructRecord; // @@ -392,7 +392,7 @@ public: void arrayLimitCheck(const TSourceLoc&, const TString&, int size); void limitCheck(const TSourceLoc&, int value, const char* limit, const char* feature); - void inductiveLoopBodyCheck(TIntermNode*, int loopIndexId, TSymbolTable&); + void inductiveLoopBodyCheck(TIntermNode*, long long loopIndexId, TSymbolTable&); void constantIndexExpressionCheck(TIntermNode*); void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&); diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index c6030bd7..5a26c098 100644 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -949,6 +949,9 @@ bool ProcessDeferred( if (cachedTable) symbolTable->adoptLevels(*cachedTable); + if (intermediate.getUniqueId() != 0) + symbolTable->overwriteUniqueId(intermediate.getUniqueId()); + // Add built-in symbols that are potentially context dependent; // they get popped again further down. if (! AddContextSpecificSymbols(resources, compiler->infoSink, *symbolTable, version, profile, spvVersion, @@ -1011,6 +1014,7 @@ bool ProcessDeferred( bool success = processingContext(*parseContext, ppContext, fullInput, versionWillBeError, *symbolTable, intermediate, optLevel, messages); + intermediate.setUniqueId(symbolTable->getMaxSymbolId()); return success; } @@ -1810,6 +1814,11 @@ void TShader::addProcesses(const std::vector& p) intermediate->addProcesses(p); } +void TShader::setUniqueId(unsigned long long id) +{ + intermediate->setUniqueId(id); +} + void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); } void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); } diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp index f6291c39..0e5ee195 100644 --- a/glslang/MachineIndependent/SymbolTable.cpp +++ b/glslang/MachineIndependent/SymbolTable.cpp @@ -170,7 +170,7 @@ void TType::buildMangledName(TString& mangledName) const for (int i = 0; i < arraySizes->getNumDims(); ++i) { if (arraySizes->getDimNode(i)) { if (arraySizes->getDimNode(i)->getAsSymbolNode()) - snprintf(buf, maxSize, "s%d", arraySizes->getDimNode(i)->getAsSymbolNode()->getId()); + snprintf(buf, maxSize, "s%lld", arraySizes->getDimNode(i)->getAsSymbolNode()->getId()); else snprintf(buf, maxSize, "s%p", arraySizes->getDimNode(i)); } else diff --git a/glslang/MachineIndependent/SymbolTable.h b/glslang/MachineIndependent/SymbolTable.h index db16c19b..54c3ca50 100644 --- a/glslang/MachineIndependent/SymbolTable.h +++ b/glslang/MachineIndependent/SymbolTable.h @@ -104,8 +104,8 @@ public: virtual const TAnonMember* getAsAnonMember() const { return 0; } virtual const TType& getType() const = 0; virtual TType& getWritableType() = 0; - virtual void setUniqueId(int id) { uniqueId = id; } - virtual int getUniqueId() const { return uniqueId; } + virtual void setUniqueId(long long id) { uniqueId = id; } + virtual long long getUniqueId() const { return uniqueId; } virtual void setExtensions(int numExts, const char* const exts[]) { assert(extensions == 0); @@ -130,7 +130,7 @@ protected: TSymbol& operator=(const TSymbol&); const TString *name; - unsigned int uniqueId; // For cross-scope comparing during code generation + unsigned long long uniqueId; // For cross-scope comparing during code generation // For tracking what extensions must be present // (don't use if correct version/profile is present). @@ -612,6 +612,7 @@ public: // 3: user-shader globals // protected: + static const uint32_t LevelFlagBitOffset = 56; static const int globalLevel = 3; static bool isSharedLevel(int level) { return level <= 1; } // exclude all per-compile levels static bool isBuiltInLevel(int level) { return level <= 2; } // exclude user globals @@ -620,10 +621,12 @@ public: bool isEmpty() { return table.size() == 0; } bool atBuiltInLevel() { return isBuiltInLevel(currentLevel()); } bool atGlobalLevel() { return isGlobalLevel(currentLevel()); } - static bool isBuiltInSymbol(int uniqueId) { - int level = uniqueId >> LevelFlagBitOffset; + static bool isBuiltInSymbol(long long uniqueId) { + int level = static_cast(uniqueId >> LevelFlagBitOffset); return isBuiltInLevel(level); } + static constexpr uint64_t uniqueIdMask = (1LL << LevelFlagBitOffset) - 1; + static const uint32_t MaxLevelInUniqueID = 127; void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; } void setSeparateNameSpaces() { separateNameSpaces = true; } @@ -691,6 +694,16 @@ public: return table[currentLevel()]->amend(symbol, firstNewMember); } + // Update the level info in symbol's unique ID to current level + void amendSymbolIdLevel(TSymbol& symbol) + { + // clamp level to avoid overflow + uint64_t level = currentLevel() > MaxLevelInUniqueID ? MaxLevelInUniqueID : currentLevel(); + uint64_t symbolId = symbol.getUniqueId(); + symbolId &= uniqueIdMask; + symbolId |= (level << LevelFlagBitOffset); + symbol.setUniqueId(symbolId); + } // // To allocate an internal temporary, which will need to be uniquely // identified by the consumer of the AST, but never need to @@ -859,7 +872,7 @@ public: } } - int getMaxSymbolId() { return uniqueId; } + long long getMaxSymbolId() { return uniqueId; } #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) void dump(TInfoSink& infoSink, bool complete = false) const; #endif @@ -876,19 +889,24 @@ public: // Add current level in the high-bits of unique id void updateUniqueIdLevelFlag() { // clamp level to avoid overflow - uint32_t level = currentLevel() > 7 ? 7 : currentLevel(); - uniqueId &= ((1 << LevelFlagBitOffset) - 1); + uint64_t level = currentLevel() > MaxLevelInUniqueID ? MaxLevelInUniqueID : currentLevel(); + uniqueId &= uniqueIdMask; uniqueId |= (level << LevelFlagBitOffset); } + void overwriteUniqueId(long long id) + { + uniqueId = id; + updateUniqueIdLevelFlag(); + } + protected: TSymbolTable(TSymbolTable&); TSymbolTable& operator=(TSymbolTableLevel&); int currentLevel() const { return static_cast(table.size()) - 1; } - static const uint32_t LevelFlagBitOffset = 28; std::vector table; - int uniqueId; // for unique identification in code generation + long long uniqueId; // for unique identification in code generation bool noBuiltInRedeclarations; bool separateNameSpaces; unsigned int adoptedLevels; diff --git a/glslang/MachineIndependent/iomapper.h b/glslang/MachineIndependent/iomapper.h index 7934c4a9..1dce8ff5 100644 --- a/glslang/MachineIndependent/iomapper.h +++ b/glslang/MachineIndependent/iomapper.h @@ -52,7 +52,7 @@ namespace glslang { class TIntermediate; struct TVarEntryInfo { - int id; + long long id; TIntermSymbol* symbol; bool live; int newBinding; diff --git a/glslang/MachineIndependent/limits.cpp b/glslang/MachineIndependent/limits.cpp index 51d93003..39157057 100644 --- a/glslang/MachineIndependent/limits.cpp +++ b/glslang/MachineIndependent/limits.cpp @@ -63,14 +63,14 @@ namespace glslang { class TInductiveTraverser : public TIntermTraverser { public: - TInductiveTraverser(int id, TSymbolTable& st) + TInductiveTraverser(long long id, TSymbolTable& st) : loopId(id), symbolTable(st), bad(false) { } virtual bool visitBinary(TVisit, TIntermBinary* node); virtual bool visitUnary(TVisit, TIntermUnary* node); virtual bool visitAggregate(TVisit, TIntermAggregate* node); - int loopId; // unique ID of the symbol that's the loop inductive variable + long long loopId; // unique ID of the symbol that's the loop inductive variable TSymbolTable& symbolTable; bool bad; TSourceLoc badLoc; @@ -129,7 +129,7 @@ bool TInductiveTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* n // // External function to call for loop check. // -void TParseContext::inductiveLoopBodyCheck(TIntermNode* body, int loopId, TSymbolTable& symbolTable) +void TParseContext::inductiveLoopBodyCheck(TIntermNode* body, long long loopId, TSymbolTable& symbolTable) { TInductiveTraverser it(loopId, symbolTable); diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index 1796feda..2b6738c6 100644 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -48,6 +48,7 @@ #include "localintermediate.h" #include "../Include/InfoSink.h" +#include "SymbolTable.h" namespace glslang { @@ -304,9 +305,9 @@ void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit) // Map by global name to unique ID to rationalize the same object having // differing IDs in different trees. TIdMaps idMaps; - int maxId; - seedIdMap(idMaps, maxId); - remapIds(idMaps, maxId + 1, unit); + long long idShift; + seedIdMap(idMaps, idShift); + remapIds(idMaps, idShift + 1, unit); mergeBodies(infoSink, globals, unitGlobals); mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects); @@ -327,14 +328,14 @@ static const TString& getNameForIdMap(TIntermSymbol* symbol) // Traverser that seeds an ID map with all built-ins, and tracks the -// maximum ID used. +// maximum ID used, currently using (maximum ID + 1) as new symbol id shift seed. +// Level id will keep same after shifting. // (It would be nice to put this in a function, but that causes warnings // on having no bodies for the copy-constructor/operator=.) class TBuiltInIdTraverser : public TIntermTraverser { public: - TBuiltInIdTraverser(TIdMaps& idMaps) : idMaps(idMaps), maxId(0) { } + TBuiltInIdTraverser(TIdMaps& idMaps) : idMaps(idMaps), idShift(0) { } // If it's a built in, add it to the map. - // Track the max ID. virtual void visitSymbol(TIntermSymbol* symbol) { const TQualifier& qualifier = symbol->getType().getQualifier(); @@ -342,14 +343,16 @@ public: TShaderInterface si = symbol->getType().getShaderInterface(); idMaps[si][getNameForIdMap(symbol)] = symbol->getId(); } - maxId = std::max(maxId, symbol->getId()); + idShift = (symbol->getId() & ~TSymbolTable::uniqueIdMask) | + std::max(idShift & TSymbolTable::uniqueIdMask, + symbol->getId() & TSymbolTable::uniqueIdMask); } - int getMaxId() const { return maxId; } + long long getIdShift() const { return idShift; } protected: TBuiltInIdTraverser(TBuiltInIdTraverser&); TBuiltInIdTraverser& operator=(TBuiltInIdTraverser&); TIdMaps& idMaps; - int maxId; + long long idShift; }; // Traverser that seeds an ID map with non-builtins. @@ -375,12 +378,12 @@ protected: }; // Initialize the the ID map with what we know of 'this' AST. -void TIntermediate::seedIdMap(TIdMaps& idMaps, int& maxId) +void TIntermediate::seedIdMap(TIdMaps& idMaps, long long& idShift) { // all built-ins everywhere need to align on IDs and contribute to the max ID TBuiltInIdTraverser builtInIdTraverser(idMaps); treeRoot->traverse(&builtInIdTraverser); - maxId = builtInIdTraverser.getMaxId(); + idShift = builtInIdTraverser.getIdShift() & TSymbolTable::uniqueIdMask; // user variables in the linker object list need to align on ids TUserIdTraverser userIdTraverser(idMaps); @@ -392,7 +395,7 @@ void TIntermediate::seedIdMap(TIdMaps& idMaps, int& maxId) // on having no bodies for the copy-constructor/operator=.) class TRemapIdTraverser : public TIntermTraverser { public: - TRemapIdTraverser(const TIdMaps& idMaps, int idShift) : idMaps(idMaps), idShift(idShift) { } + TRemapIdTraverser(const TIdMaps& idMaps, long long idShift) : idMaps(idMaps), idShift(idShift) { } // Do the mapping: // - if the same symbol, adopt the 'this' ID // - otherwise, ensure a unique ID by shifting to a new space @@ -404,7 +407,9 @@ public: TShaderInterface si = symbol->getType().getShaderInterface(); auto it = idMaps[si].find(getNameForIdMap(symbol)); if (it != idMaps[si].end()) { - symbol->changeId(it->second); + uint64_t id = (symbol->getId() & ~TSymbolTable::uniqueIdMask) | + (it->second & TSymbolTable::uniqueIdMask); + symbol->changeId(id); remapped = true; } } @@ -415,10 +420,10 @@ protected: TRemapIdTraverser(TRemapIdTraverser&); TRemapIdTraverser& operator=(TRemapIdTraverser&); const TIdMaps& idMaps; - int idShift; + long long idShift; }; -void TIntermediate::remapIds(const TIdMaps& idMaps, int idShift, TIntermediate& unit) +void TIntermediate::remapIds(const TIdMaps& idMaps, long long idShift, TIntermediate& unit) { // Remap all IDs to either share or be unique, as dictated by the idMap and idShift. TRemapIdTraverser idTraverser(idMaps, idShift); diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index f8747015..c7f8efb9 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -227,10 +227,10 @@ enum ComputeDerivativeMode { class TIdMaps { public: - TMap& operator[](int i) { return maps[i]; } - const TMap& operator[](int i) const { return maps[i]; } + TMap& operator[](long long i) { return maps[i]; } + const TMap& operator[](long long i) const { return maps[i]; } private: - TMap maps[EsiCount]; + TMap maps[EsiCount]; }; class TNumericFeatures { @@ -292,7 +292,8 @@ public: invertY(false), useStorageBuffer(false), nanMinMaxClamp(false), - depthReplacing(false) + depthReplacing(false), + uniqueId(0) #ifndef GLSLANG_WEB , implicitThisName("@this"), implicitCounterName("@count"), @@ -898,6 +899,8 @@ public: void addProcess(const std::string& process) { processes.addProcess(process); } void addProcessArgument(const std::string& arg) { processes.addArgument(arg); } const std::vector& getProcesses() const { return processes.getProcesses(); } + unsigned long long getUniqueId() const { return uniqueId; } + void setUniqueId(unsigned long long id) { uniqueId = id; } // Certain explicit conversions are allowed conditionally #ifdef GLSLANG_WEB @@ -926,14 +929,14 @@ public: #endif protected: - TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&); + TIntermSymbol* addSymbol(long long Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&); void error(TInfoSink& infoSink, const char*); void warn(TInfoSink& infoSink, const char*); void mergeCallGraphs(TInfoSink&, TIntermediate&); void mergeModes(TInfoSink&, TIntermediate&); void mergeTrees(TInfoSink&, TIntermediate&); - void seedIdMap(TIdMaps& idMaps, int& maxId); - void remapIds(const TIdMaps& idMaps, int idShift, TIntermediate&); + void seedIdMap(TIdMaps& idMaps, long long& IdShift); + void remapIds(const TIdMaps& idMaps, long long idShift, TIntermediate&); void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals); void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects); void mergeImplicitArraySizes(TType&, const TType&); @@ -986,6 +989,7 @@ protected: int localSize[3]; bool localSizeNotDefault[3]; int localSizeSpecId[3]; + unsigned long long uniqueId; #ifndef GLSLANG_WEB public: const char* const implicitThisName; diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index 273f1569..59705756 100644 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -458,6 +458,7 @@ public: GLSLANG_EXPORT void setEntryPoint(const char* entryPoint); GLSLANG_EXPORT void setSourceEntryPoint(const char* sourceEntryPointName); GLSLANG_EXPORT void addProcesses(const std::vector&); + GLSLANG_EXPORT void setUniqueId(unsigned long long id); // IO resolver binding data: see comments in ShaderLang.cpp GLSLANG_EXPORT void setShiftBinding(TResourceType res, unsigned int base); -- cgit v1.2.3