diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 38469d27b4..9bf1a62adc 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -1586,14 +1586,22 @@ void GLGSRender::flip(int buffer, bool emu_flip) u32 buffer_height = display_buffers[buffer].height; u32 buffer_pitch = display_buffers[buffer].pitch; - if (!buffer_pitch) buffer_pitch = buffer_width * 4; + u32 av_format; + const auto avconfig = fxm::get(); - auto avconfig = fxm::get(); if (avconfig) { + av_format = avconfig->get_compatible_gcm_format(); + if (!buffer_pitch) buffer_pitch = buffer_width * avconfig->get_bpp(); + buffer_width = std::min(buffer_width, avconfig->resolution_x); buffer_height = std::min(buffer_height, avconfig->resolution_y); } + else + { + av_format = CELL_GCM_TEXTURE_A8R8G8B8; + if (!buffer_pitch) buffer_pitch = buffer_width * 4; + } // Disable scissor test (affects blit, clear, etc) gl_state.enable(GL_FALSE, GL_SCISSOR_TEST); @@ -1673,7 +1681,7 @@ void GLGSRender::flip(int buffer, bool emu_flip) } } } - else if (auto surface = m_gl_texture_cache.find_texture_from_dimensions(absolute_address, buffer_width, buffer_height)) + else if (auto surface = m_gl_texture_cache.find_texture_from_dimensions(absolute_address, av_format, buffer_width, buffer_height)) { //Hack - this should be the first location to check for output //The render might have been done offscreen or in software and a blit used to display diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 170619c7ed..a81e7752a2 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -3294,14 +3294,22 @@ void VKGSRender::flip(int buffer, bool emu_flip) u32 buffer_height = display_buffers[buffer].height; u32 buffer_pitch = display_buffers[buffer].pitch; - if (!buffer_pitch) buffer_pitch = buffer_width * 4; // TODO: Check avconf + u32 av_format; + const auto avconfig = fxm::get(); - auto avconfig = fxm::get(); if (avconfig) { + av_format = avconfig->get_compatible_gcm_format(); + if (!buffer_pitch) buffer_pitch = buffer_width * avconfig->get_bpp(); + buffer_width = std::min(buffer_width, avconfig->resolution_x); buffer_height = std::min(buffer_height, avconfig->resolution_y); } + else + { + av_format = CELL_GCM_TEXTURE_A8R8G8B8; + if (!buffer_pitch) buffer_pitch = buffer_width * 4; + } coordi aspect_ratio; @@ -3419,7 +3427,7 @@ void VKGSRender::flip(int buffer, bool emu_flip) } } } - else if (auto surface = m_texture_cache.find_texture_from_dimensions(absolute_address, buffer_width, buffer_height)) + else if (auto surface = m_texture_cache.find_texture_from_dimensions(absolute_address, av_format, buffer_width, buffer_height)) { //Hack - this should be the first location to check for output //The render might have been done offscreen or in software and a blit used to display diff --git a/rpcs3/Emu/RSX/rsx_utils.h b/rpcs3/Emu/RSX/rsx_utils.h index e7f774948e..b1a0ba6e27 100644 --- a/rpcs3/Emu/RSX/rsx_utils.h +++ b/rpcs3/Emu/RSX/rsx_utils.h @@ -94,6 +94,34 @@ namespace rsx f32 gamma = 1.f; // NO GAMMA CORRECTION u32 resolution_x = 1280; // X RES u32 resolution_y = 720; // Y RES + + u32 get_compatible_gcm_format() + { + switch (format) + { + default: + LOG_ERROR(RSX, "Invalid AV format 0x%x", format); + case 0: // CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8R8G8B8: + case 1: // CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8B8G8R8: + return CELL_GCM_TEXTURE_A8R8G8B8; + case 2: // CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_R16G16B16X16_FLOAT: + return CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT; + } + } + + u8 get_bpp() + { + switch (format) + { + default: + LOG_ERROR(RSX, "Invalid AV format 0x%x", format); + case 0: // CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8R8G8B8: + case 1: // CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8B8G8R8: + return 4; + case 2: // CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_R16G16B16X16_FLOAT: + return 8; + } + } }; struct blit_src_info