OpenGLES: simulate glTextureView() with texture-to-texture copies.

This is obviously a non-optimal solution, but works in all cases
except compressed textures.

Change-Id: I3fd5fd89ef4978a18917b068632f25f75527c594
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/84160
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Stephen White <senorblanco@google.com>
diff --git a/src/dawn/native/opengl/CommandBufferGL.cpp b/src/dawn/native/opengl/CommandBufferGL.cpp
index 8971979..ba5b8dd 100644
--- a/src/dawn/native/opengl/CommandBufferGL.cpp
+++ b/src/dawn/native/opengl/CommandBufferGL.cpp
@@ -249,6 +249,17 @@
                     const BindingInfo& bindingInfo =
                         group->GetLayout()->GetBindingInfo(bindingIndex);
 
+                    if (bindingInfo.bindingType == BindingInfoType::Texture) {
+                        TextureView* view = ToBackend(group->GetBindingAsTextureView(bindingIndex));
+                        view->CopyIfNeeded();
+                    }
+                }
+
+                for (BindingIndex bindingIndex{0};
+                     bindingIndex < group->GetLayout()->GetBindingCount(); ++bindingIndex) {
+                    const BindingInfo& bindingInfo =
+                        group->GetLayout()->GetBindingInfo(bindingIndex);
+
                     switch (bindingInfo.bindingType) {
                         case BindingInfoType::Buffer: {
                             BufferBinding binding = group->GetBindingAsBufferBinding(bindingIndex);
@@ -361,6 +372,7 @@
                             gl.BindImageTexture(imageIndex, handle, view->GetBaseMipLevel(),
                                                 isLayered, view->GetBaseArrayLayer(), access,
                                                 texture->GetGLFormat().internalFormat);
+                            texture->Touch();
                             break;
                         }
 
@@ -402,6 +414,7 @@
                     gl.BlitFramebuffer(0, 0, renderPass->width, renderPass->height, 0, 0,
                                        renderPass->width, renderPass->height, GL_COLOR_BUFFER_BIT,
                                        GL_NEAREST);
+                    ToBackend(resolveView->GetTexture())->Touch();
                 }
             }
 
@@ -552,6 +565,7 @@
                     DoTexSubImage(gl, dst, reinterpret_cast<void*>(src.offset), dataLayout,
                                   copy->copySize);
                     gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+                    ToBackend(dst.texture)->Touch();
                     break;
                 }
 
@@ -698,6 +712,7 @@
                                      srcTexture->GetGLTarget(), src.mipLevel, src.origin,
                                      dstTexture->GetHandle(), dstTexture->GetGLTarget(),
                                      dst.mipLevel, dst.origin, copySize);
+                    ToBackend(dst.texture)->Touch();
                     break;
                 }
 
@@ -1134,6 +1149,17 @@
                 case Command::EndRenderPass: {
                     mCommands.NextCommand<EndRenderPassCmd>();
 
+                    for (ColorAttachmentIndex i :
+                         IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) {
+                        TextureView* textureView =
+                            ToBackend(renderPass->colorAttachments[i].view.Get());
+                        ToBackend(textureView->GetTexture())->Touch();
+                    }
+                    if (renderPass->attachmentState->HasDepthStencilAttachment()) {
+                        TextureView* textureView =
+                            ToBackend(renderPass->depthStencilAttachment.view.Get());
+                        ToBackend(textureView->GetTexture())->Touch();
+                    }
                     if (renderPass->attachmentState->GetSampleCount() > 1) {
                         ResolveMultisampledRenderTargets(gl, renderPass);
                     }
diff --git a/src/dawn/native/opengl/QueueGL.cpp b/src/dawn/native/opengl/QueueGL.cpp
index 541d93b..6456dfa 100644
--- a/src/dawn/native/opengl/QueueGL.cpp
+++ b/src/dawn/native/opengl/QueueGL.cpp
@@ -74,6 +74,7 @@
             ToBackend(destination.texture)->EnsureSubresourceContentInitialized(range);
         }
         DoTexSubImage(ToBackend(GetDevice())->gl, textureCopy, data, dataLayout, writeSizePixel);
