OpenGLES: implement 1D texture workaround.

OpenGLES doesn't support 1D textures, so use 2D textures of width x 1
as a workaround (requires dependent Tint change).

Bug: dawn:1301
Change-Id: I99dbccfae497ee86d6f9b9e1ca1608049971016d
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/114820
Reviewed-by: Austin Eng <enga@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Stephen White <senorblanco@chromium.org>
diff --git a/src/dawn/native/opengl/CommandBufferGL.cpp b/src/dawn/native/opengl/CommandBufferGL.cpp
index f0ea75b..8844615 100644
--- a/src/dawn/native/opengl/CommandBufferGL.cpp
+++ b/src/dawn/native/opengl/CommandBufferGL.cpp
@@ -52,6 +52,10 @@
     UNREACHABLE();
 }
 
+bool Is1DOr2D(wgpu::TextureDimension dimension) {
+    return dimension == wgpu::TextureDimension::e1D || dimension == wgpu::TextureDimension::e2D;
+}
+
 GLenum VertexFormatType(wgpu::VertexFormat format) {
     switch (format) {
         case wgpu::VertexFormat::Uint8x2:
@@ -586,7 +590,6 @@
 
                 buffer->EnsureDataInitializedAsDestination(copy);
 
-                ASSERT(texture->GetDimension() != wgpu::TextureDimension::e1D);
                 SubresourceRange subresources = GetSubresourcesAffectedByCopy(src, copy->copySize);
                 texture->EnsureSubresourceContentInitialized(subresources);
                 // The only way to move data from a texture to a buffer in GL is via
@@ -631,6 +634,7 @@
 
                 uint8_t* offset = reinterpret_cast<uint8_t*>(static_cast<uintptr_t>(dst.offset));
                 switch (texture->GetDimension()) {
+                    case wgpu::TextureDimension::e1D:
                     case wgpu::TextureDimension::e2D: {
                         if (texture->GetArrayLayers() == 1) {
                             gl.FramebufferTexture2D(GL_READ_FRAMEBUFFER, glAttachment, target,
@@ -656,9 +660,6 @@
                         }
                         break;
                     }
-
-                    case wgpu::TextureDimension::e1D:
-                        UNREACHABLE();
                 }
 
                 gl.PixelStorei(GL_PACK_ROW_LENGTH, 0);
@@ -1227,7 +1228,6 @@
                    const TextureDataLayout& dataLayout,
                    const Extent3D& copySize) {
     Texture* texture = ToBackend(destination.texture.Get());
-    ASSERT(texture->GetDimension() != wgpu::TextureDimension::e1D);
 
     const GLFormat& format = texture->GetGLFormat();
     GLenum target = texture->GetGLTarget();
@@ -1263,8 +1263,7 @@
             gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, blockInfo.height);
             gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 1);
 
-            if (texture->GetArrayLayers() == 1 &&
-                texture->GetDimension() == wgpu::TextureDimension::e2D) {
+            if (texture->GetArrayLayers() == 1 && Is1DOr2D(texture->GetDimension())) {
                 gl.CompressedTexSubImage2D(target, destination.mipLevel, x, y, width, height,
                                            format.internalFormat, imageSize, data);
             } else {
@@ -1281,8 +1280,7 @@
             gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, 0);
             gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 0);
         } else {
-            if (texture->GetArrayLayers() == 1 &&
-                texture->GetDimension() == wgpu::TextureDimension::e2D) {
+            if (texture->GetArrayLayers() == 1 && Is1DOr2D(texture->GetDimension())) {
                 const uint8_t* d = static_cast<const uint8_t*>(data);
 
                 for (; y < destination.origin.y + copySize.height; y += blockInfo.height) {
@@ -1315,8 +1313,7 @@
         if (dataLayout.bytesPerRow % blockInfo.byteSize == 0) {
             gl.PixelStorei(GL_UNPACK_ROW_LENGTH,
                            dataLayout.bytesPerRow / blockInfo.byteSize * blockInfo.width);
-            if (texture->GetArrayLayers() == 1 &&
-                texture->GetDimension() == wgpu::TextureDimension::e2D) {
+            if (texture->GetArrayLayers() == 1 && Is1DOr2D(texture->GetDimension())) {
                 gl.TexSubImage2D(target, destination.mipLevel, x, y, width, height, format.format,
                                  format.type, data);
             } else {
@@ -1327,8 +1324,7 @@
             }
             gl.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
         } else {
-            if (texture->GetArrayLayers() == 1 &&
-                texture->GetDimension() == wgpu::TextureDimension::e2D) {
+            if (texture->GetArrayLayers() == 1 && Is1DOr2D(texture->GetDimension())) {
                 const uint8_t* d = static_cast<const uint8_t*>(data);
                 for (; y < destination.origin.y + height; ++y) {
                     gl.TexSubImage2D(target, destination.mipLevel, x, y, width, 1, format.format,
diff --git a/src/dawn/native/opengl/TextureGL.cpp b/src/dawn/native/opengl/TextureGL.cpp
index 6b47342..1b4783d 100644
--- a/src/dawn/native/opengl/TextureGL.cpp
+++ b/src/dawn/native/opengl/TextureGL.cpp
@@ -31,6 +31,7 @@
 
 GLenum TargetForTexture(const TextureDescriptor* descriptor) {
     switch (descriptor->dimension) {
+        case wgpu::TextureDimension::e1D:
         case wgpu::TextureDimension::e2D:
             if (descriptor->size.depthOrArrayLayers > 1) {
                 ASSERT(descriptor->sampleCount == 1);
@@ -45,9 +46,6 @@
         case wgpu::TextureDimension::e3D:
             ASSERT(descriptor->sampleCount == 1);
             return GL_TEXTURE_3D;
-
-        case wgpu::TextureDimension::e1D:
-            break;
     }
     UNREACHABLE();
 }
@@ -56,6 +54,7 @@
                                      uint32_t arrayLayerCount,
                                      uint32_t sampleCount) {
     switch (dimension) {
+        case wgpu::TextureViewDimension::e1D:
         case wgpu::TextureViewDimension::e2D:
             return (sampleCount > 1) ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
         case wgpu::TextureViewDimension::e2DArray:
@@ -76,7 +75,6 @@
         case wgpu::TextureViewDimension::e3D:
             return GL_TEXTURE_3D;
 
-        case wgpu::TextureViewDimension::e1D:
         case wgpu::TextureViewDimension::Undefined:
             break;
     }
@@ -289,6 +287,7 @@
             for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
                  ++level) {
                 switch (GetDimension()) {
+                    case wgpu::TextureDimension::e1D:
                     case wgpu::TextureDimension::e2D:
                         if (GetArrayLayers() == 1) {
                             Aspect aspectsToClear = Aspect::None;
@@ -305,7 +304,6 @@
                             if (aspectsToClear == Aspect::None) {
                                 continue;
                             }
-
                             gl.FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GetGLTarget(),
                                                     GetHandle(), static_cast<GLint>(level));
                             DoClear(aspectsToClear);
@@ -336,7 +334,6 @@
                         }
                         break;
 
-                    case wgpu::TextureDimension::e1D:
                     case wgpu::TextureDimension::e3D:
                         UNREACHABLE();
                 }
@@ -437,7 +434,6 @@
                     if (GetArrayLayers() == 1) {
                         switch (GetDimension()) {
                             case wgpu::TextureDimension::e1D:
-                                UNREACHABLE();
                             case wgpu::TextureDimension::e2D:
                                 gl.FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment,
                                                         GetGLTarget(), GetHandle(), level);
diff --git a/src/dawn/tests/end2end/StorageTextureTests.cpp b/src/dawn/tests/end2end/StorageTextureTests.cpp
index 4e1fb27..bd61cc1 100644
--- a/src/dawn/tests/end2end/StorageTextureTests.cpp
+++ b/src/dawn/tests/end2end/StorageTextureTests.cpp
@@ -765,9 +765,6 @@
 
 // Verify 1D write-only storage textures work correctly.
 TEST_P(StorageTextureTests, Writeonly1DStorageTexture) {
-    // TODO(crbug.com/dawn/547): implement 1D storage texture on OpenGL and OpenGLES.
-    DAWN_TEST_UNSUPPORTED_IF(IsOpenGL() || IsOpenGLES());
-
     constexpr wgpu::TextureFormat kTextureFormat = wgpu::TextureFormat::R32Uint;
 
     // Prepare the write-only storage texture.
diff --git a/src/dawn/tests/end2end/TextureViewTests.cpp b/src/dawn/tests/end2end/TextureViewTests.cpp
index 2955338..e153b0c 100644
--- a/src/dawn/tests/end2end/TextureViewTests.cpp
+++ b/src/dawn/tests/end2end/TextureViewTests.cpp
@@ -1113,4 +1113,9 @@
     EXPECT_PIXEL_RGBA8_EQ(data[3], rp.color, 3, 0);
 }
 
-DAWN_INSTANTIATE_TEST(TextureView1DTest, D3D12Backend(), MetalBackend(), VulkanBackend());
+DAWN_INSTANTIATE_TEST(TextureView1DTest,
+                      D3D12Backend(),
+                      MetalBackend(),
+                      VulkanBackend(),
+                      OpenGLBackend(),
+                      OpenGLESBackend());