Expose varying variables and also precision for all variables.

ANGLEBUG=457
R=alokp@chromium.org, kbr@chromium.org

Review URL: https://codereview.appspot.com/12487043
diff --git a/include/GLSLANG/ShaderLang.h b/include/GLSLANG/ShaderLang.h
index 722ac64..f26bb84 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 110
+#define ANGLE_SH_VERSION 111
 
 //
 // The names of the following enums have been derived by replacing GL prefix
@@ -109,12 +109,20 @@
 } ShDataType;
 
 typedef enum {
+  SH_PRECISION_HIGHP    = 0x5001,
+  SH_PRECISION_MEDIUMP  = 0x5002,
+  SH_PRECISION_LOWP     = 0x5003
+} ShPrecisionType;
+
+typedef enum {
   SH_INFO_LOG_LENGTH             =  0x8B84,
   SH_OBJECT_CODE_LENGTH          =  0x8B88,  // GL_SHADER_SOURCE_LENGTH
   SH_ACTIVE_UNIFORMS             =  0x8B86,
   SH_ACTIVE_UNIFORM_MAX_LENGTH   =  0x8B87,
   SH_ACTIVE_ATTRIBUTES           =  0x8B89,
   SH_ACTIVE_ATTRIBUTE_MAX_LENGTH =  0x8B8A,
+  SH_VARYINGS                    =  0x8BBB,
+  SH_VARYING_MAX_LENGTH          =  0x8BBC,
   SH_MAPPED_NAME_MAX_LENGTH      =  0x6000,
   SH_NAME_MAX_LENGTH             =  0x6001,
   SH_HASHED_NAME_MAX_LENGTH      =  0x6002,
@@ -128,7 +136,7 @@
   SH_VALIDATE_LOOP_INDEXING  = 0x0001,
   SH_INTERMEDIATE_TREE       = 0x0002,
   SH_OBJECT_CODE             = 0x0004,
-  SH_ATTRIBUTES_UNIFORMS     = 0x0008,
+  SH_VARIABLES               = 0x0008,
   SH_LINE_DIRECTIVES         = 0x0010,
   SH_SOURCE_PATH             = 0x0020,
   SH_MAP_LONG_VARIABLE_NAMES = 0x0040,
@@ -294,9 +302,8 @@
 //                       Can be queried by calling ShGetInfoLog().
 // SH_OBJECT_CODE: Translates intermediate tree to glsl or hlsl shader.
 //                 Can be queried by calling ShGetObjectCode().
-// SH_ATTRIBUTES_UNIFORMS: Extracts attributes and uniforms.
-//                         Can be queried by calling ShGetActiveAttrib() and
-//                         ShGetActiveUniform().
+// SH_VARIABLES: Extracts attributes, uniforms, and varyings.
+//               Can be queried by calling ShGetVariableInfo().
 //
 COMPILER_EXPORT int ShCompile(
     const ShHandle handle,
@@ -322,6 +329,9 @@
 // SH_ACTIVE_UNIFORM_MAX_LENGTH: the length of the longest active uniform
 //                               variable name including the null
 //                               termination character.
+// SH_VARYINGS: the number of varying variables.
+// SH_VARYING_MAX_LENGTH: the length of the longest varying variable name
+//                        including the null termination character.
 // SH_MAPPED_NAME_MAX_LENGTH: the length of the mapped variable name including
 //                            the null termination character.
 // SH_NAME_MAX_LENGTH: the max length of a user-defined name including the
@@ -355,60 +365,39 @@
 //          ShGetInfo with SH_OBJECT_CODE_LENGTH.
 COMPILER_EXPORT void ShGetObjectCode(const ShHandle handle, char* objCode);
 
-// Returns information about an active attribute variable.
+// Returns information about a shader variable.
 // Parameters:
 // handle: Specifies the compiler
-// index: Specifies the index of the attribute variable to be queried.
+// variableType: Specifies the variable type; options include
+//               SH_ACTIVE_ATTRIBUTES, SH_ACTIVE_UNIFORMS, SH_VARYINGS.
+// index: Specifies the index of the variable to be queried.
 // length: Returns the number of characters actually written in the string
 //         indicated by name (excluding the null terminator) if a value other
 //         than NULL is passed.
-// size: Returns the size of the attribute variable.
-// type: Returns the data type of the attribute variable.
+// size: Returns the size of the variable.
+// type: Returns the data type of the variable.
+// precision: Returns the precision of the variable.
 // name: Returns a null terminated string containing the name of the
-//       attribute variable. It is assumed that name has enough memory to
-//       accomodate the attribute variable name. The size of the buffer
-//       required to store the attribute variable name can be obtained by
-//       calling ShGetInfo with SH_ACTIVE_ATTRIBUTE_MAX_LENGTH.
+//       variable. It is assumed that name has enough memory to accormodate
+//       the variable name. The size of the buffer required to store the
+//       variable name can be obtained by calling ShGetInfo with
+//       SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_ACTIVE_UNIFORM_MAX_LENGTH,
+//       SH_VARYING_MAX_LENGTH.
 // mappedName: Returns a null terminated string containing the mapped name of
-//             the attribute variable, It is assumed that mappedName has enough
-//             memory (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care
-//             about the mapped name. If the name is not mapped, then name and
-//             mappedName are the same.
-COMPILER_EXPORT void ShGetActiveAttrib(const ShHandle handle,
+//             the variable, It is assumed that mappedName has enough memory
+//             (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care about the
+//             mapped name. If the name is not mapped, then name and mappedName
+//             are the same.
+COMPILER_EXPORT void ShGetVariableInfo(const ShHandle handle,
+                                       ShShaderInfo variableType,
                                        int index,
                                        size_t* length,
                                        int* size,
                                        ShDataType* type,
+                                       ShPrecisionType* precision,
                                        char* name,
                                        char* mappedName);
 
-// Returns information about an active uniform variable.
-// Parameters:
-// handle: Specifies the compiler
-// index: Specifies the index of the uniform variable to be queried.
-// length: Returns the number of characters actually written in the string
-//         indicated by name (excluding the null terminator) if a value
-//         other than NULL is passed.
-// size: Returns the size of the uniform variable.
-// type: Returns the data type of the uniform variable.
-// name: Returns a null terminated string containing the name of the
-//       uniform variable. It is assumed that name has enough memory to
-//       accomodate the uniform variable name. The size of the buffer required
-//       to store the uniform variable name can be obtained by calling
-//       ShGetInfo with SH_ACTIVE_UNIFORMS_MAX_LENGTH.
-// mappedName: Returns a null terminated string containing the mapped name of
-//             the uniform variable, It is assumed that mappedName has enough
-//             memory (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care
-//             about the mapped name. If the name is not mapped, then name and
-//             mappedName are the same.
-COMPILER_EXPORT void ShGetActiveUniform(const ShHandle handle,
-                                        int index,
-                                        size_t* length,
-                                        int* size,
-                                        ShDataType* type,
-                                        char* name,
-                                        char* mappedName);
-
 // Returns information about a name hashing entry from the latest compile.
 // Parameters:
 // handle: Specifies the compiler
diff --git a/src/common/version.h b/src/common/version.h
index dc7fded..6733700 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 2436
+#define BUILD_REVISION 2437
 
 #define STRINGIFY(x) #x
 #define MACRO_STRINGIFY(x) STRINGIFY(x)
diff --git a/src/compiler/Compiler.cpp b/src/compiler/Compiler.cpp
index 3e80d96..8fc7960 100644
--- a/src/compiler/Compiler.cpp
+++ b/src/compiler/Compiler.cpp
@@ -178,8 +178,8 @@
         if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES) && hashFunction == NULL)
             mapLongVariableNames(root);
 
-        if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS)) {
-            collectAttribsUniforms(root);
+        if (success && (compileOptions & SH_VARIABLES)) {
+            collectVariables(root);
             if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) {
                 success = enforcePackingRestrictions();
                 if (!success) {
@@ -358,9 +358,9 @@
     return restrictor.numErrors() == 0;
 }
 
-void TCompiler::collectAttribsUniforms(TIntermNode* root)
+void TCompiler::collectVariables(TIntermNode* root)
 {
-    CollectAttribsUniforms collect(attribs, uniforms, hashFunction);
+    CollectVariables collect(attribs, uniforms, varyings, hashFunction);
     root->traverse(&collect);
 }
 
diff --git a/src/compiler/ShHandle.h b/src/compiler/ShHandle.h
index eaf6f68..873580a 100644
--- a/src/compiler/ShHandle.h
+++ b/src/compiler/ShHandle.h
@@ -70,6 +70,7 @@
     TInfoSink& getInfoSink() { return infoSink; }
     const TVariableInfoList& getAttribs() const { return attribs; }
     const TVariableInfoList& getUniforms() const { return uniforms; }
+    const TVariableInfoList& getVaryings() const { return varyings; }
     int getMappedNameMaxLength() const;
 
     ShHashFunction64 getHashFunction() const { return hashFunction; }
@@ -90,8 +91,8 @@
     // Returns true if the given shader does not exceed the minimum
     // functionality mandated in GLSL 1.0 spec Appendix A.
     bool validateLimitations(TIntermNode* root);
-    // Collect info for all attribs and uniforms.
-    void collectAttribsUniforms(TIntermNode* root);
+    // Collect info for all attribs, uniforms, varyings.
+    void collectVariables(TIntermNode* root);
     // Map long variable names into shorter ones.
     void mapLongVariableNames(TIntermNode* root);
     // Translate to object code.
@@ -142,6 +143,7 @@
     TInfoSink infoSink;  // Output sink.
     TVariableInfoList attribs;  // Active attributes in the compiled shader.
     TVariableInfoList uniforms;  // Active uniforms in the compiled shader.
+    TVariableInfoList varyings;  // Varyings in the compiled shader.
 
     // Cached copy of the ref-counted singleton.
     LongNameMap* longNameMap;
diff --git a/src/compiler/ShaderLang.cpp b/src/compiler/ShaderLang.cpp
index 147894e..fcf9a54 100644
--- a/src/compiler/ShaderLang.cpp
+++ b/src/compiler/ShaderLang.cpp
@@ -21,14 +21,18 @@
 // and the shading language compiler.
 //
 
-static bool checkActiveUniformAndAttribMaxLengths(const ShHandle handle,
-                                                  size_t expectedValue)
+static bool checkVariableMaxLengths(const ShHandle handle,
+                                    size_t expectedValue)
 {
     size_t activeUniformLimit = 0;
     ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
     size_t activeAttribLimit = 0;
     ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
-    return (expectedValue == activeUniformLimit && expectedValue == activeAttribLimit);
+    size_t varyingLimit = 0;
+    ShGetInfo(handle, SH_VARYING_MAX_LENGTH, &varyingLimit);
+    return (expectedValue == activeUniformLimit &&
+            expectedValue == activeAttribLimit &&
+            expectedValue == varyingLimit);
 }
 
 static bool checkMappedNameMaxLength(const ShHandle handle, size_t expectedValue)
@@ -38,52 +42,6 @@
     return (expectedValue == mappedNameMaxLength);
 }
 
-static void getVariableInfo(ShShaderInfo varType,
-                            const ShHandle handle,
-                            int index,
-                            size_t* length,
-                            int* size,
-                            ShDataType* type,
-                            char* name,
-                            char* mappedName)
-{
-    if (!handle || !size || !type || !name)
-        return;
-    ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
-           (varType == SH_ACTIVE_UNIFORMS));
-
-    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
-    TCompiler* compiler = base->getAsCompiler();
-    if (compiler == 0)
-        return;
-
-    const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ?
-        compiler->getAttribs() : compiler->getUniforms();
-    if (index < 0 || index >= static_cast<int>(varList.size()))
-        return;
-
-    const TVariableInfo& varInfo = varList[index];
-    if (length) *length = varInfo.name.size();
-    *size = varInfo.size;
-    *type = varInfo.type;
-
-    // This size must match that queried by
-    // SH_ACTIVE_UNIFORM_MAX_LENGTH and SH_ACTIVE_ATTRIBUTE_MAX_LENGTH
-    // in ShGetInfo, below.
-    size_t activeUniformAndAttribLength = 1 + MAX_SYMBOL_NAME_LEN;
-    ASSERT(checkActiveUniformAndAttribMaxLengths(handle, activeUniformAndAttribLength));
-    strncpy(name, varInfo.name.c_str(), activeUniformAndAttribLength);
-    name[activeUniformAndAttribLength - 1] = 0;
-    if (mappedName) {
-        // This size must match that queried by
-        // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
-        size_t maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN;
-        ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
-        strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength);
-        mappedName[maxMappedNameLength - 1] = 0;
-    }
-}
-
 //
 // Driver must call this first, once, before doing any other compiler operations.
 // Subsequent calls to this function are no-op.
