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 <senorblanco@chromium.org>
Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
Stephen White 2021-02-16 22:07:22 +00:00 committed by Commit Bot service account
parent 536c7aea7d
commit a5ba2827f5
3 changed files with 46 additions and 1 deletions

View File

@ -713,6 +713,11 @@ namespace dawn_native { namespace opengl {
copyDataSize, copyDataSize,
reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset))); reinterpret_cast<void*>(static_cast<uintptr_t>(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 { } else {
switch (texture->GetDimension()) { switch (texture->GetDimension()) {

View File

@ -73,7 +73,45 @@ namespace dawn_native { namespace opengl {
gl.BindTexture(target, texture->GetHandle()); gl.BindTexture(target, texture->GetHandle());
const TexelBlockInfo& blockInfo = const TexelBlockInfo& blockInfo =
texture->GetFormat().GetAspectInfo(destination.aspect).block; 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<const uint8_t*>(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<const uint8_t*>(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, 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) {

View File

@ -1232,4 +1232,6 @@ TEST_P(CompressedTextureWriteTextureTest,
DAWN_INSTANTIATE_TEST(CompressedTextureWriteTextureTest, DAWN_INSTANTIATE_TEST(CompressedTextureWriteTextureTest,
D3D12Backend(), D3D12Backend(),
MetalBackend(), MetalBackend(),
OpenGLBackend(),
OpenGLESBackend(),
VulkanBackend()); VulkanBackend());