Fix copying between images and buffers with padding
Changed the algorithm to compute the copySize value.
Earlier, in the isEntireRow && isSingleSlice case we were putting
copySize = imageExtent.height * imageRowPitchBytes which is wrong
in the case when imageRowPitchBytes is the same as
bufferRowPitchBytes, but also contains some extra padding.
For example, for copying to the whole 127 x 64 texture with RGBA8
format with bufferRowPitchBytes = 4 * 128 and buffer size =
4 * (63 * 128 + 127) will produce an assertion error.
Bug: swiftshader:152
Change-Id: If7524534ff268a70b77cfeda8611abc99f148888
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/46908
Tested-by: Tomek Ponitka <tommek@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Vulkan/VkImage.cpp b/src/Vulkan/VkImage.cpp
index 2036aed..6807404 100644
--- a/src/Vulkan/VkImage.cpp
+++ b/src/Vulkan/VkImage.cpp
@@ -497,6 +497,12 @@
Format copyFormat = getFormat(aspect);
VkExtent3D imageExtent = imageExtentInBlocks(region.imageExtent, aspect);
+
+ if(imageExtent.width == 0 || imageExtent.height == 0 || imageExtent.depth == 0)
+ {
+ return;
+ }
+
VkExtent2D bufferExtent = bufferExtentInBlocks({ imageExtent.width, imageExtent.height }, region);
int bytesPerBlock = copyFormat.bytesPerBlock();
int bufferRowPitchBytes = bufferExtent.width * bytesPerBlock;
@@ -530,15 +536,15 @@
}
else if(isEntireRow && isSingleSlice)
{
- copySize = imageExtent.height * imageRowPitchBytes;
+ copySize = (imageExtent.height - 1) * imageRowPitchBytes + imageExtent.width * bytesPerBlock;
}
else if(isEntireSlice)
{
- copySize = imageExtent.depth * imageSlicePitchBytes; // Copy multiple slices
+ copySize = (imageExtent.depth - 1) * imageSlicePitchBytes + (imageExtent.height - 1) * imageRowPitchBytes + imageExtent.width * bytesPerBlock; // Copy multiple slices
}
else if(isEntireRow) // Copy slice by slice
{
- copySize = imageExtent.height * imageRowPitchBytes;
+ copySize = (imageExtent.height - 1) * imageRowPitchBytes + imageExtent.width * bytesPerBlock;
}
else // Copy row by row
{