Infrastructure: Make shared symbol-table cache complete, delete work around.
Fixes issue #370 and replaces PR #371.
This commit is contained in:
parent
0b5214486b
commit
0a6fb85494
@ -2,5 +2,5 @@
|
|||||||
// For the version, it uses the latest git tag followed by the number of commits.
|
// 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).
|
// For the date, it uses the current date (when then script is run).
|
||||||
|
|
||||||
#define GLSLANG_REVISION "SPIRV99.1394"
|
#define GLSLANG_REVISION "SPIRV99.1396"
|
||||||
#define GLSLANG_DATE "08-Aug-2016"
|
#define GLSLANG_DATE "09-Aug-2016"
|
||||||
|
@ -146,6 +146,23 @@ int MapProfileToIndex(EProfile profile)
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int SourceCount = 2;
|
||||||
|
|
||||||
|
int MapSourceToIndex(EShSource source)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
switch (source) {
|
||||||
|
case EShSourceGlsl: index = 0; break;
|
||||||
|
case EShSourceHlsl: index = 1; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(index < SourceCount);
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
// only one of these needed for non-ES; ES needs 2 for different precision defaults of built-ins
|
// only one of these needed for non-ES; ES needs 2 for different precision defaults of built-ins
|
||||||
enum EPrecisionClass {
|
enum EPrecisionClass {
|
||||||
EPcGeneral,
|
EPcGeneral,
|
||||||
@ -161,8 +178,8 @@ enum EPrecisionClass {
|
|||||||
// Each has a different set of built-ins, and we want to preserve that from
|
// Each has a different set of built-ins, and we want to preserve that from
|
||||||
// compile to compile.
|
// compile to compile.
|
||||||
//
|
//
|
||||||
TSymbolTable* CommonSymbolTable[VersionCount][SpvVersionCount][ProfileCount][EPcCount] = {};
|
TSymbolTable* CommonSymbolTable[VersionCount][SpvVersionCount][ProfileCount][SourceCount][EPcCount] = {};
|
||||||
TSymbolTable* SharedSymbolTables[VersionCount][SpvVersionCount][ProfileCount][EShLangCount] = {};
|
TSymbolTable* SharedSymbolTables[VersionCount][SpvVersionCount][ProfileCount][SourceCount][EShLangCount] = {};
|
||||||
|
|
||||||
TPoolAllocator* PerProcessGPA = 0;
|
TPoolAllocator* PerProcessGPA = 0;
|
||||||
|
|
||||||
@ -305,7 +322,8 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp
|
|||||||
int versionIndex = MapVersionToIndex(version);
|
int versionIndex = MapVersionToIndex(version);
|
||||||
int spvVersionIndex = MapSpvVersionToIndex(spvVersion);
|
int spvVersionIndex = MapSpvVersionToIndex(spvVersion);
|
||||||
int profileIndex = MapProfileToIndex(profile);
|
int profileIndex = MapProfileToIndex(profile);
|
||||||
if (CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][EPcGeneral]) {
|
int sourceIndex = MapSourceToIndex(source);
|
||||||
|
if (CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][EPcGeneral]) {
|
||||||
glslang::ReleaseGlobalLock();
|
glslang::ReleaseGlobalLock();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -333,18 +351,18 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp
|
|||||||
// Copy the local symbol tables from the new pool to the global tables using the process-global pool
|
// Copy the local symbol tables from the new pool to the global tables using the process-global pool
|
||||||
for (int precClass = 0; precClass < EPcCount; ++precClass) {
|
for (int precClass = 0; precClass < EPcCount; ++precClass) {
|
||||||
if (! commonTable[precClass]->isEmpty()) {
|
if (! commonTable[precClass]->isEmpty()) {
|
||||||
CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][precClass] = new TSymbolTable;
|
CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][precClass] = new TSymbolTable;
|
||||||
CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][precClass]->copyTable(*commonTable[precClass]);
|
CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][precClass]->copyTable(*commonTable[precClass]);
|
||||||
CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][precClass]->readOnly();
|
CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][precClass]->readOnly();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int stage = 0; stage < EShLangCount; ++stage) {
|
for (int stage = 0; stage < EShLangCount; ++stage) {
|
||||||
if (! stageTables[stage]->isEmpty()) {
|
if (! stageTables[stage]->isEmpty()) {
|
||||||
SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][stage] = new TSymbolTable;
|
SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage] = new TSymbolTable;
|
||||||
SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][stage]->adoptLevels(*CommonSymbolTable
|
SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage]->adoptLevels(*CommonSymbolTable
|
||||||
[versionIndex][spvVersionIndex][profileIndex][CommonIndex(profile, (EShLanguage)stage)]);
|
[versionIndex][spvVersionIndex][profileIndex][sourceIndex][CommonIndex(profile, (EShLanguage)stage)]);
|
||||||
SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][stage]->copyTable(*stageTables[stage]);
|
SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage]->copyTable(*stageTables[stage]);
|
||||||
SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][stage]->readOnly();
|
SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage]->readOnly();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -656,6 +674,7 @@ bool ProcessDeferred(
|
|||||||
TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
|
TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
|
||||||
[MapSpvVersionToIndex(spvVersion)]
|
[MapSpvVersionToIndex(spvVersion)]
|
||||||
[MapProfileToIndex(profile)]
|
[MapProfileToIndex(profile)]
|
||||||
|
[MapSourceToIndex(source)]
|
||||||
[compiler->getLanguage()];
|
[compiler->getLanguage()];
|
||||||
|
|
||||||
// Dynamically allocate the symbol table so we can control when it is deallocated WRT the pool.
|
// Dynamically allocate the symbol table so we can control when it is deallocated WRT the pool.
|
||||||
@ -1092,9 +1111,11 @@ int __fastcall ShFinalize()
|
|||||||
for (int version = 0; version < VersionCount; ++version) {
|
for (int version = 0; version < VersionCount; ++version) {
|
||||||
for (int spvVersion = 0; spvVersion < SpvVersionCount; ++spvVersion) {
|
for (int spvVersion = 0; spvVersion < SpvVersionCount; ++spvVersion) {
|
||||||
for (int p = 0; p < ProfileCount; ++p) {
|
for (int p = 0; p < ProfileCount; ++p) {
|
||||||
for (int lang = 0; lang < EShLangCount; ++lang) {
|
for (int source = 0; source < SourceCount; ++source) {
|
||||||
delete SharedSymbolTables[version][spvVersion][p][lang];
|
for (int stage = 0; stage < EShLangCount; ++stage) {
|
||||||
SharedSymbolTables[version][spvVersion][p][lang] = 0;
|
delete SharedSymbolTables[version][spvVersion][p][source][stage];
|
||||||
|
SharedSymbolTables[version][spvVersion][p][source][stage] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1103,9 +1124,11 @@ int __fastcall ShFinalize()
|
|||||||
for (int version = 0; version < VersionCount; ++version) {
|
for (int version = 0; version < VersionCount; ++version) {
|
||||||
for (int spvVersion = 0; spvVersion < SpvVersionCount; ++spvVersion) {
|
for (int spvVersion = 0; spvVersion < SpvVersionCount; ++spvVersion) {
|
||||||
for (int p = 0; p < ProfileCount; ++p) {
|
for (int p = 0; p < ProfileCount; ++p) {
|
||||||
for (int pc = 0; pc < EPcCount; ++pc) {
|
for (int source = 0; source < SourceCount; ++source) {
|
||||||
delete CommonSymbolTable[version][spvVersion][p][pc];
|
for (int pc = 0; pc < EPcCount; ++pc) {
|
||||||
CommonSymbolTable[version][spvVersion][p][pc] = 0;
|
delete CommonSymbolTable[version][spvVersion][p][source][pc];
|
||||||
|
CommonSymbolTable[version][spvVersion][p][source][pc] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,46 +40,14 @@
|
|||||||
namespace glslangtest {
|
namespace glslangtest {
|
||||||
|
|
||||||
// Initializes glslang on creation, and destroys it on completion.
|
// Initializes glslang on creation, and destroys it on completion.
|
||||||
// And provides .Acquire() as a way to reinitialize glslang if semantics change.
|
|
||||||
// This object is expected to be a singleton, so that internal glslang state
|
// This object is expected to be a singleton, so that internal glslang state
|
||||||
// can be correctly handled.
|
// can be correctly handled.
|
||||||
//
|
//
|
||||||
// TODO(antiagainst): It's a known bug that some of the internal states need to
|
|
||||||
// be reset if semantics change:
|
|
||||||
// https://github.com/KhronosGroup/glslang/issues/166
|
|
||||||
// Therefore, the following mechanism is needed. Remove this once the above bug
|
|
||||||
// gets fixed.
|
|
||||||
class GlslangInitializer {
|
class GlslangInitializer {
|
||||||
public:
|
public:
|
||||||
GlslangInitializer() : lastMessages(EShMsgCascadingErrors)
|
GlslangInitializer() { glslang::InitializeProcess(); }
|
||||||
{
|
|
||||||
glslang::InitializeProcess();
|
|
||||||
}
|
|
||||||
|
|
||||||
~GlslangInitializer() { glslang::FinalizeProcess(); }
|
~GlslangInitializer() { glslang::FinalizeProcess(); }
|
||||||
|
|
||||||
// A token indicates that the glslang is reinitialized (if necessary) to the
|
|
||||||
// required semantics. And that won't change until the token is destroyed.
|
|
||||||
class InitializationToken {
|
|
||||||
};
|
|
||||||
|
|
||||||
// Re-initializes glsl state iff the previous messages and the current
|
|
||||||
// messages are incompatible. We assume external synchronization, i.e.
|
|
||||||
// there is at most one acquired token at any one time.
|
|
||||||
InitializationToken acquire(EShMessages new_messages)
|
|
||||||
{
|
|
||||||
if ((lastMessages ^ new_messages) &
|
|
||||||
(EShMsgVulkanRules | EShMsgSpvRules | EShMsgReadHlsl)) {
|
|
||||||
glslang::FinalizeProcess();
|
|
||||||
glslang::InitializeProcess();
|
|
||||||
}
|
|
||||||
lastMessages = new_messages;
|
|
||||||
return InitializationToken();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
EShMessages lastMessages;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace glslangtest
|
} // namespace glslangtest
|
||||||
|
@ -179,8 +179,6 @@ public:
|
|||||||
|
|
||||||
shader->setStringsWithLengths(&shaderStrings, &shaderLengths, 1);
|
shader->setStringsWithLengths(&shaderStrings, &shaderLengths, 1);
|
||||||
if (!entryPointName.empty()) shader->setEntryPoint(entryPointName.c_str());
|
if (!entryPointName.empty()) shader->setEntryPoint(entryPointName.c_str());
|
||||||
// Reinitialize glslang if the semantics change.
|
|
||||||
GlobalTestSettings.initializer->acquire(controls);
|
|
||||||
return shader->parse(
|
return shader->parse(
|
||||||
(resources ? resources : &glslang::DefaultTBuiltInResource),
|
(resources ? resources : &glslang::DefaultTBuiltInResource),
|
||||||
defaultVersion, isForwardCompatible, controls);
|
defaultVersion, isForwardCompatible, controls);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user