Open GL ES: implement a fallback path for glClearTexSubImage().

Also enable the CopyTests on OpenGL ES, since they now pass on 3.2.
Enable all tests that are no longer failing due to crbug.com/dawn/581
and update bug references for bugs which are still failing.

Bug: dawn:581, dawn:636
Change-Id: I6b74143f11dd4e1824551720024be174f2eaa003
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/38140
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Stephen White <senorblanco@chromium.org>
diff --git a/src/dawn_native/opengl/TextureGL.cpp b/src/dawn_native/opengl/TextureGL.cpp
index 1d55b16..e1aea41 100644
--- a/src/dawn_native/opengl/TextureGL.cpp
+++ b/src/dawn_native/opengl/TextureGL.cpp
@@ -329,9 +329,17 @@
                                                 mipSize.height, 1, glFormat.format, glFormat.type,
                                                 clearColorData.data());
                         } else {
-                            // TODO(crbug.com/dawn/581): Implement a fallback path on OpenGL ES
-                            // because it doesn't support glClearTexSubImage.
-                            ASSERT(false);
+                            GLuint framebuffer = 0;
+                            gl.GenFramebuffers(1, &framebuffer);
+                            gl.BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
+                            gl.FramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR, GetHandle(),
+                                                       static_cast<int>(level),
+                                                       static_cast<int>(layer));
+                            gl.Disable(GL_SCISSOR_TEST);
+                            gl.ClearBufferiv(GL_COLOR, 0,
+                                             reinterpret_cast<const GLint*>(clearColorData.data()));
+                            gl.Enable(GL_SCISSOR_TEST);
+                            gl.DeleteFramebuffers(1, &framebuffer);
                         }
                     }
                 }
diff --git a/src/tests/end2end/CopyTests.cpp b/src/tests/end2end/CopyTests.cpp
index 15e34c1..37629b5 100644
--- a/src/tests/end2end/CopyTests.cpp
+++ b/src/tests/end2end/CopyTests.cpp
@@ -888,6 +888,7 @@
                       D3D12Backend(),
                       MetalBackend(),
                       OpenGLBackend(),
+                      OpenGLESBackend(),
                       VulkanBackend());
 
 // Test that copying an entire texture with 256-byte aligned dimensions works
@@ -1358,6 +1359,7 @@
                       D3D12Backend(),
                       MetalBackend(),
                       OpenGLBackend(),
+                      OpenGLESBackend(),
                       VulkanBackend());
 
 TEST_P(CopyTests_T2T, Texture) {
@@ -1584,6 +1586,7 @@
                       D3D12Backend(),
                       MetalBackend(),
                       OpenGLBackend(),
+                      OpenGLESBackend(),
                       VulkanBackend());
 
 static constexpr uint64_t kSmallBufferSize = 4;
