OpenGL: DoTexSubImage() cleanup.

Use the same pattern for all conditionals: single-call, then row-by-row,
2D case, then 3D.

Bug: dawn:684

Change-Id: I410183815299e9ec2d90790809a056dd578771e3
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/47320
Commit-Queue: Stephen White <senorblanco@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Stephen White 2021-04-13 14:14:54 +00:00 committed by Commit Bot service account
parent 71c33c807f
commit f3fe648675

View File

@ -1283,10 +1283,13 @@ namespace dawn_native { namespace opengl {
const TexelBlockInfo& blockInfo = const TexelBlockInfo& blockInfo =
texture->GetFormat().GetAspectInfo(destination.aspect).block; texture->GetFormat().GetAspectInfo(destination.aspect).block;
uint32_t x = destination.origin.x;
uint32_t y = destination.origin.y;
uint32_t z = destination.origin.z;
if (texture->GetFormat().isCompressed) { if (texture->GetFormat().isCompressed) {
size_t rowSize = copySize.width / blockInfo.width * blockInfo.byteSize; size_t rowSize = copySize.width / blockInfo.width * blockInfo.byteSize;
Extent3D virtSize = texture->GetMipLevelVirtualSize(destination.mipLevel); Extent3D virtSize = texture->GetMipLevelVirtualSize(destination.mipLevel);
uint32_t width = std::min(copySize.width, virtSize.width - destination.origin.x); uint32_t width = std::min(copySize.width, virtSize.width - x);
// In GLES glPixelStorei() doesn't affect CompressedTexSubImage*D() and // In GLES glPixelStorei() doesn't affect CompressedTexSubImage*D() and
// GL_UNPACK_COMPRESSED_BLOCK_* isn't defined, so we have to workaround // GL_UNPACK_COMPRESSED_BLOCK_* isn't defined, so we have to workaround
@ -1294,13 +1297,41 @@ namespace dawn_native { namespace opengl {
// See OpenGL ES 3.2 SPEC Chapter 8.4.1, "Pixel Storage Modes and Pixel // See OpenGL ES 3.2 SPEC Chapter 8.4.1, "Pixel Storage Modes and Pixel
// Buffer Objects" for more details. For Desktop GL, we use row-by-row // Buffer Objects" for more details. For Desktop GL, we use row-by-row
// copies only for uploads where bytesPerRow is not a multiple of byteSize. // copies only for uploads where bytesPerRow is not a multiple of byteSize.
if (gl.GetVersion().IsES() || dataLayout.bytesPerRow % blockInfo.byteSize != 0) { if (dataLayout.bytesPerRow % blockInfo.byteSize == 0 && gl.GetVersion().IsDesktop()) {
uint32_t x = destination.origin.x; size_t imageSize =
rowSize * (copySize.height / blockInfo.height) * copySize.depthOrArrayLayers;
uint32_t height = std::min(copySize.height, virtSize.height - y);
gl.PixelStorei(GL_UNPACK_ROW_LENGTH,
dataLayout.bytesPerRow / blockInfo.byteSize * blockInfo.width);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, blockInfo.byteSize);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, blockInfo.width);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, blockInfo.height);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 1);
if (texture->GetArrayLayers() == 1) {
gl.CompressedTexSubImage2D(target, destination.mipLevel, x, y, width, height,
format.internalFormat, imageSize, data);
} else {
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT,
dataLayout.rowsPerImage * blockInfo.height);
gl.CompressedTexSubImage3D(target, destination.mipLevel, x, y, z, width, height,
copySize.depthOrArrayLayers, format.internalFormat,
imageSize, data);
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
}
gl.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
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 {
if (texture->GetArrayLayers() == 1) { if (texture->GetArrayLayers() == 1) {
const uint8_t* d = static_cast<const uint8_t*>(data); const uint8_t* d = static_cast<const uint8_t*>(data);
for (uint32_t y = destination.origin.y; for (; y < destination.origin.y + copySize.height; y += blockInfo.height) {
y < destination.origin.y + copySize.height; y += blockInfo.height) {
uint32_t height = std::min(blockInfo.height, virtSize.height - y); uint32_t height = std::min(blockInfo.height, virtSize.height - y);
gl.CompressedTexSubImage2D(target, destination.mipLevel, x, y, width, gl.CompressedTexSubImage2D(target, destination.mipLevel, x, y, width,
height, format.internalFormat, rowSize, d); height, format.internalFormat, rowSize, d);
@ -1309,12 +1340,11 @@ namespace dawn_native { namespace opengl {
} else { } else {
const uint8_t* slice = static_cast<const uint8_t*>(data); const uint8_t* slice = static_cast<const uint8_t*>(data);
for (uint32_t z = destination.origin.z; for (; z < destination.origin.z + copySize.depthOrArrayLayers; ++z) {
z < destination.origin.z + copySize.depthOrArrayLayers; ++z) {
const uint8_t* d = slice; const uint8_t* d = slice;
for (uint32_t y = destination.origin.y; for (y = destination.origin.y; y < destination.origin.y + copySize.height;
y < destination.origin.y + copySize.height; y += blockInfo.height) { y += blockInfo.height) {
uint32_t height = std::min(blockInfo.height, virtSize.height - y); uint32_t height = std::min(blockInfo.height, virtSize.height - y);
gl.CompressedTexSubImage3D(target, destination.mipLevel, x, y, z, width, gl.CompressedTexSubImage3D(target, destination.mipLevel, x, y, z, width,
height, 1, format.internalFormat, rowSize, height, 1, format.internalFormat, rowSize,
@ -1325,72 +1355,39 @@ namespace dawn_native { namespace opengl {
slice += dataLayout.rowsPerImage * dataLayout.bytesPerRow; slice += dataLayout.rowsPerImage * dataLayout.bytesPerRow;
} }
} }
} else {
size_t imageSize =
rowSize * (copySize.height / blockInfo.height) * copySize.depthOrArrayLayers;
uint32_t height = std::min(copySize.height, virtSize.height - destination.origin.y);
gl.PixelStorei(GL_UNPACK_ROW_LENGTH,
dataLayout.bytesPerRow / blockInfo.byteSize * blockInfo.width);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, blockInfo.byteSize);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, blockInfo.width);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, blockInfo.height);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 1);
if (texture->GetArrayLayers() > 1) {
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT,
dataLayout.rowsPerImage * blockInfo.height);
gl.CompressedTexSubImage3D(target, destination.mipLevel, destination.origin.x,
destination.origin.y, destination.origin.z, width,
height, copySize.depthOrArrayLayers,
format.internalFormat, imageSize, data);
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
} else {
gl.CompressedTexSubImage2D(target, destination.mipLevel, destination.origin.x,
destination.origin.y, width, height,
format.internalFormat, imageSize, data);
} }
} else {
gl.PixelStorei(GL_UNPACK_ROW_LENGTH, 0); uint32_t width = copySize.width;
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_SIZE, 0); uint32_t height = copySize.height;
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_WIDTH, 0); if (dataLayout.bytesPerRow % blockInfo.byteSize == 0) {
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, 0);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 0);
}
} 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) {
gl.TexSubImage2D(target, destination.mipLevel, destination.origin.x, gl.TexSubImage2D(target, destination.mipLevel, x, y, width, height,
destination.origin.y, copySize.width, copySize.height,
format.format, format.type, data); format.format, format.type, data);
} else { } else {
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, dataLayout.rowsPerImage * blockInfo.height); gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT,
gl.TexSubImage3D(target, destination.mipLevel, destination.origin.x, dataLayout.rowsPerImage * blockInfo.height);
destination.origin.y, destination.origin.z, copySize.width, gl.TexSubImage3D(target, destination.mipLevel, x, y, z, width, height,
copySize.height, copySize.depthOrArrayLayers, format.format, copySize.depthOrArrayLayers, format.format, format.type, data);
format.type, data);
gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); gl.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
} }
gl.PixelStorei(GL_UNPACK_ROW_LENGTH, 0); gl.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
} else { } else {
if (texture->GetArrayLayers() == 1) { if (texture->GetArrayLayers() == 1) {
const uint8_t* d = static_cast<const uint8_t*>(data); const uint8_t* d = static_cast<const uint8_t*>(data);
for (uint32_t y = 0; y < copySize.height; ++y) { for (; y < destination.origin.y + height; ++y) {
gl.TexSubImage2D(target, destination.mipLevel, destination.origin.x, gl.TexSubImage2D(target, destination.mipLevel, x, y, width, 1,
destination.origin.y + y, copySize.width, 1, format.format, format.format, format.type, d);
format.type, d);
d += dataLayout.bytesPerRow; d += dataLayout.bytesPerRow;
} }
} else { } else {
const uint8_t* slice = static_cast<const uint8_t*>(data); const uint8_t* slice = static_cast<const uint8_t*>(data);
for (uint32_t z = 0; z < copySize.depthOrArrayLayers; ++z) { for (; z < destination.origin.z + copySize.depthOrArrayLayers; ++z) {
const uint8_t* d = slice; const uint8_t* d = slice;
for (uint32_t y = 0; y < copySize.height; ++y) { for (y = destination.origin.y; y < destination.origin.y + height; ++y) {
gl.TexSubImage3D(target, destination.mipLevel, destination.origin.x, gl.TexSubImage3D(target, destination.mipLevel, x, y, z, width, 1, 1,
destination.origin.y + y, destination.origin.z + z, format.format, format.type, d);
copySize.width, 1, 1, format.format, format.type, d);
d += dataLayout.bytesPerRow; d += dataLayout.bytesPerRow;
} }
slice += dataLayout.rowsPerImage * dataLayout.bytesPerRow; slice += dataLayout.rowsPerImage * dataLayout.bytesPerRow;
@ -1398,5 +1395,6 @@ namespace dawn_native { namespace opengl {
} }
} }
} }
}
}} // namespace dawn_native::opengl }} // namespace dawn_native::opengl