+        ToBackend(destination.texture)->Touch();
         return {};
     }
 
diff --git a/src/dawn/native/opengl/TextureGL.cpp b/src/dawn/native/opengl/TextureGL.cpp
index 0f5bf7b..cbbe1db 100644
--- a/src/dawn/native/opengl/TextureGL.cpp
+++ b/src/dawn/native/opengl/TextureGL.cpp
@@ -199,6 +199,14 @@
         }
     }
 
+    void Texture::Touch() {
+        mGenID++;
+    }
+
+    uint32_t Texture::GetGenID() const {
+        return mGenID;
+    }
+
     Texture::Texture(Device* device,
                      const TextureDescriptor* descriptor,
                      GLuint handle,
@@ -538,6 +546,7 @@
             SetIsSubresourceContentInitialized(true, range);
             device->IncrementLazyClearCountForTesting();
         }
+        Touch();
         return {};
     }
 
@@ -565,23 +574,19 @@
         if (!RequiresCreatingNewTextureView(texture, descriptor)) {
             mHandle = ToBackend(texture)->GetHandle();
         } else {
-            // glTextureView() is supported on OpenGL version >= 4.3
-            // TODO(crbug.com/dawn/593): support texture view on OpenGL version <= 4.2 and ES
             const OpenGLFunctions& gl = ToBackend(GetDevice())->gl;
-            mHandle = GenTexture(gl);
-            const Texture* textureGL = ToBackend(texture);
-
-            const Format& textureFormat = GetTexture()->GetFormat();
-            // Depth/stencil don't support reinterpretation, and the aspect is specified at
-            // bind time. In that case, we use the base texture format.
-            const GLFormat& glFormat = textureFormat.HasDepthOrStencil()
-                                           ? ToBackend(GetDevice())->GetGLFormat(textureFormat)
-                                           : ToBackend(GetDevice())->GetGLFormat(GetFormat());
-
-            gl.TextureView(mHandle, mTarget, textureGL->GetHandle(), glFormat.internalFormat,
-                           descriptor->baseMipLevel, descriptor->mipLevelCount,
-                           descriptor->baseArrayLayer, descriptor->arrayLayerCount);
-            mOwnsHandle = true;
+            if (gl.IsAtLeastGL(4, 3)) {
+                mHandle = GenTexture(gl);
+                const Texture* textureGL = ToBackend(texture);
+                gl.TextureView(mHandle, mTarget, textureGL->GetHandle(), GetInternalFormat(),
+                               descriptor->baseMipLevel, descriptor->mipLevelCount,
+                               descriptor->baseArrayLayer, descriptor->arrayLayerCount);
+                mOwnsHandle = true;
+            } else {
+                // Simulate glTextureView() with texture-to-texture copies.
+                mUseCopy = true;
+                mHandle = 0;
+            }
         }
     }
 
@@ -632,4 +637,50 @@
         }
     }
 
+    void TextureView::CopyIfNeeded() {
+        if (!mUseCopy) {
+            return;
+        }
+
+        const Texture* texture = ToBackend(GetTexture());
+        if (mGenID == texture->GetGenID()) {
+            return;
+        }
+
+        Device* device = ToBackend(GetDevice());
+        const OpenGLFunctions& gl = device->gl;
+        uint32_t srcLevel = GetBaseMipLevel();
+        uint32_t numLevels = GetLevelCount();
+
+        uint32_t width = texture->GetWidth() >> srcLevel;
+        uint32_t height = texture->GetHeight() >> srcLevel;
+        Extent3D size{width, height, GetLayerCount()};
+
+        if (mHandle == 0) {
+            mHandle = GenTexture(gl);
+            gl.BindTexture(mTarget, mHandle);
+            AllocateTexture(gl, mTarget, texture->GetSampleCount(), numLevels, GetInternalFormat(),
+                            size);
+            mOwnsHandle = true;
+        }
+
+        Origin3D src{0, 0, GetBaseArrayLayer()};
+        Origin3D dst{0, 0, 0};
+        for (GLuint level = 0; level < numLevels; ++level) {
+            CopyImageSubData(gl, GetAspects(), texture->GetHandle(), texture->GetGLTarget(),
+                             srcLevel + level, src, mHandle, mTarget, level, dst, size);
+        }
+
+        mGenID = texture->GetGenID();
+    }
+
+    GLenum TextureView::GetInternalFormat() const {
+        // Depth/stencil don't support reinterpretation, and the aspect is specified at
+        // bind time. In that case, we use the base texture format.
+        const Format& format =
+            GetFormat().HasDepthOrStencil() ? GetTexture()->GetFormat() : GetFormat();
+        const GLFormat& glFormat = ToBackend(GetDevice())->GetGLFormat(format);
+        return glFormat.internalFormat;
+    }
+
 }  // namespace dawn::native::opengl
