Add a new path for querying active attributes from the shader translator, for use with layout qualifier support.

TRAC #23269

Signed-off-by: Geoff Lang
Signed-off-by: Nicolas Capens
Author: Jamie Madill
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index eead8ab..34cec04 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -1210,12 +1210,14 @@
                   "{\n";
 
     int semanticIndex = 0;
-    for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
+    const sh::ActiveShaderVariables &activeAttributes = vertexShader->mActiveAttributes;
+    for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
     {
-        vertexHLSL += "    " + gl_d3d::TypeString(TransposeMatrixType(attribute->type)) + " ";
-        vertexHLSL += decorateAttribute(attribute->name) + " : TEXCOORD" + str(semanticIndex) + ";\n";
+        const sh::ShaderVariable &attribute = activeAttributes[attributeIndex];
+        vertexHLSL += "    " + gl_d3d::TypeString(TransposeMatrixType(attribute.type)) + " ";
+        vertexHLSL += decorateAttribute(attribute.name) + " : TEXCOORD" + str(semanticIndex) + ";\n";
 
-        semanticIndex += AttributeRegisterCount(attribute->type);
+        semanticIndex += AttributeRegisterCount(attribute.type);
     }
 
     vertexHLSL += "};\n"
@@ -1250,16 +1252,17 @@
                   "VS_OUTPUT main(VS_INPUT input)\n"
                   "{\n";
 
-    for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
+    for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
     {
-        vertexHLSL += "    " + decorateAttribute(attribute->name) + " = ";
+        const sh::ShaderVariable &attribute = activeAttributes[attributeIndex];
+        vertexHLSL += "    " + decorateAttribute(attribute.name) + " = ";
 
-        if (IsMatrixType(attribute->type))   // Matrix
+        if (IsMatrixType(attribute.type))   // Matrix
         {
             vertexHLSL += "transpose";
         }
 
-        vertexHLSL += "(input." + decorateAttribute(attribute->name) + ");\n";
+        vertexHLSL += "(input." + decorateAttribute(attribute.name) + ");\n";
     }
 
     if (vertexHLSL.find("dx_initConstantBuffers") != std::string::npos)