@@ -220,6 +178,12 @@
     case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
         *params = 1 + MAX_SYMBOL_NAME_LEN;
         break;
+    case SH_VARYINGS:
+        *params = compiler->getVaryings().size();
+        break;
+    case SH_VARYING_MAX_LENGTH:
+        *params = 1 + MAX_SYMBOL_NAME_LEN;
+        break;
     case SH_MAPPED_NAME_MAX_LENGTH:
         // Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to
         // handle array and struct dereferences.
@@ -277,28 +241,67 @@
     strcpy(objCode, infoSink.obj.c_str());
 }
 
-void ShGetActiveAttrib(const ShHandle handle,
+void ShGetVariableInfo(const ShHandle handle,
+                       ShShaderInfo varType,
                        int index,
                        size_t* length,
                        int* size,
                        ShDataType* type,
+                       ShPrecisionType* precision,
                        char* name,
                        char* mappedName)
 {
-    getVariableInfo(SH_ACTIVE_ATTRIBUTES,
-                    handle, index, length, size, type, name, mappedName);
-}
+    if (!handle || !size || !type || !name)
+        return;
+    ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
+           (varType == SH_ACTIVE_UNIFORMS) ||
+           (varType == SH_VARYINGS));
 
-void ShGetActiveUniform(const ShHandle handle,
-                        int index,
-                        size_t* length,
-                        int* size,
-                        ShDataType* type,
-                        char* name,
-                        char* mappedName)
-{
-    getVariableInfo(SH_ACTIVE_UNIFORMS,
-                    handle, index, length, size, type, name, mappedName);
+    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
+    TCompiler* compiler = base->getAsCompiler();
+    if (compiler == 0)
+        return;
+
+    const TVariableInfoList& varList =
+        varType == SH_ACTIVE_ATTRIBUTES ? compiler->getAttribs() :
+            (varType == SH_ACTIVE_UNIFORMS ? compiler->getUniforms() :
+                compiler->getVaryings());
+    if (index < 0 || index >= static_cast<int>(varList.size()))
+        return;
+
+    const TVariableInfo& varInfo = varList[index];
+    if (length) *length = varInfo.name.size();
+    *size = varInfo.size;
+    *type = varInfo.type;
+    switch (varInfo.precision) {
+    case EbpLow:
+        *precision = SH_PRECISION_LOWP;
+        break;
+    case EbpMedium:
+        *precision = SH_PRECISION_MEDIUMP;
+        break;
+    case EbpHigh:
+        *precision = SH_PRECISION_HIGHP;
+        break;
+    default:
+        ASSERT(false);
+    }
+
+    // This size must match that queried by
+    // SH_ACTIVE_UNIFORM_MAX_LENGTH, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_VARYING_MAX_LENGTH
+    // in ShGetInfo, below.
+    size_t variableLength = 1 + MAX_SYMBOL_NAME_LEN;
+    ASSERT(checkVariableMaxLengths(handle, variableLength));
+    strncpy(name, varInfo.name.c_str(), variableLength);
+    name[variableLength - 1] = 0;
+    if (mappedName) {
+        // This size must match that queried by
+        // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
+        size_t maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN;
+        ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
+        strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength);
+        mappedName[maxMappedNameLength - 1] = 0;
+    }
 }
 
 void ShGetNameHashingEntry(const ShHandle handle,
diff --git a/src/compiler/VariableInfo.cpp b/src/compiler/VariableInfo.cpp
index 84db807..4aaa948 100644
--- a/src/compiler/VariableInfo.cpp
+++ b/src/compiler/VariableInfo.cpp
@@ -119,6 +119,7 @@
         varInfo.mappedName = mappedName.c_str();
         varInfo.size = 1;
     }