diff --git a/src/dawn/native/opengl/TextureGL.h b/src/dawn/native/opengl/TextureGL.h
index 2b0b4b1..cf77972 100644
--- a/src/dawn/native/opengl/TextureGL.h
+++ b/src/dawn/native/opengl/TextureGL.h
@@ -35,6 +35,8 @@
         GLuint GetHandle() const;
         GLenum GetGLTarget() const;
         const GLFormat& GetGLFormat() const;
+        uint32_t GetGenID() const;
+        void Touch();
 
         void EnsureSubresourceContentInitialized(const SubresourceRange& range);
 
@@ -46,6 +48,7 @@
 
         GLuint mHandle;
         GLenum mTarget;
+        uint32_t mGenID = 0;
     };
 
     class TextureView final : public TextureViewBase {
@@ -55,15 +58,19 @@
         GLuint GetHandle() const;
         GLenum GetGLTarget() const;
         void BindToFramebuffer(GLenum target, GLenum attachment);
+        void CopyIfNeeded();
 
       private:
         ~TextureView() override;
         void DestroyImpl() override;
+        GLenum GetInternalFormat() const;
 
         // TODO(crbug.com/dawn/1355): Delete this handle on texture destroy.
         GLuint mHandle;
         GLenum mTarget;
         bool mOwnsHandle;
+        bool mUseCopy = false;
+        uint32_t mGenID = 0;
     };
 
 }  // namespace dawn::native::opengl
