Enable MRT pixel shader rewriting.

Writing to all 8 pixel outputs was causing performance problems on
Intel and AMD. Enabling Geoff's work to rewrite our pixel shaders
solves the regression.

This patch also includes a workaround to the nVidia driver bug
where it would ignore NULL RT values in OMSetRenderTargets, by
compacting the RT list to skip NULL values.

BUG=angle:705
BUG=365078

Change-Id: Ia68af6f0ccd5f10c484d6f76297a0bec694948f0
Reviewed-on: https://chromium-review.googlesource.com/214852
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp b/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
index 6aa0d13..cd2b1a8 100644
--- a/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
+++ b/src/libGLESv2/renderer/d3d/DynamicHLSL.cpp
@@ -22,7 +22,7 @@
 
 using namespace gl;
 
-namespace gl_d3d
+namespace
 {
 
 std::string HLSLComponentTypeString(GLenum componentType)
@@ -70,6 +70,21 @@
     return HLSLComponentTypeString(gl::VariableComponentType(type), gl::VariableComponentCount(type));
 }
 
+const rx::PixelShaderOuputVariable &GetOutputAtLocation(const std::vector<rx::PixelShaderOuputVariable> &outputVariables,
+                                                        unsigned int location)
+{
+    for (size_t variableIndex = 0; variableIndex < outputVariables.size(); ++variableIndex)
+    {
+        if (outputVariables[variableIndex].outputIndex == location)
+        {
+            return outputVariables[variableIndex];
+        }
+    }
+
+    UNREACHABLE();
+    return outputVariables[0];
+}
+
 }
 
 namespace rx
@@ -328,7 +343,7 @@
                     {
                         GLenum componentType = VariableComponentType(transposedType);
                         int columnCount = VariableColumnCount(transposedType);
-                        typeString = gl_d3d::HLSLComponentTypeString(componentType, columnCount);
+                        typeString = HLSLComponentTypeString(componentType, columnCount);
                     }
                     varyingHLSL += typeString + " v" + n + " : " + varyingSemantic + n + ";\n";
                 }
@@ -361,12 +376,12 @@
             if (IsMatrixType(shaderAttribute.type))
             {
                 // Matrix types are always transposed
-                structHLSL += "    " + gl_d3d::HLSLMatrixTypeString(TransposeMatrixType(shaderAttribute.type));
+                structHLSL += "    " + HLSLMatrixTypeString(TransposeMatrixType(shaderAttribute.type));
             }
             else
             {
                 GLenum componentType = mRenderer->getVertexComponentType(vertexFormat);
-                structHLSL += "    " + gl_d3d::HLSLComponentTypeString(componentType, VariableComponentCount(shaderAttribute.type));
+                structHLSL += "    " + HLSLComponentTypeString(componentType, VariableComponentCount(shaderAttribute.type));
             }
 
             structHLSL += " " + decorateVariable(shaderAttribute.name) + " : TEXCOORD" + Str(semanticIndex) + ";\n";
@@ -421,17 +436,19 @@
 
     std::string declarationHLSL;
     std::string copyHLSL;
-    for (size_t i = 0; i < outputVariables.size(); i++)
-    {
-        const PixelShaderOuputVariable& outputVariable = outputVariables[i];
-        ASSERT(outputLayout.size() > outputVariable.outputIndex);
 
-        // FIXME(geofflang): Work around NVIDIA driver bug by repacking buffers
-        bool outputIndexEnabled = true; // outputLayout[outputVariable.outputIndex] != GL_NONE
-        if (outputIndexEnabled)
+    for (size_t layoutIndex = 0; layoutIndex < outputLayout.size(); ++layoutIndex)
+    {
+        GLenum binding = outputLayout[layoutIndex];
+
+        if (binding != GL_NONE)
         {
-            declarationHLSL += "    " + gl_d3d::HLSLTypeString(outputVariable.type) + " " + outputVariable.name +
-                               " : " + targetSemantic + Str(outputVariable.outputIndex) + ";\n";
+            unsigned int location = (binding - GL_COLOR_ATTACHMENT0);
+
+            const PixelShaderOuputVariable &outputVariable = GetOutputAtLocation(outputVariables, location);
+
+            declarationHLSL += "    " + HLSLTypeString(outputVariable.type) + " " + outputVariable.name +
+                               " : " + targetSemantic + Str(layoutIndex) + ";\n";
 
             copyHLSL += "    output." + outputVariable.name + " = " + outputVariable.source + ";\n";
         }