Merge pull request #2458 from ShchchowAMD/unique_id-fix

Fix issue for new unique id system.
This commit is contained in:
greg-lunarg 2021-02-15 13:22:14 -07:00 committed by GitHub
commit b0f8a0c3ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 110 additions and 71 deletions

View File

@ -257,15 +257,15 @@ protected:
spv::Id nonSemanticDebugPrintf; spv::Id nonSemanticDebugPrintf;
std::unordered_map<const char*, spv::Id> extBuiltinMap; std::unordered_map<const char*, spv::Id> extBuiltinMap;
std::unordered_map<int, spv::Id> symbolValues; std::unordered_map<long long, spv::Id> symbolValues;
std::unordered_set<int> rValueParameters; // set of formal function parameters passed as rValues, std::unordered_set<long long> rValueParameters; // set of formal function parameters passed as rValues,
// rather than a pointer // rather than a pointer
std::unordered_map<std::string, spv::Function*> functionMap; std::unordered_map<std::string, spv::Function*> functionMap;
std::unordered_map<const glslang::TTypeList*, spv::Id> structMap[glslang::ElpCount][glslang::ElmCount]; std::unordered_map<const glslang::TTypeList*, spv::Id> structMap[glslang::ElpCount][glslang::ElmCount];
// for mapping glslang block indices to spv indices (e.g., due to hidden members): // for mapping glslang block indices to spv indices (e.g., due to hidden members):
std::unordered_map<int, std::vector<int>> memberRemapper; std::unordered_map<long long, std::vector<int>> memberRemapper;
// for mapping glslang symbol struct to symbol Id // for mapping glslang symbol struct to symbol Id
std::unordered_map<const glslang::TTypeList*, int> glslangTypeToIdMap; std::unordered_map<const glslang::TTypeList*, long long> glslangTypeToIdMap;
std::stack<bool> breakForLoop; // false means break for switch std::stack<bool> breakForLoop; // false means break for switch
std::unordered_map<std::string, const glslang::TIntermSymbol*> counterOriginator; std::unordered_map<std::string, const glslang::TIntermSymbol*> counterOriginator;
// Map pointee types for EbtReference to their forward pointers // Map pointee types for EbtReference to their forward pointers
@ -1994,7 +1994,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
{ {
// This may be, e.g., an anonymous block-member selection, which generally need // This may be, e.g., an anonymous block-member selection, which generally need
// index remapping due to hidden members in anonymous blocks. // 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()) { if (memberRemapper.find(glslangId) != memberRemapper.end()) {
std::vector<int>& remapper = memberRemapper[glslangId]; std::vector<int>& remapper = memberRemapper[glslangId];
assert(remapper.size() > 0); assert(remapper.size() > 0);

View File

@ -328,14 +328,14 @@ output primitive = triangle_strip
Decorate 59(Vertex) Block Decorate 59(Vertex) Block
Decorate 61(oV) Location 0 Decorate 61(oV) Location 0
Decorate 64(Vertex) Block Decorate 64(Vertex) Block
Decorate 68(iV) Location 1 Decorate 68(iV) Location 0
MemberDecorate 95(BufferBlock) 0 ColMajor MemberDecorate 95(BufferBlock) 0 ColMajor
MemberDecorate 95(BufferBlock) 0 Offset 0 MemberDecorate 95(BufferBlock) 0 Offset 0
MemberDecorate 95(BufferBlock) 0 MatrixStride 16 MemberDecorate 95(BufferBlock) 0 MatrixStride 16
Decorate 95(BufferBlock) BufferBlock Decorate 95(BufferBlock) BufferBlock
Decorate 97(uBuf) DescriptorSet 0 Decorate 97(uBuf) DescriptorSet 0
Decorate 97(uBuf) Binding 1 Decorate 97(uBuf) Binding 1
Decorate 100(P) Location 0 Decorate 100(P) Location 2
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeFloat 32 6: TypeFloat 32

View File

@ -11,7 +11,7 @@ spv.specConstant.vert
Source GLSL 400 Source GLSL 400
Name 4 "main" Name 4 "main"
Name 9 "arraySize" Name 9 "arraySize"
Name 14 "foo(vf4[s805310914];" Name 14 "foo(vf4[s216172782];"
Name 13 "p" Name 13 "p"
Name 17 "builtin_spec_constant(" Name 17 "builtin_spec_constant("
Name 20 "color" Name 20 "color"
@ -106,10 +106,10 @@ spv.specConstant.vert
Store 20(color) 46 Store 20(color) 46
48: 10 Load 22(ucol) 48: 10 Load 22(ucol)
Store 47(param) 48 Store 47(param) 48
49: 2 FunctionCall 14(foo(vf4[s805310914];) 47(param) 49: 2 FunctionCall 14(foo(vf4[s216172782];) 47(param)
Return Return
FunctionEnd FunctionEnd
14(foo(vf4[s805310914];): 2 Function None 12 14(foo(vf4[s216172782];): 2 Function None 12
13(p): 11(ptr) FunctionParameter 13(p): 11(ptr) FunctionParameter
15: Label 15: Label
54: 24(ptr) AccessChain 53(dupUcol) 23 54: 24(ptr) AccessChain 53(dupUcol) 23

View File

@ -1376,7 +1376,7 @@ TIntermTyped* HlslParseContext::flattenAccess(TIntermTyped* base, int member)
return flattened ? flattened : base; 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 TType& dereferencedType, int subset)
{ {
const auto flattenData = flattenMap.find(uniqueId); 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. // 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); const auto splitNonIoVar = splitNonIoVars.find(id);
if (splitNonIoVar == splitNonIoVars.end()) if (splitNonIoVar == splitNonIoVars.end())
@ -3256,7 +3256,7 @@ TIntermAggregate* HlslParseContext::handleSamplerTextureCombine(const TSourceLoc
// shadow state. This depends on downstream optimization to // shadow state. This depends on downstream optimization to
// DCE one variant in [shadow, nonshadow] if both are present, // DCE one variant in [shadow, nonshadow] if both are present,
// or the SPIR-V module would be invalid. // 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. // Check to see if this texture has been given a shadow mode already.
// If so, look up the one we already have. // If so, look up the one we already have.

View File

@ -253,12 +253,12 @@ protected:
// Array and struct flattening // Array and struct flattening
TIntermTyped* flattenAccess(TIntermTyped* base, int member); 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 TIntermNode&) const;
int findSubtreeOffset(const TType&, int subset, const TVector<int>& offsets) const; int findSubtreeOffset(const TType&, int subset, const TVector<int>& offsets) const;
bool shouldFlatten(const TType&, TStorageQualifier, bool topLevel) const; bool shouldFlatten(const TType&, TStorageQualifier, bool topLevel) const;
bool wasFlattened(const TIntermTyped* node) 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, int addFlattenedMember(const TVariable&, const TType&, TFlattenData&, const TString& name, bool linkage,
const TQualifier& outerQualifier, const TArraySizes* builtInArraySizes); const TQualifier& outerQualifier, const TArraySizes* builtInArraySizes);
@ -267,8 +267,8 @@ protected:
void splitBuiltIn(const TString& baseName, const TType& memberType, const TArraySizes*, const TQualifier&); void splitBuiltIn(const TString& baseName, const TType& memberType, const TArraySizes*, const TQualifier&);
const TType& split(const TType& type, const TString& name, const TQualifier&); const TType& split(const TType& type, const TString& name, const TQualifier&);
bool wasSplit(const TIntermTyped* node) const; bool wasSplit(const TIntermTyped* node) const;
bool wasSplit(int id) const { return splitNonIoVars.find(id) != splitNonIoVars.end(); } bool wasSplit(long long id) const { return splitNonIoVars.find(id) != splitNonIoVars.end(); }
TVariable* getSplitNonIoVar(int id) const; TVariable* getSplitNonIoVar(long long id) const;
void addPatchConstantInvocation(); void addPatchConstantInvocation();
void fixTextureShadowModes(); void fixTextureShadowModes();
void finalizeAppendMethods(); void finalizeAppendMethods();
@ -386,7 +386,7 @@ protected:
// //
TVector<TSymbol*> ioArraySymbolResizeList; TVector<TSymbol*> ioArraySymbolResizeList;
TMap<int, TFlattenData> flattenMap; TMap<long long, TFlattenData> flattenMap;
// IO-type map. Maps a pure symbol-table form of a structure-member list into // 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, // each of the (up to) three kinds of IO, as each as different allowed decorations,
@ -399,7 +399,7 @@ protected:
TMap<const TTypeList*, tIoKinds> ioTypeMap; TMap<const TTypeList*, tIoKinds> ioTypeMap;
// Structure splitting data: // Structure splitting data:
TMap<int, TVariable*> splitNonIoVars; // variables with the built-in interstage IO removed, indexed by unique ID. TMap<long long, TVariable*> splitNonIoVars; // variables with the built-in interstage IO removed, indexed by unique ID.
// Structuredbuffer shared types. Typically there are only a few. // Structuredbuffer shared types. Typically there are only a few.
TVector<TType*> structBufferTypes; TVector<TType*> structBufferTypes;
@ -488,18 +488,18 @@ protected:
struct tShadowTextureSymbols { struct tShadowTextureSymbols {
tShadowTextureSymbols() { symId.fill(-1); } tShadowTextureSymbols() { symId.fill(-1); }
void set(bool shadow, int id) { symId[int(shadow)] = id; } void set(bool shadow, long long id) { symId[int(shadow)] = id; }
int get(bool shadow) const { return symId[int(shadow)]; } long long get(bool shadow) const { return symId[int(shadow)]; }
// True if this texture has been seen with both shadow and non-shadow modes // 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 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: private:
std::array<int, 2> symId; std::array<long long, 2> symId;
}; };
TMap<int, tShadowTextureSymbols*> textureShadowVariant; TMap<long long, tShadowTextureSymbols*> textureShadowVariant;
bool parsingEntrypointParameters; bool parsingEntrypointParameters;
}; };

View File

@ -1275,15 +1275,15 @@ public:
// if symbol is initialized as symbol(sym), the memory comes from the pool allocator of sym. If sym comes from // 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 // per process threadPoolAllocator, then it causes increased memory usage per compile
// it is essential to use "symbol = sym" to assign to symbol // 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), : TIntermTyped(t), id(i),
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
flattenSubset(-1), flattenSubset(-1),
#endif #endif
constSubtree(nullptr) constSubtree(nullptr)
{ name = n; } { name = n; }
virtual int getId() const { return id; } virtual long long getId() const { return id; }
virtual void changeId(int i) { id = i; } virtual void changeId(long long i) { id = i; }
virtual const TString& getName() const { return name; } virtual const TString& getName() const { return name; }
virtual void traverse(TIntermTraverser*); virtual void traverse(TIntermTraverser*);
virtual TIntermSymbol* getAsSymbolNode() { return this; } virtual TIntermSymbol* getAsSymbolNode() { return this; }
@ -1301,10 +1301,10 @@ public:
// This is meant for cases where a node has already been constructed, and // This is meant for cases where a node has already been constructed, and
// later on, it becomes necessary to switch to a different symbol. // 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: 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 #ifndef GLSLANG_WEB
int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced
#endif #endif

View File

@ -65,7 +65,7 @@ namespace glslang {
// Returns the added node. // 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) TIntermTyped* constSubtree, const TSourceLoc& loc)
{ {
TIntermSymbol* node = new TIntermSymbol(id, name, type); TIntermSymbol* node = new TIntermSymbol(id, name, type);

View File

@ -4296,8 +4296,10 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
// If it wasn't at a built-in level, then it's already been redeclared; // 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 // that is, this is a redeclaration of a redeclaration; reuse that initial
// redeclaration. Otherwise, make the new one. // redeclaration. Otherwise, make the new one.
if (builtIn) if (builtIn) {
makeEditable(symbol); makeEditable(symbol);
symbolTable.amendSymbolIdLevel(*symbol);
}
// Now, modify the type of the copy, as per the type of the current redeclaration. // Now, modify the type of the copy, as per the type of the current redeclaration.
@ -4826,7 +4828,7 @@ void TParseContext::inductiveLoopCheck(const TSourceLoc& loc, TIntermNode* init,
} }
// get the unique id of the loop index // get the unique id of the loop index
int loopIndex = binaryInit->getLeft()->getAsSymbolNode()->getId(); long long loopIndex = binaryInit->getLeft()->getAsSymbolNode()->getId();
inductiveLoopIds.insert(loopIndex); inductiveLoopIds.insert(loopIndex);
// condition's form must be "loop-index relational-operator constant-expression" // condition's form must be "loop-index relational-operator constant-expression"

View File

@ -67,7 +67,7 @@ struct TPragma {
class TScanContext; class TScanContext;
class TPpContext; class TPpContext;
typedef std::set<int> TIdSetType; typedef std::set<long long> TIdSetType;
typedef std::map<const TTypeList*, std::map<size_t, const TTypeList*>> TStructRecord; typedef std::map<const TTypeList*, std::map<size_t, const TTypeList*>> TStructRecord;
// //
@ -392,7 +392,7 @@ public:
void arrayLimitCheck(const TSourceLoc&, const TString&, int size); void arrayLimitCheck(const TSourceLoc&, const TString&, int size);
void limitCheck(const TSourceLoc&, int value, const char* limit, const char* feature); 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 constantIndexExpressionCheck(TIntermNode*);
void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&); void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&);

View File

@ -949,6 +949,9 @@ bool ProcessDeferred(
if (cachedTable) if (cachedTable)
symbolTable->adoptLevels(*cachedTable); symbolTable->adoptLevels(*cachedTable);
if (intermediate.getUniqueId() != 0)
symbolTable->overwriteUniqueId(intermediate.getUniqueId());
// Add built-in symbols that are potentially context dependent; // Add built-in symbols that are potentially context dependent;
// they get popped again further down. // they get popped again further down.
if (! AddContextSpecificSymbols(resources, compiler->infoSink, *symbolTable, version, profile, spvVersion, if (! AddContextSpecificSymbols(resources, compiler->infoSink, *symbolTable, version, profile, spvVersion,
@ -1011,6 +1014,7 @@ bool ProcessDeferred(
bool success = processingContext(*parseContext, ppContext, fullInput, bool success = processingContext(*parseContext, ppContext, fullInput,
versionWillBeError, *symbolTable, versionWillBeError, *symbolTable,
intermediate, optLevel, messages); intermediate, optLevel, messages);
intermediate.setUniqueId(symbolTable->getMaxSymbolId());
return success; return success;
} }
@ -1810,6 +1814,11 @@ void TShader::addProcesses(const std::vector<std::string>& p)
intermediate->addProcesses(p); intermediate->addProcesses(p);
} }
void TShader::setUniqueId(unsigned long long id)
{
intermediate->setUniqueId(id);
}
void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); } void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); }
void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); } void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); }