diff --git a/src/dawn/tests/end2end/BufferZeroInitTests.cpp b/src/dawn/tests/end2end/BufferZeroInitTests.cpp
index 515e187..5788ddd 100644
--- a/src/dawn/tests/end2end/BufferZeroInitTests.cpp
+++ b/src/dawn/tests/end2end/BufferZeroInitTests.cpp
@@ -960,9 +960,6 @@
 // Test that the code path of CopyTextureToBuffer clears the destination buffer correctly when it is
 // the first use of the buffer and the texture is a 2D array texture.
 TEST_P(BufferZeroInitTest, Copy2DArrayTextureToBuffer) {
-    // TODO(crbug.com/dawn/593): This test uses glTextureView() which is not supported on OpenGL ES.
-    DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
-
     constexpr wgpu::Extent3D kTextureSize = {64u, 4u, 3u};
 
     // bytesPerRow == texelBlockSizeInBytes * copySize.width && rowsPerImage == copySize.height &&
diff --git a/src/dawn/tests/end2end/CompressedTextureFormatTests.cpp b/src/dawn/tests/end2end/CompressedTextureFormatTests.cpp
index a8a9983..5bc75ab 100644
--- a/src/dawn/tests/end2end/CompressedTextureFormatTests.cpp
+++ b/src/dawn/tests/end2end/CompressedTextureFormatTests.cpp
@@ -694,7 +694,7 @@
 
     DAWN_TEST_UNSUPPORTED_IF(!IsFormatSupported());
 
-    // This test uses glTextureView() which is not supported in OpenGL ES.
+    // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures.
     DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
 
     constexpr uint32_t kArrayLayerCount = 3;
@@ -714,7 +714,7 @@
 
     DAWN_TEST_UNSUPPORTED_IF(!IsFormatSupported());
 
-    // This test uses glTextureView() which is not supported in OpenGL ES.
+    // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures.
     DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
 
     CopyConfig config = GetDefaultFullConfig();
@@ -732,7 +732,7 @@
 
     DAWN_TEST_UNSUPPORTED_IF(!IsFormatSupported());
 
-    // This test uses glTextureView() which is not supported in OpenGL ES.
+    // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures.
     DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
 
     // TODO(crbug.com/dawn/816): This consistently fails on with the 12th pixel being opaque
@@ -1083,7 +1083,7 @@
 
     DAWN_TEST_UNSUPPORTED_IF(!IsFormatSupported());
 
-    // This test uses glTextureView() which is not supported in OpenGL ES.
+    // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures.
     DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
 
     CopyConfig config = GetDefaultFullConfig();
@@ -1105,7 +1105,7 @@
 
     DAWN_TEST_UNSUPPORTED_IF(!IsFormatSupported());
 
-    // This test uses glTextureView() which is not supported in OpenGL ES.
+    // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures.
     DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
 
     constexpr uint32_t kArrayLayerCount = 3;
@@ -1125,7 +1125,7 @@
 
     DAWN_TEST_UNSUPPORTED_IF(!IsFormatSupported());
 
-    // This test uses glTextureView() which is not supported in OpenGL ES.
+    // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures.
     DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
 
     constexpr uint32_t kArrayLayerCount = 3;
@@ -1276,7 +1276,7 @@
     // TODO(crbug.com/dawn/976): Failing on Linux Intel OpenGL drivers.
     DAWN_SUPPRESS_TEST_IF(IsIntel() && IsOpenGL() && IsLinux());
 
-    // TODO(crbug.com/dawn/593): This test uses glTextureView() which is not supported on OpenGLES.
+    // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures.
     DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
 
     // TODO(b/198674734): Width multiplier set to 7 because 5 results in square size for ASTC6x5.
@@ -1309,7 +1309,7 @@
     // TODO(crbug.com/dawn/976): Failing on Linux Intel OpenGL drivers.
     DAWN_SUPPRESS_TEST_IF(IsIntel() && IsOpenGL() && IsLinux());
 
-    // TODO(crbug.com/dawn/593): This test uses glTextureView() which is not supported on OpenGLES.
+    // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures.
     DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
 
     CopyConfig config = GetDefaultFullConfig();
diff --git a/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp b/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp
index 3047aeb..6bd1582 100644
--- a/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp
+++ b/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp
@@ -604,8 +604,8 @@
 // Test that sampling a depth/stencil texture at components 1, 2, and 3 yield 0, 0, and 1
 // respectively
 TEST_P(DepthStencilSamplingTest, SampleExtraComponents) {
-    // TODO(crbug.com/dawn/593): This test requires glTextureView, which is unsupported on GLES.
-    DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
+    // This test fails on SwANGLE (although it passes on other ANGLE backends).
+    DAWN_TEST_UNSUPPORTED_IF(IsANGLE());
 
     wgpu::TextureFormat format = GetParam().mTextureFormat;
 
@@ -622,9 +622,6 @@
 
 // Test sampling both depth and stencil with a render/compute pipeline works.
 TEST_P(DepthStencilSamplingTest, SampleDepthAndStencilRender) {
-    // TODO(crbug.com/dawn/593): This test requires glTextureView, which is unsupported on GLES.
-    DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
-
     wgpu::TextureFormat format = GetParam().mTextureFormat;
 
     wgpu::SamplerDescriptor samplerDesc;
@@ -787,8 +784,8 @@
 
 // Test that sampling a stencil texture with a render/compute pipeline works
 TEST_P(StencilSamplingTest, SampleStencilOnly) {
-    // TODO(crbug.com/dawn/593): This test requires glTextureView, which is unsupported on GLES.
-    DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
+    // This test fails on SwANGLE (although it passes on other ANGLE backends).
+    DAWN_TEST_UNSUPPORTED_IF(IsANGLE());
 
     wgpu::TextureFormat format = GetParam().mTextureFormat;
 
diff --git a/src/dawn/tests/end2end/NonzeroTextureCreationTests.cpp b/src/dawn/tests/end2end/NonzeroTextureCreationTests.cpp
index 5327406..c3fcc96a 100644
--- a/src/dawn/tests/end2end/NonzeroTextureCreationTests.cpp
+++ b/src/dawn/tests/end2end/NonzeroTextureCreationTests.cpp
@@ -111,12 +111,6 @@
             DAWN_SUPPRESS_TEST_IF(GetParam().mFormat == wgpu::TextureFormat::Depth24PlusStencil8 &&
                                   GetParam().mAspect == wgpu::TextureAspect::StencilOnly &&
                                   HasToggleEnabled("disable_depth_stencil_read"));
-
-            // TODO(crbug.com/dawn/593): Test depends on glTextureView which is unsupported on GLES.
-            DAWN_SUPPRESS_TEST_IF(GetParam().mFormat == wgpu::TextureFormat::Depth24PlusStencil8 &&
-                                  GetParam().mAspect == wgpu::TextureAspect::DepthOnly &&
-                                  IsOpenGLES());
-
             // GL may support the feature, but reading data back is not implemented.
             DAWN_TEST_UNSUPPORTED_IF(GetParam().mFormat == wgpu::TextureFormat::BC1RGBAUnorm &&
                                      (IsOpenGL() || IsOpenGLES()));
diff --git a/src/dawn/tests/end2end/TextureSubresourceTests.cpp b/src/dawn/tests/end2end/TextureSubresourceTests.cpp
index fac0885..caa94c7 100644
--- a/src/dawn/tests/end2end/TextureSubresourceTests.cpp
+++ b/src/dawn/tests/end2end/TextureSubresourceTests.cpp
@@ -138,9 +138,6 @@
 
 // Test different mipmap levels
 TEST_P(TextureSubresourceTest, MipmapLevelsTest) {
-    // TODO(crbug.com/dawn/593): This test requires glTextureView, which is unsupported on GLES.
-    DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
-
     // Create a texture with 2 mipmap levels and 1 layer
     wgpu::Texture texture =
         CreateTexture(2, 1,
@@ -167,8 +164,6 @@
 
 // Test different array layers
 TEST_P(TextureSubresourceTest, ArrayLayersTest) {
-    // TODO(crbug.com/dawn/593): This test requires glTextureView, which is unsupported on GLES.
-    DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
     // Create a texture with 1 mipmap level and 2 layers
     wgpu::Texture texture =
         CreateTexture(1, 2,
diff --git a/src/dawn/tests/end2end/TextureViewTests.cpp b/src/dawn/tests/end2end/TextureViewTests.cpp
index d3746f4..2b85f54 100644
--- a/src/dawn/tests/end2end/TextureViewTests.cpp
+++ b/src/dawn/tests/end2end/TextureViewTests.cpp
@@ -203,8 +203,6 @@
                            uint32_t textureMipLevels,
                            uint32_t textureViewBaseLayer,
                            uint32_t textureViewBaseMipLevel) {
-        // TODO(crbug.com/dawn/593): This test requires glTextureView, which is unsupported on GLES.
-        DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
         ASSERT(textureViewBaseLayer < textureArrayLayers);
         ASSERT(textureViewBaseMipLevel < textureMipLevels);
 
@@ -236,8 +234,6 @@
                                 uint32_t textureMipLevels,
                                 uint32_t textureViewBaseLayer,
                                 uint32_t textureViewBaseMipLevel) {
-        // TODO(crbug.com/dawn/593): This test requires glTextureView, which is unsupported on GLES.
-        DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
         ASSERT(textureViewBaseLayer < textureArrayLayers);
         ASSERT(textureViewBaseMipLevel < textureMipLevels);
 
@@ -316,9 +312,9 @@
                             uint32_t textureViewBaseLayer,
                             uint32_t textureViewLayerCount,
                             bool isCubeMapArray) {
-        // TODO(crbug.com/dawn/600): In OpenGL ES, cube map textures cannot be treated as arrays
-        // of 2D textures. Find a workaround.
-        DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
+        // TODO(crbug.com/dawn/1300): OpenGLES does not support cube map arrays.
+        DAWN_TEST_UNSUPPORTED_IF(isCubeMapArray && IsOpenGLES());
+
         constexpr uint32_t kMipLevels = 1u;
         InitTexture(textureArrayLayers, kMipLevels);
 
@@ -396,8 +392,6 @@
 // Test sampling from a 2D array texture view created on a 2D texture with one layer.
 // Regression test for crbug.com/dawn/1309.
 TEST_P(TextureViewSamplingTest, Texture2DArrayViewOnSingleLayer2DTexture) {
-    // TODO(crbug.com/dawn/593): This test requires glTextureView, which is unsupported on GLES.
-    DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
     InitTexture(1 /* array layer count */, 1 /* mip level count */);
 
     wgpu::TextureViewDescriptor descriptor = mDefaultTextureViewDescriptor;
diff --git a/src/dawn/tests/end2end/TextureZeroInitTests.cpp b/src/dawn/tests/end2end/TextureZeroInitTests.cpp
index ed473cd..a7f5849 100644
--- a/src/dawn/tests/end2end/TextureZeroInitTests.cpp
+++ b/src/dawn/tests/end2end/TextureZeroInitTests.cpp
@@ -899,9 +899,6 @@
 // sampled and attachment (with LoadOp::Clear so the lazy clear can be skipped) then the sampled
 // subresource is correctly cleared.
 TEST_P(TextureZeroInitTest, TextureBothSampledAndAttachmentClear) {
-    // TODO(crbug.com/dawn/593): This test uses glTextureView() which is not supported on OpenGL ES.
-    DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
-
     // Create a 2D array texture, layer 0 will be used as attachment, layer 1 as sampled.
     wgpu::TextureDescriptor texDesc;
     texDesc.usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::RenderAttachment |
@@ -1342,9 +1339,6 @@
 // Test that if one layer of a texture is initialized and another is uninitialized, lazy clearing
 // the uninitialized layer does not clear the initialized layer.
 TEST_P(TextureZeroInitTest, PreservesInitializedArrayLayer) {
-    // TODO(crbug.com/dawn/593): This test uses glTextureView() which is not supported on OpenGL ES.
-    DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
-
     wgpu::TextureDescriptor sampleTextureDescriptor =
         CreateTextureDescriptor(1, 2,
                                 wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst |
@@ -1875,7 +1869,7 @@
 // Test that 0 lazy clear count happens when we copy buffer to texture to a nonzero mip level
 // (with physical size different from the virtual mip size)
 TEST_P(CompressedTextureZeroInitTest, FullCopyToNonZeroMipLevel) {
-    // TODO(crbug.com/dawn/593): This test uses glTextureView() which is not supported on OpenGL ES.
+    // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures.
     DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
 
     wgpu::TextureDescriptor textureDescriptor;
@@ -1924,7 +1918,7 @@
 
 // Test that 0 lazy clear count happens when we copy buffer to nonzero array layer
 TEST_P(CompressedTextureZeroInitTest, FullCopyToNonZeroArrayLayer) {
-    // TODO(crbug.com/dawn/593): This test uses glTextureView() which is not supported on OpenGL ES.
+    // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures.
     DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
 
     wgpu::TextureDescriptor textureDescriptor;
@@ -1964,7 +1958,7 @@
 
 // full copy texture to texture, 0 lazy clears are needed
 TEST_P(CompressedTextureZeroInitTest, FullCopyTextureToTextureMipLevel) {
-    // TODO(crbug.com/dawn/593): This test uses glTextureView() which is not supported on OpenGL ES.
+    // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures.
     DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
 
     // create srcTexture and fill it with data