From a5ba2827f5810b7b1cd6ee046e8df6e109bb02b6 Mon Sep 17 00:00:00 2001 From: Stephen White Date: Tue, 16 Feb 2021 22:07:22 +0000 Subject: [PATCH] GL: Implement WriteTexture for compressed textures. Bug: dawn:681 Change-Id: I5d9cd3636a656df1ba9d23964c18011b9cfcf5c0 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/41440 Reviewed-by: Stephen White Commit-Queue: Stephen White --- src/dawn_native/opengl/CommandBufferGL.cpp | 5 +++ src/dawn_native/opengl/QueueGL.cpp | 40 ++++++++++++++++++- .../end2end/CompressedTextureFormatTests.cpp | 2 + 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/dawn_native/opengl/CommandBufferGL.cpp b/src/dawn_native/opengl/CommandBufferGL.cpp index b6d9725639..6de98ecffa 100644 --- a/src/dawn_native/opengl/CommandBufferGL.cpp +++ b/src/dawn_native/opengl/CommandBufferGL.cpp @@ -713,6 +713,11 @@ namespace dawn_native { namespace opengl { copyDataSize, reinterpret_cast(static_cast(src.offset))); } + + gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, 0); + gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, 0); + gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, 0); + gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 0); } } else { switch (texture->GetDimension()) { diff --git a/src/dawn_native/opengl/QueueGL.cpp b/src/dawn_native/opengl/QueueGL.cpp index 5158fbe91e..5340d986a2 100644 --- a/src/dawn_native/opengl/QueueGL.cpp +++ b/src/dawn_native/opengl/QueueGL.cpp @@ -73,7 +73,45 @@ namespace dawn_native { namespace opengl { gl.BindTexture(target, texture->GetHandle()); const TexelBlockInfo& blockInfo = texture->GetFormat().GetAspectInfo(destination.aspect).block; - if (dataLayout.bytesPerRow % blockInfo.byteSize == 0) { + + if (texture->GetFormat().isCompressed) { + size_t imageSize = writeSizePixel.width / blockInfo.width * blockInfo.byteSize; + Extent3D virtSize = texture->GetMipLevelVirtualSize(destination.mipLevel); + uint32_t width = std::min(writeSizePixel.width, virtSize.width - destination.origin.x); + uint32_t x = destination.origin.x; + + // For now, we use row-by-row texture uploads of compressed textures in all cases. + // TODO(crbug.com/dawn/684): For contiguous cases, we should be able to use a single + // texture upload per layer, as we do in the non-compressed case. + if (texture->GetArrayLayers() == 1) { + const uint8_t* d = static_cast(data); + + for (uint32_t y = destination.origin.y; + y < destination.origin.y + writeSizePixel.height; y += blockInfo.height) { + uint32_t height = std::min(blockInfo.height, virtSize.height - y); + gl.CompressedTexSubImage2D(target, destination.mipLevel, x, y, width, height, + format.internalFormat, imageSize, d); + d += dataLayout.bytesPerRow; + } + } else { + const uint8_t* slice = static_cast(data); + + for (uint32_t z = destination.origin.z; + z < destination.origin.z + writeSizePixel.depth; ++z) { + const uint8_t* d = slice; + + for (uint32_t y = destination.origin.y; + y < destination.origin.y + writeSizePixel.height; y += blockInfo.height) { + uint32_t height = std::min(blockInfo.height, virtSize.height - y); + gl.CompressedTexSubImage3D(target, destination.mipLevel, x, y, z, width, + height, 1, format.internalFormat, imageSize, d); + d += dataLayout.bytesPerRow; + } + + slice += dataLayout.rowsPerImage * dataLayout.bytesPerRow; + } + } + } else if (dataLayout.bytesPerRow % blockInfo.byteSize == 0) { gl.PixelStorei(GL_UNPACK_ROW_LENGTH, dataLayout.bytesPerRow / blockInfo.byteSize * blockInfo.width); if (texture->GetArrayLayers() == 1) { diff --git a/src/tests/end2end/CompressedTextureFormatTests.cpp b/src/tests/end2end/CompressedTextureFormatTests.cpp index 3e1ff37867..ec01e89035 100644 --- a/src/tests/end2end/CompressedTextureFormatTests.cpp +++ b/src/tests/end2end/CompressedTextureFormatTests.cpp @@ -1232,4 +1232,6 @@ TEST_P(CompressedTextureWriteTextureTest, DAWN_INSTANTIATE_TEST(CompressedTextureWriteTextureTest, D3D12Backend(), MetalBackend(), + OpenGLBackend(), + OpenGLESBackend(), VulkanBackend());