Add shader translator support for OVR_multiview

The OVR_multiview and OVR_multiview2 extensions add gl_ViewID_OVR to
shaders. gl_ViewID_OVR can be translated either as is in GLSL output
or as a uniform by setting the SH_TRANSLATE_VIEWID_OVR_AS_UNIFORM
compiler flag.

If WebGL output is selected, the shaders will be validated according
to proposed rules in the WEBGL_multiview spec.

BUG=angleproject:1669
TEST=angle_unittests

Change-Id: I19ea3a6c8b4edb78be03f1a50a96bfef018870d0
Reviewed-on: https://chromium-review.googlesource.com/422848
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index bda45d4..212aa0d 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -30,6 +30,7 @@
 #include "compiler/translator/UseInterfaceBlockFields.h"
 #include "compiler/translator/ValidateLimitations.h"
 #include "compiler/translator/ValidateMaxParameters.h"
+#include "compiler/translator/ValidateMultiviewWebGL.h"
 #include "compiler/translator/ValidateOutputs.h"
 #include "compiler/translator/VariablePacker.h"
 #include "third_party/compiler/ArrayBoundsClamper.h"
@@ -320,11 +321,22 @@
         mComputeShaderLocalSizeDeclared = parseContext.isComputeShaderLocalSizeDeclared();
         mComputeShaderLocalSize         = parseContext.getComputeShaderLocalSize();
 
+        mNumViews = parseContext.getNumViews();
+
         root = parseContext.getTreeRoot();
 
         // Highp might have been auto-enabled based on shader version
         fragmentPrecisionHigh = parseContext.getFragmentPrecisionHigh();
 
+        if (success && (IsWebGLBasedSpec(shaderSpec) &&
+                        IsExtensionEnabled(extensionBehavior, "GL_OVR_multiview") &&
+                        IsExtensionEnabled(extensionBehavior, "GL_OVR_multiview2")))
+        {
+            // Can't enable both extensions at the same time.
+            mDiagnostics.globalError("Can't enable both OVR_multiview and OVR_multiview2");
+            success = false;
+        }
+
         // Disallow expressions deemed too complex.
         if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY))
             success = limitExpressionComplexity(root);
@@ -358,6 +370,11 @@
         if (success && shouldRunLoopAndIndexingValidation(compileOptions))
             success = validateLimitations(root);
 
+        bool multiview2 = IsExtensionEnabled(extensionBehavior, "GL_OVR_multiview2");
+        if (success && compileResources.OVR_multiview && IsWebGLBasedSpec(shaderSpec) &&
+            (IsExtensionEnabled(extensionBehavior, "GL_OVR_multiview") || multiview2))
+            success = ValidateMultiviewWebGL(root, shaderType, multiview2, &mDiagnostics);
+
         // Fail compilation if precision emulation not supported.
         if (success && getResources().WEBGL_debug_shader_precision &&
             getPragma().debugShaderPrecision)
@@ -650,6 +667,8 @@
     interfaceBlocks.clear();
     variablesCollected = false;
 
+    mNumViews = -1;
+
     builtInFunctionEmulator.Cleanup();
 
     nameMap.clear();