From 2f45d93d5be7731488c47bb597834e665b9ed1a6 Mon Sep 17 00:00:00 2001 From: Jamie Madill Date: Wed, 18 Aug 2021 16:58:44 -0400 Subject: [PATCH] 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 Reviewed-by: Cody Northrop Reviewed-by: Tim Van Patten --- include/platform/FrontendFeatures.h | 9 ++++++++- src/libANGLE/Shader.cpp | 7 ++++++- src/tests/capture_replay_tests.py | 15 ++++++++++----- .../capture_replay_tests/CaptureReplayTests.cpp | 5 +++-- util/EGLPlatformParameters.h | 3 ++- util/EGLWindow.cpp | 5 +++++ 6 files changed, 34 insertions(+), 10 deletions(-) diff --git a/include/platform/FrontendFeatures.h b/include/platform/FrontendFeatures.h index db6374506..aee4fbffe 100644 --- a/include/platform/FrontendFeatures.h +++ b/include/platform/FrontendFeatures.h @@ -77,9 +77,16 @@ struct FrontendFeatures : angle::FeatureSetBase "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 bbda668cf..1ecbbef5a 100644 --- a/src/libANGLE/Shader.cpp +++ b/src/libANGLE/Shader.cpp @@ -356,7 +356,7 @@ void Shader::compile(const Context *context) 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 @@ void Shader::compile(const Context *context) options |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS; } + if (context->getFrontendFeatures().forceInitShaderOutputVariables.enabled) + { + options |= SH_INIT_OUTPUT_VARIABLES; + } + mCurrentMaxComputeWorkGroupInvocations = static_cast(context->getCaps().maxComputeWorkGroupInvocations); diff --git a/src/tests/capture_replay_tests.py b/src/tests/capture_replay_tests.py index b4e6e64a5..e2a22bf19 100755 --- a/src/tests/capture_replay_tests.py +++ b/src/tests/capture_replay_tests.py @@ -566,11 +566,16 @@ class TestBatch(): 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 c0914e5a1..11621a24b 100644 --- a/src/tests/capture_replay_tests/CaptureReplayTests.cpp +++ b/src/tests/capture_replay_tests/CaptureReplayTests.cpp @@ -88,8 +88,9 @@ class CaptureReplayTests 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 544252241..269f8c416 100644 --- a/util/EGLPlatformParameters.h +++ b/util/EGLPlatformParameters.h @@ -66,7 +66,7 @@ struct EGLPlatformParameters hasExplicitMemBarrierFeatureMtl, hasCheapRenderPassFeatureMtl, forceBufferGPUStorageFeatureMtl, supportsVulkanViewportFlip, emulatedVAOs, directSPIRVGeneration, captureLimits, forceRobustResourceInit, - directMetalGeneration); + directMetalGeneration, forceInitShaderOutputVariables); } EGLint renderer = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE; @@ -93,6 +93,7 @@ struct EGLPlatformParameters 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 50db3d2ae..993483374 100644 --- a/util/EGLWindow.cpp +++ b/util/EGLWindow.cpp @@ -300,6 +300,11 @@ bool EGLWindow::initializeDisplay(OSWindow *osWindow, enabledFeatureOverrides.push_back("forceRobustResourceInit"); } + if (params.forceInitShaderOutputVariables == EGL_TRUE) + { + enabledFeatureOverrides.push_back("forceInitShaderOutputVariables"); + } + const bool hasFeatureControlANGLE = strstr(extensionString, "EGL_ANGLE_feature_control") != nullptr;