Move shader attributes into Program shared data.

Making the Program own the attribs, and the Impl only see a read-only
copy cleans up the Impl object. It also allows us to more cleanly
isolate certain coded into D3D.

BUG=angleproject:1123

Change-Id: I469051eb066fc56e55282affa2d5398b394ab8d2
Reviewed-on: https://chromium-review.googlesource.com/293826
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index c41dc78..e4f7d54 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -1003,7 +1003,8 @@
     }
 
     // Generate new dynamic layout with attribute conversions
-    std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(mVertexHLSL, inputLayout, getShaderAttributes());
+    std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(
+        mVertexHLSL, inputLayout, mData.getAttributes());
 
     // Generate new vertex executable
     ShaderExecutableD3D *vertexExecutable = NULL;
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.h b/src/libANGLE/renderer/d3d/ProgramD3D.h
index 17f7c3d..7207d8c 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.h
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.h
@@ -124,6 +124,7 @@
     void sortAttributesByLayout(const std::vector<TranslatedAttribute> &unsortedAttributes,
                                 int sortedSemanticIndicesOut[gl::MAX_VERTEX_ATTRIBS],
                                 const rx::TranslatedAttribute *sortedAttributesOut[gl::MAX_VERTEX_ATTRIBS]) const;
+    const SemanticIndexArray &getAttributesByLayout() const { return mAttributesByLayout; }
 
     void updateCachedInputLayout(const gl::Program *program, const gl::State &state);
     const gl::InputLayout &getCachedInputLayout() const { return mCachedInputLayout; }
@@ -245,7 +246,7 @@
 
     int mShaderVersion;
 
-    int mAttributesByLayout[gl::MAX_VERTEX_ATTRIBS];
+    SemanticIndexArray mAttributesByLayout;
 
     unsigned int mSerial;
 
diff --git a/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
index 67c59a3..bae230c 100644
--- a/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
@@ -46,20 +46,20 @@
     return inputLayout;
 }
 
-GLenum GetNextGLSLAttributeType(const std::vector<sh::Attribute> &linkedAttributes, int index)
+GLenum GetGLSLAttributeType(const std::vector<sh::Attribute> &shaderAttributes, int index)
 {
     // Count matrices differently
-    int subIndex = 0;
-    for (const sh::Attribute &attrib : linkedAttributes)
+    for (const sh::Attribute &attrib : shaderAttributes)
     {
-        if (attrib.type == GL_NONE)
+        if (attrib.location == -1)
         {
             continue;
         }
 
         GLenum transposedType = gl::TransposeMatrixType(attrib.type);
-        subIndex += gl::VariableRowCount(transposedType);
-        if (subIndex > index)
+        int rows              = gl::VariableRowCount(transposedType);
+
+        if (index >= attrib.location && index < attrib.location + rows)
         {
             return transposedType;
         }
@@ -185,6 +185,8 @@
     bool instancedPointSpritesActive = programUsesInstancedPointSprites && (mode == GL_POINTS);
     bool indexedPointSpriteEmulationActive = instancedPointSpritesActive && (sourceInfo != nullptr);
 
+    const auto &semanticToLocation = programD3D->getAttributesByLayout();
+
     if (!mDevice || !mDeviceContext)
     {
         return gl::Error(GL_OUT_OF_MEMORY, "Internal input layout cache is not initialized.");
@@ -200,7 +202,7 @@
     unsigned int firstInstancedElement = gl::MAX_VERTEX_ATTRIBS;
     unsigned int nextAvailableInputSlot = 0;
 
-    const std::vector<sh::Attribute> &linkedAttributes = program->getLinkedAttributes();
+    const std::vector<sh::Attribute> &shaderAttributes = program->getAttributes();
 
     for (unsigned int i = 0; i < unsortedAttributes.size(); i++)
     {
@@ -232,7 +234,8 @@
 
             // Record the type of the associated vertex shader vector in our key
             // This will prevent mismatched vertex shaders from using the same input layout
-            GLenum glslElementType = GetNextGLSLAttributeType(linkedAttributes, inputElementCount);
+            GLenum glslElementType = GetGLSLAttributeType(
+                shaderAttributes, semanticToLocation[sortedSemanticIndices[i]]);
 
             layout.addAttributeData(glslElementType,
                                     sortedSemanticIndices[i],