glslang: Formally track all built-in variables, right from the beginning, to enable avoiding all textual compares at any subsequent stage in the stack. (To be used in future check ins.)

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@31224 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich
2015-05-18 16:45:49 +00:00
parent ca3457f1a7
commit dff18a2be0
105 changed files with 1262 additions and 975 deletions

View File

@@ -66,8 +66,8 @@ enum TStorageQualifier {
EvqTemporary, // For temporaries (within a function), read/write
EvqGlobal, // For globals read/write
EvqConst, // User-defined constant values, will be semantically constant and constant folded
EvqVaryingIn, // pipeline input, read only
EvqVaryingOut, // pipeline ouput, read/write
EvqVaryingIn, // pipeline input, read only, also supercategory for all built-ins not included in this enum (see TBuiltIn)
EvqVaryingOut, // pipeline ouput, read/write, also supercategory for all built-ins not included in this enum (see TBuiltIn)
EvqUniform, // read only, shared with app
EvqBuffer, // read/write, shared with app
EvqShared, // compute shader's read/write 'shared' qualifier
@@ -97,7 +97,78 @@ enum TStorageQualifier {
EvqFragDepth,
// end of list
EvqLast,
EvqLast
};
//
// Subcategories of the TStorageQualifier, simply to give a direct mapping
// between built-in variable names and an numerical value (the enum).
//
// For backward compatibility, there is some redundancy between the
// TStorageQualifier and these. Both should be maintained accurately.
// However, any new built-in variable (and any existing non-redundant one)
// must follow the pattern that the specific built-in is here, and only its
// general qualifier is in TStorageQualifier.
//
// Something like gl_Position, which is sometimes 'in' and sometimes 'out'
// shows up as two different built-in variables in a single stage, but
// only has a single enum in TBuiltInVariable, so both the
// TStorageQualifier and the TBuitinVariable are needed to distinguish
// between them.
//
enum TBuiltInVariable {
EbvNone,
EbvNumWorkGroups,
EbvWorkGroupSize,
EbvWorkGroupId,
EbvLocalInvocationId,
EbvGlobalInvocationId,
EbvLocalInvocationIndex,
EbvVertexId,
EbvInstanceId,
EbvPosition,
EbvPointSize,
EbvClipVertex,
EbvClipDistance,
EbvCullDistance,
EbvNormal,
EbvVertex,
EbvMultiTexCoord0,
EbvMultiTexCoord1,
EbvMultiTexCoord2,
EbvMultiTexCoord3,
EbvMultiTexCoord4,
EbvMultiTexCoord5,
EbvMultiTexCoord6,
EbvMultiTexCoord7,
EbvFrontColor,
EbvBackColor,
EbvFrontSecondaryColor,
EbvBackSecondaryColor,
EbvTexCoord,
EbvFogFragCoord,
EbvInvocationId,
EbvPrimitiveId,
EbvLayer,
EbvViewportIndex,
EbvPatchVertices,
EbvTessLevelOuter,
EbvTessLevelInner,
EbvTessCoord,
EbvColor,
EbvSecondaryColor,
EbvFace,
EbvFragCoord,
EbvPointCoord,
EbvFragColor,
EbvFragData,
EbvFragDepth,
EbvSampleId,
EbvSamplePosition,
EbvSampleMask,
EbvHelperInvocation,
EbvLast
};
// These will show up in error messages
@@ -130,6 +201,63 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q)
}
}
__inline const char* GetBuiltInVariableString(TBuiltInVariable v)
{
switch (v) {
case EbvNone: return "";
case EbvNumWorkGroups: return "NumWorkGroups";
case EbvWorkGroupSize: return "WorkGroupSize";
case EbvWorkGroupId: return "WorkGroupID";
case EbvLocalInvocationId: return "LocalInvocationID";
case EbvGlobalInvocationId: return "GlobalInvocationID";
case EbvLocalInvocationIndex: return "LocalInvocationIndex";
case EbvVertexId: return "VertexId";
case EbvInstanceId: return "InstanceId";
case EbvPosition: return "Position";
case EbvPointSize: return "PointSize";
case EbvClipVertex: return "ClipVertex";
case EbvClipDistance: return "ClipDistance";
case EbvCullDistance: return "CullDistance";
case EbvNormal: return "Normal";
case EbvVertex: return "Vertex";
case EbvMultiTexCoord0: return "MultiTexCoord0";
case EbvMultiTexCoord1: return "MultiTexCoord1";
case EbvMultiTexCoord2: return "MultiTexCoord2";
case EbvMultiTexCoord3: return "MultiTexCoord3";
case EbvMultiTexCoord4: return "MultiTexCoord4";
case EbvMultiTexCoord5: return "MultiTexCoord5";
case EbvMultiTexCoord6: return "MultiTexCoord6";
case EbvMultiTexCoord7: return "MultiTexCoord7";
case EbvFrontColor: return "FrontColor";
case EbvBackColor: return "BackColor";
case EbvFrontSecondaryColor: return "FrontSecondaryColor";
case EbvBackSecondaryColor: return "BackSecondaryColor";
case EbvTexCoord: return "TexCoord";
case EbvFogFragCoord: return "FogFragCoord";
case EbvInvocationId: return "InvocationID";
case EbvPrimitiveId: return "PrimitiveID";
case EbvLayer: return "Layer";
case EbvViewportIndex: return "ViewportIndex";
case EbvPatchVertices: return "PatchVertices";
case EbvTessLevelOuter: return "TessLevelOuter";
case EbvTessLevelInner: return "TessLevelInner";
case EbvTessCoord: return "TessCoord";
case EbvColor: return "Color";
case EbvSecondaryColor: return "SecondaryColor";
case EbvFace: return "Face";
case EbvFragCoord: return "FragCoord";
case EbvPointCoord: return "PointCoord";
case EbvFragColor: return "FragColor";
case EbvFragData: return "FragData";
case EbvFragDepth: return "FragDepth";
case EbvSampleId: return "SampleId";
case EbvSamplePosition: return "SamplePosition";
case EbvSampleMask: return "SampleMaskIn";
case EbvHelperInvocation: return "HelperInvocation";
default: return "unknown built-in variable";
}
}
// In this enum, order matters; users can assume higher precision is a bigger value
// and EpqNone is 0.
enum TPrecisionQualifier {

View File

@@ -328,6 +328,7 @@ public:
void makeTemporary()
{
storage = EvqTemporary;
builtIn = EbvNone;
centroid = false;
smooth = false;
flat = false;
@@ -343,6 +344,7 @@ public:
}
TStorageQualifier storage : 6;
TBuiltInVariable builtIn : 8;
TPrecisionQualifier precision : 3;
bool invariant : 1;
bool centroid : 1;
@@ -1281,6 +1283,11 @@ public:
TString s(buf);
s.append(getBasicTypeString());
if (qualifier.builtIn != EbvNone) {
s.append(" ");
s.append(getBuiltInVariableString());
}
// Add struct/block members
if (structure) {
s.append("{");
@@ -1308,6 +1315,7 @@ public:
}
const char* getStorageQualifierString() const { return GetStorageQualifierString(qualifier.storage); }
const char* getBuiltInVariableString() const { return GetBuiltInVariableString(qualifier.builtIn); }
const char* getPrecisionQualifierString() const { return GetPrecisionQualifierString(qualifier.precision); }
const TTypeList* getStruct() const { return structure; }
TTypeList* getWritableStruct() const { return structure; } // This should only be used when known to not be sharing with other threads

View File

@@ -1365,7 +1365,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
"attribute vec4 gl_MultiTexCoord5;"
"attribute vec4 gl_MultiTexCoord6;"
"attribute vec4 gl_MultiTexCoord7;"
"attribute float gl_FogCoord;"
"attribute float gl_FogCoord;"
"\n");
} else if (IncludeLegacy(version, profile)) {
stageBuiltins[EShLangVertex].append(
@@ -2591,14 +2591,60 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
//
// Safe to call even if name is not present.
//
// N.B.: longer term, having special qualifiers is probably not the way to go, but this is keeping
// in place the legacy ones.
// Only use this for built-in variables that have a special qualifier in TStorageQualifier.
// New built-in variables should use a generic (textually declarable) qualifier in
// TStoraregQualifier and only call BuiltInVariable().
//
void SpecialQualifier(const char* name, TStorageQualifier qualifier, TSymbolTable& symbolTable)
void SpecialQualifier(const char* name, TStorageQualifier qualifier, TBuiltInVariable builtIn, TSymbolTable& symbolTable)
{
TSymbol* symbol = symbolTable.find(name);
if (symbol)
symbol->getWritableType().getQualifier().storage = qualifier;
if (symbol) {
TQualifier& symQualifier = symbol->getWritableType().getQualifier();
symQualifier.storage = qualifier;
symQualifier.builtIn = builtIn;
}
}
//
// To tag built-in variables with their TBuiltInVariable enum. Use this when the
// normal declaration text already gets the qualifier right, and all that's needed
// is setting the builtIn field. This should be the normal way for all new
// built-in variables.
//
// If SpecialQualifier() was called, this does not need to be called.
//
// Safe to call even if name is not present.
//
void BuiltInVariable(const char* name, TBuiltInVariable builtIn, TSymbolTable& symbolTable)
{
TSymbol* symbol = symbolTable.find(name);
if (! symbol)
return;
TQualifier& symQualifier = symbol->getWritableType().getQualifier();
symQualifier.builtIn = builtIn;
}
//
// For built-in variables inside a named block.
// SpecialQualifier() won't ever go inside a block; their member's qualifier come
// from the qualification of the block.
//
// See comments above for other detail.
//
void BuiltInVariable(const char* blockName, const char* name, TBuiltInVariable builtIn, TSymbolTable& symbolTable)
{
TSymbol* symbol = symbolTable.find(blockName);
if (! symbol)
return;
TTypeList& structure = *symbol->getWritableType().getWritableStruct();
for (int i = 0; i < (int)structure.size(); ++i) {
if (structure[i].type->getFieldName().compare(name) == 0) {
structure[i].type->getQualifier().builtIn = builtIn;
return;
}
}
}
//
@@ -2622,26 +2668,119 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
switch(language) {
case EShLangVertex:
// Compatibility variables, vertex only
BuiltInVariable("gl_Color", EbvColor, symbolTable);
BuiltInVariable("gl_SecondaryColor", EbvSecondaryColor, symbolTable);
BuiltInVariable("gl_Normal", EbvNormal, symbolTable);
BuiltInVariable("gl_Vertex", EbvVertex, symbolTable);
BuiltInVariable("gl_MultiTexCoord0", EbvMultiTexCoord0, symbolTable);
BuiltInVariable("gl_MultiTexCoord1", EbvMultiTexCoord1, symbolTable);
BuiltInVariable("gl_MultiTexCoord2", EbvMultiTexCoord2, symbolTable);
BuiltInVariable("gl_MultiTexCoord3", EbvMultiTexCoord3, symbolTable);
BuiltInVariable("gl_MultiTexCoord4", EbvMultiTexCoord4, symbolTable);
BuiltInVariable("gl_MultiTexCoord5", EbvMultiTexCoord5, symbolTable);
BuiltInVariable("gl_MultiTexCoord6", EbvMultiTexCoord6, symbolTable);
BuiltInVariable("gl_MultiTexCoord7", EbvMultiTexCoord7, symbolTable);
BuiltInVariable("gl_FogCoord", EbvFogFragCoord, symbolTable);
// Fall through
case EShLangTessControl:
case EShLangTessEvaluation:
case EShLangGeometry:
SpecialQualifier("gl_Position", EvqPosition, symbolTable);
SpecialQualifier("gl_PointSize", EvqPointSize, symbolTable);
SpecialQualifier("gl_ClipVertex", EvqClipVertex, symbolTable);
SpecialQualifier("gl_VertexID", EvqVertexId, symbolTable);
SpecialQualifier("gl_InstanceID", EvqInstanceId, symbolTable);
SpecialQualifier("gl_Position", EvqPosition, EbvPosition, symbolTable);
SpecialQualifier("gl_PointSize", EvqPointSize, EbvPointSize, symbolTable);
SpecialQualifier("gl_ClipVertex", EvqClipVertex, EbvClipVertex, symbolTable);
SpecialQualifier("gl_VertexID", EvqVertexId, EbvVertexId, symbolTable);
SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable);
BuiltInVariable("gl_in", "gl_Position", EbvPosition, symbolTable);
BuiltInVariable("gl_in", "gl_PointSize", EbvPointSize, symbolTable);
BuiltInVariable("gl_in", "gl_ClipDistance", EbvClipDistance, symbolTable);
BuiltInVariable("gl_in", "gl_CullDistance", EbvCullDistance, symbolTable);
BuiltInVariable("gl_out", "gl_Position", EbvPosition, symbolTable);
BuiltInVariable("gl_out", "gl_PointSize", EbvPointSize, symbolTable);
BuiltInVariable("gl_out", "gl_ClipDistance", EbvClipDistance, symbolTable);
BuiltInVariable("gl_out", "gl_CullDistance", EbvCullDistance, symbolTable);
BuiltInVariable("gl_ClipDistance", EbvClipDistance, symbolTable);
BuiltInVariable("gl_CullDistance", EbvCullDistance, symbolTable);
BuiltInVariable("gl_PrimitiveID", EbvPrimitiveId, symbolTable);
BuiltInVariable("gl_InvocationID", EbvInvocationId, symbolTable);
BuiltInVariable("gl_Layer", EbvLayer, symbolTable);
BuiltInVariable("gl_ViewportIndex", EbvViewportIndex, symbolTable);
BuiltInVariable("gl_PatchVerticesIn", EbvPatchVertices, symbolTable);
BuiltInVariable("gl_TessLevelOuter", EbvTessLevelOuter, symbolTable);
BuiltInVariable("gl_TessLevelInner", EbvTessLevelInner, symbolTable);
BuiltInVariable("gl_TessCoord", EbvTessCoord, symbolTable);
if (version < 410)
symbolTable.setVariableExtensions("gl_ViewportIndex", 1, &GL_ARB_viewport_array);
// Compatibility variables
BuiltInVariable("gl_in", "gl_ClipVertex", EbvClipVertex, symbolTable);
BuiltInVariable("gl_in", "gl_FrontColor", EbvFrontColor, symbolTable);
BuiltInVariable("gl_in", "gl_BackColor", EbvBackColor, symbolTable);
BuiltInVariable("gl_in", "gl_FrontSecondaryColor", EbvFrontSecondaryColor, symbolTable);
BuiltInVariable("gl_in", "gl_BackSecondaryColor", EbvBackSecondaryColor, symbolTable);
BuiltInVariable("gl_in", "gl_TexCoord", EbvTexCoord, symbolTable);
BuiltInVariable("gl_in", "gl_FogFragCoord", EbvFogFragCoord, symbolTable);
BuiltInVariable("gl_out", "gl_ClipVertex", EbvClipVertex, symbolTable);
BuiltInVariable("gl_out", "gl_FrontColor", EbvFrontColor, symbolTable);
BuiltInVariable("gl_out", "gl_BackColor", EbvBackColor, symbolTable);
BuiltInVariable("gl_out", "gl_FrontSecondaryColor", EbvFrontSecondaryColor, symbolTable);
BuiltInVariable("gl_out", "gl_BackSecondaryColor", EbvBackSecondaryColor, symbolTable);
BuiltInVariable("gl_out", "gl_TexCoord", EbvTexCoord, symbolTable);
BuiltInVariable("gl_out", "gl_FogFragCoord", EbvFogFragCoord, symbolTable);
BuiltInVariable("gl_ClipVertex", EbvClipVertex, symbolTable);
BuiltInVariable("gl_FrontColor", EbvFrontColor, symbolTable);
BuiltInVariable("gl_BackColor", EbvBackColor, symbolTable);
BuiltInVariable("gl_FrontSecondaryColor", EbvFrontSecondaryColor, symbolTable);
BuiltInVariable("gl_BackSecondaryColor", EbvBackSecondaryColor, symbolTable);
BuiltInVariable("gl_TexCoord", EbvTexCoord, symbolTable);
BuiltInVariable("gl_FogFragCoord", EbvFogFragCoord, symbolTable);
break;
case EShLangFragment:
SpecialQualifier("gl_FrontFacing", EvqFace, symbolTable);
SpecialQualifier("gl_FragCoord", EvqFragCoord, symbolTable);
SpecialQualifier("gl_PointCoord", EvqPointCoord, symbolTable);
SpecialQualifier("gl_FragColor", EvqFragColor, symbolTable);
SpecialQualifier("gl_FragDepth", EvqFragDepth, symbolTable);
SpecialQualifier("gl_FragDepthEXT", EvqFragDepth, symbolTable);
SpecialQualifier("gl_HelperInvocation", EvqIn, symbolTable);
SpecialQualifier("gl_FrontFacing", EvqFace, EbvFace, symbolTable);
SpecialQualifier("gl_FragCoord", EvqFragCoord, EbvFragCoord, symbolTable);
SpecialQualifier("gl_PointCoord", EvqPointCoord, EbvPointCoord, symbolTable);
SpecialQualifier("gl_FragColor", EvqFragColor, EbvFragColor, symbolTable);
SpecialQualifier("gl_FragDepth", EvqFragDepth, EbvFragDepth, symbolTable);
SpecialQualifier("gl_FragDepthEXT", EvqFragDepth, EbvFragDepth, symbolTable);
SpecialQualifier("gl_HelperInvocation", EvqIn, EbvHelperInvocation, symbolTable);
BuiltInVariable("gl_ClipDistance", EbvClipDistance, symbolTable);
BuiltInVariable("gl_CullDistance", EbvCullDistance, symbolTable);
BuiltInVariable("gl_PrimitiveID", EbvPrimitiveId, symbolTable);
BuiltInVariable("gl_SampleID", EbvSampleId, symbolTable);
BuiltInVariable("gl_SamplePosition", EbvSamplePosition, symbolTable);
BuiltInVariable("gl_SampleMaskIn", EbvSampleMask, symbolTable);
BuiltInVariable("gl_SampleMask", EbvSampleMask, symbolTable);
BuiltInVariable("gl_Layer", EbvLayer, symbolTable);
BuiltInVariable("gl_ViewportIndex", EbvViewportIndex, symbolTable);
// Compatibility variables
SpecialQualifier("gl_FragData", EvqFragColor, EbvFragData, symbolTable);
BuiltInVariable("gl_in", "gl_FogFragCoord", EbvFogFragCoord, symbolTable);
BuiltInVariable("gl_in", "gl_TexCoord", EbvTexCoord, symbolTable);
BuiltInVariable("gl_in", "gl_Color", EbvColor, symbolTable);
BuiltInVariable("gl_in", "gl_SecondaryColor", EbvSecondaryColor, symbolTable);
BuiltInVariable("gl_FogFragCoord", EbvFogFragCoord, symbolTable);
BuiltInVariable("gl_TexCoord", EbvTexCoord, symbolTable);
BuiltInVariable("gl_Color", EbvColor, symbolTable);
BuiltInVariable("gl_SecondaryColor", EbvSecondaryColor, symbolTable);
// built-in functions
if (version == 100) {
symbolTable.setFunctionExtensions("dFdx", 1, &GL_OES_standard_derivatives);
symbolTable.setFunctionExtensions("dFdy", 1, &GL_OES_standard_derivatives);
@@ -2716,6 +2855,12 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
break;
case EShLangCompute:
BuiltInVariable("gl_NumWorkGroups", EbvNumWorkGroups, symbolTable);
BuiltInVariable("gl_WorkGroupSize", EbvWorkGroupSize, symbolTable);
BuiltInVariable("gl_WorkGroupID", EbvWorkGroupId, symbolTable);
BuiltInVariable("gl_LocalInvocationID", EbvLocalInvocationId, symbolTable);
BuiltInVariable("gl_GlobalInvocationID", EbvGlobalInvocationId, symbolTable);
BuiltInVariable("gl_LocalInvocationIndex", EbvLocalInvocationIndex, symbolTable);
break;
default:

View File

@@ -82,7 +82,7 @@ class TSymbol {
public:
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
explicit TSymbol(const TString *n) : name(n), numExtensions(0), extensions(0), writable(true) { }
virtual TSymbol* clone() const = 0;
virtual TSymbol* clone() const = 0;
virtual ~TSymbol() { } // rely on all symbol owned memory coming from the pool
virtual const TString& getName() const { return *name; }
@@ -114,7 +114,7 @@ public:
virtual void makeReadOnly() { writable = false; }
protected:
explicit TSymbol(const TSymbol&);
explicit TSymbol(const TSymbol&);
TSymbol& operator=(const TSymbol&);
const TString *name;
@@ -145,7 +145,7 @@ protected:
class TVariable : public TSymbol {
public:
TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), userType(uT) { type.shallowCopy(t); }
virtual TVariable* clone() const;
virtual TVariable* clone() const;
virtual ~TVariable() { }
virtual TVariable* getAsVariable() { return this; }
@@ -177,14 +177,14 @@ protected:
struct TParameter {
TString *name;
TType* type;
void copyParam(const TParameter& param)
void copyParam(const TParameter& param)
{
if (param.name)
if (param.name)
name = NewPoolTString(param.name->c_str());
else
name = 0;
type = param.type->clone();
}
type = param.type->clone();
}
};
//
@@ -201,8 +201,8 @@ public:
mangledName(*name + '('),
op(tOp),
defined(false), prototyped(false) { returnType.shallowCopy(retType); }
virtual TFunction* clone() const;
virtual ~TFunction();
virtual TFunction* clone() const;
virtual ~TFunction();
virtual TFunction* getAsFunction() { return this; }
virtual const TFunction* getAsFunction() const { return this; }
@@ -235,7 +235,7 @@ protected:
TFunction& operator=(const TFunction&);
typedef TVector<TParameter> TParamList;
TParamList parameters;
TParamList parameters;
TType returnType;
TString mangledName;
TOperator op;
@@ -243,15 +243,21 @@ protected:
bool prototyped;
};
//
// Members of anonymous blocks are a kind of TSymbol. They are not hidden in
// the symbol table behind a container; rather they are visible and point to
// their anonymous container. (The anonymous container is found through the
// member, not the other way around.)
//
class TAnonMember : public TSymbol {
public:
TAnonMember(const TString* n, unsigned int m, const TVariable& a, int an) : TSymbol(n), anonContainer(a), memberNumber(m), anonId(an) { }
virtual TAnonMember* clone() const;
virtual TAnonMember* clone() const;
virtual ~TAnonMember() { }
virtual const TAnonMember* getAsAnonMember() const { return this; }
virtual const TVariable& getAnonContainer() const { return anonContainer; }
virtual unsigned int getMemberNumber() const { return memberNumber; }
virtual unsigned int getMemberNumber() const { return memberNumber; }
virtual const TType& getType() const
{
@@ -282,7 +288,7 @@ class TSymbolTableLevel {
public:
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
TSymbolTableLevel() : defaultPrecision(0), anonId(0) { }
~TSymbolTableLevel();
~TSymbolTableLevel();
bool insert(TSymbol& symbol, bool separateNameSpaces)
{
@@ -426,7 +432,7 @@ public:
void relateToOperator(const char* name, TOperator op);
void setFunctionExtensions(const char* name, int num, const char* const extensions[]);
void dump(TInfoSink &infoSink) const;
TSymbolTableLevel* clone() const;
TSymbolTableLevel* clone() const;
void readOnly();
protected:
@@ -650,7 +656,7 @@ public:
int getMaxSymbolId() { return uniqueId; }
void dump(TInfoSink &infoSink) const;
void copyTable(const TSymbolTable& copyOf);
void copyTable(const TSymbolTable& copyOf);
void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); }