mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-15 04:30:05 +00:00
vk_texture_runtime: Resolve MSAA source image before blit
Resolves the MSAA image to the upscale-image before blitting to ensure it is getting the freshest MSAA resolve. Todo: use a dirty flag.
This commit is contained in:
parent
a2aee70b86
commit
4de9d81b50
@ -576,6 +576,87 @@ bool TextureRuntime::BlitTextures(Surface& source, Surface& dest,
|
|||||||
.dst_image = dest.Image(1),
|
.dst_image = dest.Image(1),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Must resolve source-image first
|
||||||
|
if ((source.sample_count > dest.sample_count) && (dest.sample_count == 1)) {
|
||||||
|
|
||||||
|
scheduler.Record([&source](vk::CommandBuffer cmdbuf) {
|
||||||
|
const vk::ImageResolve resolve_area = {
|
||||||
|
.srcSubresource{
|
||||||
|
.aspectMask = source.Aspect(),
|
||||||
|
.mipLevel = 0,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
},
|
||||||
|
.srcOffset = {},
|
||||||
|
.dstSubresource{
|
||||||
|
.aspectMask = source.Aspect(),
|
||||||
|
.mipLevel = 0,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
},
|
||||||
|
.dstOffset = {},
|
||||||
|
.extent{source.GetScaledWidth(), source.GetScaledHeight(), 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::array read_barriers = {
|
||||||
|
vk::ImageMemoryBarrier{
|
||||||
|
.srcAccessMask = source.AccessFlags(),
|
||||||
|
.dstAccessMask = vk::AccessFlagBits::eTransferRead,
|
||||||
|
.oldLayout = vk::ImageLayout::eGeneral,
|
||||||
|
.newLayout = vk::ImageLayout::eTransferSrcOptimal,
|
||||||
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.image = source.Image(3),
|
||||||
|
.subresourceRange = MakeSubresourceRange(source.Aspect(), 0),
|
||||||
|
},
|
||||||
|
vk::ImageMemoryBarrier{
|
||||||
|
.srcAccessMask = source.AccessFlags(),
|
||||||
|
.dstAccessMask = vk::AccessFlagBits::eTransferWrite,
|
||||||
|
.oldLayout = vk::ImageLayout::eGeneral,
|
||||||
|
.newLayout = vk::ImageLayout::eTransferDstOptimal,
|
||||||
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.image = source.Image(1),
|
||||||
|
.subresourceRange = MakeSubresourceRange(source.Aspect(), 0),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const std::array write_barriers = {
|
||||||
|
vk::ImageMemoryBarrier{
|
||||||
|
.srcAccessMask = vk::AccessFlagBits::eTransferRead,
|
||||||
|
.dstAccessMask = source.AccessFlags(),
|
||||||
|
.oldLayout = vk::ImageLayout::eTransferSrcOptimal,
|
||||||
|
.newLayout = vk::ImageLayout::eGeneral,
|
||||||
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.image = source.Image(3),
|
||||||
|
.subresourceRange = MakeSubresourceRange(source.Aspect(), 0),
|
||||||
|
},
|
||||||
|
vk::ImageMemoryBarrier{
|
||||||
|
.srcAccessMask = vk::AccessFlagBits::eTransferWrite,
|
||||||
|
.dstAccessMask = source.AccessFlags(),
|
||||||
|
.oldLayout = vk::ImageLayout::eTransferDstOptimal,
|
||||||
|
.newLayout = vk::ImageLayout::eGeneral,
|
||||||
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.image = source.Image(1),
|
||||||
|
.subresourceRange = MakeSubresourceRange(source.Aspect(), 0),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
cmdbuf.pipelineBarrier(source.PipelineStageFlags(),
|
||||||
|
vk::PipelineStageFlagBits::eTransfer,
|
||||||
|
vk::DependencyFlagBits::eByRegion, {}, {}, read_barriers);
|
||||||
|
|
||||||
|
cmdbuf.resolveImage(source.Image(3), vk::ImageLayout::eTransferSrcOptimal,
|
||||||
|
source.Image(1), vk::ImageLayout::eTransferDstOptimal,
|
||||||
|
resolve_area);
|
||||||
|
|
||||||
|
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer,
|
||||||
|
source.PipelineStageFlags(), vk::DependencyFlagBits::eByRegion,
|
||||||
|
{}, {}, write_barriers);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
scheduler.Record([params, blit](vk::CommandBuffer cmdbuf) {
|
scheduler.Record([params, blit](vk::CommandBuffer cmdbuf) {
|
||||||
const std::array source_offsets = {
|
const std::array source_offsets = {
|
||||||
vk::Offset3D{static_cast<s32>(blit.src_rect.left),
|
vk::Offset3D{static_cast<s32>(blit.src_rect.left),
|
||||||
|
Loading…
Reference in New Issue
Block a user