[Compat] Add toggle to add egl attrib to use min gles version and no extension
We can config bot to run end2endtests with
`--enable-toggles=gl_force_es_31_and_no_extensions` to
add test coverage of compat mode support on devices without
certain extensions.
Bug: 382084196
Change-Id: I7bb3877abf41c13abedb9f243cc02c58d854f019
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/217974
Reviewed-by: Stephen White <senorblanco@chromium.org>
Auto-Submit: Shrek Shao <shrekshao@google.com>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
diff --git a/src/dawn/native/Toggles.cpp b/src/dawn/native/Toggles.cpp
index 8248c17..2a8ca23 100644
--- a/src/dawn/native/Toggles.cpp
+++ b/src/dawn/native/Toggles.cpp
@@ -564,6 +564,12 @@
"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::GLForceES31AndNoExtensions,
+ {"gl_force_es_31_and_no_extensions",
+ "Force EGLContext creation with the minimal ES version and no extensions required by the "
+ "Compat spec, which for OpenGLES is version 3.1 with no extensions. This toggle is used by "
+ "end2end testing.",
+ "crbug.com/382084196", ToggleStage::Adapter}},
{Toggle::VulkanMonolithicPipelineCache,
{"vulkan_monolithic_pipeline_cache",
"Use a monolithic VkPipelineCache per device. The embedder is responsible for calling "
diff --git a/src/dawn/native/Toggles.h b/src/dawn/native/Toggles.h
index 0993ef9..5a80e6a 100644
--- a/src/dawn/native/Toggles.h
+++ b/src/dawn/native/Toggles.h
@@ -136,6 +136,7 @@
D3D12ForceStencilComponentReplicateSwizzle,
D3D12ExpandShaderResourceStateTransitionsToCopySource,
GLDepthBiasModifier,
+ GLForceES31AndNoExtensions,
VulkanMonolithicPipelineCache,
MetalSerializeTimestampGenerationAndResolution,
D3D12RelaxMinSubgroupSizeTo8,
diff --git a/src/dawn/native/opengl/BackendGL.cpp b/src/dawn/native/opengl/BackendGL.cpp
index 5eb4db7..5ec72f5 100644
--- a/src/dawn/native/opengl/BackendGL.cpp
+++ b/src/dawn/native/opengl/BackendGL.cpp
@@ -63,6 +63,15 @@
return {};
}
+ bool forceES31AndNoExtensions = false;
+ if (auto* togglesDesc = options.Get<DawnTogglesDescriptor>()) {
+ TogglesState toggles =
+ TogglesState::CreateFromTogglesDescriptor(togglesDesc, ToggleStage::Adapter);
+ if (toggles.IsEnabled(Toggle::GLForceES31AndNoExtensions)) {
+ forceES31AndNoExtensions = true;
+ }
+ }
+
std::vector<Ref<PhysicalDeviceBase>> devices;
// A helper function performing checks on the display we're trying to use, and adding the
@@ -80,7 +89,8 @@
}
Ref<PhysicalDevice> device;
- DAWN_TRY_ASSIGN(device, PhysicalDevice::Create(GetType(), std::move(display)));
+ DAWN_TRY_ASSIGN(device, PhysicalDevice::Create(GetType(), std::move(display),
+ forceES31AndNoExtensions));
devices.push_back(device);
return {};
diff --git a/src/dawn/native/opengl/ContextEGL.cpp b/src/dawn/native/opengl/ContextEGL.cpp
index a7d753e..db9704c 100644
--- a/src/dawn/native/opengl/ContextEGL.cpp
+++ b/src/dawn/native/opengl/ContextEGL.cpp
@@ -39,15 +39,27 @@
#define EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE 0x33AF
#endif
+// https://chromium.googlesource.com/angle/angle/+/main/extensions/EGL_ANGLE_create_context_backwards_compatible.txt
+#ifndef EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE
+#define EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE 0x3483
+#endif
+
+// https://chromium.googlesource.com/angle/angle.git/+/refs/heads/chromium/5996/extensions/EGL_ANGLE_create_context_extensions_enabled.txt
+#ifndef EGL_EXTENSIONS_ENABLED_ANGLE
+#define EGL_EXTENSIONS_ENABLED_ANGLE 0x345F
+#endif
+
namespace dawn::native::opengl {
// static
ResultOrError<std::unique_ptr<ContextEGL>> ContextEGL::Create(Ref<DisplayEGL> display,
wgpu::BackendType backend,
bool useRobustness,
- bool useANGLETextureSharing) {
+ bool useANGLETextureSharing,
+ bool forceES31AndNoExtensionss) {
auto context = std::make_unique<ContextEGL>(std::move(display));
- DAWN_TRY(context->Initialize(backend, useRobustness, useANGLETextureSharing));
+ DAWN_TRY(context->Initialize(backend, useRobustness, useANGLETextureSharing,
+ forceES31AndNoExtensionss));
return std::move(context);
}
@@ -66,7 +78,8 @@
MaybeError ContextEGL::Initialize(wgpu::BackendType backend,
bool useRobustness,
- bool useANGLETextureSharing) {
+ bool useANGLETextureSharing,
+ bool forceES31AndNoExtensionss) {
const EGLFunctions& egl = mDisplay->egl;
// Unless EGL_KHR_no_config is present, we need to choose an EGLConfig on context creation that
@@ -126,6 +139,15 @@
AddAttrib(EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_TRUE);
}
+ if (forceES31AndNoExtensionss) {
+ if (egl.HasExt(EGLExt::ANGLECreateContextBackwardsCompatible)) {
+ AddAttrib(EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE, EGL_FALSE);
+ }
+ if (egl.HasExt(EGLExt::ANGLECreateContextExtensionsEnabled)) {
+ AddAttrib(EGL_EXTENSIONS_ENABLED_ANGLE, EGL_FALSE);
+ }
+ }
+
// The attrib list is finished with an EGL_NONE tag.
attribs.push_back(EGL_NONE);
diff --git a/src/dawn/native/opengl/ContextEGL.h b/src/dawn/native/opengl/ContextEGL.h
index 6cfff8f..77f3b40 100644
--- a/src/dawn/native/opengl/ContextEGL.h
+++ b/src/dawn/native/opengl/ContextEGL.h
@@ -46,14 +46,16 @@
static ResultOrError<std::unique_ptr<ContextEGL>> Create(Ref<DisplayEGL> display,
wgpu::BackendType backend,
bool useRobustness,
- bool useANGLETextureSharing);
+ bool useANGLETextureSharing,
+ bool forceES31AndNoExtensionss);
explicit ContextEGL(Ref<DisplayEGL> display);
~ContextEGL();
MaybeError Initialize(wgpu::BackendType backend,
bool useRobustness,
- bool useANGLETextureSharing);
+ bool useANGLETextureSharing,
+ bool forceES31AndNoExtensionss);
// Make the surface used by all MakeCurrent until the scoper gets out of scope.
class ScopedMakeSurfaceCurrent : NonMovable {
diff --git a/src/dawn/native/opengl/EGLFunctions.cpp b/src/dawn/native/opengl/EGLFunctions.cpp
index 128c9f1..3b9c87f 100644
--- a/src/dawn/native/opengl/EGLFunctions.cpp
+++ b/src/dawn/native/opengl/EGLFunctions.cpp
@@ -90,6 +90,11 @@
{EGLExt::ImageNativeBuffer, "EGL_ANDROID_image_native_buffer", NeverPromoted, ExtType::Display},
{EGLExt::GetNativeClientBuffer, "EGL_ANDROID_get_native_client_buffer", NeverPromoted,
ExtType::Display},
+
+ {EGLExt::ANGLECreateContextBackwardsCompatible, "EGL_ANGLE_create_context_backwards_compatible",
+ NeverPromoted, ExtType::Display},
+ {EGLExt::ANGLECreateContextExtensionsEnabled, "EGL_ANGLE_create_context_extensions_enabled",
+ NeverPromoted, ExtType::Display},
//
}};
diff --git a/src/dawn/native/opengl/EGLFunctions.h b/src/dawn/native/opengl/EGLFunctions.h
index eb1538e..b3b5829 100644
--- a/src/dawn/native/opengl/EGLFunctions.h
+++ b/src/dawn/native/opengl/EGLFunctions.h
@@ -66,6 +66,10 @@
ImageNativeBuffer, // EGL_ANDROID_image_native_buffer
GetNativeClientBuffer, // EGL_ANDROID_get_native_client_buffer
+ // ANGLE specific
+ ANGLECreateContextBackwardsCompatible, // EGL_ANGLE_create_context_backwards_compatible
+ ANGLECreateContextExtensionsEnabled, // EGL_ANGLE_create_context_extensions_enabled
+
EnumCount,
};
diff --git a/src/dawn/native/opengl/PhysicalDeviceGL.cpp b/src/dawn/native/opengl/PhysicalDeviceGL.cpp
index 73b3bbc..dd944fe 100644
--- a/src/dawn/native/opengl/PhysicalDeviceGL.cpp
+++ b/src/dawn/native/opengl/PhysicalDeviceGL.cpp
@@ -89,13 +89,13 @@
return deviceId;
}
-bool IsANGLEDesktopGL(std::string renderer) {
+bool IsANGLEDesktopGL(std::string_view renderer) {
return renderer.find("ANGLE") != std::string::npos &&
renderer.find("OpenGL") != std::string::npos &&
renderer.find("OpenGL ES") == std::string::npos;
}
-bool IsSwiftShader(std::string renderer) {
+bool IsSwiftShader(std::string_view renderer) {
return renderer.find("SwiftShader") != std::string::npos;
}
@@ -103,7 +103,8 @@
// static
ResultOrError<Ref<PhysicalDevice>> PhysicalDevice::Create(wgpu::BackendType backendType,
- Ref<DisplayEGL> display) {
+ Ref<DisplayEGL> display,
+ bool forceES31AndNoExtensions) {
const EGLFunctions& egl = display->egl;
EGLDisplay eglDisplay = display->GetDisplay();
@@ -111,8 +112,10 @@
// that we can query the limits and other properties. Assumes that the limit are the same
// irrespective of the context creation options.
std::unique_ptr<ContextEGL> context;
- DAWN_TRY_ASSIGN(context, ContextEGL::Create(display, backendType, /*useRobustness*/ false,
- /*useANGLETextureSharing*/ false));
+ DAWN_TRY_ASSIGN(context,
+ ContextEGL::Create(display, backendType, /*useRobustness*/ false,
+ /*useANGLETextureSharing*/ false,
+ /*forceES31AndNoExtensions*/ forceES31AndNoExtensions));
EGLSurface prevDrawSurface = egl.GetCurrentSurface(EGL_DRAW);
EGLSurface prevReadSurface = egl.GetCurrentSurface(EGL_READ);
@@ -449,10 +452,11 @@
}
bool useRobustness = !deviceToggles.IsEnabled(Toggle::DisableRobustness);
+ bool forceES31AndNoExtensions = deviceToggles.IsEnabled(Toggle::GLForceES31AndNoExtensions);
std::unique_ptr<ContextEGL> context;
DAWN_TRY_ASSIGN(context, ContextEGL::Create(mDisplay, GetBackendType(), useRobustness,
- useANGLETextureSharing));
+ useANGLETextureSharing, forceES31AndNoExtensions));
return Device::Create(adapter, descriptor, mFunctions, std::move(context), deviceToggles,
std::move(lostEvent));
diff --git a/src/dawn/native/opengl/PhysicalDeviceGL.h b/src/dawn/native/opengl/PhysicalDeviceGL.h
index 84c0f93..8d8d661 100644
--- a/src/dawn/native/opengl/PhysicalDeviceGL.h
+++ b/src/dawn/native/opengl/PhysicalDeviceGL.h
@@ -41,7 +41,8 @@
class PhysicalDevice : public PhysicalDeviceBase {
public:
static ResultOrError<Ref<PhysicalDevice>> Create(wgpu::BackendType backendType,
- Ref<DisplayEGL> display);
+ Ref<DisplayEGL> display,
+ bool forceES31AndNoExtensions);
~PhysicalDevice() override = default;
diff --git a/src/dawn/tests/BUILD.gn b/src/dawn/tests/BUILD.gn
index 1eed546..4a597c4 100644
--- a/src/dawn/tests/BUILD.gn
+++ b/src/dawn/tests/BUILD.gn
@@ -741,6 +741,10 @@
if (dawn_enable_vulkan && is_chromeos) {
sources += [ "end2end/VideoViewsTests_gbm.cpp" ]
}
+
+ if (dawn_enable_opengles) {
+ sources += [ "end2end/GLExplicitExtensionsTests.cpp" ]
+ }
}
source_set("white_box_tests_sources") {
@@ -849,8 +853,10 @@
}
if (dawn_enable_opengles) {
- sources += [ "white_box/EGLImageWrappingTests.cpp" ]
- sources += [ "white_box/GLTextureWrappingTests.cpp" ]
+ sources += [
+ "white_box/EGLImageWrappingTests.cpp",
+ "white_box/GLTextureWrappingTests.cpp",
+ ]
include_dirs = [ "//third_party/khronos" ]
}
}
diff --git a/src/dawn/tests/end2end/GLExplicitExtensionsTests.cpp b/src/dawn/tests/end2end/GLExplicitExtensionsTests.cpp
new file mode 100644
index 0000000..aa05786
--- /dev/null
+++ b/src/dawn/tests/end2end/GLExplicitExtensionsTests.cpp
@@ -0,0 +1,68 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "dawn/tests/DawnTest.h"
+namespace dawn {
+namespace {
+
+class GLExplicitExtensionsTests : public DawnTest {
+ protected:
+ void SetUp() override {
+ DawnTest::SetUp();
+ // Without ANGLE we cannot have a GL context requesting extensions explicitly.
+ DAWN_TEST_UNSUPPORTED_IF(!IsANGLE());
+ }
+};
+
+TEST_P(GLExplicitExtensionsTests, Features) {
+ // Make sure this toggle is inherited correctly during re-initialization
+ EXPECT_EQ(HasToggleEnabled("gl_force_es_31_and_no_extensions"), true);
+
+ // GL_KHR_texture_compression_astc_ldr
+ EXPECT_EQ(device.HasFeature(wgpu::FeatureName::TextureCompressionASTC), false);
+ // GL_AMD_gpu_shader_half_float
+ EXPECT_EQ(device.HasFeature(wgpu::FeatureName::ShaderF16), false);
+ // GL_EXT_float_blend
+ EXPECT_EQ(device.HasFeature(wgpu::FeatureName::Float32Blendable), false);
+}
+
+TEST_P(GLExplicitExtensionsTests, Toggles) {
+ // Make sure this toggle is inherited correctly during re-initialization
+ EXPECT_EQ(HasToggleEnabled("gl_force_es_31_and_no_extensions"), true);
+
+ // GL_OES_texture_stencil8
+ EXPECT_EQ(HasToggleEnabled("use_blit_for_stencil_texture_write"), true);
+ // GL_EXT_read_format_bgra
+ EXPECT_EQ(HasToggleEnabled("use_blit_for_bgra8unorm_texture_to_buffer_copy"), true);
+}
+
+DAWN_INSTANTIATE_TEST(GLExplicitExtensionsTests,
+ // Force GLES 3.1 context with fewest extensions requested.
+ OpenGLESBackend({"gl_force_es_31_and_no_extensions"}));
+
+} // anonymous namespace
+} // namespace dawn