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>
This commit is contained in:
Stephen White 2023-01-07 18:09:14 +00:00 committed by Dawn LUCI CQ
parent 64e900e456
commit 797cbf4f58
4 changed files with 18 additions and 24 deletions

View File

@ -52,6 +52,10 @@ GLenum IndexFormatType(wgpu::IndexFormat format) {
UNREACHABLE(); UNREACHABLE();
} }
bool Is1DOr2D(wgpu::TextureDimension dimension) {
return dimension == wgpu::TextureDimension::e1D || dimension == wgpu::TextureDimension::e2D;
}
GLenum VertexFormatType(wgpu::VertexFormat format) { GLenum VertexFormatType(wgpu::VertexFormat format) {
switch (format) { switch (format) {
case wgpu::VertexFormat::Uint8x2: case wgpu::VertexFormat::Uint8x2:
@ -586,7 +590,6 @@ MaybeError CommandBuffer::Execute() {
buffer->EnsureDataInitializedAsDestination(copy); buffer->EnsureDataInitializedAsDestination(copy);
ASSERT(texture->GetDimension() != wgpu::TextureDimension::e1D);
SubresourceRange subresources = GetSubresourcesAffectedByCopy(src, copy->copySize); SubresourceRange subresources = GetSubresourcesAffectedByCopy(src, copy->copySize);
texture->EnsureSubresourceContentInitialized(subresources); texture->EnsureSubresourceContentInitialized(subresources);
// The only way to move data from a texture to a buffer in GL is via // The only way to move data from a texture to a buffer in GL is via
@ -631,6 +634,7 @@ MaybeError CommandBuffer::Execute() {
uint8_t* offset = reinterpret_cast<uint8_t*>(static_cast<uintptr_t>(dst.offset)); uint8_t* offset = reinterpret_cast<uint8_t*>(static_cast<uintptr_t>(dst.offset));
switch (texture->GetDimension()) { switch (texture->GetDimension()) {
case wgpu::TextureDimension::e1D:
case wgpu::TextureDimension::e2D: { case wgpu::TextureDimension::e2D: {
if (texture->GetArrayLayers() == 1) { if (texture->GetArrayLayers() == 1) {
gl.FramebufferTexture2D(GL_READ_FRAMEBUFFER, glAttachment, target, gl.FramebufferTexture2D(GL_READ_FRAMEBUFFER, glAttachment, target,
@ -656,9 +660,6 @@ MaybeError CommandBuffer::Execute() {
} }
break; break;
} }
case wgpu::TextureDimension::e1D:
UNREACHABLE();
} }
gl.PixelStorei(GL_PACK_ROW_LENGTH, 0); gl.PixelStorei(GL_PACK_ROW_LENGTH, 0);
@ -1227,7 +1228,6 @@ void DoTexSubImage(const OpenGLFunctions& gl,
const TextureDataLayout& dataLayout, const TextureDataLayout& dataLayout,
const Extent3D& copySize) { const Extent3D& copySize) {
Texture* texture = ToBackend(destination.texture.Get()); Texture* texture = ToBackend(destination.texture.Get());
ASSERT(texture->GetDimension() != wgpu::TextureDimension::e1D);
const GLFormat& format = texture->GetGLFormat(); const GLFormat& format = texture->GetGLFormat();
GLenum target = texture->GetGLTarget(); GLenum target = texture->GetGLTarget();
@ -1263,8 +1263,7 @@ void DoTexSubImage(const OpenGLFunctions& gl,
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, blockInfo.height); gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, blockInfo.height);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 1); gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 1);
if (texture->GetArrayLayers() == 1 && if (texture->GetArrayLayers() == 1 && Is1DOr2D(texture->GetDimension())) {
texture->GetDimension() == wgpu::TextureDimension::e2D) {
gl.CompressedTexSubImage2D(target, destination.mipLevel, x, y, width, height, gl.CompressedTexSubImage2D(target, destination.mipLevel, x, y, width, height,
format.internalFormat, imageSize, data); format.internalFormat, imageSize, data);
} else { } else {
@ -1281,8 +1280,7 @@ void DoTexSubImage(const OpenGLFunctions& gl,
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, 0); gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, 0);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 0); gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 0);
} else { } else {
if (texture->GetArrayLayers() == 1 && if (texture->GetArrayLayers() == 1 && Is1DOr2D(texture->GetDimension())) {
texture->GetDimension() == wgpu::TextureDimension::e2D) {
const uint8_t* d = static_cast<const uint8_t*>(data); const uint8_t* d = static_cast<const uint8_t*>(data);
for (; y < destination.origin.y + copySize.height; y += blockInfo.height) { for (; y < destination.origin.y + copySize.height; y += blockInfo.height) {
@ -1315,8 +1313,7 @@ void DoTexSubImage(const OpenGLFunctions& gl,
if (dataLayout.bytesPerRow % blockInfo.byteSize == 0) { if (dataLayout.bytesPerRow % blockInfo.byteSize == 0) {
gl.PixelStorei(GL_UNPACK_ROW_LENGTH, gl.PixelStorei(GL_UNPACK_ROW_LENGTH,
dataLayout.bytesPerRow / blockInfo.byteSize * blockInfo.width); dataLayout.bytesPerRow / blockInfo.byteSize * blockInfo.width);
if (texture->GetArrayLayers() == 1 && if (texture->GetArrayLayers() == 1 && Is1DOr2D(texture->GetDimension())) {
texture->GetDimension() == wgpu::TextureDimension::e2D) {
gl.TexSubImage2D(target, destination.mipLevel, x, y, width, height, format.format, gl.TexSubImage2D(target, destination.mipLevel, x, y, width, height, format.format,
format.type, data); format.type, data);
} else { } else {
@ -1327,8 +1324,7 @@ void DoTexSubImage(const OpenGLFunctions& gl,
} }
gl.PixelStorei(GL_UNPACK_ROW_LENGTH, 0); gl.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
} else { } else {
if (texture->GetArrayLayers() == 1 && if (texture->GetArrayLayers() == 1 && Is1DOr2D(texture->GetDimension())) {
texture->GetDimension() == wgpu::TextureDimension::e2D) {
const uint8_t* d = static_cast<const uint8_t*>(data); const uint8_t* d = static_cast<const uint8_t*>(data);
for (; y < destination.origin.y + height; ++y) { for (; y < destination.origin.y + height; ++y) {
gl.TexSubImage2D(target, destination.mipLevel, x, y, width, 1, format.format, gl.TexSubImage2D(target, destination.mipLevel, x, y, width, 1, format.format,

View File

@ -31,6 +31,7 @@ namespace {
GLenum TargetForTexture(const TextureDescriptor* descriptor) { GLenum TargetForTexture(const TextureDescriptor* descriptor) {
switch (descriptor->dimension) { switch (descriptor->dimension) {
case wgpu::TextureDimension::e1D:
case wgpu::TextureDimension::e2D: case wgpu::TextureDimension::e2D:
if (descriptor->size.depthOrArrayLayers > 1) { if (descriptor->size.depthOrArrayLayers > 1) {
ASSERT(descriptor->sampleCount == 1); ASSERT(descriptor->sampleCount == 1);
@ -45,9 +46,6 @@ GLenum TargetForTexture(const TextureDescriptor* descriptor) {
case wgpu::TextureDimension::e3D: case wgpu::TextureDimension::e3D:
ASSERT(descriptor->sampleCount == 1); ASSERT(descriptor->sampleCount == 1);
return GL_TEXTURE_3D; return GL_TEXTURE_3D;
case wgpu::TextureDimension::e1D:
break;
} }
UNREACHABLE(); UNREACHABLE();
} }
@ -56,6 +54,7 @@ GLenum TargetForTextureViewDimension(wgpu::TextureViewDimension dimension,
uint32_t arrayLayerCount, uint32_t arrayLayerCount,
uint32_t sampleCount) { uint32_t sampleCount) {
switch (dimension) { switch (dimension) {
case wgpu::TextureViewDimension::e1D:
case wgpu::TextureViewDimension::e2D: case wgpu::TextureViewDimension::e2D:
return (sampleCount > 1) ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D; return (sampleCount > 1) ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
case wgpu::TextureViewDimension::e2DArray: case wgpu::TextureViewDimension::e2DArray:
@ -76,7 +75,6 @@ GLenum TargetForTextureViewDimension(wgpu::TextureViewDimension dimension,
case wgpu::TextureViewDimension::e3D: case wgpu::TextureViewDimension::e3D:
return GL_TEXTURE_3D; return GL_TEXTURE_3D;
case wgpu::TextureViewDimension::e1D:
case wgpu::TextureViewDimension::Undefined: case wgpu::TextureViewDimension::Undefined:
break; break;
} }
@ -289,6 +287,7 @@ MaybeError Texture::ClearTexture(const SubresourceRange& range,
for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount; for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
++level) { ++level) {
switch (GetDimension()) { switch (GetDimension()) {
case wgpu::TextureDimension::e1D:
case wgpu::TextureDimension::e2D: case wgpu::TextureDimension::e2D:
if (GetArrayLayers() == 1) { if (GetArrayLayers() == 1) {
Aspect aspectsToClear = Aspect::None; Aspect aspectsToClear = Aspect::None;
@ -305,7 +304,6 @@ MaybeError Texture::ClearTexture(const SubresourceRange& range,
if (aspectsToClear == Aspect::None) { if (aspectsToClear == Aspect::None) {
continue; continue;
} }
gl.FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GetGLTarget(), gl.FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GetGLTarget(),
GetHandle(), static_cast<GLint>(level)); GetHandle(), static_cast<GLint>(level));
DoClear(aspectsToClear); DoClear(aspectsToClear);
@ -336,7 +334,6 @@ MaybeError Texture::ClearTexture(const SubresourceRange& range,
} }
break; break;
case wgpu::TextureDimension::e1D:
case wgpu::TextureDimension::e3D: case wgpu::TextureDimension::e3D:
UNREACHABLE(); UNREACHABLE();
} }
@ -437,7 +434,6 @@ MaybeError Texture::ClearTexture(const SubresourceRange& range,
if (GetArrayLayers() == 1) { if (GetArrayLayers() == 1) {
switch (GetDimension()) { switch (GetDimension()) {
case wgpu::TextureDimension::e1D: case wgpu::TextureDimension::e1D:
UNREACHABLE();
case wgpu::TextureDimension::e2D: case wgpu::TextureDimension::e2D:
gl.FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, gl.FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment,
GetGLTarget(), GetHandle(), level); GetGLTarget(), GetHandle(), level);

View File

@ -765,9 +765,6 @@ TEST_P(StorageTextureTests, Writeonly2DArrayOr3DStorageTexture) {
// Verify 1D write-only storage textures work correctly. // Verify 1D write-only storage textures work correctly.
TEST_P(StorageTextureTests, Writeonly1DStorageTexture) { 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; constexpr wgpu::TextureFormat kTextureFormat = wgpu::TextureFormat::R32Uint;
// Prepare the write-only storage texture. // Prepare the write-only storage texture.

View File

@ -1113,4 +1113,9 @@ TEST_P(TextureView1DTest, Sampling) {
EXPECT_PIXEL_RGBA8_EQ(data[3], rp.color, 3, 0); 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());