SPV: Non-functional: Condense SPV-related versioning, and rationalize all uses.

This commit is contained in:
John Kessenich 2016-06-16 20:59:42 -06:00
parent 65336488a8
commit b901ade058
17 changed files with 174 additions and 153 deletions

View file

@ -141,12 +141,12 @@ TPoolAllocator* PerProcessGPA = 0;
//
// Parse and add to the given symbol table the content of the given shader string.
//
bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profile, int spv, int vulkan, EShLanguage language, TInfoSink& infoSink,
bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TInfoSink& infoSink,
TSymbolTable& symbolTable)
{
TIntermediate intermediate(language, version, profile);
TParseContext parseContext(symbolTable, intermediate, true, version, profile, spv, vulkan, language, infoSink);
TParseContext parseContext(symbolTable, intermediate, true, version, profile, spvVersion, language, infoSink);
TShader::ForbidInclude includer;
TPpContext ppContext(parseContext, "", includer);
TScanContext scanContext(parseContext);
@ -189,12 +189,12 @@ int CommonIndex(EProfile profile, EShLanguage language)
//
// To initialize per-stage shared tables, with the common table already complete.
//
void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int version, EProfile profile, int spv, int vulkan,
void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int version, EProfile profile, const SpvVersion& spvVersion,
EShLanguage language, TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables)
{
(*symbolTables[language]).adoptLevels(*commonTable[CommonIndex(profile, language)]);
InitializeSymbolTable(builtInParseables.getStageString(language), version, profile, spv, vulkan, language, infoSink, *symbolTables[language]);
builtInParseables.identifyBuiltIns(version, profile, spv, vulkan, language, *symbolTables[language]);
InitializeSymbolTable(builtInParseables.getStageString(language), version, profile, spvVersion, language, infoSink, *symbolTables[language]);
builtInParseables.identifyBuiltIns(version, profile, spvVersion, language, *symbolTables[language]);
if (profile == EEsProfile && version >= 300)
(*symbolTables[language]).setNoBuiltInRedeclarations();
if (version == 110)
@ -205,51 +205,51 @@ void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int versi
// Initialize the full set of shareable symbol tables;
// The common (cross-stage) and those shareable per-stage.
//
bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables, int version, EProfile profile, int spv, int vulkan, EShSource source)
bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables, int version, EProfile profile, const SpvVersion& spvVersion, EShSource source)
{
std::unique_ptr<TBuiltInParseables> builtInParseables(CreateBuiltInParseables(infoSink, source));
builtInParseables->initialize(version, profile, spv, vulkan);
builtInParseables->initialize(version, profile, spvVersion);
// do the common tables
InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spv, vulkan, EShLangVertex, infoSink, *commonTable[EPcGeneral]);
InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, EShLangVertex, infoSink, *commonTable[EPcGeneral]);
if (profile == EEsProfile)
InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spv, vulkan, EShLangFragment, infoSink, *commonTable[EPcFragment]);
InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, EShLangFragment, infoSink, *commonTable[EPcFragment]);
// do the per-stage tables
// always have vertex and fragment
InitializeStageSymbolTable(*builtInParseables, version, profile, spv, vulkan, EShLangVertex, infoSink, commonTable, symbolTables);
InitializeStageSymbolTable(*builtInParseables, version, profile, spv, vulkan, EShLangFragment, infoSink, commonTable, symbolTables);
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangVertex, infoSink, commonTable, symbolTables);
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangFragment, infoSink, commonTable, symbolTables);
// check for tessellation
if ((profile != EEsProfile && version >= 150) ||
(profile == EEsProfile && version >= 310)) {
InitializeStageSymbolTable(*builtInParseables, version, profile, spv, vulkan, EShLangTessControl, infoSink, commonTable, symbolTables);
InitializeStageSymbolTable(*builtInParseables, version, profile, spv, vulkan, EShLangTessEvaluation, infoSink, commonTable, symbolTables);
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTessControl, infoSink, commonTable, symbolTables);
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTessEvaluation, infoSink, commonTable, symbolTables);
}
// check for geometry
if ((profile != EEsProfile && version >= 150) ||
(profile == EEsProfile && version >= 310))
InitializeStageSymbolTable(*builtInParseables, version, profile, spv, vulkan, EShLangGeometry, infoSink, commonTable, symbolTables);
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangGeometry, infoSink, commonTable, symbolTables);
// check for compute
if ((profile != EEsProfile && version >= 420) ||
(profile == EEsProfile && version >= 310))
InitializeStageSymbolTable(*builtInParseables, version, profile, spv, vulkan, EShLangCompute, infoSink, commonTable, symbolTables);
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, infoSink, commonTable, symbolTables);
return true;
}
bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& infoSink, TSymbolTable& symbolTable, int version,
EProfile profile, int spv, int vulkan, EShLanguage language, EShSource source)
EProfile profile, const SpvVersion& spvVersion, EShLanguage language, EShSource source)
{
std::unique_ptr<TBuiltInParseables> builtInParseables(CreateBuiltInParseables(infoSink, source));
builtInParseables->initialize(*resources, version, profile, spv, vulkan, language);
InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spv, vulkan, language, infoSink, symbolTable);
builtInParseables->identifyBuiltIns(version, profile, spv, vulkan, language, symbolTable, *resources);
builtInParseables->initialize(*resources, version, profile, spvVersion, language);
InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, language, infoSink, symbolTable);
builtInParseables->identifyBuiltIns(version, profile, spvVersion, language, symbolTable, *resources);
return true;
}
@ -266,7 +266,7 @@ bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& inf
// This only gets done the first time any thread needs a particular symbol table
// (lazy evaluation).
//
void SetupBuiltinSymbolTable(int version, EProfile profile, int spv, int vulkan, EShSource source)
void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& spvVersion, EShSource source)
{
TInfoSink infoSink;
@ -296,7 +296,7 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, int spv, int vulkan,
stageTables[stage] = new TSymbolTable;
// Generate the local symbol tables using the new pool
InitializeSymbolTables(infoSink, commonTable, stageTables, version, profile, spv, vulkan, source);
InitializeSymbolTables(infoSink, commonTable, stageTables, version, profile, spvVersion, source);
// Switch to the process-global pool
SetThreadPoolAllocator(*PerProcessGPA);
@ -332,7 +332,7 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, int spv, int vulkan,
// Return true if the shader was correctly specified for version/profile/stage.
bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNotFirst, int defaultVersion,
EShSource source, int& version, EProfile& profile, int spv)
EShSource source, int& version, EProfile& profile, const SpvVersion& spvVersion)
{
const int FirstProfileVersion = 150;
bool correct = true;
@ -430,19 +430,27 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
}
// Check for SPIR-V compatibility
if (spv > 0) {
if (profile == EEsProfile) {
if (version < 310) {
if (spvVersion.spv != 0) {
switch (profile) {
case EEsProfile:
if (spvVersion.vulkan >= 100 && version < 310) {
correct = false;
infoSink.info.message(EPrefixError, "#version: ES shaders for SPIR-V require version 310 or higher");
infoSink.info.message(EPrefixError, "#version: ES shaders for Vulkan SPIR-V require version 310 or higher");
version = 310;
}
} else {
if (version < 140) {
// gl_spirv TODO: test versions
break;
case ECompatibilityProfile:
infoSink.info.message(EPrefixError, "#version: compilation for SPIR-V does not support the compatibility profile");
break;
default:
if (spvVersion.vulkan >= 100 && version < 140) {
correct = false;
infoSink.info.message(EPrefixError, "#version: Desktop shaders for SPIR-V require version 140 or higher");
infoSink.info.message(EPrefixError, "#version: Desktop shaders for Vulkan SPIR-V require version 140 or higher");
version = 140;
}
// gl_spirv TODO: test versions
break;
}
}
@ -581,9 +589,11 @@ bool ProcessDeferred(
version = defaultVersion;
profile = defaultProfile;
}
int spv = (messages & EShMsgSpvRules) ? 100 : 0; // TODO find path to get real version number here, for now non-0 is what matters
SpvVersion spvVersion;
if (messages & EShMsgSpvRules)
spvVersion.spv = 0x00010000; // TODO: eventually have this come from the outside
EShSource source = (messages & EShMsgReadHlsl) ? EShSourceHlsl : EShSourceGlsl;
bool goodVersion = DeduceVersionProfile(compiler->infoSink, compiler->getLanguage(), versionNotFirst, defaultVersion, source, version, profile, spv);
bool goodVersion = DeduceVersionProfile(compiler->infoSink, compiler->getLanguage(), versionNotFirst, defaultVersion, source, version, profile, spvVersion);
bool versionWillBeError = (versionNotFound || (profile == EEsProfile && version >= 300 && versionNotFirst));
bool warnVersionNotFirst = false;
if (! versionWillBeError && versionNotFirstToken) {
@ -593,14 +603,17 @@ bool ProcessDeferred(
versionWillBeError = true;
}
int vulkan = (messages & EShMsgVulkanRules) ? 100 : 0; // TODO find path to get real version number here, for now non-0 is what matters
if (messages & EShMsgVulkanRules)
spvVersion.vulkan = 100; // TODO: eventually have this come from the outside
else if (spvVersion.spv != 0)
spvVersion.openGl = 100;
intermediate.setSource(source);
intermediate.setVersion(version);
intermediate.setProfile(profile);
intermediate.setSpv(spv);
if (vulkan)
intermediate.setSpv(spvVersion);
if (spvVersion.vulkan >= 100)
intermediate.setOriginUpperLeft();
SetupBuiltinSymbolTable(version, profile, spv, vulkan, source);
SetupBuiltinSymbolTable(version, profile, spvVersion, source);
TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
[MapProfileToIndex(profile)]
@ -614,7 +627,7 @@ bool ProcessDeferred(
// Add built-in symbols that are potentially context dependent;
// they get popped again further down.
AddContextSpecificSymbols(resources, compiler->infoSink, symbolTable, version, profile, spv, vulkan,
AddContextSpecificSymbols(resources, compiler->infoSink, symbolTable, version, profile, spvVersion,
compiler->getLanguage(), source);
//
@ -623,12 +636,12 @@ bool ProcessDeferred(
TParseContextBase* parseContext;
if (source == EShSourceHlsl) {
parseContext = new HlslParseContext(symbolTable, intermediate, false, version, profile, spv, vulkan,
parseContext = new HlslParseContext(symbolTable, intermediate, false, version, profile, spvVersion,
compiler->getLanguage(), compiler->infoSink, forwardCompatible, messages);
}
else {
intermediate.setEntryPoint("main");
parseContext = new TParseContext(symbolTable, intermediate, false, version, profile, spv, vulkan,
parseContext = new TParseContext(symbolTable, intermediate, false, version, profile, spvVersion,
compiler->getLanguage(), compiler->infoSink, forwardCompatible, messages);
}
TPpContext ppContext(*parseContext, names[numPre]? names[numPre]: "", includer);