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
This commit is contained in:
kd-11 2017-07-26 21:18:04 +03:00
parent 4cd5624fa7
commit f613901eac
2 changed files with 44 additions and 42 deletions

View File

@ -989,25 +989,48 @@ void GLGSRender::flip(int buffer)
u32 buffer_height = gcm_buffers[buffer].height; u32 buffer_height = gcm_buffers[buffer].height;
u32 buffer_pitch = gcm_buffers[buffer].pitch; u32 buffer_pitch = gcm_buffers[buffer].pitch;
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Calculate blit coordinates
glDisable(GL_SCISSOR_TEST); coordi aspect_ratio;
glDisable(GL_DEPTH_TEST); areai screen_area = coordi({}, { (int)buffer_width, (int)buffer_height });
glDisable(GL_STENCIL_TEST); 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); 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; 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); 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(); m_flip_fbo.bind();
auto *flip_fbo = &m_flip_fbo;
if (render_target_texture) 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.color = *render_target_texture;
__glcheck m_flip_fbo.read_buffer(m_flip_fbo.color); __glcheck m_flip_fbo.read_buffer(m_flip_fbo.color);
} }
else else
{ {
@ -1040,36 +1063,14 @@ void GLGSRender::flip(int buffer)
__glcheck m_flip_fbo.read_buffer(m_flip_fbo.color); __glcheck m_flip_fbo.read_buffer(m_flip_fbo.color);
} }
areai screen_area = coordi({}, { (int)buffer_width, (int)buffer_height }); // Blit source image to the screen
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
coordi aspect_ratio; glDisable(GL_SCISSOR_TEST);
glDisable(GL_DEPTH_TEST);
sizei csize(m_frame->client_width(), m_frame->client_height()); glDisable(GL_STENCIL_TEST);
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;
gl::screen.clear(gl::buffers::color_depth_stencil); gl::screen.clear(gl::buffers::color_depth_stencil);
__glcheck m_flip_fbo.blit(gl::screen, screen_area, areai(aspect_ratio).flipped_vertical(), gl::buffers::color, gl::filter::linear);
__glcheck flip_fbo->blit(gl::screen, screen_area, areai(aspect_ratio).flipped_vertical(), gl::buffers::color, gl::filter::linear);
if (g_cfg.video.overlay) if (g_cfg.video.overlay)
{ {
@ -1086,6 +1087,7 @@ void GLGSRender::flip(int buffer)
m_frame->flip(m_context); m_frame->flip(m_context);
rsx::thread::flip(buffer); rsx::thread::flip(buffer);
// Cleanup
m_gl_texture_cache.clear_temporary_surfaces(); m_gl_texture_cache.clear_temporary_surfaces();
for (auto &tex : m_rtts.invalidated_resources) for (auto &tex : m_rtts.invalidated_resources)
@ -1098,7 +1100,7 @@ void GLGSRender::flip(int buffer)
m_vertex_cache->purge(); 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; if (skip_frame) return;
m_draw_calls = 0; m_draw_calls = 0;

View File

@ -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)); CHECK_RESULT(vkAcquireNextImageKHR((*m_device), (*m_swap_chain), 0, m_present_semaphore, VK_NULL_HANDLE, &m_current_present_image));
//Blit contents to screen.. //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) 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) 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); VkImage target_image = m_swap_chain->get_swap_chain_image(m_current_present_image);
if (image_to_flip) 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, 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, buffer_width, buffer_height, aspect_ratio.x, aspect_ratio.y, aspect_ratio.width, aspect_ratio.height, 1, VK_IMAGE_ASPECT_COLOR_BIT); 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 else
{ {