From bd6cd0056c8211b334d7a525034c8603b6cd4297 Mon Sep 17 00:00:00 2001 From: PixelyIon Date: Wed, 8 Dec 2021 14:28:45 +0530 Subject: [PATCH] Support Multi-Aspect Copy in `Texture::CopyIntoStagingBuffer` Only copying a single aspect was supported by `CopyIntoStagingBuffer` earlier due to not supplying a `VkBufferImageCopy` for each aspect separately, this has now been done with Color/Depth/Stencil aspects having their own `VkBufferImageCopy` for the `VkCmdCopyImageToBuffer` command. --- .../main/cpp/skyline/gpu/texture/texture.cpp | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/app/src/main/cpp/skyline/gpu/texture/texture.cpp b/app/src/main/cpp/skyline/gpu/texture/texture.cpp index bbe4dc94..93648706 100644 --- a/app/src/main/cpp/skyline/gpu/texture/texture.cpp +++ b/app/src/main/cpp/skyline/gpu/texture/texture.cpp @@ -172,13 +172,26 @@ namespace skyline::gpu { }, }); - commandBuffer.copyImageToBuffer(image, layout, stagingBuffer->vkBuffer, vk::BufferImageCopy{ - .imageExtent = dimensions, - .imageSubresource = { - .aspectMask = format->vkAspect, - .layerCount = layerCount, - }, - }); + boost::container::static_vector bufferImageCopies; + auto pushBufferImageCopyWithAspect{[&](vk::ImageAspectFlagBits aspect) { + bufferImageCopies.emplace_back( + vk::BufferImageCopy{ + .imageExtent = dimensions, + .imageSubresource = { + .aspectMask = aspect, + .layerCount = layerCount, + }, + }); + }}; + + if (format->vkAspect & vk::ImageAspectFlagBits::eColor) + pushBufferImageCopyWithAspect(vk::ImageAspectFlagBits::eColor); + if (format->vkAspect & vk::ImageAspectFlagBits::eDepth) + pushBufferImageCopyWithAspect(vk::ImageAspectFlagBits::eDepth); + if (format->vkAspect & vk::ImageAspectFlagBits::eStencil) + pushBufferImageCopyWithAspect(vk::ImageAspectFlagBits::eStencil); + + commandBuffer.copyImageToBuffer(image, layout, stagingBuffer->vkBuffer, vk::ArrayProxy(static_cast(bufferImageCopies.size()), bufferImageCopies.data())); commandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eHost, {}, {}, vk::BufferMemoryBarrier{ .srcAccessMask = vk::AccessFlagBits::eTransferWrite,