diff --git a/src/tests/end2end/StorageTextureTests.cpp b/src/tests/end2end/StorageTextureTests.cpp
index ca03cae..b0b0973 100644
--- a/src/tests/end2end/StorageTextureTests.cpp
+++ b/src/tests/end2end/StorageTextureTests.cpp
@@ -807,13 +807,13 @@
 
 // Test that write-only storage textures are supported in compute shader.
 TEST_P(StorageTextureTests, WriteonlyStorageTextureInComputeShader) {
-    // TODO(crbug.com/dawn/581): this test requires glClearTexSubImage(), unsupported on GLES.
-    DAWN_SKIP_TEST_IF(IsOpenGLES());
-
     for (wgpu::TextureFormat format : utils::kAllTextureFormats) {
         if (!utils::TextureFormatSupportsStorageTexture(format)) {
             continue;
         }
+        if (!OpenGLESSupportsStorageTexture(format)) {
+            continue;
+        }
 
         // TODO(jiawei.shao@intel.com): investigate why this test fails with RGBA8Snorm on Linux
         // Intel OpenGL driver.
@@ -837,12 +837,16 @@
 // Test that reading from one read-only storage texture then writing into another write-only storage
 // texture in one dispatch are supported in compute shader.
 TEST_P(StorageTextureTests, ReadWriteDifferentStorageTextureInOneDispatchInComputeShader) {
-    // TODO(crbug.com/dawn/581): this test requires glClearTexSubImage(), unsupported on GLES.
+    // TODO(crbug.com/dawn/636): diagnose and fix this failure on OpenGL ES
     DAWN_SKIP_TEST_IF(IsOpenGLES());
+
     for (wgpu::TextureFormat format : utils::kAllTextureFormats) {
         if (!utils::TextureFormatSupportsStorageTexture(format)) {
             continue;
         }
+        if (IsOpenGLES() && !OpenGLESSupportsStorageTexture(format)) {
+            continue;
+        }
 
         // TODO(jiawei.shao@intel.com): investigate why this test fails with RGBA8Snorm on Linux
         // Intel OpenGL driver.
@@ -871,12 +875,13 @@
 
 // Test that write-only storage textures are supported in fragment shader.
 TEST_P(StorageTextureTests, WriteonlyStorageTextureInFragmentShader) {
-    // TODO(crbug.com/dawn/581): this test requires glClearTexSubImage(), unsupported on GLES.
-    DAWN_SKIP_TEST_IF(IsOpenGLES());
     for (wgpu::TextureFormat format : utils::kAllTextureFormats) {
         if (!utils::TextureFormatSupportsStorageTexture(format)) {
             continue;
         }
+        if (IsOpenGLES() && !OpenGLESSupportsStorageTexture(format)) {
+            continue;
+        }
 
         // TODO(jiawei.shao@intel.com): investigate why this test fails with RGBA8Snorm on Linux
         // Intel OpenGL driver.
@@ -933,8 +938,6 @@
 
 // Verify 2D array write-only storage texture works correctly.
 TEST_P(StorageTextureTests, Writeonly2DArrayStorageTexture) {
-    // TODO(crbug.com/dawn/581): this test requires glClearTexSubImage(), unsupported on GLES.
-    DAWN_SKIP_TEST_IF(IsOpenGLES());
     constexpr uint32_t kArrayLayerCount = 3u;
 
     constexpr wgpu::TextureFormat kTextureFormat = wgpu::TextureFormat::R32Uint;
@@ -955,8 +958,9 @@
 // Test that multiple dispatches to increment values by ping-ponging between a read-only storage
 // texture and a write-only storage texture are synchronized in one pass.
 TEST_P(StorageTextureTests, ReadonlyAndWriteonlyStorageTexturePingPong) {
-    // TODO(crbug.com/dawn/581): this test requires glClearTexSubImage(), unsupported on GLES.
+    // TODO(crbug.com/dawn/636): diagnose and fix this failure on OpenGL ES
     DAWN_SKIP_TEST_IF(IsOpenGLES());
+
     constexpr wgpu::TextureFormat kTextureFormat = wgpu::TextureFormat::R32Uint;
     wgpu::Texture storageTexture1 = CreateTexture(
         kTextureFormat, wgpu::TextureUsage::Storage | wgpu::TextureUsage::CopySrc, 1u, 1u);
@@ -1030,8 +1034,9 @@
 // Test that multiple dispatches to increment values by ping-ponging between a sampled texture and
 // a write-only storage texture are synchronized in one pass.
 TEST_P(StorageTextureTests, SampledAndWriteonlyStorageTexturePingPong) {
-    // TODO(crbug.com/dawn/581): this test requires glClearTexSubImage(), unsupported on GLES.
+    // TODO(crbug.com/dawn/636): diagnose and fix this failure on OpenGL ES
     DAWN_SKIP_TEST_IF(IsOpenGLES());
+
     constexpr wgpu::TextureFormat kTextureFormat = wgpu::TextureFormat::R32Uint;
     wgpu::Texture storageTexture1 = CreateTexture(
         kTextureFormat,