@@ -2065,11 +2068,13 @@
 bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader)
 {
     unsigned int usedLocations = 0;
+    const sh::ActiveShaderVariables &activeAttributes = vertexShader->mActiveAttributes;
 
     // Link attributes that have a binding location
-    for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
+    for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
     {
-        int location = attributeBindings.getAttributeBinding(attribute->name);
+        const sh::ShaderVariable &attribute = activeAttributes[attributeIndex];
+        const int location = attributeBindings.getAttributeBinding(attribute.name);
 
         if (location != -1)   // Set by glBindAttribLocation
         {
@@ -2078,13 +2083,13 @@
                 // Multiple active attributes bound to the same location; not an error
             }
 
-            mLinkedAttribute[location] = *attribute;
+            mLinkedAttribute[location] = attribute;
 
-            int rows = AttributeRegisterCount(attribute->type);
+            int rows = AttributeRegisterCount(attribute.type);
 
             if (rows + location > MAX_VERTEX_ATTRIBS)
             {
-                infoLog.append("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location);
+                infoLog.append("Active attribute (%s) at location %d is too big to fit", attribute.name.c_str(), location);
 
                 return false;
             }
@@ -2097,23 +2102,24 @@
     }
 
     // Link attributes that don't have a binding location
-    for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
+    for (unsigned int attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
     {
-        int location = attributeBindings.getAttributeBinding(attribute->name);
+        const sh::ShaderVariable &attribute = activeAttributes[attributeIndex];
+        int location = attributeBindings.getAttributeBinding(attribute.name);
 
         if (location == -1)   // Not set by glBindAttribLocation
         {
-            int rows = AttributeRegisterCount(attribute->type);
+            int rows = AttributeRegisterCount(attribute.type);
             int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);
 
             if (availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
             {
-                infoLog.append("Too many active attributes (%s)", attribute->name.c_str());
+                infoLog.append("Too many active attributes (%s)", attribute.name.c_str());
 
                 return false;   // Fail to link
             }
 
-            mLinkedAttribute[availableIndex] = *attribute;
+            mLinkedAttribute[availableIndex] = attribute;
         }
     }
 
diff --git a/src/libGLESv2/ProgramBinary.h b/src/libGLESv2/ProgramBinary.h
index a29cf93..8401483 100644
--- a/src/libGLESv2/ProgramBinary.h
+++ b/src/libGLESv2/ProgramBinary.h
@@ -186,7 +186,7 @@
     rx::ShaderExecutable *mVertexExecutable;
     rx::ShaderExecutable *mGeometryExecutable;
 
-    Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
+    sh::ShaderVariable mLinkedAttribute[MAX_VERTEX_ATTRIBS];
     int mSemanticIndex[MAX_VERTEX_ATTRIBS];
 
     struct Sampler
diff --git a/src/libGLESv2/Shader.cpp b/src/libGLESv2/Shader.cpp
index c18706a..4ab3789 100644
--- a/src/libGLESv2/Shader.cpp
+++ b/src/libGLESv2/Shader.cpp
@@ -628,7 +628,7 @@
     Shader::uncompile();
 
     // set by ParseAttributes
-    mAttributes.clear();
+    mActiveAttributes.clear();
 }
 
 void VertexShader::compile()
@@ -645,14 +645,16 @@
     if (!attributeName.empty())
     {
         int semanticIndex = 0;
-        for (AttributeArray::iterator attribute = mAttributes.begin(); attribute != mAttributes.end(); attribute++)
+        for (unsigned int attributeIndex = 0; attributeIndex < mActiveAttributes.size(); attributeIndex++)
         {
-            if (attribute->name == attributeName)
+            const sh::ShaderVariable &attribute = mActiveAttributes[attributeIndex];
+
+            if (attribute.name == attributeName)
             {
                 return semanticIndex;
             }
 
-            semanticIndex += AttributeRegisterCount(attribute->type);
+            semanticIndex += AttributeRegisterCount(attribute.type);
         }
     }
 
@@ -664,24 +666,9 @@
     const char *hlsl = getHLSL();
     if (hlsl)
     {
-        const char *input = strstr(hlsl, "// Attributes") + 14;
-
-        while(true)
-        {
-            char attributeType[256];
-            char attributeName[256];
-
-            int matches = sscanf(input, "static %255s _%255s", attributeType, attributeName);
-
-            if (matches != 2)
-            {
-                break;
-            }
-
-            mAttributes.push_back(Attribute(parseType(attributeType), attributeName));
-
-            input = strstr(input, ";") + 2;
-        }
+        void *activeAttributes;
+        ShGetInfoPointer(mVertexCompiler, SH_ACTIVE_ATTRIBUTES_ARRAY, &activeAttributes);
+        mActiveAttributes = *(sh::ActiveShaderVariables*)activeAttributes;
     }
 }
 
diff --git a/src/libGLESv2/Shader.h b/src/libGLESv2/Shader.h
index e5c600a..b5df3f4 100644
--- a/src/libGLESv2/Shader.h
+++ b/src/libGLESv2/Shader.h
@@ -141,22 +141,6 @@
     ResourceManager *mResourceManager;
 };
 
-struct Attribute
-{
-    Attribute() : type(GL_NONE), name("")
-    {
-    }
-
-    Attribute(GLenum type, const std::string &name) : type(type), name(name)
-    {
-    }
-
-    GLenum type;
-    std::string name;
-};
-
-typedef std::vector<Attribute> AttributeArray;
-
 class VertexShader : public Shader
 {
     friend class ProgramBinary;
@@ -176,7 +160,7 @@
 
     void parseAttributes();
 
-    AttributeArray mAttributes;
+    sh::ActiveShaderVariables mActiveAttributes;
 };
 
 class FragmentShader : public Shader