Fix Depth+Stencil image copy
As long as both source and destination provide both depth+stencil,
it is allowed to copy both simultaneously. When this happens,
Image::copyTo() will simply perform the copy operations one aspect
after the other.
Bug: b/202987708
Tests: dEQP-VK.api.*.depth_stencil.*
Change-Id: I4e79c88595e708475c93f46aabbb8cf33ad5b835
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/58168
Commit-Queue: Alexis Hétu <sugoi@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Vulkan/VkImage.cpp b/src/Vulkan/VkImage.cpp
index fea51cc..7adb5e3 100644
--- a/src/Vulkan/VkImage.cpp
+++ b/src/Vulkan/VkImage.cpp
@@ -356,6 +356,27 @@
void Image::copyTo(Image *dstImage, const VkImageCopy ®ion) const
{
+ static constexpr VkImageAspectFlags CombinedDepthStencilAspects =
+ VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+ if((region.srcSubresource.aspectMask == CombinedDepthStencilAspects) &&
+ (region.dstSubresource.aspectMask == CombinedDepthStencilAspects))
+ {
+ // Depth and stencil can be specified together, copy each separately
+ VkImageCopy singleAspectRegion = region;
+ singleAspectRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
+ singleAspectRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
+ copySingleAspectTo(dstImage, singleAspectRegion);
+ singleAspectRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
+ singleAspectRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
+ copySingleAspectTo(dstImage, singleAspectRegion);
+ return;
+ }
+
+ copySingleAspectTo(dstImage, region);
+}
+
+void Image::copySingleAspectTo(Image *dstImage, const VkImageCopy ®ion) const
+{
// Image copy does not perform any conversion, it simply copies memory from
// an image to another image that has the same number of bytes per pixel.
diff --git a/src/Vulkan/VkImage.hpp b/src/Vulkan/VkImage.hpp
index 5d2f88c..2c89be2 100644
--- a/src/Vulkan/VkImage.hpp
+++ b/src/Vulkan/VkImage.hpp
@@ -59,7 +59,7 @@
size_t getSizeInBytes(const VkImageSubresourceRange &subresourceRange) const;
void getSubresourceLayout(const VkImageSubresource *pSubresource, VkSubresourceLayout *pLayout) const;
void bind(DeviceMemory *pDeviceMemory, VkDeviceSize pMemoryOffset);
- void copyTo(Image *dstImage, const VkImageCopy &pRegion) const;
+ void copyTo(Image *dstImage, const VkImageCopy ®ion) const;
void copyTo(Buffer *dstBuffer, const VkBufferImageCopy ®ion);
void copyFrom(Buffer *srcBuffer, const VkBufferImageCopy ®ion);
@@ -120,6 +120,7 @@
private:
void copy(Buffer *buffer, const VkBufferImageCopy ®ion, bool bufferIsSource);
+ void copySingleAspectTo(Image *dstImage, const VkImageCopy ®ion) const;
VkDeviceSize getStorageSize(VkImageAspectFlags flags) const;
VkDeviceSize getMultiSampledLevelSize(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;
VkDeviceSize getLayerOffset(VkImageAspectFlagBits aspect, uint32_t mipLevel) const;