Support multiple default versions, to enable ES vs. desktop contexts, for shaders missing a #version statement.
This also moved some parseContext code from the flex file to the proper C++ file. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@20501 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
c435c71d87
commit
46eaf4939e
@ -45,17 +45,82 @@
|
|||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage L, TInfoSink& is) :
|
TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage L, TInfoSink& is, int defaultVersion) :
|
||||||
intermediate(interm), symbolTable(symt), infoSink(is), language(L), treeRoot(0),
|
intermediate(interm), symbolTable(symt), infoSink(is), language(L), treeRoot(0),
|
||||||
recoveredFromError(false), numErrors(0), lexAfterType(false), loopNestingLevel(0),
|
recoveredFromError(false), numErrors(0), lexAfterType(false), loopNestingLevel(0),
|
||||||
switchNestingLevel(0), inTypeParen(false),
|
switchNestingLevel(0), inTypeParen(false),
|
||||||
version(110), profile(ENoProfile), futureCompatibility(false),
|
futureCompatibility(false),
|
||||||
contextPragma(true, false)
|
contextPragma(true, false)
|
||||||
{
|
{
|
||||||
// Default precisions for version 110, to be overridden for
|
// Default precisions for version 110, to be overridden for
|
||||||
// other versions/profiles/stage combinations
|
// other versions/profiles/stage combinations
|
||||||
for (int type = 0; type < EbtNumTypes; ++type)
|
for (int type = 0; type < EbtNumTypes; ++type)
|
||||||
defaultPrecision[type] = EpqNone;
|
defaultPrecision[type] = EpqNone;
|
||||||
|
|
||||||
|
setVersion(defaultVersion);
|
||||||
|
setProfile(ENoProfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TParseContext::setVersion(int newVersion)
|
||||||
|
{
|
||||||
|
version = newVersion;
|
||||||
|
if (version == 100 || version == 300) {
|
||||||
|
if (language == EShLangVertex) {
|
||||||
|
defaultPrecision[EbtInt] = EpqHigh;
|
||||||
|
defaultPrecision[EbtFloat] = EpqHigh;
|
||||||
|
defaultPrecision[EbtSampler2D] = EpqLow;
|
||||||
|
defaultPrecision[EbtSamplerCube] = EpqLow;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (language == EShLangFragment) {
|
||||||
|
defaultPrecision[EbtInt] = EpqMedium;
|
||||||
|
defaultPrecision[EbtSampler2D] = EpqLow;
|
||||||
|
defaultPrecision[EbtSamplerCube] = EpqLow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Important assumption: SetVersion() is called before SetProfile(), and is always called
|
||||||
|
// if there is a version, sending in a ENoProfile if there is no profile given.
|
||||||
|
void TParseContext::setProfile(EProfile newProfile)
|
||||||
|
{
|
||||||
|
const int FirstProfileVersion = 150;
|
||||||
|
|
||||||
|
if (newProfile == ENoProfile) {
|
||||||
|
if (version == 300) {
|
||||||
|
error(1, "version 300 requires specifying the 'es' profile", "#version", "");
|
||||||
|
profile = EEsProfile;
|
||||||
|
} else if (version == 100)
|
||||||
|
profile = EEsProfile;
|
||||||
|
else if (version >= FirstProfileVersion)
|
||||||
|
profile = ECoreProfile;
|
||||||
|
else
|
||||||
|
profile = ENoProfile;
|
||||||
|
} else {
|
||||||
|
// a profile was provided...
|
||||||
|
if (version < 150) {
|
||||||
|
error(1, "versions before 150 do not allow a profile token", "#version", "");
|
||||||
|
if (version == 100)
|
||||||
|
profile = EEsProfile;
|
||||||
|
else
|
||||||
|
profile = ENoProfile;
|
||||||
|
} else if (version == 300) {
|
||||||
|
if (newProfile != EEsProfile)
|
||||||
|
error(1, "only version 300 supports the es profile", "#version", "");
|
||||||
|
profile = EEsProfile;
|
||||||
|
} else {
|
||||||
|
if (newProfile == EEsProfile) {
|
||||||
|
error(1, "only version 300 supports the es profile", "#version", "");
|
||||||
|
if (version >= FirstProfileVersion)
|
||||||
|
profile = ECoreProfile;
|
||||||
|
else
|
||||||
|
profile = ENoProfile;
|
||||||
|
} else {
|
||||||
|
// typical desktop case... e.g., "#version 410 core"
|
||||||
|
profile = newProfile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -67,7 +67,7 @@ struct TPragma {
|
|||||||
// they can be passed to the parser without needing a global.
|
// they can be passed to the parser without needing a global.
|
||||||
//
|
//
|
||||||
struct TParseContext {
|
struct TParseContext {
|
||||||
TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage L, TInfoSink& is);
|
TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage L, TInfoSink& is, int defaultVersion);
|
||||||
TIntermediate& intermediate; // to hold and build a parse tree
|
TIntermediate& intermediate; // to hold and build a parse tree
|
||||||
TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed
|
TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed
|
||||||
TInfoSink& infoSink;
|
TInfoSink& infoSink;
|
||||||
@ -92,6 +92,9 @@ struct TParseContext {
|
|||||||
TString HashErrMsg;
|
TString HashErrMsg;
|
||||||
bool AfterEOF;
|
bool AfterEOF;
|
||||||
|
|
||||||
|
void setVersion(int);
|
||||||
|
void setProfile(EProfile);
|
||||||
|
|
||||||
void initializeExtensionBehavior();
|
void initializeExtensionBehavior();
|
||||||
|
|
||||||
void C_DECL error(TSourceLoc, const char *szReason, const char *szToken,
|
void C_DECL error(TSourceLoc, const char *szReason, const char *szToken,
|
||||||
|
@ -190,7 +190,7 @@ bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language
|
|||||||
else
|
else
|
||||||
symbolTable = &symbolTables[language];
|
symbolTable = &symbolTables[language];
|
||||||
|
|
||||||
TParseContext parseContext(*symbolTable, intermediate, language, infoSink);
|
TParseContext parseContext(*symbolTable, intermediate, language, infoSink, 110);
|
||||||
|
|
||||||
GlobalParseContext = &parseContext;
|
GlobalParseContext = &parseContext;
|
||||||
|
|
||||||
@ -255,7 +255,8 @@ int ShCompile(
|
|||||||
const int numStrings,
|
const int numStrings,
|
||||||
const EShOptimizationLevel optLevel,
|
const EShOptimizationLevel optLevel,
|
||||||
const TBuiltInResource* resources,
|
const TBuiltInResource* resources,
|
||||||
int debugOptions
|
int debugOptions,
|
||||||
|
int defaultVersion
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!InitThread())
|
if (!InitThread())
|
||||||
@ -281,9 +282,7 @@ int ShCompile(
|
|||||||
|
|
||||||
GenerateBuiltInSymbolTable(resources, compiler->infoSink, &symbolTable, compiler->getLanguage());
|
GenerateBuiltInSymbolTable(resources, compiler->infoSink, &symbolTable, compiler->getLanguage());
|
||||||
|
|
||||||
// TODO: this is happening *after* initialization, which already parsed some things... what parse context was that?
|
TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->infoSink, defaultVersion);
|
||||||
// what extensions did it have?
|
|
||||||
TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->infoSink);
|
|
||||||
parseContext.initializeExtensionBehavior();
|
parseContext.initializeExtensionBehavior();
|
||||||
|
|
||||||
GlobalParseContext = &parseContext;
|
GlobalParseContext = &parseContext;
|
||||||
|
@ -798,66 +798,13 @@ void ResetTString(void)
|
|||||||
void SetVersion(int version)
|
void SetVersion(int version)
|
||||||
{
|
{
|
||||||
TParseContext& parseContext = *((TParseContext *)cpp->pC);
|
TParseContext& parseContext = *((TParseContext *)cpp->pC);
|
||||||
parseContext.version = version;
|
parseContext.setVersion(version);
|
||||||
|
|
||||||
if (version == 100 || version == 300) {
|
|
||||||
if (parseContext.language == EShLangVertex) {
|
|
||||||
parseContext.defaultPrecision[EbtInt] = EpqHigh;
|
|
||||||
parseContext.defaultPrecision[EbtFloat] = EpqHigh;
|
|
||||||
parseContext.defaultPrecision[EbtSampler2D] = EpqLow;
|
|
||||||
parseContext.defaultPrecision[EbtSamplerCube] = EpqLow;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parseContext.language == EShLangFragment) {
|
|
||||||
parseContext.defaultPrecision[EbtInt] = EpqMedium;
|
|
||||||
parseContext.defaultPrecision[EbtSampler2D] = EpqLow;
|
|
||||||
parseContext.defaultPrecision[EbtSamplerCube] = EpqLow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Important assumption: SetVersion() is called before SetProfile(), and is always called
|
|
||||||
// if there is a version, sending in a ENoProfile if there is no profile given.
|
|
||||||
void SetProfile(EProfile profile)
|
void SetProfile(EProfile profile)
|
||||||
{
|
{
|
||||||
const int FirstProfileVersion = 150;
|
|
||||||
TParseContext& parseContext = *((TParseContext *)cpp->pC);
|
TParseContext& parseContext = *((TParseContext *)cpp->pC);
|
||||||
|
parseContext.setProfile(profile);
|
||||||
if (profile == ENoProfile) {
|
|
||||||
if (parseContext.version == 300) {
|
|
||||||
CPPErrorToInfoLog("version 300 requires specifying the 'es' profile");
|
|
||||||
parseContext.profile = EEsProfile;
|
|
||||||
} else if (parseContext.version == 100)
|
|
||||||
parseContext.profile = EEsProfile;
|
|
||||||
else if (parseContext.version >= FirstProfileVersion)
|
|
||||||
parseContext.profile = ECoreProfile;
|
|
||||||
else
|
|
||||||
parseContext.profile = ENoProfile;
|
|
||||||
} else {
|
|
||||||
// a profile was provided...
|
|
||||||
if (parseContext.version < 150) {
|
|
||||||
CPPErrorToInfoLog("versions before 150 do not allow a profile token");
|
|
||||||
if (parseContext.version == 100)
|
|
||||||
parseContext.profile = EEsProfile;
|
|
||||||
else
|
|
||||||
parseContext.profile = ENoProfile;
|
|
||||||
} else if (parseContext.version == 300) {
|
|
||||||
if (profile != EEsProfile)
|
|
||||||
CPPErrorToInfoLog("only version 300 supports the es profile");
|
|
||||||
parseContext.profile = EEsProfile;
|
|
||||||
} else {
|
|
||||||
if (profile == EEsProfile) {
|
|
||||||
CPPErrorToInfoLog("only version 300 supports the es profile");
|
|
||||||
if (parseContext.version >= FirstProfileVersion)
|
|
||||||
parseContext.profile = ECoreProfile;
|
|
||||||
else
|
|
||||||
parseContext.profile = ENoProfile;
|
|
||||||
} else {
|
|
||||||
// typical desktop case... e.g., "#version 410 core"
|
|
||||||
parseContext.profile = profile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TBehavior GetBehavior(const char* behavior)
|
TBehavior GetBehavior(const char* behavior)
|
||||||
|
@ -154,7 +154,8 @@ SH_IMPORT_EXPORT int ShCompile(
|
|||||||
const int numStrings,
|
const int numStrings,
|
||||||
const EShOptimizationLevel,
|
const EShOptimizationLevel,
|
||||||
const TBuiltInResource *resources,
|
const TBuiltInResource *resources,
|
||||||
int debugOptions
|
int debugOptions,
|
||||||
|
int defaultVersion = 110 // use 100 for ES environment
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user