GLES: Fix a bug in the impl of CopyBufferToTexture() with compressed formats
In OpenGL ES glPixelStorei() doesn't affect the execution of glCompressedTexSubImage*D(), and GL_UNPACK_COMPRESSED_BLOCK_* is not defined in OpenGL ES, so on the OpenGL ES backends, to implement CopyBufferToTexture() with compressed texture formats, we can only copy the compressed texture data once per compressed block row. With this patch CompressedTextureBCFormatTest/* can pass on Intel Mesa OpenGL ES driver. BUG=dawn:42, dawn:580 TEST=dawn_end2end_tests Change-Id: Ied84a187beaf9105d3664c4e874b3b7ddda4e4b0 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/36020 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
This commit is contained in:
parent
3af532b8a8
commit
3272f9da37
|
@ -546,16 +546,70 @@ namespace dawn_native { namespace opengl {
|
||||||
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, src.rowsPerImage * blockInfo.height);
|
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, src.rowsPerImage * blockInfo.height);
|
||||||
|
|
||||||
if (formatInfo.isCompressed) {
|
if (formatInfo.isCompressed) {
|
||||||
|
ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
|
||||||
|
|
||||||
|
Extent3D copyExtent = ComputeTextureCopyExtent(dst, copySize);
|
||||||
|
|
||||||
|
// In GLES glPixelStorei() doesn't affect CompressedTexSubImage*D() and
|
||||||
|
// GL_UNPACK_COMPRESSED_BLOCK_* isn't defined, so we have to workaround
|
||||||
|
// this limitation by copying the compressed texture data once per row.
|
||||||
|
// See OpenGL ES 3.2 SPEC Chapter 8.4.1, "Pixel Storage Modes and Pixel
|
||||||
|
// Buffer Objects" for more details.
|
||||||
|
if (gl.GetVersion().IsES()) {
|
||||||
|
uint64_t copyDataSizePerBlockRow =
|
||||||
|
(copySize.width / blockInfo.width) * blockInfo.byteSize;
|
||||||
|
size_t copyBlockRowsPerImage = copySize.height / blockInfo.height;
|
||||||
|
|
||||||
|
if (texture->GetArrayLayers() > 1) {
|
||||||
|
// TODO(jiawei.shao@intel.com): do a single copy when the data is
|
||||||
|
// correctly packed.
|
||||||
|
for (size_t copyZ = 0; copyZ < copyExtent.depth; ++copyZ) {
|
||||||
|
uintptr_t offsetPerImage = static_cast<uintptr_t>(
|
||||||
|
src.offset + copyZ * src.bytesPerRow * src.rowsPerImage);
|
||||||
|
uint32_t dstOriginY = dst.origin.y;
|
||||||
|
uint32_t dstOriginZ = dst.origin.z + copyZ;
|
||||||
|
|
||||||
|
for (size_t copyBlockRow = 0;
|
||||||
|
copyBlockRow < copyBlockRowsPerImage; ++copyBlockRow) {
|
||||||
|
gl.CompressedTexSubImage3D(
|
||||||
|
target, dst.mipLevel, dst.origin.x, dstOriginY,
|
||||||
|
dstOriginZ, copyExtent.width, blockInfo.height, 1,
|
||||||
|
format.internalFormat, copyDataSizePerBlockRow,
|
||||||
|
reinterpret_cast<void*>(
|
||||||
|
static_cast<uintptr_t>(offsetPerImage)));
|
||||||
|
|
||||||
|
offsetPerImage += src.bytesPerRow;
|
||||||
|
dstOriginY += blockInfo.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uintptr_t offset = static_cast<uintptr_t>(src.offset);
|
||||||
|
uint32_t dstOriginY = dst.origin.y;
|
||||||
|
|
||||||
|
// TODO(jiawei.shao@intel.com): do a single copy when the data is
|
||||||
|
// correctly packed.
|
||||||
|
for (size_t copyBlockRow = 0; copyBlockRow < copyBlockRowsPerImage;
|
||||||
|
++copyBlockRow) {
|
||||||
|
gl.CompressedTexSubImage2D(
|
||||||
|
target, dst.mipLevel, dst.origin.x, dstOriginY,
|
||||||
|
copyExtent.width, blockInfo.height, format.internalFormat,
|
||||||
|
copyDataSizePerBlockRow,
|
||||||
|
reinterpret_cast<void*>(static_cast<uintptr_t>(offset)));
|
||||||
|
|
||||||
|
offset += src.bytesPerRow;
|
||||||
|
dstOriginY += blockInfo.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, blockInfo.byteSize);
|
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, blockInfo.byteSize);
|
||||||
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, blockInfo.width);
|
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, blockInfo.width);
|
||||||
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);
|
||||||
|
|
||||||
ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
|
|
||||||
uint64_t copyDataSize = (copySize.width / blockInfo.width) *
|
uint64_t copyDataSize = (copySize.width / blockInfo.width) *
|
||||||
(copySize.height / blockInfo.height) *
|
(copySize.height / blockInfo.height) *
|
||||||
blockInfo.byteSize * copySize.depth;
|
blockInfo.byteSize * copySize.depth;
|
||||||
Extent3D copyExtent = ComputeTextureCopyExtent(dst, copySize);
|
|
||||||
|
|
||||||
if (texture->GetArrayLayers() > 1) {
|
if (texture->GetArrayLayers() > 1) {
|
||||||
gl.CompressedTexSubImage3D(
|
gl.CompressedTexSubImage3D(
|
||||||
|
@ -565,10 +619,12 @@ namespace dawn_native { namespace opengl {
|
||||||
reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
|
reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
|
||||||
} else {
|
} else {
|
||||||
gl.CompressedTexSubImage2D(
|
gl.CompressedTexSubImage2D(
|
||||||
target, dst.mipLevel, dst.origin.x, dst.origin.y, copyExtent.width,
|
target, dst.mipLevel, dst.origin.x, dst.origin.y,
|
||||||
copyExtent.height, format.internalFormat, copyDataSize,
|
copyExtent.width, copyExtent.height, format.internalFormat,
|
||||||
|
copyDataSize,
|
||||||
reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
|
reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (texture->GetDimension()) {
|
switch (texture->GetDimension()) {
|
||||||
case wgpu::TextureDimension::e2D:
|
case wgpu::TextureDimension::e2D:
|
||||||
|
|
Loading…
Reference in New Issue