Commit 61c2d141 by John Kessenich

Document how to add a new feature enabled by an extension in Versions.cpp. Also…

Document how to add a new feature enabled by an extension in Versions.cpp. Also reorganized slightly to localize related functions. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@23376 e7fa87d3-cd2b-0410-9028-fcbf551c1848
parent a5830dfc
...@@ -7,10 +7,13 @@ There are two components: ...@@ -7,10 +7,13 @@ There are two components:
2) A standalone wrapper, glslangValidator, that can be used as a shader 2) A standalone wrapper, glslangValidator, that can be used as a shader
validation tool. validation tool.
How to add a feature protected by a version/extension/stage/profile: See the
comment in glslang/MachineIndependent/Versions.cpp.
Things left to do: See Todo.txt Things left to do: See Todo.txt
Execution Execution of Standalone Wrapper
--------- -------------------------------
There are binaries in the Install/Windows and Install/Linux directories. There are binaries in the Install/Windows and Install/Linux directories.
...@@ -26,7 +29,10 @@ The applied stage-specific rules are based on the file extension: ...@@ -26,7 +29,10 @@ The applied stage-specific rules are based on the file extension:
.frag for a fragment shader .frag for a fragment shader
.comp for a compute shader .comp for a compute shader
Source: Build and run on linux There is also a non-shader extension
.conf for a configuration file of limits, see usage statement for example
Source: Build and run on Linux
------------------------------- -------------------------------
A simple bash script "BuildLinux.sh" is provided at the root directory A simple bash script "BuildLinux.sh" is provided at the root directory
......
Current functionality level: ESSL 3.0 Current functionality level: ESSL 3.0
- extension adding process
Link Validation Link Validation
+ provide input config file for setting limits + provide input config file for setting limits
- also consider spitting out measures of complexity - also consider spitting out measures of complexity
...@@ -166,22 +164,24 @@ Shader Functionality to Implement/Finish ...@@ -166,22 +164,24 @@ Shader Functionality to Implement/Finish
- Allow swizzle operations on scalars. - Allow swizzle operations on scalars.
- Positive signed decimal literals, as well as octal and hexadecimal, can set all 32 bits. This includes setting the sign bit to create a negative value. - Positive signed decimal literals, as well as octal and hexadecimal, can set all 32 bits. This includes setting the sign bit to create a negative value.
- Make GLSL consistent with the API regarding user clipping, by no longer referring to gl_Positionwhen gl_ClipVertex is not written. Rather, user clipping becomes undefined. - Make GLSL consistent with the API regarding user clipping, by no longer referring to gl_Positionwhen gl_ClipVertex is not written. Rather, user clipping becomes undefined.
- Clarified that a comma sequence-operator expression cannot be a constant expression. E.g., “(2,3)” is not allowed, semantically, as a valid constant expression 3, even though it is an expression that will evaluate to 3. - Clarified that a comma sequence-operator expression cannot be a constant expression. E.g., “(2,3)” is not allowed, semantically,
as a valid constant expression 3, even though it is an expression that will evaluate to 3.
- Use vec2 instead of vec3 for coordinate in textureGather*(sampler2DRect,...). - Use vec2 instead of vec3 for coordinate in textureGather*(sampler2DRect,...).
- Clarify that textureGatherOffset() can take non-constants for the offsets. - Clarify that textureGatherOffset() can take non-constants for the offsets.
GLSL 4.3 GLSL 4.3
- Add shader storage bufferobjects, as per the ARB_shader_storage_buffer_object extension. - Add shader storage buffer objects, as per the ARB_shader_storage_buffer_object extension. This includes
This includes 1) allowing the last member of a storage buffer block to be an array that does not - allowing the last member of a storage buffer block to be an array that does not know its size until render time
know its size until render time, and 2) read/write memory shared with the application and other - read/write memory shared with the application and other shader invocations
shader invocations. It also adds the std430layout qualifier for shader storage blocks. - adding the std430 layout qualifier for shader storage blocks
- Allow .length() on all arrays; returning a compile-time constant or not, depending on how the - Allow .length() on all arrays; returning a compile-time constant or not, depending on how the
array is sized, as per the ARB_shader_storage_buffer_object extension. array is sized, as per the ARB_shader_storage_buffer_object extension.
- Be clear that implicit array sizing is only within a stage, not cross stage. - Be clear that implicit array sizing is only within a stage, not cross stage.
- Array clarifications: 1) All arrays are inherently homogeneous, except for arrays of the new - Array clarifications:
shader storage buffer objects. 2) Arrays of shader storage buffer objects will be dereferenced - All arrays are inherently homogeneous, except for arrays of the new shader storage buffer objects
when the .length() method is used on an unsized array member, so that must a have valid index. - Arrays of shader storage buffer objects will be dereferenced when the .length() method is used on an unsized array
3) Arrays of other objects (uniform blocks) containing implicitly sized arrays will have the same member, so that must a have valid index.
implicit size for all elements of the array. - Arrays of other objects (uniform blocks) containing implicitly sized arrays will have the same implicit size for all
elements of the array.
- Arrays of arrays are now supported, as per the GL_ARB_arrays_of_arraysextension. - Arrays of arrays are now supported, as per the GL_ARB_arrays_of_arraysextension.
- Compute shaders are now supported, as per the GL_ARB_compute_shader extension. - Compute shaders are now supported, as per the GL_ARB_compute_shader extension.
- Added imageSize() built-ins to query the dimensions of an image. - Added imageSize() built-ins to query the dimensions of an image.
......
...@@ -584,7 +584,7 @@ void TBuiltIns::initialize(int version, EProfile profile) ...@@ -584,7 +584,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
s.append("\n"); s.append("\n");
// //
// Original-style texture Functions existing in both stages. // Original-style texture functions existing in both stages.
// (Per-stage functions below.) // (Per-stage functions below.)
// //
if (profile == EEsProfile && version == 100 || if (profile == EEsProfile && version == 100 ||
......
...@@ -1098,7 +1098,7 @@ void TIntermediate::checkCallGraphCycles(TInfoSink& infoSink) ...@@ -1098,7 +1098,7 @@ void TIntermediate::checkCallGraphCycles(TInfoSink& infoSink)
void TIntermediate::error(TInfoSink& infoSink, const char* message) void TIntermediate::error(TInfoSink& infoSink, const char* message)
{ {
infoSink.info.prefix(EPrefixError); infoSink.info.prefix(EPrefixError);
infoSink.info << "Linking " << StageName[language] << " stage: " << message << "\n"; infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
++numErrors; ++numErrors;
} }
......
...@@ -249,59 +249,6 @@ void TParseContext::handlePragma(const char **tokens, int numTokens) ...@@ -249,59 +249,6 @@ void TParseContext::handlePragma(const char **tokens, int numTokens)
} }
} }
TBehavior TParseContext::getExtensionBehavior(const char* behavior)
{
if (!strcmp("require", behavior))
return EBhRequire;
else if (!strcmp("enable", behavior))
return EBhEnable;
else if (!strcmp("disable", behavior))
return EBhDisable;
else if (!strcmp("warn", behavior))
return EBhWarn;
else {
error(currentLoc, "behavior not supported", "#extension", behavior);
return EBhDisable;
}
}
void TParseContext::updateExtensionBehavior(const char* extName, const char* behavior)
{
TBehavior behaviorVal = getExtensionBehavior(behavior);
TMap<TString, TBehavior>:: iterator iter;
TString msg;
// special cased for all extension
if (!strcmp(extName, "all")) {
if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) {
error(currentLoc, "extension 'all' cannot have 'require' or 'enable' behavior", "#extension", "");
return;
} else {
for (iter = extensionBehavior.begin(); iter != extensionBehavior.end(); ++iter)
iter->second = behaviorVal;
}
} else {
iter = extensionBehavior.find(TString(extName));
if (iter == extensionBehavior.end()) {
switch (behaviorVal) {
case EBhRequire:
error(currentLoc, "extension not supported", "#extension", extName);
break;
case EBhEnable:
case EBhWarn:
case EBhDisable:
warn(currentLoc, "extension not supported", "#extension", extName);
break;
default:
assert(0 && "unexpected behaviorVal");
}
return;
} else
iter->second = behaviorVal;
}
}
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// //
// Sub- vector and matrix fields // Sub- vector and matrix fields
...@@ -538,12 +485,11 @@ TIntermTyped* TParseContext::handleBracketDereference(TSourceLoc loc, TIntermTyp ...@@ -538,12 +485,11 @@ TIntermTyped* TParseContext::handleBracketDereference(TSourceLoc loc, TIntermTyp
if (base->isArray() && base->getType().getArraySize() == 0) if (base->isArray() && base->getType().getArraySize() == 0)
error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable"); error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable");
if (base->getBasicType() == EbtBlock) if (base->getBasicType() == EbtBlock)
requireProfile(base->getLoc(), static_cast<EProfileMask>(~EEsProfileMask), "variable indexing block array"); requireProfile(base->getLoc(), ~EEsProfile, "variable indexing block array");
if (base->getBasicType() == EbtSampler && version >= 130) { if (base->getBasicType() == EbtSampler && version >= 130) {
const char* explanation = "variable indexing sampler array"; const char* explanation = "variable indexing sampler array";
requireProfile(base->getLoc(), static_cast<EProfileMask>(ECoreProfileMask | ECompatibilityProfileMask), explanation); requireProfile(base->getLoc(), ECoreProfile | ECompatibilityProfile, explanation);
profileRequires(base->getLoc(), ECoreProfile, 400, 0, explanation); profileRequires(base->getLoc(), ECoreProfile | ECompatibilityProfile, 400, 0, explanation);
profileRequires(base->getLoc(), ECompatibilityProfile, 400, 0, explanation);
} }
result = intermediate.addIndex(EOpIndexIndirect, base, index, loc); result = intermediate.addIndex(EOpIndexIndirect, base, index, loc);
...@@ -662,7 +608,7 @@ TFunction* TParseContext::handleFunctionDeclarator(TSourceLoc loc, TFunction& fu ...@@ -662,7 +608,7 @@ TFunction* TParseContext::handleFunctionDeclarator(TSourceLoc loc, TFunction& fu
{ {
// ES can't declare prototypes inside functions // ES can't declare prototypes inside functions
if (! symbolTable.atGlobalLevel()) if (! symbolTable.atGlobalLevel())
requireProfile(loc, static_cast<EProfileMask>(~EEsProfileMask), "local function declaration"); requireProfile(loc, ~EEsProfile, "local function declaration");
// //
// Multiple declarations of the same function are allowed. // Multiple declarations of the same function are allowed.
...@@ -1479,7 +1425,7 @@ void TParseContext::globalQualifierFix(TSourceLoc loc, TQualifier& qualifier, co ...@@ -1479,7 +1425,7 @@ void TParseContext::globalQualifierFix(TSourceLoc loc, TQualifier& qualifier, co
return; return;
} }
if (publicType.arraySizes) { if (publicType.arraySizes) {
requireProfile(loc, (EProfileMask)~EEsProfileMask, "vertex input arrays"); requireProfile(loc, ~EEsProfile, "vertex input arrays");
profileRequires(loc, ENoProfile, 150, 0, "vertex input arrays"); profileRequires(loc, ENoProfile, 150, 0, "vertex input arrays");
} }
} }
...@@ -1706,7 +1652,7 @@ bool TParseContext::arrayQualifierError(TSourceLoc loc, const TQualifier& qualif ...@@ -1706,7 +1652,7 @@ bool TParseContext::arrayQualifierError(TSourceLoc loc, const TQualifier& qualif
profileRequires(loc, ENoProfile, 120, "GL_3DL_array_objects", "const array"); profileRequires(loc, ENoProfile, 120, "GL_3DL_array_objects", "const array");
if (qualifier.storage == EvqVaryingIn && language == EShLangVertex) { if (qualifier.storage == EvqVaryingIn && language == EShLangVertex) {
requireProfile(loc, (EProfileMask)~EEsProfileMask, "vertex input arrays"); requireProfile(loc, ~EEsProfile, "vertex input arrays");
profileRequires(loc, ENoProfile, 150, 0, "vertex input arrays"); profileRequires(loc, ENoProfile, 150, 0, "vertex input arrays");
} }
...@@ -1726,9 +1672,8 @@ void TParseContext::arraySizeRequiredCheck(TSourceLoc loc, int size) ...@@ -1726,9 +1672,8 @@ void TParseContext::arraySizeRequiredCheck(TSourceLoc loc, int size)
void TParseContext::arrayDimError(TSourceLoc loc) void TParseContext::arrayDimError(TSourceLoc loc)
{ {
requireProfile(loc, (EProfileMask)(ECoreProfileMask | ECompatibilityProfileMask), "arrays of arrays"); requireProfile(loc, ECoreProfile | ECompatibilityProfile, "arrays of arrays");
profileRequires(loc, ECoreProfile, 430, 0, "arrays of arrays"); profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, "arrays of arrays");
profileRequires(loc, ECompatibilityProfile, 430, 0, "arrays of arrays");
} }
void TParseContext::arrayDimCheck(TSourceLoc loc, TArraySizes* sizes1, TArraySizes* sizes2) void TParseContext::arrayDimCheck(TSourceLoc loc, TArraySizes* sizes1, TArraySizes* sizes2)
...@@ -2387,7 +2332,7 @@ void TParseContext::addBlock(TSourceLoc loc, TTypeList& typeList, const TString* ...@@ -2387,7 +2332,7 @@ void TParseContext::addBlock(TSourceLoc loc, TTypeList& typeList, const TString*
arraySizeRequiredCheck(loc, arraySizes->getSize()); arraySizeRequiredCheck(loc, arraySizes->getSize());
if (currentBlockDefaults.storage == EvqUniform) { if (currentBlockDefaults.storage == EvqUniform) {
requireProfile(loc, (EProfileMask)(~ENoProfileMask), "uniform block"); requireProfile(loc, ~ENoProfile, "uniform block");
profileRequires(loc, EEsProfile, 300, 0, "uniform block"); profileRequires(loc, EEsProfile, 300, 0, "uniform block");
} else { } else {
error(loc, "only uniform interface blocks are supported", blockName->c_str(), ""); error(loc, "only uniform interface blocks are supported", blockName->c_str(), "");
...@@ -2788,17 +2733,4 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n ...@@ -2788,17 +2733,4 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n
return typedNode; return typedNode;
} }
//
// Initialize all supported extensions to disable
//
void TParseContext::initializeExtensionBehavior()
{
//
// example code: extensionBehavior["test"] = EBhDisable; // where "test" is the name of
// supported extension
//
extensionBehavior["GL_ARB_texture_rectangle"] = EBhDisable;
extensionBehavior["GL_3DL_array_objects"] = EBhDisable;
}
} // end namespace glslang } // end namespace glslang
...@@ -43,13 +43,6 @@ ...@@ -43,13 +43,6 @@
namespace glslang { namespace glslang {
typedef enum {
EBhRequire,
EBhEnable,
EBhWarn,
EBhDisable
} TBehavior;
struct TPragma { struct TPragma {
TPragma(bool o, bool d) : optimize(o), debug(d) { } TPragma(bool o, bool d) : optimize(o), debug(d) { }
bool optimize; bool optimize;
...@@ -71,7 +64,6 @@ public: ...@@ -71,7 +64,6 @@ public:
public: public:
bool parseShaderStrings(TPpContext&, char* strings[], int strLen[], int numStrings); bool parseShaderStrings(TPpContext&, char* strings[], int strLen[], int numStrings);
void initializeExtensionBehavior();
void parserError(const char *s); // for bison's yyerror void parserError(const char *s); // for bison's yyerror
void C_DECL error(TSourceLoc, const char *szReason, const char *szToken, void C_DECL error(TSourceLoc, const char *szReason, const char *szToken,
...@@ -148,15 +140,6 @@ public: ...@@ -148,15 +140,6 @@ public:
bool arraySetMaxSize(TSourceLoc, TIntermSymbol*, int); bool arraySetMaxSize(TSourceLoc, TIntermSymbol*, int);
void requireProfile(TSourceLoc, EProfileMask profileMask, const char *featureDesc);
void requireStage(TSourceLoc, EShLanguageMask languageMask, const char *featureDesc);
void profileRequires(TSourceLoc, EProfile callingProfile, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc);
void profileRequires(TSourceLoc, EProfile callingProfile, int minVersion, const char* extension, const char *featureDesc);
void checkDeprecated(TSourceLoc, EProfile callingProfile, int depVersion, const char *featureDesc);
void requireNotRemoved(TSourceLoc, EProfile callingProfile, int removedVersion, const char *featureDesc);
void fullIntegerCheck(TSourceLoc, const char* op);
void doubleCheck(TSourceLoc, const char* op);
void setScanContext(TScanContext* c) { scanContext = c; } void setScanContext(TScanContext* c) { scanContext = c; }
TScanContext* getScanContext() const { return scanContext; } TScanContext* getScanContext() const { return scanContext; }
void setPpContext(TPpContext* c) { ppContext = c; } void setPpContext(TPpContext* c) { ppContext = c; }
...@@ -164,9 +147,21 @@ public: ...@@ -164,9 +147,21 @@ public:
void addError() { ++numErrors; } void addError() { ++numErrors; }
int getNumErrors() const { return numErrors; } int getNumErrors() const { return numErrors; }
// The following are implemented in Versions.cpp to localize version/profile/stage/extensions control
void initializeExtensionBehavior();
void requireProfile(TSourceLoc, int queryProfiles, const char *featureDesc);
void profileRequires(TSourceLoc, int queryProfiles, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc);
void profileRequires(TSourceLoc, int queryProfiles, int minVersion, const char* extension, const char *featureDesc);
void requireStage(TSourceLoc, EShLanguageMask, const char *featureDesc);
void requireStage(TSourceLoc, EShLanguage, const char *featureDesc);
void checkDeprecated(TSourceLoc, int queryProfiles, int depVersion, const char *featureDesc);
void requireNotRemoved(TSourceLoc, int queryProfiles, int removedVersion, const char *featureDesc);
void fullIntegerCheck(TSourceLoc, const char* op);
void doubleCheck(TSourceLoc, const char* op);
protected: protected:
const char* getPreamble(); const char* getPreamble();
TBehavior getExtensionBehavior(const char* behavior); TExtensionBehavior getExtensionBehavior(const char* behavior);
void nonInitConstCheck(TSourceLoc, TString& identifier, TType& type); void nonInitConstCheck(TSourceLoc, TString& identifier, TType& type);
TVariable* declareNonArray(TSourceLoc, TString& identifier, TType&, bool& newDeclaration); TVariable* declareNonArray(TSourceLoc, TString& identifier, TType&, bool& newDeclaration);
void declareArray(TSourceLoc, TString& identifier, const TType&, TVariable*&, bool& newDeclaration); void declareArray(TSourceLoc, TString& identifier, const TType&, TVariable*&, bool& newDeclaration);
...@@ -208,7 +203,7 @@ protected: ...@@ -208,7 +203,7 @@ protected:
TPpContext* ppContext; TPpContext* ppContext;
int numErrors; // number of compile-time errors encountered int numErrors; // number of compile-time errors encountered
bool parsingBuiltins; // true if parsing built-in symbols/functions bool parsingBuiltins; // true if parsing built-in symbols/functions
TMap<TString, TBehavior> extensionBehavior; // for each extension string, what it's current enablement is TMap<TString, TExtensionBehavior> extensionBehavior; // for each extension string, what it's current behavior is set to
static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2)); // see computeSamplerTypeIndex() static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2)); // see computeSamplerTypeIndex()
TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex]; TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex];
bool afterEOF; bool afterEOF;
......
...@@ -59,9 +59,11 @@ namespace { // anonymous namespace for file-local functions and symbols ...@@ -59,9 +59,11 @@ namespace { // anonymous namespace for file-local functions and symbols
using namespace glslang; using namespace glslang;
// Local mapping functions for making arrays of symbol tables....
int MapVersionToIndex(int version) int MapVersionToIndex(int version)
{ {
switch(version) { switch (version) {
case 100: return 0; case 100: return 0;
case 110: return 1; case 110: return 1;
case 120: return 2; case 120: return 2;
...@@ -81,6 +83,19 @@ int MapVersionToIndex(int version) ...@@ -81,6 +83,19 @@ int MapVersionToIndex(int version)
} // V } // V
const int VersionCount = 13; // number of case statements above const int VersionCount = 13; // number of case statements above
int MapProfileToIndex(EProfile profile)
{
switch (profile) {
case ENoProfile: return 0;
case ECoreProfile: return 1;
case ECompatibilityProfile: return 2;
case EEsProfile: return 3;
default: // |
return 0; // |
} // |
} // V
const int ProfileCount = 4; // number of case statements above
// 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,
...@@ -96,8 +111,8 @@ enum EPrecisionClass { ...@@ -96,8 +111,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][EProfileCount][EPcCount] = {}; TSymbolTable* CommonSymbolTable[VersionCount][ProfileCount][EPcCount] = {};
TSymbolTable* SharedSymbolTables[VersionCount][EProfileCount][EShLangCount] = {}; TSymbolTable* SharedSymbolTables[VersionCount][ProfileCount][EShLangCount] = {};
TPoolAllocator* PerProcessGPA = 0; TPoolAllocator* PerProcessGPA = 0;
...@@ -216,7 +231,8 @@ void SetupBuiltinSymbolTable(int version, EProfile profile) ...@@ -216,7 +231,8 @@ void SetupBuiltinSymbolTable(int version, EProfile profile)
// See if it's already been done for this version/profile combination // See if it's already been done for this version/profile combination
int versionIndex = MapVersionToIndex(version); int versionIndex = MapVersionToIndex(version);
if (CommonSymbolTable[versionIndex][profile][EPcGeneral]) { int profileIndex = MapProfileToIndex(profile);
if (CommonSymbolTable[versionIndex][profileIndex][EPcGeneral]) {
glslang::ReleaseGlobalLock(); glslang::ReleaseGlobalLock();
return; return;
...@@ -244,17 +260,17 @@ void SetupBuiltinSymbolTable(int version, EProfile profile) ...@@ -244,17 +260,17 @@ void SetupBuiltinSymbolTable(int version, EProfile profile)
// 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][profile][precClass] = new TSymbolTable; CommonSymbolTable[versionIndex][profileIndex][precClass] = new TSymbolTable;
CommonSymbolTable[versionIndex][profile][precClass]->copyTable(*commonTable[precClass]); CommonSymbolTable[versionIndex][profileIndex][precClass]->copyTable(*commonTable[precClass]);
CommonSymbolTable[versionIndex][profile][precClass]->readOnly(); CommonSymbolTable[versionIndex][profileIndex][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][profile][stage] = new TSymbolTable; SharedSymbolTables[versionIndex][profileIndex][stage] = new TSymbolTable;
SharedSymbolTables[versionIndex][profile][stage]->adoptLevels(*CommonSymbolTable[versionIndex][profile][CommonIndex(profile, (EShLanguage)stage)]); SharedSymbolTables[versionIndex][profileIndex][stage]->adoptLevels(*CommonSymbolTable[versionIndex][profileIndex][CommonIndex(profile, (EShLanguage)stage)]);
SharedSymbolTables[versionIndex][profile][stage]->copyTable(*stageTables[stage]); SharedSymbolTables[versionIndex][profileIndex][stage]->copyTable(*stageTables[stage]);
SharedSymbolTables[versionIndex][profile][stage]->readOnly(); SharedSymbolTables[versionIndex][profileIndex][stage]->readOnly();
} }
} }
...@@ -433,7 +449,7 @@ bool CompileDeferred( ...@@ -433,7 +449,7 @@ bool CompileDeferred(
SetupBuiltinSymbolTable(version, profile); SetupBuiltinSymbolTable(version, profile);
TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)] TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
[profile] [MapProfileToIndex(profile)]
[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.
...@@ -569,7 +585,7 @@ void ShDestruct(ShHandle handle) ...@@ -569,7 +585,7 @@ void ShDestruct(ShHandle handle)
int __fastcall ShFinalize() int __fastcall ShFinalize()
{ {
for (int version = 0; version < VersionCount; ++version) for (int version = 0; version < VersionCount; ++version)
for (int p = 0; p < EProfileCount; ++p) for (int p = 0; p < ProfileCount; ++p)
for (int lang = 0; lang < EShLangCount; ++lang) for (int lang = 0; lang < EShLangCount; ++lang)
delete SharedSymbolTables[version][p][lang]; delete SharedSymbolTables[version][p][lang];
...@@ -964,7 +980,7 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages) ...@@ -964,7 +980,7 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
merged = intermediate[stage]; merged = intermediate[stage];
} }
infoSink->info << "\nLinked " << StageName[stage] << " stage:\n\n"; infoSink->info << "\nLinked " << StageName(stage) << " stage:\n\n";
if (stages[stage].size() > 1) { if (stages[stage].size() > 1) {
std::list<TShader*>::const_iterator it; std::list<TShader*>::const_iterator it;
......
...@@ -40,19 +40,29 @@ ...@@ -40,19 +40,29 @@
// Help manage multiple profiles, versions, extensions etc. // Help manage multiple profiles, versions, extensions etc.
// //
//
// The behaviors from "#extension extension_name : behavior"
//
typedef enum { typedef enum {
ENoProfile, // only for desktop, before profiles showed up EBhRequire,
ECoreProfile, EBhEnable,
ECompatibilityProfile, EBhWarn,
EEsProfile, EBhDisable
EProfileCount, } TExtensionBehavior;
} EProfile;
//
// Profiles are set up for masking operations, so queries can be done on multiple
// profiles at the same time.
//
// Don't maintain an ordinal set of enums (0,1,2,3...) to avoid all possible
// defects from mixing the two different forms.
//
typedef enum { typedef enum {
ENoProfileMask = (1 << ENoProfile), EBadProfile = 0,
ECoreProfileMask = (1 << ECoreProfile), ENoProfile = (1 << 0), // only for desktop, before profiles showed up
ECompatibilityProfileMask = (1 << ECompatibilityProfile), ECoreProfile = (1 << 1),
EEsProfileMask = (1 << EEsProfile) ECompatibilityProfile = (1 << 2),
} EProfileMask; EEsProfile = (1 << 3)
} EProfile;
#endif // _VERSIONS_INCLUDED_ #endif // _VERSIONS_INCLUDED_
...@@ -1047,7 +1047,7 @@ interpolation_qualifier ...@@ -1047,7 +1047,7 @@ interpolation_qualifier
} }
| NOPERSPECTIVE { | NOPERSPECTIVE {
parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "noperspective"); parseContext.globalCheck($1.loc, parseContext.symbolTable.atGlobalLevel(), "noperspective");
parseContext.requireProfile($1.loc, static_cast<EProfileMask>(~EEsProfileMask), "noperspective"); parseContext.requireProfile($1.loc, ~EEsProfile, "noperspective");
parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "noperspective"); parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "noperspective");
$$.init($1.loc); $$.init($1.loc);
$$.qualifier.nopersp = true; $$.qualifier.nopersp = true;
...@@ -1138,7 +1138,7 @@ storage_qualifier ...@@ -1138,7 +1138,7 @@ storage_qualifier
$$.qualifier.storage = EvqConst; $$.qualifier.storage = EvqConst;
} }
| ATTRIBUTE { | ATTRIBUTE {
parseContext.requireStage($1.loc, EShLangVertexMask, "attribute"); parseContext.requireStage($1.loc, EShLangVertex, "attribute");
parseContext.checkDeprecated($1.loc, ECoreProfile, 130, "attribute"); parseContext.checkDeprecated($1.loc, ECoreProfile, 130, "attribute");
parseContext.checkDeprecated($1.loc, ENoProfile, 130, "attribute"); parseContext.checkDeprecated($1.loc, ENoProfile, 130, "attribute");
parseContext.requireNotRemoved($1.loc, ECoreProfile, 420, "attribute"); parseContext.requireNotRemoved($1.loc, ECoreProfile, 420, "attribute");
...@@ -1206,9 +1206,9 @@ storage_qualifier ...@@ -1206,9 +1206,9 @@ storage_qualifier
$$.qualifier.storage = EvqUniform; // TODO: 4.0 functionality: implement BUFFER $$.qualifier.storage = EvqUniform; // TODO: 4.0 functionality: implement BUFFER
} }
| SHARED { | SHARED {
parseContext.requireProfile($1.loc, static_cast<EProfileMask>(~EEsProfileMask), "shared"); parseContext.requireProfile($1.loc, ~EEsProfile, "shared");
parseContext.profileRequires($1.loc, ECoreProfile, 430, 0, "shared"); parseContext.profileRequires($1.loc, ECoreProfile, 430, 0, "shared");
parseContext.requireStage($1.loc, EShLangComputeMask, "shared"); parseContext.requireStage($1.loc, EShLangCompute, "shared");
$$.init($1.loc); $$.init($1.loc);
$$.qualifier.shared = true; $$.qualifier.shared = true;
} }
...@@ -2315,7 +2315,7 @@ jump_statement ...@@ -2315,7 +2315,7 @@ jump_statement
parseContext.error($1.loc, "function return is not matching type:", "return", ""); parseContext.error($1.loc, "function return is not matching type:", "return", "");
} }
| DISCARD SEMICOLON { | DISCARD SEMICOLON {
parseContext.requireStage($1.loc, EShLangFragmentMask, "discard"); parseContext.requireStage($1.loc, EShLangFragment, "discard");
$$ = parseContext.intermediate.addBranch(EOpKill, $1.loc); $$ = parseContext.intermediate.addBranch(EOpKill, $1.loc);
} }
; ;
......
...@@ -529,7 +529,7 @@ int TPpContext::CPPifdef(int defined, TPpToken * yylvalpp) ...@@ -529,7 +529,7 @@ int TPpContext::CPPifdef(int defined, TPpToken * yylvalpp)
int token = currentInput->scan(this, currentInput, yylvalpp); int token = currentInput->scan(this, currentInput, yylvalpp);
int name = yylvalpp->atom; int name = yylvalpp->atom;
if (++ifdepth > maxIfNesting) { if (++ifdepth > maxIfNesting) {
parseContext.error(yylvalpp->loc, "maximum nesting depth exceededextension name not specified", "#ifdef", ""); parseContext.error(yylvalpp->loc, "maximum nesting depth exceeded", "#ifdef", "");
return 0; return 0;
} }
elsetracker++; elsetracker++;
......
...@@ -96,7 +96,7 @@ typedef enum { ...@@ -96,7 +96,7 @@ typedef enum {
namespace glslang { namespace glslang {
extern const char* StageName[EShLangCount]; const char* StageName(EShLanguage);
} // end namespace glslang } // end namespace glslang
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment