[Compat] Add GLDepthBiasModifier toggle

Empirically some GL drivers (desktop)
select n+1 when a depth value lies between 2^n and 2^(n+1),
while WebGPU CTS is expecting n.

This change will make android compat passes depth bias tests,
where they seem to select n.

Bug: 42241017, 352360580, 366411883
Change-Id: Ia7e71508ed65089c945f9b6613c68f632c83264a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/208494
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Shrek Shao <shrekshao@google.com>
Reviewed-by: Stephen White <senorblanco@chromium.org>
diff --git a/src/dawn/native/Toggles.cpp b/src/dawn/native/Toggles.cpp
index 888996f..4ea8bd7 100644
--- a/src/dawn/native/Toggles.cpp
+++ b/src/dawn/native/Toggles.cpp
@@ -558,6 +558,12 @@
       "COPY_SOURCE too on Nvidia since the shader resource states seem to miss flushing all caches "
       "and layout transitions causing rendering corruption.",
       "https://crbug.com/356905061", ToggleStage::Device}},
+    {Toggle::GLDepthBiasModifier,
+     {"gl_depth_bias_modifier",
+      "Empirically some GL drivers select n+1 when a depth value lies between 2^n and 2^(n+1), "
+      "while the WebGPU CTS is expecting n. Scale the depth bias value by multiple 0.5 on certain "
+      "backends to achieve conformant result.",
+      "https://crbug.com/42241017", ToggleStage::Device}},
     {Toggle::NoWorkaroundSampleMaskBecomesZeroForAllButLastColorTarget,
      {"no_workaround_sample_mask_becomes_zero_for_all_but_last_color_target",
       "MacOS 12.0+ Intel has a bug where the sample mask is only applied for the last color "
diff --git a/src/dawn/native/Toggles.h b/src/dawn/native/Toggles.h
index 674dedc..c40770f 100644
--- a/src/dawn/native/Toggles.h
+++ b/src/dawn/native/Toggles.h
@@ -134,6 +134,7 @@
     UsePackedDepth24UnormStencil8Format,
     D3D12ForceStencilComponentReplicateSwizzle,
     D3D12ExpandShaderResourceStateTransitionsToCopySource,
+    GLDepthBiasModifier,
 
     // Unresolved issues.
     NoWorkaroundSampleMaskBecomesZeroForAllButLastColorTarget,
diff --git a/src/dawn/native/opengl/PhysicalDeviceGL.cpp b/src/dawn/native/opengl/PhysicalDeviceGL.cpp
index 2020e9c..4de25b2 100644
--- a/src/dawn/native/opengl/PhysicalDeviceGL.cpp
+++ b/src/dawn/native/opengl/PhysicalDeviceGL.cpp
@@ -95,6 +95,10 @@
            renderer.find("OpenGL ES") == std::string::npos;
 }
 
+bool IsSwiftShader(std::string renderer) {
+    return renderer.find("SwiftShader") != std::string::npos;
+}
+
 }  // anonymous namespace
 
 // static
@@ -415,6 +419,11 @@
 
     // Use T2B and B2T copies to emulate a T2T copy between sRGB and non-sRGB textures.
     deviceToggles->Default(Toggle::UseT2B2TForSRGBTextureCopy, true);
+
+    // Scale depth bias value by * 0.5 on certain GL drivers.
+    deviceToggles->Default(Toggle::GLDepthBiasModifier, gl.GetVersion().IsDesktop() ||
+                                                            IsANGLEDesktopGL(mName) ||
+                                                            IsSwiftShader(mName));
 }
 
 ResultOrError<Ref<DeviceBase>> PhysicalDevice::CreateDeviceImpl(
diff --git a/src/dawn/native/opengl/RenderPipelineGL.cpp b/src/dawn/native/opengl/RenderPipelineGL.cpp
index cd0387c..f2ae926 100644
--- a/src/dawn/native/opengl/RenderPipelineGL.cpp
+++ b/src/dawn/native/opengl/RenderPipelineGL.cpp
@@ -294,14 +294,17 @@
 
     if (IsDepthBiasEnabled()) {
         gl.Enable(GL_POLYGON_OFFSET_FILL);
-        // There is an ambiguity in the GL and Vulkan specs with respect to
-        // depthBias: If a depth value lies between 2^n and 2^(n+1), is the
-        // "exponent of the depth value" n or n+1? Empirically, GL drivers use
-        // n+1, while the WebGPU CTS is expecting n. Scaling the depth
-        // bias value by 0.5 gives results in line with other backends.
-        // See: https://gitlab.khronos.org/Tracker/vk-gl-cts/-/issues/4169
-        // See also the GL ES 3.1 spec, section "13.5.2 Depth Offset".
-        float depthBias = GetDepthBias() * 0.5f;
+        float depthBias = GetDepthBias();
+        if (GetDevice()->IsToggleEnabled(Toggle::GLDepthBiasModifier)) {
+            // There is an ambiguity in the GL and Vulkan specs with respect to
+            // depthBias: If a depth value lies between 2^n and 2^(n+1), is the
+            // "exponent of the depth value" n or n+1? Empirically, desktop GL drivers use
+            // n+1, while the WebGPU CTS is expecting n. Scaling the depth
+            // bias value by 0.5 gives results in line with other backends.
+            // See: https://gitlab.khronos.org/Tracker/vk-gl-cts/-/issues/4169
+            // See also the GL ES 3.1 spec, section "13.5.2 Depth Offset".
+            depthBias *= 0.5f;
+        }
         float slopeScale = GetDepthBiasSlopeScale();
         if (gl.PolygonOffsetClamp != nullptr) {
             gl.PolygonOffsetClamp(slopeScale, depthBias, GetDepthBiasClamp());
diff --git a/src/dawn/tests/end2end/DepthBiasTests.cpp b/src/dawn/tests/end2end/DepthBiasTests.cpp
index 43f817b..e36fcbe 100644
--- a/src/dawn/tests/end2end/DepthBiasTests.cpp
+++ b/src/dawn/tests/end2end/DepthBiasTests.cpp
@@ -208,10 +208,6 @@
 TEST_P(DepthBiasTests, NegativeBiasOnFloat) {
     // NVIDIA GPUs seems to be using a different scale than everyone else
     DAWN_SUPPRESS_TEST_IF(IsVulkan() && IsNvidia());
-    // TODO(crbug.com/352360580): Investigate failures.
-    DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid());
-    DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsANGLED3D11());
-
     // Draw quad flat on z = 0.25 with -0.25 bias, depth clear of 0.125
     RunDepthBiasTest(wgpu::TextureFormat::Depth32Float, 0.125, QuadAngle::Flat,
                      -kPointTwoFiveBiasForPointTwoFiveZOnFloat, 0, 0);
@@ -331,14 +327,6 @@
 
 // Test adding positive bias to output
 TEST_P(DepthBiasTests, PositiveBiasOn24bit) {
-    // ANGLE/D3D11 is failing this test for unknown reasons.
-    DAWN_TEST_UNSUPPORTED_IF(IsANGLED3D11());
-
-    // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 4 OpenGLES
-    DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsQualcomm());
-    // TODO(crbug.com/dawn/2295): diagnose this failure on Pixel 6 OpenGLES
-    DAWN_SUPPRESS_TEST_IF(IsOpenGLES() && IsAndroid() && IsARM());
-
     // Draw quad flat on z = 0.25 with 0.25 bias
     RunDepthBiasTest(wgpu::TextureFormat::Depth24PlusStencil8, 0.4f, QuadAngle::Flat,
                      0.25f * (1 << 25), 0, 0);
diff --git a/webgpu-cts/compat-expectations.txt b/webgpu-cts/compat-expectations.txt
index 1884241..96d53cf 100644
--- a/webgpu-cts/compat-expectations.txt
+++ b/webgpu-cts/compat-expectations.txt
@@ -1307,11 +1307,6 @@
 crbug.com/dawn/0000 [ android arm ] webgpu:api,operation,memory_sync,buffer,single_buffer:wr:boundary="queue-op";readOp="input-indirect-dispatch";readContext="compute-pass-encoder";writeOp="storage";writeContext="render-bundle-encoder" [ Failure ]
 crbug.com/dawn/0000 [ android arm ] webgpu:api,operation,memory_sync,buffer,single_buffer:ww:boundary="command-buffer";writeOps=["storage","t2b-copy"];contexts=["render-bundle-encoder","command-encoder"] [ Failure ]
 
-# rendering,depth_bias failures on Pixel 6
-crbug.com/366411883 [ android arm ] webgpu:api,operation,rendering,depth_bias:depth_bias:quadAngle=0;bias=8388608;biasSlopeScale=0;biasClamp=0 [ Failure ]
-crbug.com/366411883 [ android arm ] webgpu:api,operation,rendering,depth_bias:depth_bias_24bit_format:format="depth24plus";quadAngle=0;bias=8388608;biasSlopeScale=0;biasClamp=0 [ Failure ]
-crbug.com/366411883 [ android arm ] webgpu:api,operation,rendering,depth_bias:depth_bias_24bit_format:format="depth24plus-stencil8";quadAngle=0;bias=8388608;biasSlopeScale=0;biasClamp=0 [ Failure ]
-
 # Compressed texture image_copy failures on Pixel 6
 crbug.com/364917742 [ android arm ] webgpu:api,operation,command_buffer,image_copy:offsets_and_sizes:initMethod="CopyB2T";checkMethod="FullCopyT2B";format="astc-10x10-unorm";dimension="2d" [ Failure ]
 crbug.com/364917742 [ android arm ] webgpu:api,operation,command_buffer,image_copy:offsets_and_sizes:initMethod="CopyB2T";checkMethod="FullCopyT2B";format="astc-10x5-unorm";dimension="2d" [ Failure ]