From 179db44c2586346ebc80beb0d054d781f4561e40 Mon Sep 17 00:00:00 2001 From: Brandon Jones Date: Fri, 30 Nov 2018 17:39:24 +0000 Subject: [PATCH] Refactor Internal Command Buffer Copy APIs Modify internal command buffer types to reflect the front end APIs for copyTextureToBuffer and copyBufferToTexture. Bug: dawn:17 Change-Id: I088a167ee7145d741e70ed28c1df7a12d24b72fc Reviewed-on: https://dawn-review.googlesource.com/c/2740 Commit-Queue: Brandon1 Jones Reviewed-by: Corentin Wallez --- src/dawn_native/CommandBuffer.cpp | 79 +++++++------- src/dawn_native/Commands.h | 28 ++--- src/dawn_native/d3d12/CommandBufferD3D12.cpp | 15 ++- src/dawn_native/d3d12/TextureCopySplitter.cpp | 100 +++++++----------- src/dawn_native/d3d12/TextureCopySplitter.h | 28 ++--- src/dawn_native/metal/CommandBufferMTL.mm | 34 +++--- src/dawn_native/opengl/CommandBufferGL.cpp | 20 ++-- src/dawn_native/vulkan/CommandBufferVk.cpp | 35 +++--- src/tests/unittests/d3d12/CopySplitTests.cpp | 5 +- 9 files changed, 155 insertions(+), 189 deletions(-) diff --git a/src/dawn_native/CommandBuffer.cpp b/src/dawn_native/CommandBuffer.cpp index 8ddcc15b5c..5bdd2771d8 100644 --- a/src/dawn_native/CommandBuffer.cpp +++ b/src/dawn_native/CommandBuffer.cpp @@ -35,29 +35,30 @@ namespace dawn_native { namespace { - MaybeError ValidateCopyLocationFitsInTexture(const TextureCopyLocation& location) { - const TextureBase* texture = location.texture.Get(); - if (location.level >= texture->GetNumMipLevels()) { + MaybeError ValidateCopySizeFitsInTexture(const TextureCopy& textureCopy, + const Extent3D& copySize) { + const TextureBase* texture = textureCopy.texture.Get(); + if (textureCopy.level >= texture->GetNumMipLevels()) { return DAWN_VALIDATION_ERROR("Copy mip-level out of range"); } - if (location.slice >= texture->GetArrayLayers()) { + if (textureCopy.slice >= texture->GetArrayLayers()) { return DAWN_VALIDATION_ERROR("Copy array-layer out of range"); } // All texture dimensions are in uint32_t so by doing checks in uint64_t we avoid // overflows. - uint64_t level = location.level; - if (uint64_t(location.x) + uint64_t(location.width) > + uint64_t level = textureCopy.level; + if (uint64_t(textureCopy.origin.x) + uint64_t(copySize.width) > (static_cast(texture->GetSize().width) >> level) || - uint64_t(location.y) + uint64_t(location.height) > + uint64_t(textureCopy.origin.y) + uint64_t(copySize.height) > (static_cast(texture->GetSize().height) >> level)) { return DAWN_VALIDATION_ERROR("Copy would touch outside of the texture"); } // TODO(cwallez@chromium.org): Check the depth bound differently for 2D arrays and 3D // textures - if (location.z != 0 || location.depth != 1) { + if (textureCopy.origin.z != 0 || copySize.depth != 1) { return DAWN_VALIDATION_ERROR("No support for z != 0 and depth != 1 for now"); } @@ -69,31 +70,29 @@ namespace dawn_native { return offset <= bufferSize && (size <= (bufferSize - offset)); } - MaybeError ValidateCopySizeFitsInBuffer(const BufferCopyLocation& location, - uint32_t dataSize) { - if (!FitsInBuffer(location.buffer.Get(), location.offset, dataSize)) { + MaybeError ValidateCopySizeFitsInBuffer(const BufferCopy& bufferCopy, uint32_t dataSize) { + if (!FitsInBuffer(bufferCopy.buffer.Get(), bufferCopy.offset, dataSize)) { return DAWN_VALIDATION_ERROR("Copy would overflow the buffer"); } return {}; } - MaybeError ValidateTexelBufferOffset(TextureBase* texture, - const BufferCopyLocation& location) { + MaybeError ValidateTexelBufferOffset(TextureBase* texture, const BufferCopy& bufferCopy) { uint32_t texelSize = static_cast(TextureFormatPixelSize(texture->GetFormat())); - if (location.offset % texelSize != 0) { + if (bufferCopy.offset % texelSize != 0) { return DAWN_VALIDATION_ERROR("Buffer offset must be a multiple of the texel size"); } return {}; } - MaybeError ComputeTextureCopyBufferSize(const TextureCopyLocation& location, + MaybeError ComputeTextureCopyBufferSize(const Extent3D& copySize, uint32_t rowPitch, uint32_t* bufferSize) { // TODO(cwallez@chromium.org): check for overflows - *bufferSize = (rowPitch * (location.height - 1) + location.width) * location.depth; + *bufferSize = (rowPitch * (copySize.height - 1) + copySize.width) * copySize.depth; return {}; } @@ -103,13 +102,15 @@ namespace dawn_native { return texelSize * width; } - MaybeError ValidateRowPitch(const TextureCopyLocation& location, uint32_t rowPitch) { + MaybeError ValidateRowPitch(dawn::TextureFormat format, + const Extent3D& copySize, + uint32_t rowPitch) { if (rowPitch % kTextureRowPitchAlignment != 0) { return DAWN_VALIDATION_ERROR("Row pitch must be a multiple of 256"); } - uint32_t texelSize = TextureFormatPixelSize(location.texture.Get()->GetFormat()); - if (rowPitch < location.width * texelSize) { + uint32_t texelSize = TextureFormatPixelSize(format); + if (rowPitch < copySize.width * texelSize) { return DAWN_VALIDATION_ERROR( "Row pitch must not be less than the number of bytes per row"); } @@ -385,11 +386,12 @@ namespace dawn_native { CopyBufferToTextureCmd* copy = mIterator.NextCommand(); uint32_t bufferCopySize = 0; - DAWN_TRY(ValidateRowPitch(copy->destination, copy->rowPitch)); - DAWN_TRY(ComputeTextureCopyBufferSize(copy->destination, copy->rowPitch, + DAWN_TRY(ValidateRowPitch(copy->destination.texture->GetFormat(), + copy->copySize, copy->source.rowPitch)); + DAWN_TRY(ComputeTextureCopyBufferSize(copy->copySize, copy->source.rowPitch, &bufferCopySize)); - DAWN_TRY(ValidateCopyLocationFitsInTexture(copy->destination)); + DAWN_TRY(ValidateCopySizeFitsInTexture(copy->destination, copy->copySize)); DAWN_TRY(ValidateCopySizeFitsInBuffer(copy->source, bufferCopySize)); DAWN_TRY( ValidateTexelBufferOffset(copy->destination.texture.Get(), copy->source)); @@ -407,11 +409,12 @@ namespace dawn_native { CopyTextureToBufferCmd* copy = mIterator.NextCommand(); uint32_t bufferCopySize = 0; - DAWN_TRY(ValidateRowPitch(copy->source, copy->rowPitch)); - DAWN_TRY(ComputeTextureCopyBufferSize(copy->source, copy->rowPitch, - &bufferCopySize)); + DAWN_TRY(ValidateRowPitch(copy->source.texture->GetFormat(), copy->copySize, + copy->destination.rowPitch)); + DAWN_TRY(ComputeTextureCopyBufferSize( + copy->copySize, copy->destination.rowPitch, &bufferCopySize)); - DAWN_TRY(ValidateCopyLocationFitsInTexture(copy->source)); + DAWN_TRY(ValidateCopySizeFitsInTexture(copy->source, copy->copySize)); DAWN_TRY(ValidateCopySizeFitsInBuffer(copy->destination, bufferCopySize)); DAWN_TRY( ValidateTexelBufferOffset(copy->source.texture.Get(), copy->destination)); @@ -657,18 +660,14 @@ namespace dawn_native { copy->source.buffer = source->buffer; copy->source.offset = source->offset; copy->destination.texture = destination->texture; - copy->destination.x = destination->origin.x; - copy->destination.y = destination->origin.y; - copy->destination.z = destination->origin.z; - copy->destination.width = copySize->width; - copy->destination.height = copySize->height; - copy->destination.depth = copySize->depth; + copy->destination.origin = destination->origin; + copy->copySize = *copySize; copy->destination.level = destination->level; copy->destination.slice = destination->slice; if (source->rowPitch == 0) { - copy->rowPitch = ComputeDefaultRowPitch(destination->texture, copySize->width); + copy->source.rowPitch = ComputeDefaultRowPitch(destination->texture, copySize->width); } else { - copy->rowPitch = source->rowPitch; + copy->source.rowPitch = source->rowPitch; } } @@ -682,20 +681,16 @@ namespace dawn_native { mAllocator.Allocate(Command::CopyTextureToBuffer); new (copy) CopyTextureToBufferCmd; copy->source.texture = source->texture; - copy->source.x = source->origin.x; - copy->source.y = source->origin.y; - copy->source.z = source->origin.z; - copy->source.width = copySize->width; - copy->source.height = copySize->height; - copy->source.depth = copySize->depth; + copy->source.origin = source->origin; + copy->copySize = *copySize; copy->source.level = source->level; copy->source.slice = source->slice; copy->destination.buffer = destination->buffer; copy->destination.offset = destination->offset; if (destination->rowPitch == 0) { - copy->rowPitch = ComputeDefaultRowPitch(source->texture, copySize->width); + copy->destination.rowPitch = ComputeDefaultRowPitch(source->texture, copySize->width); } else { - copy->rowPitch = destination->rowPitch; + copy->destination.rowPitch = destination->rowPitch; } } diff --git a/src/dawn_native/Commands.h b/src/dawn_native/Commands.h index e4598ad6a8..6ddf58ddc7 100644 --- a/src/dawn_native/Commands.h +++ b/src/dawn_native/Commands.h @@ -54,35 +54,37 @@ namespace dawn_native { Ref info; }; - struct BufferCopyLocation { + struct BufferCopy { Ref buffer; - uint32_t offset; + uint32_t offset; // Bytes + uint32_t rowPitch; // Bytes + uint32_t imageHeight; // Texels }; - struct TextureCopyLocation { + struct TextureCopy { Ref texture; - uint32_t x, y, z; - uint32_t width, height, depth; uint32_t level; uint32_t slice; + Origin3D origin; // Texels + dawn::TextureAspect aspect; }; struct CopyBufferToBufferCmd { - BufferCopyLocation source; - BufferCopyLocation destination; + BufferCopy source; + BufferCopy destination; uint32_t size; }; struct CopyBufferToTextureCmd { - BufferCopyLocation source; - TextureCopyLocation destination; - uint32_t rowPitch; + BufferCopy source; + TextureCopy destination; + Extent3D copySize; // Texels }; struct CopyTextureToBufferCmd { - TextureCopyLocation source; - BufferCopyLocation destination; - uint32_t rowPitch; + TextureCopy source; + BufferCopy destination; + Extent3D copySize; // Texels }; struct DispatchCmd { diff --git a/src/dawn_native/d3d12/CommandBufferD3D12.cpp b/src/dawn_native/d3d12/CommandBufferD3D12.cpp index 65e7d6cec3..d2aff42bdc 100644 --- a/src/dawn_native/d3d12/CommandBufferD3D12.cpp +++ b/src/dawn_native/d3d12/CommandBufferD3D12.cpp @@ -329,10 +329,9 @@ namespace dawn_native { namespace d3d12 { texture->TransitionUsageNow(commandList, dawn::TextureUsageBit::TransferDst); auto copySplit = ComputeTextureCopySplit( - copy->destination.x, copy->destination.y, copy->destination.z, - copy->destination.width, copy->destination.height, copy->destination.depth, + copy->destination.origin, copy->copySize, static_cast(TextureFormatPixelSize(texture->GetFormat())), - copy->source.offset, copy->rowPitch); + copy->source.offset, copy->source.rowPitch); D3D12_TEXTURE_COPY_LOCATION textureLocation; textureLocation.pResource = texture->GetD3D12Resource(); @@ -352,7 +351,7 @@ namespace dawn_native { namespace d3d12 { bufferLocation.PlacedFootprint.Footprint.Width = info.bufferSize.width; bufferLocation.PlacedFootprint.Footprint.Height = info.bufferSize.height; bufferLocation.PlacedFootprint.Footprint.Depth = info.bufferSize.depth; - bufferLocation.PlacedFootprint.Footprint.RowPitch = copy->rowPitch; + bufferLocation.PlacedFootprint.Footprint.RowPitch = copy->source.rowPitch; D3D12_BOX sourceRegion; sourceRegion.left = info.bufferOffset.x; @@ -377,10 +376,9 @@ namespace dawn_native { namespace d3d12 { buffer->TransitionUsageNow(commandList, dawn::BufferUsageBit::TransferDst); auto copySplit = ComputeTextureCopySplit( - copy->source.x, copy->source.y, copy->source.z, copy->source.width, - copy->source.height, copy->source.depth, + copy->source.origin, copy->copySize, static_cast(TextureFormatPixelSize(texture->GetFormat())), - copy->destination.offset, copy->rowPitch); + copy->destination.offset, copy->destination.rowPitch); D3D12_TEXTURE_COPY_LOCATION textureLocation; textureLocation.pResource = texture->GetD3D12Resource(); @@ -399,7 +397,8 @@ namespace dawn_native { namespace d3d12 { bufferLocation.PlacedFootprint.Footprint.Width = info.bufferSize.width; bufferLocation.PlacedFootprint.Footprint.Height = info.bufferSize.height; bufferLocation.PlacedFootprint.Footprint.Depth = info.bufferSize.depth; - bufferLocation.PlacedFootprint.Footprint.RowPitch = copy->rowPitch; + bufferLocation.PlacedFootprint.Footprint.RowPitch = + copy->destination.rowPitch; D3D12_BOX sourceRegion; sourceRegion.left = info.textureOffset.x; diff --git a/src/dawn_native/d3d12/TextureCopySplitter.cpp b/src/dawn_native/d3d12/TextureCopySplitter.cpp index 32f53094c6..7c58e89bbe 100644 --- a/src/dawn_native/d3d12/TextureCopySplitter.cpp +++ b/src/dawn_native/d3d12/TextureCopySplitter.cpp @@ -24,32 +24,26 @@ namespace dawn_native { namespace d3d12 { uint32_t rowPitch, uint32_t slicePitch, uint32_t texelSize, - uint32_t* texelOffsetX, - uint32_t* texelOffsetY, - uint32_t* texelOffsetZ) { + Origin3D* texelOffset) { uint32_t byteOffsetX = offset % rowPitch; offset -= byteOffsetX; uint32_t byteOffsetY = offset % slicePitch; uint32_t byteOffsetZ = offset - byteOffsetY; - *texelOffsetX = byteOffsetX / texelSize; - *texelOffsetY = byteOffsetY / rowPitch; - *texelOffsetZ = byteOffsetZ / slicePitch; + texelOffset->x = byteOffsetX / texelSize; + texelOffset->y = byteOffsetY / rowPitch; + texelOffset->z = byteOffsetZ / slicePitch; } } // namespace - TextureCopySplit ComputeTextureCopySplit(uint32_t x, - uint32_t y, - uint32_t z, - uint32_t width, - uint32_t height, - uint32_t depth, + TextureCopySplit ComputeTextureCopySplit(Origin3D origin, + Extent3D copySize, uint32_t texelSize, uint32_t offset, uint32_t rowPitch) { TextureCopySplit copy; - if (z != 0 || depth > 1) { + if (origin.z != 0 || copySize.depth > 1) { // TODO(enga@google.com): Handle 3D ASSERT(false); return copy; @@ -63,20 +57,14 @@ namespace dawn_native { namespace d3d12 { if (offset == alignedOffset) { copy.count = 1; - copy.copies[0].textureOffset.x = x; - copy.copies[0].textureOffset.y = y; - copy.copies[0].textureOffset.z = z; + copy.copies[0].textureOffset = origin; - copy.copies[0].copySize.width = width; - copy.copies[0].copySize.height = height; - copy.copies[0].copySize.depth = depth; + copy.copies[0].copySize = copySize; copy.copies[0].bufferOffset.x = 0; copy.copies[0].bufferOffset.y = 0; copy.copies[0].bufferOffset.z = 0; - copy.copies[0].bufferSize.width = width; - copy.copies[0].bufferSize.height = height; - copy.copies[0].bufferSize.depth = depth; + copy.copies[0].bufferSize = copySize; // Return early. There is only one copy needed because the offset is already 512-byte // aligned @@ -85,13 +73,13 @@ namespace dawn_native { namespace d3d12 { ASSERT(alignedOffset < offset); - uint32_t texelOffsetX, texelOffsetY, texelOffsetZ; - ComputeTexelOffsets(offset - alignedOffset, rowPitch, rowPitch * height, texelSize, - &texelOffsetX, &texelOffsetY, &texelOffsetZ); + Origin3D texelOffset; + ComputeTexelOffsets(offset - alignedOffset, rowPitch, rowPitch * copySize.height, texelSize, + &texelOffset); uint32_t rowPitchInTexels = rowPitch / texelSize; - if (width + texelOffsetX <= rowPitchInTexels) { + if (copySize.width + texelOffset.x <= rowPitchInTexels) { // The region's rows fit inside the row pitch. In this case, extend the width of the // PlacedFootprint and copy the buffer with an offset location // |<--------------- row pitch --------------->| @@ -117,20 +105,14 @@ namespace dawn_native { namespace d3d12 { copy.count = 1; - copy.copies[0].textureOffset.x = x; - copy.copies[0].textureOffset.y = y; - copy.copies[0].textureOffset.z = z; + copy.copies[0].textureOffset = origin; - copy.copies[0].copySize.width = width; - copy.copies[0].copySize.height = height; - copy.copies[0].copySize.depth = depth; + copy.copies[0].copySize = copySize; - copy.copies[0].bufferOffset.x = texelOffsetX; - copy.copies[0].bufferOffset.y = texelOffsetY; - copy.copies[0].bufferOffset.z = texelOffsetZ; - copy.copies[0].bufferSize.width = width + texelOffsetX; - copy.copies[0].bufferSize.height = height + texelOffsetY; - copy.copies[0].bufferSize.depth = depth + texelOffsetZ; + copy.copies[0].bufferOffset = texelOffset; + copy.copies[0].bufferSize.width = copySize.width + texelOffset.x; + copy.copies[0].bufferSize.height = copySize.height + texelOffset.y; + copy.copies[0].bufferSize.depth = copySize.depth + texelOffset.z; return copy; } @@ -171,37 +153,33 @@ namespace dawn_native { namespace d3d12 { copy.count = 2; - copy.copies[0].textureOffset.x = x; - copy.copies[0].textureOffset.y = y; - copy.copies[0].textureOffset.z = z; + copy.copies[0].textureOffset = origin; - ASSERT(rowPitchInTexels > texelOffsetX); - copy.copies[0].copySize.width = rowPitchInTexels - texelOffsetX; - copy.copies[0].copySize.height = height; - copy.copies[0].copySize.depth = depth; + ASSERT(rowPitchInTexels > texelOffset.x); + copy.copies[0].copySize.width = rowPitchInTexels - texelOffset.x; + copy.copies[0].copySize.height = copySize.height; + copy.copies[0].copySize.depth = copySize.depth; - copy.copies[0].bufferOffset.x = texelOffsetX; - copy.copies[0].bufferOffset.y = texelOffsetY; - copy.copies[0].bufferOffset.z = texelOffsetZ; + copy.copies[0].bufferOffset = texelOffset; copy.copies[0].bufferSize.width = rowPitchInTexels; - copy.copies[0].bufferSize.height = height + texelOffsetY; - copy.copies[0].bufferSize.depth = depth + texelOffsetZ; + copy.copies[0].bufferSize.height = copySize.height + texelOffset.y; + copy.copies[0].bufferSize.depth = copySize.depth + texelOffset.z; - copy.copies[1].textureOffset.x = x + copy.copies[0].copySize.width; - copy.copies[1].textureOffset.y = y; - copy.copies[1].textureOffset.z = z; + copy.copies[1].textureOffset.x = origin.x + copy.copies[0].copySize.width; + copy.copies[1].textureOffset.y = origin.y; + copy.copies[1].textureOffset.z = origin.z; - ASSERT(width > copy.copies[0].copySize.width); - copy.copies[1].copySize.width = width - copy.copies[0].copySize.width; - copy.copies[1].copySize.height = height; - copy.copies[1].copySize.depth = depth; + ASSERT(copySize.width > copy.copies[0].copySize.width); + copy.copies[1].copySize.width = copySize.width - copy.copies[0].copySize.width; + copy.copies[1].copySize.height = copySize.height; + copy.copies[1].copySize.depth = copySize.depth; copy.copies[1].bufferOffset.x = 0; - copy.copies[1].bufferOffset.y = texelOffsetY + 1; - copy.copies[1].bufferOffset.z = texelOffsetZ; + copy.copies[1].bufferOffset.y = texelOffset.y + 1; + copy.copies[1].bufferOffset.z = texelOffset.z; copy.copies[1].bufferSize.width = copy.copies[1].copySize.width; - copy.copies[1].bufferSize.height = height + texelOffsetY + 1; - copy.copies[1].bufferSize.depth = depth + texelOffsetZ; + copy.copies[1].bufferSize.height = copySize.height + texelOffset.y + 1; + copy.copies[1].bufferSize.depth = copySize.depth + texelOffset.z; return copy; } diff --git a/src/dawn_native/d3d12/TextureCopySplitter.h b/src/dawn_native/d3d12/TextureCopySplitter.h index eec55e2986..f82da87858 100644 --- a/src/dawn_native/d3d12/TextureCopySplitter.h +++ b/src/dawn_native/d3d12/TextureCopySplitter.h @@ -24,24 +24,12 @@ namespace dawn_native { namespace d3d12 { struct TextureCopySplit { static constexpr unsigned int kMaxTextureCopyRegions = 2; - struct Extent { - uint32_t width = 0; - uint32_t height = 0; - uint32_t depth = 0; - }; - - struct Origin { - uint32_t x = 0; - uint32_t y = 0; - uint32_t z = 0; - }; - struct CopyInfo { - Origin textureOffset; - Origin bufferOffset; - Extent bufferSize; + Origin3D textureOffset; + Origin3D bufferOffset; + Extent3D bufferSize; - Extent copySize; + Extent3D copySize; }; uint32_t offset = 0; @@ -49,12 +37,8 @@ namespace dawn_native { namespace d3d12 { std::array copies; }; - TextureCopySplit ComputeTextureCopySplit(uint32_t x, - uint32_t y, - uint32_t z, - uint32_t width, - uint32_t height, - uint32_t depth, + TextureCopySplit ComputeTextureCopySplit(Origin3D origin, + Extent3D copySize, uint32_t texelSize, uint32_t offset, uint32_t rowPitch); diff --git a/src/dawn_native/metal/CommandBufferMTL.mm b/src/dawn_native/metal/CommandBufferMTL.mm index 3aff378410..bf37d1f4ce 100644 --- a/src/dawn_native/metal/CommandBufferMTL.mm +++ b/src/dawn_native/metal/CommandBufferMTL.mm @@ -253,24 +253,25 @@ namespace dawn_native { namespace metal { CopyBufferToTextureCmd* copy = mCommands.NextCommand(); auto& src = copy->source; auto& dst = copy->destination; + auto& copySize = copy->copySize; Buffer* buffer = ToBackend(src.buffer.Get()); Texture* texture = ToBackend(dst.texture.Get()); MTLOrigin origin; - origin.x = dst.x; - origin.y = dst.y; - origin.z = dst.z; + origin.x = dst.origin.x; + origin.y = dst.origin.y; + origin.z = dst.origin.z; MTLSize size; - size.width = dst.width; - size.height = dst.height; - size.depth = dst.depth; + size.width = copySize.width; + size.height = copySize.height; + size.depth = copySize.depth; encoders.EnsureBlit(commandBuffer); [encoders.blit copyFromBuffer:buffer->GetMTLBuffer() sourceOffset:src.offset - sourceBytesPerRow:copy->rowPitch - sourceBytesPerImage:(copy->rowPitch * dst.height) + sourceBytesPerRow:src.rowPitch + sourceBytesPerImage:(src.rowPitch * copySize.height) sourceSize:size toTexture:texture->GetMTLTexture() destinationSlice:dst.slice @@ -282,18 +283,19 @@ namespace dawn_native { namespace metal { CopyTextureToBufferCmd* copy = mCommands.NextCommand(); auto& src = copy->source; auto& dst = copy->destination; + auto& copySize = copy->copySize; Texture* texture = ToBackend(src.texture.Get()); Buffer* buffer = ToBackend(dst.buffer.Get()); MTLOrigin origin; - origin.x = src.x; - origin.y = src.y; - origin.z = src.z; + origin.x = src.origin.x; + origin.y = src.origin.y; + origin.z = src.origin.z; MTLSize size; - size.width = src.width; - size.height = src.height; - size.depth = src.depth; + size.width = copySize.width; + size.height = copySize.height; + size.depth = copySize.depth; encoders.EnsureBlit(commandBuffer); [encoders.blit copyFromTexture:texture->GetMTLTexture() @@ -303,8 +305,8 @@ namespace dawn_native { namespace metal { sourceSize:size toBuffer:buffer->GetMTLBuffer() destinationOffset:dst.offset - destinationBytesPerRow:copy->rowPitch - destinationBytesPerImage:copy->rowPitch * src.height]; + destinationBytesPerRow:dst.rowPitch + destinationBytesPerImage:dst.rowPitch * copySize.height]; } break; default: { UNREACHABLE(); } break; diff --git a/src/dawn_native/opengl/CommandBufferGL.cpp b/src/dawn_native/opengl/CommandBufferGL.cpp index ec03c77995..3d36fa222a 100644 --- a/src/dawn_native/opengl/CommandBufferGL.cpp +++ b/src/dawn_native/opengl/CommandBufferGL.cpp @@ -321,6 +321,7 @@ namespace dawn_native { namespace opengl { CopyBufferToTextureCmd* copy = mCommands.NextCommand(); auto& src = copy->source; auto& dst = copy->destination; + auto& copySize = copy->copySize; Buffer* buffer = ToBackend(src.buffer.Get()); Texture* texture = ToBackend(dst.texture.Get()); GLenum target = texture->GetGLTarget(); @@ -331,18 +332,18 @@ namespace dawn_native { namespace opengl { glBindTexture(target, texture->GetHandle()); glPixelStorei(GL_UNPACK_ROW_LENGTH, - copy->rowPitch / TextureFormatPixelSize(texture->GetFormat())); + src.rowPitch / TextureFormatPixelSize(texture->GetFormat())); switch (texture->GetDimension()) { case dawn::TextureDimension::e2D: if (texture->GetArrayLayers() > 1) { glTexSubImage3D( - target, dst.level, dst.x, dst.y, dst.slice, dst.width, - dst.height, 1, format.format, format.type, + target, dst.level, dst.origin.x, dst.origin.y, dst.slice, + copySize.width, copySize.height, 1, format.format, format.type, reinterpret_cast(static_cast(src.offset))); } else { glTexSubImage2D( - target, dst.level, dst.x, dst.y, dst.width, dst.height, - format.format, format.type, + target, dst.level, dst.origin.x, dst.origin.y, copySize.width, + copySize.height, format.format, format.type, reinterpret_cast(static_cast(src.offset))); } break; @@ -359,6 +360,7 @@ namespace dawn_native { namespace opengl { CopyTextureToBufferCmd* copy = mCommands.NextCommand(); auto& src = copy->source; auto& dst = copy->destination; + auto& copySize = copy->copySize; Texture* texture = ToBackend(src.texture.Get()); Buffer* buffer = ToBackend(dst.buffer.Get()); auto format = texture->GetGLFormat(); @@ -390,11 +392,11 @@ namespace dawn_native { namespace opengl { glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer->GetHandle()); glPixelStorei(GL_PACK_ROW_LENGTH, - copy->rowPitch / TextureFormatPixelSize(texture->GetFormat())); - ASSERT(src.depth == 1 && src.z == 0); + dst.rowPitch / TextureFormatPixelSize(texture->GetFormat())); + ASSERT(copySize.depth == 1 && src.origin.z == 0); void* offset = reinterpret_cast(static_cast(dst.offset)); - glReadPixels(src.x, src.y, src.width, src.height, format.format, format.type, - offset); + glReadPixels(src.origin.x, src.origin.y, copySize.width, copySize.height, + format.format, format.type, offset); glPixelStorei(GL_PACK_ROW_LENGTH, 0); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); diff --git a/src/dawn_native/vulkan/CommandBufferVk.cpp b/src/dawn_native/vulkan/CommandBufferVk.cpp index 8f5c46271c..23dfd55f00 100644 --- a/src/dawn_native/vulkan/CommandBufferVk.cpp +++ b/src/dawn_native/vulkan/CommandBufferVk.cpp @@ -39,30 +39,31 @@ namespace dawn_native { namespace vulkan { } } - VkBufferImageCopy ComputeBufferImageCopyRegion(uint32_t rowPitch, - const BufferCopyLocation& bufferLocation, - const TextureCopyLocation& textureLocation) { - const Texture* texture = ToBackend(textureLocation.texture).Get(); + VkBufferImageCopy ComputeBufferImageCopyRegion(const BufferCopy& bufferCopy, + const TextureCopy& textureCopy, + const Extent3D& copySize) { + const Texture* texture = ToBackend(textureCopy.texture.Get()); VkBufferImageCopy region; - region.bufferOffset = bufferLocation.offset; + region.bufferOffset = bufferCopy.offset; // In Vulkan the row length is in texels while it is in bytes for Dawn - region.bufferRowLength = rowPitch / TextureFormatPixelSize(texture->GetFormat()); - region.bufferImageHeight = rowPitch * textureLocation.height; + region.bufferRowLength = + bufferCopy.rowPitch / TextureFormatPixelSize(texture->GetFormat()); + region.bufferImageHeight = bufferCopy.rowPitch * copySize.height; region.imageSubresource.aspectMask = texture->GetVkAspectMask(); - region.imageSubresource.mipLevel = textureLocation.level; - region.imageSubresource.baseArrayLayer = textureLocation.slice; + region.imageSubresource.mipLevel = textureCopy.level; + region.imageSubresource.baseArrayLayer = textureCopy.slice; region.imageSubresource.layerCount = 1; - region.imageOffset.x = textureLocation.x; - region.imageOffset.y = textureLocation.y; - region.imageOffset.z = textureLocation.z; + region.imageOffset.x = textureCopy.origin.x; + region.imageOffset.y = textureCopy.origin.y; + region.imageOffset.z = textureCopy.origin.z; - region.imageExtent.width = textureLocation.width; - region.imageExtent.height = textureLocation.height; - region.imageExtent.depth = textureLocation.depth; + region.imageExtent.width = copySize.width; + region.imageExtent.height = copySize.height; + region.imageExtent.depth = copySize.depth; return region; } @@ -173,7 +174,7 @@ namespace dawn_native { namespace vulkan { VkImage dstImage = ToBackend(dst.texture)->GetHandle(); VkBufferImageCopy region = - ComputeBufferImageCopyRegion(copy->rowPitch, src, dst); + ComputeBufferImageCopyRegion(src, dst, copy->copySize); // The image is written to so the Dawn guarantees make sure it is in the // TRANSFER_DST_OPTIMAL layout @@ -196,7 +197,7 @@ namespace dawn_native { namespace vulkan { VkBuffer dstBuffer = ToBackend(dst.buffer)->GetHandle(); VkBufferImageCopy region = - ComputeBufferImageCopyRegion(copy->rowPitch, dst, src); + ComputeBufferImageCopyRegion(dst, src, copy->copySize); // The Dawn TransferSrc usage is always mapped to GENERAL device->fn.CmdCopyImageToBuffer(commands, srcImage, VK_IMAGE_LAYOUT_GENERAL, diff --git a/src/tests/unittests/d3d12/CopySplitTests.cpp b/src/tests/unittests/d3d12/CopySplitTests.cpp index 88e1ceb43b..e3d6688f7f 100644 --- a/src/tests/unittests/d3d12/CopySplitTests.cpp +++ b/src/tests/unittests/d3d12/CopySplitTests.cpp @@ -220,7 +220,10 @@ namespace { class CopySplitTest : public testing::Test { protected: TextureCopySplit DoTest(const TextureSpec& textureSpec, const BufferSpec& bufferSpec) { - TextureCopySplit copySplit = ComputeTextureCopySplit(textureSpec.x, textureSpec.y, textureSpec.z, textureSpec.width, textureSpec.height, textureSpec.depth, textureSpec.texelSize, bufferSpec.offset, bufferSpec.rowPitch); + TextureCopySplit copySplit = ComputeTextureCopySplit( + {textureSpec.x, textureSpec.y, textureSpec.z}, + {textureSpec.width, textureSpec.height, textureSpec.depth}, textureSpec.texelSize, + bufferSpec.offset, bufferSpec.rowPitch); ValidateCopySplit(textureSpec, bufferSpec, copySplit); return copySplit; }