+    varInfo.precision = type.getPrecision();
     varInfo.type = getVariableDataType(type);
     infoList.push_back(varInfo);
 }
@@ -153,40 +154,42 @@
 {
 }
 
-CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
-                                               TVariableInfoList& uniforms,
-                                               ShHashFunction64 hashFunction)
+CollectVariables::CollectVariables(TVariableInfoList& attribs,
+                                   TVariableInfoList& uniforms,
+                                   TVariableInfoList& varyings,
+                                   ShHashFunction64 hashFunction)
     : mAttribs(attribs),
       mUniforms(uniforms),
+      mVaryings(varyings),
       mHashFunction(hashFunction)
 {
 }
 
 // We are only interested in attribute and uniform variable declaration.
-void CollectAttribsUniforms::visitSymbol(TIntermSymbol*)
+void CollectVariables::visitSymbol(TIntermSymbol*)
 {
 }
 
-void CollectAttribsUniforms::visitConstantUnion(TIntermConstantUnion*)
+void CollectVariables::visitConstantUnion(TIntermConstantUnion*)
 {
 }
 
-bool CollectAttribsUniforms::visitBinary(Visit, TIntermBinary*)
+bool CollectVariables::visitBinary(Visit, TIntermBinary*)
 {
     return false;
 }
 
