Support copying multiple array layers in one B2T and T2B copy command

This patch adds the support of copying with multiple texture array
layers in one buffer-to-texture and texture-to-buffer copy command.

BUG=dawn:453
TEST=dawn_end2end_tests

Change-Id: If009dbb29f2b0ef0667715eed0d66053b1491fd4
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/23248
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
This commit is contained in:
Jiawei Shao
2020-06-21 09:33:44 +00:00
committed by Commit Bot service account
parent 250f26229b
commit 92379bff49
10 changed files with 413 additions and 215 deletions

View File

@@ -515,13 +515,15 @@ namespace dawn_native { namespace opengl {
const GLFormat& format = texture->GetGLFormat();
ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
ASSERT(copy->copySize.depth == 1);
SubresourceRange subresource =
SubresourceRange::SingleSubresource(dst.mipLevel, dst.arrayLayer);
// TODO(jiawei.shao@intel.com): use copy->destination.origin.z instead of
// copy->destination.arrayLayer once GPUTextureCopyView.arrayLayer to
// GPUTextureCopyView.origin.z is done.
SubresourceRange subresources = {dst.mipLevel, 1, dst.arrayLayer,
copy->copySize.depth};
if (IsCompleteSubresourceCopiedTo(texture, copySize, dst.mipLevel)) {
texture->SetIsSubresourceContentInitialized(true, subresource);
texture->SetIsSubresourceContentInitialized(true, subresources);
} else {
texture->EnsureSubresourceContentInitialized(subresource);
texture->EnsureSubresourceContentInitialized(subresources);
}
gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer->GetHandle());
@@ -549,8 +551,8 @@ namespace dawn_native { namespace opengl {
if (texture->GetArrayLayers() > 1) {
gl.CompressedTexSubImage3D(
target, dst.mipLevel, dst.origin.x, dst.origin.y, dst.arrayLayer,
copyExtent.width, copyExtent.height, 1, format.internalFormat,
copyDataSize,
copyExtent.width, copyExtent.height, copyExtent.depth,
format.internalFormat, copyDataSize,
reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
} else {
gl.CompressedTexSubImage2D(
@@ -564,7 +566,8 @@ namespace dawn_native { namespace opengl {
if (texture->GetArrayLayers() > 1) {
gl.TexSubImage3D(target, dst.mipLevel, dst.origin.x,
dst.origin.y, dst.arrayLayer, copySize.width,
copySize.height, 1, format.format, format.type,
copySize.height, copySize.depth, format.format,
format.type,
reinterpret_cast<void*>(
static_cast<uintptr_t>(src.offset)));
} else {
@@ -606,9 +609,9 @@ namespace dawn_native { namespace opengl {
}
ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
ASSERT(copy->copySize.depth == 1);
texture->EnsureSubresourceContentInitialized(
SubresourceRange::SingleSubresource(src.mipLevel, src.arrayLayer));
SubresourceRange subresources = {src.mipLevel, 1, src.arrayLayer,
copy->copySize.depth};
texture->EnsureSubresourceContentInitialized(subresources);
// The only way to move data from a texture to a buffer in GL is via
// glReadPixels with a pack buffer. Create a temporary FBO for the copy.
gl.BindTexture(target, texture->GetHandle());
@@ -636,29 +639,42 @@ namespace dawn_native { namespace opengl {
break;
}
gl.BindBuffer(GL_PIXEL_PACK_BUFFER, buffer->GetHandle());
gl.PixelStorei(GL_PACK_ROW_LENGTH, dst.bytesPerRow / format.blockByteSize);
gl.PixelStorei(GL_PACK_IMAGE_HEIGHT, dst.rowsPerImage);
uint8_t* offset =
reinterpret_cast<uint8_t*>(static_cast<uintptr_t>(dst.offset));
switch (texture->GetDimension()) {
case wgpu::TextureDimension::e2D:
if (texture->GetArrayLayers() > 1) {
gl.FramebufferTextureLayer(GL_READ_FRAMEBUFFER, glAttachment,
texture->GetHandle(), src.mipLevel,
src.arrayLayer);
} else {
case wgpu::TextureDimension::e2D: {
if (texture->GetArrayLayers() == 1) {
gl.FramebufferTexture2D(GL_READ_FRAMEBUFFER, glAttachment, target,
texture->GetHandle(), src.mipLevel);
gl.ReadPixels(src.origin.x, src.origin.y, copySize.width,
copySize.height, glFormat.format, glFormat.type,
offset);
break;
}
const uint64_t bytesPerImage = dst.bytesPerRow * dst.rowsPerImage;
for (uint32_t layer = 0; layer < copySize.depth; ++layer) {
gl.FramebufferTextureLayer(GL_READ_FRAMEBUFFER, glAttachment,
texture->GetHandle(), src.mipLevel,
src.arrayLayer + layer);
gl.ReadPixels(src.origin.x, src.origin.y, copySize.width,
copySize.height, glFormat.format, glFormat.type,
offset);
offset += bytesPerImage;
}
break;
}
default:
UNREACHABLE();
}
gl.BindBuffer(GL_PIXEL_PACK_BUFFER, buffer->GetHandle());
gl.PixelStorei(GL_PACK_ROW_LENGTH, dst.bytesPerRow / format.blockByteSize);
gl.PixelStorei(GL_PACK_IMAGE_HEIGHT, dst.rowsPerImage);
ASSERT(copySize.depth == 1 && src.origin.z == 0);
void* offset = reinterpret_cast<void*>(static_cast<uintptr_t>(dst.offset));
gl.ReadPixels(src.origin.x, src.origin.y, copySize.width, copySize.height,
glFormat.format, glFormat.type, offset);
gl.PixelStorei(GL_PACK_ROW_LENGTH, 0);
gl.PixelStorei(GL_PACK_IMAGE_HEIGHT, 0);