Work around NVIDIA GLSL vector-scalar op bug

This adds a new AST transform VectorizeVectorScalarArithmetic. The AST
transform works around incorrect handling of certain types of GLSL
arithmetic operations by NVIDIA's GL driver. It works around only the
most common cases where the bug reproduces, since detecting all the
cases would take more sophisticated analysis of the code than what
is currently easily implementable in ANGLE.

When a float add operator has both vector and scalar operands, the AST
transform turns the scalar operand into a vector operand. Example:

vec4 f;
f += 1.0;

gets turned into:

vec4 f;
f += vec4(1.0);

When a vector constructor contains a binary scalar float
multiplication or division operation as its only argument, the AST
transform turns both operands of the binary operation into vector
operands. Example:

float f, g;
vec4(f * g);

gets turned into:

float f, g;
vec4(vec4(f) * vec4(g));

Another example with compound assignment:

float f, g;
vec4(f *= g);

gets turned into:

float f, g;
vec4 s0 = vec4(f);
(s0 *= g, f = s0.x), s0;

This latter transformation only works in case the compound assignment
left hand expression doesn't have side effects.

BUG=chromium:772651
TEST=angle_end2end_tests

Change-Id: I84ec04287793c56a94845a725785439565debdaf
Reviewed-on: https://chromium-review.googlesource.com/721321
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index 0837868..9cb79b4 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -44,6 +44,7 @@
 #include "compiler/translator/ValidateOutputs.h"
 #include "compiler/translator/ValidateVaryingLocations.h"
 #include "compiler/translator/VariablePacker.h"
+#include "compiler/translator/VectorizeVectorScalarArithmetic.h"
 #include "third_party/compiler/ArrayBoundsClamper.h"
 
 namespace sh
@@ -606,6 +607,7 @@
                                        IntermNodePatternMatcher::kNamelessStructDeclaration,
                                    &getSymbolTable(), getShaderVersion());
         }
+
         InitializeUninitializedLocals(root, getShaderVersion());
     }
 
@@ -614,6 +616,11 @@
         ClampPointSize(root, compileResources.MaxPointSize, &getSymbolTable());
     }
 
+    if (compileOptions & SH_REWRITE_VECTOR_SCALAR_ARITHMETIC)
+    {
+        VectorizeVectorScalarArithmetic(root, &getSymbolTable());
+    }
+
     return true;
 }