diff --git a/app/src/main/cpp/skyline/gpu/presentation_engine.cpp b/app/src/main/cpp/skyline/gpu/presentation_engine.cpp index 4541fbc8..8bcec905 100644 --- a/app/src/main/cpp/skyline/gpu/presentation_engine.cpp +++ b/app/src/main/cpp/skyline/gpu/presentation_engine.cpp @@ -139,7 +139,7 @@ namespace skyline::gpu { auto &presentSemaphore{presentSemaphores[nextImage.second]}; texture->SynchronizeHost(); - nextImageTexture->CopyFrom(texture, *acquireSemaphore, *presentSemaphore, vk::ImageSubresourceRange{ + nextImageTexture->CopyFrom(texture, *acquireSemaphore, *presentSemaphore, swapchainFormat, vk::ImageSubresourceRange{ .aspectMask = vk::ImageAspectFlagBits::eColor, .levelCount = 1, .layerCount = 1, diff --git a/app/src/main/cpp/skyline/gpu/texture/texture.cpp b/app/src/main/cpp/skyline/gpu/texture/texture.cpp index d2e545dd..15591f89 100644 --- a/app/src/main/cpp/skyline/gpu/texture/texture.cpp +++ b/app/src/main/cpp/skyline/gpu/texture/texture.cpp @@ -865,7 +865,7 @@ namespace skyline::gpu { return std::make_shared(shared_from_this(), type, range, pFormat, mapping); } - void Texture::CopyFrom(std::shared_ptr source, vk::Semaphore waitSemaphore, vk::Semaphore signalSemaphore, const vk::ImageSubresourceRange &subresource) { + void Texture::CopyFrom(std::shared_ptr source, vk::Semaphore waitSemaphore, vk::Semaphore signalSemaphore, texture::Format srcFormat, const vk::ImageSubresourceRange &subresource) { if (cycle) cycle->WaitSubmit(); if (source->cycle) @@ -928,12 +928,32 @@ namespace skyline::gpu { .baseArrayLayer = subresource.baseArrayLayer, .layerCount = subresource.layerCount == VK_REMAINING_ARRAY_LAYERS ? layerCount - subresource.baseArrayLayer : subresource.layerCount, }; - for (; subresourceLayers.mipLevel < (subresource.levelCount == VK_REMAINING_MIP_LEVELS ? levelCount - subresource.baseMipLevel : subresource.levelCount); subresourceLayers.mipLevel++) - commandBuffer.copyImage(sourceBacking, vk::ImageLayout::eTransferSrcOptimal, destinationBacking, vk::ImageLayout::eTransferDstOptimal, vk::ImageCopy{ - .srcSubresource = subresourceLayers, - .dstSubresource = subresourceLayers, - .extent = dimensions, + for (; subresourceLayers.mipLevel < (subresource.levelCount == VK_REMAINING_MIP_LEVELS ? levelCount - subresource.baseMipLevel : subresource.levelCount); subresourceLayers.mipLevel++) { + if (srcFormat != format) { + commandBuffer.blitImage(sourceBacking, vk::ImageLayout::eTransferSrcOptimal, destinationBacking, vk::ImageLayout::eTransferDstOptimal, vk::ImageBlit{ + .srcSubresource = subresourceLayers, + .srcOffsets = std::array{ + vk::Offset3D{0, 0, 0}, + vk::Offset3D{static_cast(dimensions.width), + static_cast(dimensions.height), + static_cast(subresourceLayers.layerCount)} + }, + .dstSubresource = subresourceLayers, + .dstOffsets = std::array{ + vk::Offset3D{0, 0, 0}, + vk::Offset3D{static_cast(dimensions.width), + static_cast(dimensions.height), + static_cast(subresourceLayers.layerCount)} + } + }, vk::Filter::eLinear); + } else { + commandBuffer.copyImage(sourceBacking, vk::ImageLayout::eTransferSrcOptimal, destinationBacking, vk::ImageLayout::eTransferDstOptimal, vk::ImageCopy{ + .srcSubresource = subresourceLayers, + .dstSubresource = subresourceLayers, + .extent = dimensions, }); + } + } if (layout != vk::ImageLayout::eTransferDstOptimal) commandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eAllCommands, {}, {}, {}, vk::ImageMemoryBarrier{ diff --git a/app/src/main/cpp/skyline/gpu/texture/texture.h b/app/src/main/cpp/skyline/gpu/texture/texture.h index 3ce1e7ca..0c0cb6ff 100644 --- a/app/src/main/cpp/skyline/gpu/texture/texture.h +++ b/app/src/main/cpp/skyline/gpu/texture/texture.h @@ -581,7 +581,7 @@ namespace skyline::gpu { /** * @brief Copies the contents of the supplied source texture into the current texture */ - void CopyFrom(std::shared_ptr source, vk::Semaphore waitSemaphore, vk::Semaphore signalSemaphore, const vk::ImageSubresourceRange &subresource = vk::ImageSubresourceRange{ + void CopyFrom(std::shared_ptr source, vk::Semaphore waitSemaphore, vk::Semaphore signalSemaphore, texture::Format srcFormat, const vk::ImageSubresourceRange &subresource = vk::ImageSubresourceRange{ .aspectMask = vk::ImageAspectFlagBits::eColor, .levelCount = VK_REMAINING_MIP_LEVELS, .layerCount = VK_REMAINING_ARRAY_LAYERS,