diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 78a3b75ab8..04ccc6e8e5 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -365,16 +365,21 @@ void GLGSRender::end() //If ds is not initialized clear it; it seems new depth textures should have depth cleared auto copy_rtt_contents = [](gl::render_target *surface) { - //Copy data from old contents onto this one - //1. Clip a rectangular region defning the data - //2. Perform a GPU blit - u16 parent_w = surface->old_contents->width(); - u16 parent_h = surface->old_contents->height(); - u16 copy_w, copy_h; + if (surface->get_compatible_internal_format() == surface->old_contents->get_compatible_internal_format()) + { + //Copy data from old contents onto this one + //1. Clip a rectangular region defning the data + //2. Perform a GPU blit + u16 parent_w = surface->old_contents->width(); + u16 parent_h = surface->old_contents->height(); + u16 copy_w, copy_h; + + std::tie(std::ignore, std::ignore, copy_w, copy_h) = rsx::clip_region(parent_w, parent_h, 0, 0, surface->width(), surface->height(), true); + glCopyImageSubData(surface->old_contents->id(), GL_TEXTURE_2D, 0, 0, 0, 0, surface->id(), GL_TEXTURE_2D, 0, 0, 0, 0, copy_w, copy_h, 1); + surface->set_cleared(); + } + //TODO: download image contents and reupload them or do a memory cast to copy memory contents if not compatible - std::tie(std::ignore, std::ignore, copy_w, copy_h) = rsx::clip_region(parent_w, parent_h, 0, 0, surface->width(), surface->height(), true); - glCopyImageSubData(surface->old_contents->id(), GL_TEXTURE_2D, 0, 0, 0, 0, surface->id(), GL_TEXTURE_2D, 0, 0, 0, 0, copy_w, copy_h, 1); - surface->set_cleared(); surface->old_contents = nullptr; }; diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 6324c51efd..91d33cb822 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -1012,31 +1012,36 @@ void VKGSRender::end() { auto copy_rtt_contents = [&](vk::render_target* surface) { - const VkImageAspectFlags aspect = surface->attachment_aspect_flag; + if (surface->info.format == surface->old_contents->info.format) + { + const VkImageAspectFlags aspect = surface->attachment_aspect_flag; - const u16 parent_w = surface->old_contents->width(); - const u16 parent_h = surface->old_contents->height(); - u16 copy_w, copy_h; + const u16 parent_w = surface->old_contents->width(); + const u16 parent_h = surface->old_contents->height(); + u16 copy_w, copy_h; - std::tie(std::ignore, std::ignore, copy_w, copy_h) = rsx::clip_region(parent_w, parent_h, 0, 0, surface->width(), surface->height(), true); + std::tie(std::ignore, std::ignore, copy_w, copy_h) = rsx::clip_region(parent_w, parent_h, 0, 0, surface->width(), surface->height(), true); - VkImageSubresourceRange subresource_range = { aspect, 0, 1, 0, 1 }; - VkImageLayout old_layout = surface->current_layout; + VkImageSubresourceRange subresource_range = { aspect, 0, 1, 0, 1 }; + VkImageLayout old_layout = surface->current_layout; - vk::change_image_layout(*m_current_command_buffer, surface, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, subresource_range); - vk::change_image_layout(*m_current_command_buffer, surface->old_contents, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, subresource_range); + vk::change_image_layout(*m_current_command_buffer, surface, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, subresource_range); + vk::change_image_layout(*m_current_command_buffer, surface->old_contents, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, subresource_range); - VkImageCopy copy_rgn; - copy_rgn.srcOffset = { 0, 0, 0 }; - copy_rgn.dstOffset = { 0, 0, 0 }; - copy_rgn.dstSubresource = { aspect, 0, 0, 1 }; - copy_rgn.srcSubresource = { aspect, 0, 0, 1 }; - copy_rgn.extent = { copy_w, copy_h, 1 }; + VkImageCopy copy_rgn; + copy_rgn.srcOffset = { 0, 0, 0 }; + copy_rgn.dstOffset = { 0, 0, 0 }; + copy_rgn.dstSubresource = { aspect, 0, 0, 1 }; + copy_rgn.srcSubresource = { aspect, 0, 0, 1 }; + copy_rgn.extent = { copy_w, copy_h, 1 }; - vkCmdCopyImage(*m_current_command_buffer, surface->old_contents->value, surface->old_contents->current_layout, surface->value, surface->current_layout, 1, ©_rgn); - vk::change_image_layout(*m_current_command_buffer, surface, old_layout, subresource_range); + vkCmdCopyImage(*m_current_command_buffer, surface->old_contents->value, surface->old_contents->current_layout, surface->value, surface->current_layout, 1, ©_rgn); + vk::change_image_layout(*m_current_command_buffer, surface, old_layout, subresource_range); + + surface->dirty = false; + } + //TODO: download image contents and reupload them or do a memory cast to copy memory contents if not compatible - surface->dirty = false; surface->old_contents = nullptr; };