View File

@ -170,7 +170,7 @@ void TType::buildMangledName(TString& mangledName) const
for (int i = 0; i < arraySizes->getNumDims(); ++i) { for (int i = 0; i < arraySizes->getNumDims(); ++i) {
if (arraySizes->getDimNode(i)) { if (arraySizes->getDimNode(i)) {
if (arraySizes->getDimNode(i)->getAsSymbolNode()) 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 else
snprintf(buf, maxSize, "s%p", arraySizes->getDimNode(i)); snprintf(buf, maxSize, "s%p", arraySizes->getDimNode(i));
} else } else

View File

@ -104,8 +104,8 @@ public:
virtual const TAnonMember* getAsAnonMember() const { return 0; } virtual const TAnonMember* getAsAnonMember() const { return 0; }
virtual const TType& getType() const = 0; virtual const TType& getType() const = 0;
virtual TType& getWritableType() = 0; virtual TType& getWritableType() = 0;
virtual void setUniqueId(int id) { uniqueId = id; } virtual void setUniqueId(long long id) { uniqueId = id; }
virtual int getUniqueId() const { return uniqueId; } virtual long long getUniqueId() const { return uniqueId; }
virtual void setExtensions(int numExts, const char* const exts[]) virtual void setExtensions(int numExts, const char* const exts[])
{ {
assert(extensions == 0); assert(extensions == 0);
@ -130,7 +130,7 @@ protected:
TSymbol& operator=(const TSymbol&); TSymbol& operator=(const TSymbol&);
const TString *name; 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 // For tracking what extensions must be present
// (don't use if correct version/profile is present). // (don't use if correct version/profile is present).
@ -612,6 +612,7 @@ public:
// 3: user-shader globals // 3: user-shader globals
// //
protected: protected:
static const uint32_t LevelFlagBitOffset = 56;
static const int globalLevel = 3; static const int globalLevel = 3;
static bool isSharedLevel(int level) { return level <= 1; } // exclude all per-compile levels static bool isSharedLevel(int level) { return level <= 1; } // exclude all per-compile levels
static bool isBuiltInLevel(int level) { return level <= 2; } // exclude user globals static bool isBuiltInLevel(int level) { return level <= 2; } // exclude user globals
@ -620,10 +621,12 @@ public:
bool isEmpty() { return table.size() == 0; } bool isEmpty() { return table.size() == 0; }
bool atBuiltInLevel() { return isBuiltInLevel(currentLevel()); } bool atBuiltInLevel() { return isBuiltInLevel(currentLevel()); }
bool atGlobalLevel() { return isGlobalLevel(currentLevel()); } bool atGlobalLevel() { return isGlobalLevel(currentLevel()); }
static bool isBuiltInSymbol(int uniqueId) { static bool isBuiltInSymbol(long long uniqueId) {
int level = uniqueId >> LevelFlagBitOffset; int level = static_cast<int>(uniqueId >> LevelFlagBitOffset);
return isBuiltInLevel(level); return isBuiltInLevel(level);
} }
static constexpr uint64_t uniqueIdMask = (1LL << LevelFlagBitOffset) - 1;
static const uint32_t MaxLevelInUniqueID = 127;
void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; } void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; }
void setSeparateNameSpaces() { separateNameSpaces = true; } void setSeparateNameSpaces() { separateNameSpaces = true; }
@ -691,6 +694,16 @@ public:
return table[currentLevel()]->amend(symbol, firstNewMember); 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 // To allocate an internal temporary, which will need to be uniquely
// identified by the consumer of the AST, but never need to // 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) #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
void dump(TInfoSink& infoSink, bool complete = false) const; void dump(TInfoSink& infoSink, bool complete = false) const;
#endif #endif
@ -876,19 +889,24 @@ public:
// Add current level in the high-bits of unique id // Add current level in the high-bits of unique id
void updateUniqueIdLevelFlag() { void updateUniqueIdLevelFlag() {
// clamp level to avoid overflow // clamp level to avoid overflow
uint32_t level = currentLevel() > 7 ? 7 : currentLevel(); uint64_t level = currentLevel() > MaxLevelInUniqueID ? MaxLevelInUniqueID : currentLevel();
uniqueId &= ((1 << LevelFlagBitOffset) - 1); uniqueId &= uniqueIdMask;
uniqueId |= (level << LevelFlagBitOffset); uniqueId |= (level << LevelFlagBitOffset);
} }
void overwriteUniqueId(long long id)
{
uniqueId = id;
updateUniqueIdLevelFlag();
}
protected: protected:
TSymbolTable(TSymbolTable&); TSymbolTable(TSymbolTable&);
TSymbolTable& operator=(TSymbolTableLevel&); TSymbolTable& operator=(TSymbolTableLevel&);
int currentLevel() const { return static_cast<int>(table.size()) - 1; } int currentLevel() const { return static_cast<int>(table.size()) - 1; }
static const uint32_t LevelFlagBitOffset = 28;
std::vector<TSymbolTableLevel*> table; std::vector<TSymbolTableLevel*> table;
int uniqueId; // for unique identification in code generation long long uniqueId; // for unique identification in code generation
bool noBuiltInRedeclarations; bool noBuiltInRedeclarations;
bool separateNameSpaces; bool separateNameSpaces;
unsigned int adoptedLevels; unsigned int adoptedLevels;

View File

@ -52,7 +52,7 @@ namespace glslang {
class TIntermediate; class TIntermediate;
struct TVarEntryInfo { struct TVarEntryInfo {
int id; long long id;
TIntermSymbol* symbol; TIntermSymbol* symbol;
bool live; bool live;
int newBinding; int newBinding;

View File

@ -63,14 +63,14 @@ namespace glslang {
class TInductiveTraverser : public TIntermTraverser { class TInductiveTraverser : public TIntermTraverser {
public: public:
TInductiveTraverser(int id, TSymbolTable& st) TInductiveTraverser(long long id, TSymbolTable& st)
: loopId(id), symbolTable(st), bad(false) { } : loopId(id), symbolTable(st), bad(false) { }
virtual bool visitBinary(TVisit, TIntermBinary* node); virtual bool visitBinary(TVisit, TIntermBinary* node);
virtual bool visitUnary(TVisit, TIntermUnary* node); virtual bool visitUnary(TVisit, TIntermUnary* node);
virtual bool visitAggregate(TVisit, TIntermAggregate* 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; TSymbolTable& symbolTable;
bool bad; bool bad;
TSourceLoc badLoc; TSourceLoc badLoc;
@ -129,7 +129,7 @@ bool TInductiveTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* n
// //
// External function to call for loop check. // 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); TInductiveTraverser it(loopId, symbolTable);

View File

@ -48,6 +48,7 @@
#include "localintermediate.h" #include "localintermediate.h"
#include "../Include/InfoSink.h" #include "../Include/InfoSink.h"
#include "SymbolTable.h"
namespace glslang { namespace glslang {
@ -306,9 +307,9 @@ void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit)
// Map by global name to unique ID to rationalize the same object having // Map by global name to unique ID to rationalize the same object having
// differing IDs in different trees. // differing IDs in different trees.
TIdMaps idMaps; TIdMaps idMaps;
int maxId; long long idShift;
seedIdMap(idMaps, maxId); seedIdMap(idMaps, idShift);
remapIds(idMaps, maxId + 1, unit); remapIds(idMaps, idShift + 1, unit);
mergeBodies(infoSink, globals, unitGlobals); mergeBodies(infoSink, globals, unitGlobals);
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects); mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects);
@ -329,14 +330,14 @@ static const TString& getNameForIdMap(TIntermSymbol* symbol)
// Traverser that seeds an ID map with all built-ins, and tracks the // 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 // (It would be nice to put this in a function, but that causes warnings
// on having no bodies for the copy-constructor/operator=.) // on having no bodies for the copy-constructor/operator=.)
class TBuiltInIdTraverser : public TIntermTraverser { class TBuiltInIdTraverser : public TIntermTraverser {
public: 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. // If it's a built in, add it to the map.
// Track the max ID.
virtual void visitSymbol(TIntermSymbol* symbol) virtual void visitSymbol(TIntermSymbol* symbol)
{ {
const TQualifier& qualifier = symbol->getType().getQualifier(); const TQualifier& qualifier = symbol->getType().getQualifier();
@ -344,14 +345,16 @@ public:
TShaderInterface si = symbol->getType().getShaderInterface(); TShaderInterface si = symbol->getType().getShaderInterface();
idMaps[si][getNameForIdMap(symbol)] = symbol->getId(); 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: protected:
TBuiltInIdTraverser(TBuiltInIdTraverser&); TBuiltInIdTraverser(TBuiltInIdTraverser&);
TBuiltInIdTraverser& operator=(TBuiltInIdTraverser&); TBuiltInIdTraverser& operator=(TBuiltInIdTraverser&);
TIdMaps& idMaps; TIdMaps& idMaps;
int maxId; long long idShift;
}; };
// Traverser that seeds an ID map with non-builtins. // Traverser that seeds an ID map with non-builtins.
@ -377,12 +380,12 @@ protected:
}; };
// Initialize the the ID map with what we know of 'this' AST. // 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 // all built-ins everywhere need to align on IDs and contribute to the max ID
TBuiltInIdTraverser builtInIdTraverser(idMaps); TBuiltInIdTraverser builtInIdTraverser(idMaps);
treeRoot->traverse(&builtInIdTraverser); treeRoot->traverse(&builtInIdTraverser);
maxId = builtInIdTraverser.getMaxId(); idShift = builtInIdTraverser.getIdShift() & TSymbolTable::uniqueIdMask;
// user variables in the linker object list need to align on ids // user variables in the linker object list need to align on ids
TUserIdTraverser userIdTraverser(idMaps); TUserIdTraverser userIdTraverser(idMaps);
@ -394,7 +397,7 @@ void TIntermediate::seedIdMap(TIdMaps& idMaps, int& maxId)
// on having no bodies for the copy-constructor/operator=.) // on having no bodies for the copy-constructor/operator=.)
class TRemapIdTraverser : public TIntermTraverser { class TRemapIdTraverser : public TIntermTraverser {
public: 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: // Do the mapping:
// - if the same symbol, adopt the 'this' ID // - if the same symbol, adopt the 'this' ID
// - otherwise, ensure a unique ID by shifting to a new space // - otherwise, ensure a unique ID by shifting to a new space
@ -406,7 +409,9 @@ public:
TShaderInterface si = symbol->getType().getShaderInterface(); TShaderInterface si = symbol->getType().getShaderInterface();
auto it = idMaps[si].find(getNameForIdMap(symbol)); auto it = idMaps[si].find(getNameForIdMap(symbol));
if (it != idMaps[si].end()) { 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; remapped = true;
} }
} }
@ -417,10 +422,10 @@ protected:
TRemapIdTraverser(TRemapIdTraverser&); TRemapIdTraverser(TRemapIdTraverser&);
TRemapIdTraverser& operator=(TRemapIdTraverser&); TRemapIdTraverser& operator=(TRemapIdTraverser&);
const TIdMaps& idMaps; 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. // Remap all IDs to either share or be unique, as dictated by the idMap and idShift.
TRemapIdTraverser idTraverser(idMaps, idShift); TRemapIdTraverser idTraverser(idMaps, idShift);

View File

@ -227,10 +227,10 @@ enum ComputeDerivativeMode {
class TIdMaps { class TIdMaps {
public: public:
TMap<TString, int>& operator[](int i) { return maps[i]; } TMap<TString, long long>& operator[](long long i) { return maps[i]; }
const TMap<TString, int>& operator[](int i) const { return maps[i]; } const TMap<TString, long long>& operator[](long long i) const { return maps[i]; }
private: private:
TMap<TString, int> maps[EsiCount]; TMap<TString, long long> maps[EsiCount];
}; };
class TNumericFeatures { class TNumericFeatures {
@ -292,7 +292,8 @@ public:
invertY(false), invertY(false),
useStorageBuffer(false), useStorageBuffer(false),
nanMinMaxClamp(false), nanMinMaxClamp(false),
depthReplacing(false) depthReplacing(false),
uniqueId(0)
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
, ,
implicitThisName("@this"), implicitCounterName("@count"), implicitThisName("@this"), implicitCounterName("@count"),
@ -911,6 +912,8 @@ public:
void addProcess(const std::string& process) { processes.addProcess(process); } void addProcess(const std::string& process) { processes.addProcess(process); }
void addProcessArgument(const std::string& arg) { processes.addArgument(arg); } void addProcessArgument(const std::string& arg) { processes.addArgument(arg); }
const std::vector<std::string>& getProcesses() const { return processes.getProcesses(); } const std::vector<std::string>& 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 // Certain explicit conversions are allowed conditionally
#ifdef GLSLANG_WEB #ifdef GLSLANG_WEB
@ -939,14 +942,14 @@ public:
#endif #endif
protected: 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 error(TInfoSink& infoSink, const char*);
void warn(TInfoSink& infoSink, const char*); void warn(TInfoSink& infoSink, const char*);
void mergeCallGraphs(TInfoSink&, TIntermediate&); void mergeCallGraphs(TInfoSink&, TIntermediate&);
void mergeModes(TInfoSink&, TIntermediate&); void mergeModes(TInfoSink&, TIntermediate&);
void mergeTrees(TInfoSink&, TIntermediate&); void mergeTrees(TInfoSink&, TIntermediate&);
void seedIdMap(TIdMaps& idMaps, int& maxId); void seedIdMap(TIdMaps& idMaps, long long& IdShift);
void remapIds(const TIdMaps& idMaps, int idShift, TIntermediate&); void remapIds(const TIdMaps& idMaps, long long idShift, TIntermediate&);
void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals); void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals);
void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects); void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects);
void mergeImplicitArraySizes(TType&, const TType&); void mergeImplicitArraySizes(TType&, const TType&);
@ -999,6 +1002,7 @@ protected:
int localSize[3]; int localSize[3];
bool localSizeNotDefault[3]; bool localSizeNotDefault[3];
int localSizeSpecId[3]; int localSizeSpecId[3];
unsigned long long uniqueId;
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
public: public:
const char* const implicitThisName; const char* const implicitThisName;

View File

@ -458,6 +458,7 @@ public:
GLSLANG_EXPORT void setEntryPoint(const char* entryPoint); GLSLANG_EXPORT void setEntryPoint(const char* entryPoint);
GLSLANG_EXPORT void setSourceEntryPoint(const char* sourceEntryPointName); GLSLANG_EXPORT void setSourceEntryPoint(const char* sourceEntryPointName);
GLSLANG_EXPORT void addProcesses(const std::vector<std::string>&); GLSLANG_EXPORT void addProcesses(const std::vector<std::string>&);
GLSLANG_EXPORT void setUniqueId(unsigned long long id);
// IO resolver binding data: see comments in ShaderLang.cpp // IO resolver binding data: see comments in ShaderLang.cpp
GLSLANG_EXPORT void setShiftBinding(TResourceType res, unsigned int base); GLSLANG_EXPORT void setShiftBinding(TResourceType res, unsigned int base);