diff --git a/rpcs3/Emu/RSX/GL/GLPresent.cpp b/rpcs3/Emu/RSX/GL/GLPresent.cpp index 629d467550..4c116b0545 100644 --- a/rpcs3/Emu/RSX/GL/GLPresent.cpp +++ b/rpcs3/Emu/RSX/GL/GLPresent.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "GLGSRender.h" +#include "Emu/Cell/Modules/cellVideoOut.h" LOG_CHANNEL(screenshot); @@ -76,7 +77,21 @@ gl::texture* GLGSRender::get_present_source(gl::present_surface_info* info, cons const auto range = utils::address_range::start_length(info->address, info->pitch * info->height); m_gl_texture_cache.invalidate_range(cmd, range, rsx::invalidation_cause::read); - m_flip_tex_color->copy_from(vm::base(info->address), gl::texture::format::bgra, gl::texture::type::uint_8_8_8_8, unpack_settings); + gl::texture::format fmt; + switch (avconfig->format) + { + default: + rsx_log.error("Unhandled video output format 0x%x", avconfig->format); + [[fallthrough]]; + case CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8R8G8B8: + fmt = gl::texture::format::bgra; + break; + case CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8B8G8R8: + fmt = gl::texture::format::rgba; + break; + } + + m_flip_tex_color->copy_from(vm::base(info->address), fmt, gl::texture::type::uint_8_8_8_8, unpack_settings); image = m_flip_tex_color.get(); } diff --git a/rpcs3/Emu/RSX/VK/VKFormats.cpp b/rpcs3/Emu/RSX/VK/VKFormats.cpp index 6912e0f308..b543945d03 100644 --- a/rpcs3/Emu/RSX/VK/VKFormats.cpp +++ b/rpcs3/Emu/RSX/VK/VKFormats.cpp @@ -38,6 +38,7 @@ namespace vk rsx_log.error("Your GPU and/or driver does not support RGBA8 format. This can cause problems in some rare games that use this memory layout."); } + result.argb8_linear = !!(props.linearTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT); return result; } diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index c1902e46af..66560503c3 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -269,6 +269,7 @@ namespace vk bool d24_unorm_s8; bool d32_sfloat_s8; bool bgra8_linear; + bool argb8_linear; }; struct gpu_shader_types_support diff --git a/rpcs3/Emu/RSX/VK/VKPresent.cpp b/rpcs3/Emu/RSX/VK/VKPresent.cpp index 6e0aafe302..8d8d3f79ac 100644 --- a/rpcs3/Emu/RSX/VK/VKPresent.cpp +++ b/rpcs3/Emu/RSX/VK/VKPresent.cpp @@ -1,6 +1,6 @@ #include "stdafx.h" #include "VKGSRender.h" - +#include "Emu/Cell/Modules/cellVideoOut.h" void VKGSRender::reinitialize_swapchain() { @@ -347,8 +347,22 @@ vk::image* VKGSRender::get_present_source(vk::present_surface_info* info, const flush_command_queue(); } + VkFormat format; + switch (avconfig->format) + { + default: + rsx_log.error("Unhandled video output format 0x%x", avconfig->format); + [[fallthrough]]; + case CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8R8G8B8: + format = VK_FORMAT_B8G8R8A8_UNORM; + break; + case CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8B8G8R8: + format = VK_FORMAT_R8G8B8A8_UNORM; + break; + } + m_texture_cache.invalidate_range(*m_current_command_buffer, range, rsx::invalidation_cause::read); - image_to_flip = m_texture_cache.upload_image_simple(*m_current_command_buffer, info->address, info->width, info->height, info->pitch); + image_to_flip = m_texture_cache.upload_image_simple(*m_current_command_buffer, format, info->address, info->width, info->height, info->pitch); } return image_to_flip; diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 805071f91f..175ed89566 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -1471,9 +1471,24 @@ namespace vk baseclass::on_frame_end(); } - vk::image *upload_image_simple(vk::command_buffer& cmd, u32 address, u32 width, u32 height, u32 pitch) + vk::image *upload_image_simple(vk::command_buffer& cmd, VkFormat format, u32 address, u32 width, u32 height, u32 pitch) { - if (!m_formats_support.bgra8_linear) + bool linear_format_supported = false; + + switch (format) + { + case VK_FORMAT_B8G8R8A8_UNORM: + linear_format_supported = m_formats_support.bgra8_linear; + break; + case VK_FORMAT_R8G8B8A8_UNORM: + linear_format_supported = m_formats_support.argb8_linear; + break; + default: + rsx_log.error("Unsupported VkFormat 0x%x" HERE, static_cast(format)); + return nullptr; + } + + if (!linear_format_supported) { return nullptr; } @@ -1482,7 +1497,7 @@ namespace vk auto image = std::make_unique(*m_device, m_memory_types.host_visible_coherent, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_IMAGE_TYPE_2D, - VK_FORMAT_B8G8R8A8_UNORM, + format, width, height, 1, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED, VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, 0);