renderer_vulkan: Support self copy
FE games copy parts of the framebuffer to itself. Don't switch layout in that case
This commit is contained in:
@ -43,8 +43,10 @@ Swapchain::~Swapchain() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Swapchain::Create(vk::SurfaceKHR new_surface) {
|
void Swapchain::Create(vk::SurfaceKHR new_surface) {
|
||||||
is_outdated = false;
|
vk::Device device = instance.GetDevice();
|
||||||
is_suboptimal = false;
|
device.waitIdle();
|
||||||
|
Destroy();
|
||||||
|
|
||||||
if (new_surface) {
|
if (new_surface) {
|
||||||
instance.GetInstance().destroySurfaceKHR(surface);
|
instance.GetInstance().destroySurfaceKHR(surface);
|
||||||
surface = new_surface;
|
surface = new_surface;
|
||||||
@ -79,10 +81,6 @@ void Swapchain::Create(vk::SurfaceKHR new_surface) {
|
|||||||
.oldSwapchain = nullptr,
|
.oldSwapchain = nullptr,
|
||||||
};
|
};
|
||||||
|
|
||||||
vk::Device device = instance.GetDevice();
|
|
||||||
device.waitIdle();
|
|
||||||
Destroy();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
swapchain = device.createSwapchainKHR(swapchain_info);
|
swapchain = device.createSwapchainKHR(swapchain_info);
|
||||||
} catch (vk::SystemError& err) {
|
} catch (vk::SystemError& err) {
|
||||||
@ -93,6 +91,9 @@ void Swapchain::Create(vk::SurfaceKHR new_surface) {
|
|||||||
SetupImages();
|
SetupImages();
|
||||||
resource_ticks.clear();
|
resource_ticks.clear();
|
||||||
resource_ticks.resize(image_count);
|
resource_ticks.resize(image_count);
|
||||||
|
|
||||||
|
is_outdated = false;
|
||||||
|
is_suboptimal = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MICROPROFILE_DEFINE(Vulkan_Acquire, "Vulkan", "Swapchain Acquire", MP_RGB(185, 66, 245));
|
MICROPROFILE_DEFINE(Vulkan_Acquire, "Vulkan", "Swapchain Acquire", MP_RGB(185, 66, 245));
|
||||||
|
@ -625,12 +625,18 @@ bool TextureRuntime::CopyTextures(Surface& source, Surface& dest,
|
|||||||
.extent = {copy.extent.width, copy.extent.height, 1},
|
.extent = {copy.extent.width, copy.extent.height, 1},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const bool self_copy = params.src_image == params.dst_image;
|
||||||
|
const vk::ImageLayout new_src_layout =
|
||||||
|
self_copy ? vk::ImageLayout::eGeneral : vk::ImageLayout::eTransferSrcOptimal;
|
||||||
|
const vk::ImageLayout new_dst_layout =
|
||||||
|
self_copy ? vk::ImageLayout::eGeneral : vk::ImageLayout::eTransferDstOptimal;
|
||||||
|
|
||||||
const std::array pre_barriers = {
|
const std::array pre_barriers = {
|
||||||
vk::ImageMemoryBarrier{
|
vk::ImageMemoryBarrier{
|
||||||
.srcAccessMask = params.src_access,
|
.srcAccessMask = params.src_access,
|
||||||
.dstAccessMask = vk::AccessFlagBits::eTransferRead,
|
.dstAccessMask = vk::AccessFlagBits::eTransferRead,
|
||||||
.oldLayout = vk::ImageLayout::eGeneral,
|
.oldLayout = vk::ImageLayout::eGeneral,
|
||||||
.newLayout = vk::ImageLayout::eTransferSrcOptimal,
|
.newLayout = new_src_layout,
|
||||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
.image = params.src_image,
|
.image = params.src_image,
|
||||||
@ -646,7 +652,7 @@ bool TextureRuntime::CopyTextures(Surface& source, Surface& dest,
|
|||||||
.srcAccessMask = params.dst_access,
|
.srcAccessMask = params.dst_access,
|
||||||
.dstAccessMask = vk::AccessFlagBits::eTransferWrite,
|
.dstAccessMask = vk::AccessFlagBits::eTransferWrite,
|
||||||
.oldLayout = vk::ImageLayout::eGeneral,
|
.oldLayout = vk::ImageLayout::eGeneral,
|
||||||
.newLayout = vk::ImageLayout::eTransferDstOptimal,
|
.newLayout = new_dst_layout,
|
||||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
.image = params.dst_image,
|
.image = params.dst_image,
|
||||||
@ -663,7 +669,7 @@ bool TextureRuntime::CopyTextures(Surface& source, Surface& dest,
|
|||||||
vk::ImageMemoryBarrier{
|
vk::ImageMemoryBarrier{
|
||||||
.srcAccessMask = vk::AccessFlagBits::eNone,
|
.srcAccessMask = vk::AccessFlagBits::eNone,
|
||||||
.dstAccessMask = vk::AccessFlagBits::eNone,
|
.dstAccessMask = vk::AccessFlagBits::eNone,
|
||||||
.oldLayout = vk::ImageLayout::eTransferSrcOptimal,
|
.oldLayout = new_src_layout,
|
||||||
.newLayout = vk::ImageLayout::eGeneral,
|
.newLayout = vk::ImageLayout::eGeneral,
|
||||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
@ -679,7 +685,7 @@ bool TextureRuntime::CopyTextures(Surface& source, Surface& dest,
|
|||||||
vk::ImageMemoryBarrier{
|
vk::ImageMemoryBarrier{
|
||||||
.srcAccessMask = vk::AccessFlagBits::eTransferWrite,
|
.srcAccessMask = vk::AccessFlagBits::eTransferWrite,
|
||||||
.dstAccessMask = params.dst_access,
|
.dstAccessMask = params.dst_access,
|
||||||
.oldLayout = vk::ImageLayout::eTransferDstOptimal,
|
.oldLayout = new_dst_layout,
|
||||||
.newLayout = vk::ImageLayout::eGeneral,
|
.newLayout = vk::ImageLayout::eGeneral,
|
||||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
@ -697,8 +703,8 @@ bool TextureRuntime::CopyTextures(Surface& source, Surface& dest,
|
|||||||
cmdbuf.pipelineBarrier(params.pipeline_flags, vk::PipelineStageFlagBits::eTransfer,
|
cmdbuf.pipelineBarrier(params.pipeline_flags, vk::PipelineStageFlagBits::eTransfer,
|
||||||
vk::DependencyFlagBits::eByRegion, {}, {}, pre_barriers);
|
vk::DependencyFlagBits::eByRegion, {}, {}, pre_barriers);
|
||||||
|
|
||||||
cmdbuf.copyImage(params.src_image, vk::ImageLayout::eTransferSrcOptimal, params.dst_image,
|
cmdbuf.copyImage(params.src_image, new_src_layout, params.dst_image, new_dst_layout,
|
||||||
vk::ImageLayout::eTransferDstOptimal, image_copy);
|
image_copy);
|
||||||
|
|
||||||
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, params.pipeline_flags,
|
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, params.pipeline_flags,
|
||||||
vk::DependencyFlagBits::eByRegion, {}, {}, post_barriers);
|
vk::DependencyFlagBits::eByRegion, {}, {}, post_barriers);
|
||||||
|
Reference in New Issue
Block a user