Capture/Replay: Init shader outputs during self-tests.

This forces all uninitialized variables to have default values.
For instance if the application doesn't initialize the output
color, or a varying that's use in the output, this will ensure we
don't use any undefined values in the computation.

Found when working on a re-trace of T-Rex, which doesn't write to
the alpha channel in the final rendering pass. Also fixes undefined
values in GLSLTest.InactiveVaryingInVertexActiveInFragment.

Bug: angleproject:5133
Change-Id: Ia291338e5adf23dab5263cb2ebe737dc05852d3e
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3110225
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Cody Northrop <cnorthrop@google.com>
Reviewed-by: Tim Van Patten <timvp@google.com>
diff --git a/include/platform/FrontendFeatures.h b/include/platform/FrontendFeatures.h
index db63745..aee4fbf 100644
--- a/include/platform/FrontendFeatures.h
+++ b/include/platform/FrontendFeatures.h
@@ -77,9 +77,16 @@
         "enableCompressingPipelineCacheInThreadPool", angle::FeatureCategory::FrontendWorkarounds,
         "Enable compressing pipeline cache in thread pool.", &members, "http://anglebug.com/4722"};
 
+    // Forces on robust resource init. Useful for some tests to avoid undefined values.
     angle::Feature forceRobustResourceInit = {
-        "forceRobustResourceInit", angle::FeatureCategory::FrontendWorkarounds,
+        "forceRobustResourceInit", angle::FeatureCategory::FrontendFeatures,
         "Force-enable robust resource init", &members, "http://anglebug.com/6041"};
+
+    // Forces on shader output initialization to avoid undefined values in tests. Normally this
+    // feature is only enabled for WebGL.
+    angle::Feature forceInitShaderOutputVariables = {
+        "forceInitShaderOutputVariables", angle::FeatureCategory::FrontendFeatures,
+        "Force-enable shader output variable initialization", &members};
 };
 
 inline FrontendFeatures::FrontendFeatures()  = default;
diff --git a/src/libANGLE/Shader.cpp b/src/libANGLE/Shader.cpp
index bbda668..1ecbbef 100644
--- a/src/libANGLE/Shader.cpp
+++ b/src/libANGLE/Shader.cpp
@@ -356,7 +356,7 @@
         options |= SH_INIT_SHARED_VARIABLES;
     }
 
-    // Some targets (eg D3D11 Feature Level 9_3 and below) do not support non-constant loop
+    // Some targets (e.g. D3D11 Feature Level 9_3 and below) do not support non-constant loop
     // indexes in fragment shaders. Shader compilation will fail. To provide a better error
     // message we can instruct the compiler to pre-validate.
     if (mRendererLimitations.shadersRequireIndexedLoopValidation)
@@ -369,6 +369,11 @@
         options |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS;
     }
 
+    if (context->getFrontendFeatures().forceInitShaderOutputVariables.enabled)
+    {
+        options |= SH_INIT_OUTPUT_VARIABLES;
+    }
+
     mCurrentMaxComputeWorkGroupInvocations =
         static_cast<GLuint>(context->getCaps().maxComputeWorkGroupInvocations);
 
diff --git a/src/tests/capture_replay_tests.py b/src/tests/capture_replay_tests.py
index b4e6e64..e2a22bf 100755
--- a/src/tests/capture_replay_tests.py
+++ b/src/tests/capture_replay_tests.py
@@ -566,11 +566,16 @@
         test_exe_path = os.path.join(args.out_dir, 'Capture', args.test_suite)
 
         extra_env = {
-            'ANGLE_CAPTURE_FRAME_END': '{}'.format(self.CAPTURE_FRAME_END),
-            'ANGLE_CAPTURE_SERIALIZE_STATE': '1',
-            'ANGLE_FEATURE_OVERRIDES_ENABLED': 'forceRobustResourceInit',
-            'ANGLE_CAPTURE_ENABLED': '1',
-            'ANGLE_CAPTURE_OUT_DIR': self.trace_folder_path,
+            'ANGLE_CAPTURE_FRAME_END':
+                '{}'.format(self.CAPTURE_FRAME_END),
+            'ANGLE_CAPTURE_SERIALIZE_STATE':
+                '1',
+            'ANGLE_FEATURE_OVERRIDES_ENABLED':
+                'forceRobustResourceInit:forceInitShaderOutputVariables',
+            'ANGLE_CAPTURE_ENABLED':
+                '1',
+            'ANGLE_CAPTURE_OUT_DIR':
+                self.trace_folder_path,
         }
 
         env = {**os.environ.copy(), **extra_env}
diff --git a/src/tests/capture_replay_tests/CaptureReplayTests.cpp b/src/tests/capture_replay_tests/CaptureReplayTests.cpp
index c0914e5..11621a2 100644
--- a/src/tests/capture_replay_tests/CaptureReplayTests.cpp
+++ b/src/tests/capture_replay_tests/CaptureReplayTests.cpp
@@ -88,8 +88,9 @@
         configParams.webGLCompatibility    = testTraceInfo.webGLCompatibility;
         configParams.robustResourceInit    = testTraceInfo.robustResourceInit;
 
-        mPlatformParams.renderer   = testTraceInfo.replayPlatformType;
-        mPlatformParams.deviceType = testTraceInfo.replayDeviceType;
+        mPlatformParams.renderer                       = testTraceInfo.replayPlatformType;
+        mPlatformParams.deviceType                     = testTraceInfo.replayDeviceType;
+        mPlatformParams.forceInitShaderOutputVariables = EGL_TRUE;
 
         if (!mEGLWindow->initializeGL(mOSWindow, mEntryPointsLib.get(),
                                       angle::GLESDriverType::AngleEGL, mPlatformParams,
diff --git a/util/EGLPlatformParameters.h b/util/EGLPlatformParameters.h
index 5442522..269f8c4 100644
--- a/util/EGLPlatformParameters.h
+++ b/util/EGLPlatformParameters.h
@@ -66,7 +66,7 @@
                         hasExplicitMemBarrierFeatureMtl, hasCheapRenderPassFeatureMtl,
                         forceBufferGPUStorageFeatureMtl, supportsVulkanViewportFlip, emulatedVAOs,
                         directSPIRVGeneration, captureLimits, forceRobustResourceInit,
-                        directMetalGeneration);
+                        directMetalGeneration, forceInitShaderOutputVariables);
     }
 
     EGLint renderer                               = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
@@ -93,6 +93,7 @@
     EGLint captureLimits                          = EGL_DONT_CARE;
     EGLint forceRobustResourceInit                = EGL_DONT_CARE;
     EGLint directMetalGeneration                  = EGL_DONT_CARE;
+    EGLint forceInitShaderOutputVariables         = EGL_DONT_CARE;
 
     angle::PlatformMethods *platformMethods = nullptr;
 };
diff --git a/util/EGLWindow.cpp b/util/EGLWindow.cpp
index 50db3d2..9934833 100644
--- a/util/EGLWindow.cpp
+++ b/util/EGLWindow.cpp
@@ -300,6 +300,11 @@
         enabledFeatureOverrides.push_back("forceRobustResourceInit");
     }
 
+    if (params.forceInitShaderOutputVariables == EGL_TRUE)
+    {
+        enabledFeatureOverrides.push_back("forceInitShaderOutputVariables");
+    }
+
     const bool hasFeatureControlANGLE =
         strstr(extensionString, "EGL_ANGLE_feature_control") != nullptr;