-bool CollectAttribsUniforms::visitUnary(Visit, TIntermUnary*)
+bool CollectVariables::visitUnary(Visit, TIntermUnary*)
 {
     return false;
 }
 
-bool CollectAttribsUniforms::visitSelection(Visit, TIntermSelection*)
+bool CollectVariables::visitSelection(Visit, TIntermSelection*)
 {
     return false;
 }
 
-bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
+bool CollectVariables::visitAggregate(Visit, TIntermAggregate* node)
 {
     bool visitChildren = false;
 
@@ -199,10 +202,12 @@
     case EOpDeclaration: {
         const TIntermSequence& sequence = node->getSequence();
         TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
-        if (qualifier == EvqAttribute || qualifier == EvqUniform)
+        if (qualifier == EvqAttribute || qualifier == EvqUniform ||
+            qualifier == EvqVaryingIn || qualifier == EvqVaryingOut ||
+            qualifier == EvqInvariantVaryingIn || qualifier == EvqInvariantVaryingOut)
         {
-            TVariableInfoList& infoList = qualifier == EvqAttribute ?
-                mAttribs : mUniforms;
+            TVariableInfoList& infoList = qualifier == EvqAttribute ? mAttribs :
+                (qualifier == EvqUniform ? mUniforms : mVaryings);
             for (TIntermSequence::const_iterator i = sequence.begin();
                  i != sequence.end(); ++i)
             {
@@ -233,12 +238,12 @@
     return visitChildren;
 }
 
-bool CollectAttribsUniforms::visitLoop(Visit, TIntermLoop*)
+bool CollectVariables::visitLoop(Visit, TIntermLoop*)
 {
     return false;
 }
 
-bool CollectAttribsUniforms::visitBranch(Visit, TIntermBranch*)
+bool CollectVariables::visitBranch(Visit, TIntermBranch*)
 {
     return false;
 }
diff --git a/src/compiler/VariableInfo.h b/src/compiler/VariableInfo.h
index 4130a58..bef196d 100644
--- a/src/compiler/VariableInfo.h
+++ b/src/compiler/VariableInfo.h
@@ -20,15 +20,17 @@
     TPersistString mappedName;
     ShDataType type;
     int size;
+    TPrecision precision;
 };
 typedef std::vector<TVariableInfo> TVariableInfoList;
 
-// Traverses intermediate tree to collect all attributes and uniforms.
-class CollectAttribsUniforms : public TIntermTraverser {
+// Traverses intermediate tree to collect all attributes, uniforms, varyings.
+class CollectVariables : public TIntermTraverser {
 public:
-    CollectAttribsUniforms(TVariableInfoList& attribs,
-                           TVariableInfoList& uniforms,
-                           ShHashFunction64 hashFunction);
+    CollectVariables(TVariableInfoList& attribs,
+                     TVariableInfoList& uniforms,
+                     TVariableInfoList& varyings,
+                     ShHashFunction64 hashFunction);
 
     virtual void visitSymbol(TIntermSymbol*);
     virtual void visitConstantUnion(TIntermConstantUnion*);
@@ -42,6 +44,7 @@
 private:
     TVariableInfoList& mAttribs;
     TVariableInfoList& mUniforms;
+    TVariableInfoList& mVaryings;
 
     ShHashFunction64 mHashFunction;
 };