Add static_use to shader variable info query.
BUG=249018
ANGLEBUG=465
R=kbr@chromium.org
Review URL: https://codereview.appspot.com/13158043
diff --git a/include/GLSLANG/ShaderLang.h b/include/GLSLANG/ShaderLang.h
index b9a056f..24a0b7c 100644
--- a/include/GLSLANG/ShaderLang.h
+++ b/include/GLSLANG/ShaderLang.h
@@ -37,7 +37,7 @@
// Version number for shader translation API.
// It is incremented everytime the API changes.
-#define ANGLE_SH_VERSION 111
+#define ANGLE_SH_VERSION 112
//
// The names of the following enums have been derived by replacing GL prefix
@@ -378,6 +378,10 @@
// size: Returns the size of the variable.
// type: Returns the data type of the variable.
// precision: Returns the precision of the variable.
+// staticUse: Returns 1 if the variable is accessed in a statement after
+// pre-processing, whether or not run-time flow of control will
+// cause that statement to be executed.
+// Returns 0 otherwise.
// name: Returns a null terminated string containing the name of the
// variable. It is assumed that name has enough memory to accormodate
// the variable name. The size of the buffer required to store the
@@ -396,6 +400,7 @@
int* size,
ShDataType* type,
ShPrecisionType* precision,
+ int* staticUse,
char* name,
char* mappedName);
diff --git a/src/common/version.h b/src/common/version.h
index 1688acf..bb8d7c7 100644
--- a/src/common/version.h
+++ b/src/common/version.h
@@ -1,7 +1,7 @@
#define MAJOR_VERSION 1
#define MINOR_VERSION 2
#define BUILD_VERSION 0
-#define BUILD_REVISION 2440
+#define BUILD_REVISION 2441
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
diff --git a/src/compiler/Compiler.cpp b/src/compiler/Compiler.cpp
index c2f1a54..4866fcc 100644
--- a/src/compiler/Compiler.cpp
+++ b/src/compiler/Compiler.cpp
@@ -271,6 +271,7 @@
attribs.clear();
uniforms.clear();
+ varyings.clear();
builtInFunctionEmulator.Cleanup();
diff --git a/src/compiler/ShaderLang.cpp b/src/compiler/ShaderLang.cpp
index 7cafa34..c673fe2 100644
--- a/src/compiler/ShaderLang.cpp
+++ b/src/compiler/ShaderLang.cpp
@@ -248,10 +248,11 @@
int* size,
ShDataType* type,
ShPrecisionType* precision,
+ int* staticUse,
char* name,
char* mappedName)
{
- if (!handle || !size || !type || !name)
+ if (!handle || !size || !type || !precision || !staticUse || !name)
return;
ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
(varType == SH_ACTIVE_UNIFORMS) ||
@@ -288,6 +289,7 @@
*precision = SH_PRECISION_UNDEFINED;
break;
}
+ *staticUse = varInfo.staticUse ? 1 : 0;
// This size must match that queried by
// SH_ACTIVE_UNIFORM_MAX_LENGTH, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_VARYING_MAX_LENGTH
diff --git a/src/compiler/VariableInfo.cpp b/src/compiler/VariableInfo.cpp
index 4aaa948..f3f7b1e 100644
--- a/src/compiler/VariableInfo.cpp
+++ b/src/compiler/VariableInfo.cpp
@@ -6,15 +6,17 @@
#include "compiler/VariableInfo.h"
-static TString arrayBrackets(int index)
+namespace {
+
+TString arrayBrackets(int index)
{
TStringStream stream;
stream << "[" << index << "]";
return stream.str();
}
-// Returns the data type for an attribute or uniform.
-static ShDataType getVariableDataType(const TType& type)
+// Returns the data type for an attribute, uniform, or varying.
+ShDataType getVariableDataType(const TType& type)
{
switch (type.getBasicType()) {
case EbtFloat:
@@ -70,22 +72,22 @@
return SH_NONE;
}
-static void getBuiltInVariableInfo(const TType& type,
- const TString& name,
- const TString& mappedName,
- TVariableInfoList& infoList);
-static void getUserDefinedVariableInfo(const TType& type,
- const TString& name,
- const TString& mappedName,
- TVariableInfoList& infoList,
- ShHashFunction64 hashFunction);
-
-// Returns info for an attribute or uniform.
-static void getVariableInfo(const TType& type,
+void getBuiltInVariableInfo(const TType& type,
const TString& name,
const TString& mappedName,
- TVariableInfoList& infoList,
- ShHashFunction64 hashFunction)
+ TVariableInfoList& infoList);
+void getUserDefinedVariableInfo(const TType& type,
+ const TString& name,
+ const TString& mappedName,
+ TVariableInfoList& infoList,
+ ShHashFunction64 hashFunction);
+
+// Returns info for an attribute, uniform, or varying.
+void getVariableInfo(const TType& type,
+ const TString& name,
+ const TString& mappedName,
+ TVariableInfoList& infoList,
+ ShHashFunction64 hashFunction)
{
if (type.getBasicType() == EbtStruct) {
if (type.isArray()) {
@@ -144,13 +146,37 @@
}
}
+TVariableInfo* findVariable(const TType& type,
+ const TString& name,
+ TVariableInfoList& infoList)
+{
+ // TODO(zmo): optimize this function.
+ TString myName = name;
+ if (type.isArray())
+ myName += "[0]";
+ for (size_t ii = 0; ii < infoList.size(); ++ii)
+ {
+ if (infoList[ii].name.c_str() == myName)
+ return &(infoList[ii]);
+ }
+ return NULL;
+}
+
+} // namespace anonymous
+
TVariableInfo::TVariableInfo()
+ : type(SH_NONE),
+ size(0),
+ precision(EbpUndefined),
+ staticUse(false)
{
}
TVariableInfo::TVariableInfo(ShDataType type, int size)
: type(type),
- size(size)
+ size(size),
+ precision(EbpUndefined),
+ staticUse(false)
{
}
@@ -161,44 +187,85 @@
: mAttribs(attribs),
mUniforms(uniforms),
mVaryings(varyings),
+ mPointCoordAdded(false),
+ mFrontFacingAdded(false),
+ mFragCoordAdded(false),
mHashFunction(hashFunction)
{
}
-// We are only interested in attribute and uniform variable declaration.
-void CollectVariables::visitSymbol(TIntermSymbol*)
+// We want to check whether a uniform/varying is statically used
+// because we only count the used ones in packing computing.
+// Also, gl_FragCoord, gl_PointCoord, and gl_FrontFacing count
+// toward varying counting if they are statically used in a fragment
+// shader.
+void CollectVariables::visitSymbol(TIntermSymbol* symbol)
{
-}
-
-void CollectVariables::visitConstantUnion(TIntermConstantUnion*)
-{
-}
-
-bool CollectVariables::visitBinary(Visit, TIntermBinary*)
-{
- return false;
-}
-
-bool CollectVariables::visitUnary(Visit, TIntermUnary*)
-{
- return false;
-}
-
-bool CollectVariables::visitSelection(Visit, TIntermSelection*)
-{
- return false;
+ ASSERT(symbol != NULL);
+ TVariableInfo* var = NULL;
+ switch (symbol->getQualifier())
+ {
+ case EvqVaryingOut:
+ case EvqInvariantVaryingOut:
+ case EvqVaryingIn:
+ case EvqInvariantVaryingIn:
+ var = findVariable(symbol->getType(), symbol->getSymbol(), mVaryings);
+ break;
+ case EvqUniform:
+ var = findVariable(symbol->getType(), symbol->getSymbol(), mUniforms);
+ break;
+ case EvqFragCoord:
+ if (!mFragCoordAdded) {
+ TVariableInfo info;
+ info.name = "gl_FragCoord";
+ info.mappedName = "gl_FragCoord";
+ info.type = SH_FLOAT_VEC4;
+ info.size = 1;
+ info.precision = EbpMedium; // Use mediump as it doesn't really matter.
+ info.staticUse = true;
+ mVaryings.push_back(info);
+ mFragCoordAdded = true;
+ }
+ return;
+ case EvqFrontFacing:
+ if (!mFrontFacingAdded) {
+ TVariableInfo info;
+ info.name = "gl_FrontFacing";
+ info.mappedName = "gl_FrontFacing";
+ info.type = SH_BOOL;
+ info.size = 1;
+ info.precision = EbpUndefined;
+ info.staticUse = true;
+ mVaryings.push_back(info);
+ mFrontFacingAdded = true;
+ }
+ return;
+ case EvqPointCoord:
+ if (!mPointCoordAdded) {
+ TVariableInfo info;
+ info.name = "gl_PointCoord";
+ info.mappedName = "gl_PointCoord";
+ info.type = SH_FLOAT_VEC2;
+ info.size = 1;
+ info.precision = EbpMedium; // Use mediump as it doesn't really matter.
+ info.staticUse = true;
+ mVaryings.push_back(info);
+ mPointCoordAdded = true;
+ }
+ return;
+ default:
+ break;
+ }
+ if (var)
+ var->staticUse = true;
}
bool CollectVariables::visitAggregate(Visit, TIntermAggregate* node)
{
- bool visitChildren = false;
+ bool visitChildren = true;
switch (node->getOp())
{
- case EOpSequence:
- // We need to visit sequence children to get to variable declarations.
- visitChildren = true;
- break;
case EOpDeclaration: {
const TIntermSequence& sequence = node->getSequence();
TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
@@ -214,9 +281,9 @@
const TIntermSymbol* variable = (*i)->getAsSymbolNode();
// The only case in which the sequence will not contain a
// TIntermSymbol node is initialization. It will contain a
- // TInterBinary node in that case. Since attributes and unifroms
- // cannot be initialized in a shader, we must have only
- // TIntermSymbol nodes in the sequence.
+ // TInterBinary node in that case. Since attributes, uniforms,
+ // and varyings cannot be initialized in a shader, we must have
+ // only TIntermSymbol nodes in the sequence.
ASSERT(variable != NULL);
TString processedSymbol;
if (mHashFunction == NULL)
@@ -228,6 +295,7 @@
processedSymbol,
infoList,
mHashFunction);
+ visitChildren = false;
}
}
break;
@@ -238,13 +306,3 @@
return visitChildren;
}
-bool CollectVariables::visitLoop(Visit, TIntermLoop*)
-{
- return false;
-}
-
-bool CollectVariables::visitBranch(Visit, TIntermBranch*)
-{
- return false;
-}
-
diff --git a/src/compiler/VariableInfo.h b/src/compiler/VariableInfo.h
index bef196d..3c7f2a5 100644
--- a/src/compiler/VariableInfo.h
+++ b/src/compiler/VariableInfo.h
@@ -21,6 +21,7 @@
ShDataType type;
int size;
TPrecision precision;
+ bool staticUse;
};
typedef std::vector<TVariableInfo> TVariableInfoList;
@@ -33,19 +34,17 @@
ShHashFunction64 hashFunction);
virtual void visitSymbol(TIntermSymbol*);
- virtual void visitConstantUnion(TIntermConstantUnion*);
- virtual bool visitBinary(Visit, TIntermBinary*);
- virtual bool visitUnary(Visit, TIntermUnary*);
- virtual bool visitSelection(Visit, TIntermSelection*);
virtual bool visitAggregate(Visit, TIntermAggregate*);
- virtual bool visitLoop(Visit, TIntermLoop*);
- virtual bool visitBranch(Visit, TIntermBranch*);
private:
TVariableInfoList& mAttribs;
TVariableInfoList& mUniforms;
TVariableInfoList& mVaryings;
+ bool mPointCoordAdded;
+ bool mFrontFacingAdded;
+ bool mFragCoordAdded;
+
ShHashFunction64 mHashFunction;
};