From f613901eac2960393a894ffb1cf2b8a05efca7e8 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Wed, 26 Jul 2017 21:18:04 +0300 Subject: [PATCH] gl/vk: Do not trust gcm buffer size to match internal rendering resolution - Should fix games with strange scaling artifacts due to upscaling from lower resolutions --- rpcs3/Emu/RSX/GL/GLGSRender.cpp | 76 +++++++++++++++++---------------- rpcs3/Emu/RSX/VK/VKGSRender.cpp | 10 ++--- 2 files changed, 44 insertions(+), 42 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 58efe16bd5..eba37298e8 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -989,25 +989,48 @@ void GLGSRender::flip(int buffer) u32 buffer_height = gcm_buffers[buffer].height; u32 buffer_pitch = gcm_buffers[buffer].pitch; - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_STENCIL_TEST); + // Calculate blit coordinates + coordi aspect_ratio; + areai screen_area = coordi({}, { (int)buffer_width, (int)buffer_height }); + sizei csize(m_frame->client_width(), m_frame->client_height()); + sizei new_size = csize; + if (!g_cfg.video.stretch_to_display_area) + { + const double aq = (double)buffer_width / buffer_height; + const double rq = (double)new_size.width / new_size.height; + const double q = aq / rq; + + if (q > 1.0) + { + new_size.height = int(new_size.height / q); + aspect_ratio.y = (csize.height - new_size.height) / 2; + } + else if (q < 1.0) + { + new_size.width = int(new_size.width * q); + aspect_ratio.x = (csize.width - new_size.width) / 2; + } + } + + aspect_ratio.size = new_size; + + // Find the source image rsx::tiled_region buffer_region = get_tiled_address(gcm_buffers[buffer].offset, CELL_GCM_LOCATION_LOCAL); u32 absolute_address = buffer_region.address + buffer_region.base; - gl::texture *render_target_texture = m_rtts.get_texture_from_render_target_if_applicable(absolute_address); - __glcheck m_flip_fbo.recreate(); + m_flip_fbo.recreate(); m_flip_fbo.bind(); - auto *flip_fbo = &m_flip_fbo; - if (render_target_texture) { + buffer_width = render_target_texture->width(); + buffer_height = render_target_texture->height(); + __glcheck m_flip_fbo.color = *render_target_texture; __glcheck m_flip_fbo.read_buffer(m_flip_fbo.color); + } else { @@ -1040,36 +1063,14 @@ void GLGSRender::flip(int buffer) __glcheck m_flip_fbo.read_buffer(m_flip_fbo.color); } - areai screen_area = coordi({}, { (int)buffer_width, (int)buffer_height }); - - coordi aspect_ratio; - - sizei csize(m_frame->client_width(), m_frame->client_height()); - sizei new_size = csize; - - if (!g_cfg.video.stretch_to_display_area) - { - const double aq = (double)buffer_width / buffer_height; - const double rq = (double)new_size.width / new_size.height; - const double q = aq / rq; - - if (q > 1.0) - { - new_size.height = int(new_size.height / q); - aspect_ratio.y = (csize.height - new_size.height) / 2; - } - else if (q < 1.0) - { - new_size.width = int(new_size.width * q); - aspect_ratio.x = (csize.width - new_size.width) / 2; - } - } - - aspect_ratio.size = new_size; + // Blit source image to the screen + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glDisable(GL_SCISSOR_TEST); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); gl::screen.clear(gl::buffers::color_depth_stencil); - - __glcheck flip_fbo->blit(gl::screen, screen_area, areai(aspect_ratio).flipped_vertical(), gl::buffers::color, gl::filter::linear); + __glcheck m_flip_fbo.blit(gl::screen, screen_area, areai(aspect_ratio).flipped_vertical(), gl::buffers::color, gl::filter::linear); if (g_cfg.video.overlay) { @@ -1086,6 +1087,7 @@ void GLGSRender::flip(int buffer) m_frame->flip(m_context); rsx::thread::flip(buffer); + // Cleanup m_gl_texture_cache.clear_temporary_surfaces(); for (auto &tex : m_rtts.invalidated_resources) @@ -1098,7 +1100,7 @@ void GLGSRender::flip(int buffer) m_vertex_cache->purge(); - //If we are skipping the next frame, fo not reset perf counters + //If we are skipping the next frame, do not reset perf counters if (skip_frame) return; m_draw_calls = 0; diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 2f7c7fcfba..9ab4898c31 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -2178,18 +2178,18 @@ void VKGSRender::flip(int buffer) CHECK_RESULT(vkAcquireNextImageKHR((*m_device), (*m_swap_chain), 0, m_present_semaphore, VK_NULL_HANDLE, &m_current_present_image)); //Blit contents to screen.. - VkImage image_to_flip = nullptr; + vk::image* image_to_flip = nullptr; if (std::get<1>(m_rtts.m_bound_render_targets[0]) != nullptr) - image_to_flip = std::get<1>(m_rtts.m_bound_render_targets[0])->value; + image_to_flip = std::get<1>(m_rtts.m_bound_render_targets[0]); else if (std::get<1>(m_rtts.m_bound_render_targets[1]) != nullptr) - image_to_flip = std::get<1>(m_rtts.m_bound_render_targets[1])->value; + image_to_flip = std::get<1>(m_rtts.m_bound_render_targets[1]); VkImage target_image = m_swap_chain->get_swap_chain_image(m_current_present_image); if (image_to_flip) { - vk::copy_scaled_image(*m_current_command_buffer, image_to_flip, target_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - 0, 0, buffer_width, buffer_height, aspect_ratio.x, aspect_ratio.y, aspect_ratio.width, aspect_ratio.height, 1, VK_IMAGE_ASPECT_COLOR_BIT); + vk::copy_scaled_image(*m_current_command_buffer, image_to_flip->value, target_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + 0, 0, image_to_flip->width(), image_to_flip->height(), aspect_ratio.x, aspect_ratio.y, aspect_ratio.width, aspect_ratio.height, 1, VK_IMAGE_ASPECT_COLOR_BIT); } else {