From fd2607ad52cc81ce7322ac65cd5ff70fb69232e7 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Tue, 11 Aug 2020 20:35:50 +0300 Subject: [PATCH] rsx: Fix XBGR vs XRGB screenshots --- rpcs3/Emu/RSX/GL/GLPresent.cpp | 6 +++--- rpcs3/Emu/RSX/GSRender.h | 2 +- rpcs3/Emu/RSX/VK/VKPresent.cpp | 3 ++- rpcs3/rpcs3qt/gs_frame.cpp | 18 ++++++++++++++---- rpcs3/rpcs3qt/gs_frame.h | 2 +- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLPresent.cpp b/rpcs3/Emu/RSX/GL/GLPresent.cpp index 4c116b0545..99c7c5d25f 100644 --- a/rpcs3/Emu/RSX/GL/GLPresent.cpp +++ b/rpcs3/Emu/RSX/GL/GLPresent.cpp @@ -220,14 +220,14 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) pack_settings.apply(); if (gl::get_driver_caps().ARB_dsa_supported) - glGetTextureImage(image_to_flip, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer_height * buffer_width * 4, sshot_frame.data()); + glGetTextureImage(image_to_flip, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer_height * buffer_width * 4, sshot_frame.data()); else - glGetTextureImageEXT(image_to_flip, GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, sshot_frame.data()); + glGetTextureImageEXT(image_to_flip, GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, sshot_frame.data()); if (GLenum err; (err = glGetError()) != GL_NO_ERROR) screenshot.error("Failed to capture image: 0x%x", err); else - m_frame->take_screenshot(std::move(sshot_frame), buffer_width, buffer_height); + m_frame->take_screenshot(std::move(sshot_frame), buffer_width, buffer_height, false); } const areai screen_area = coordi({}, { static_cast(buffer_width), static_cast(buffer_height) }); diff --git a/rpcs3/Emu/RSX/GSRender.h b/rpcs3/Emu/RSX/GSRender.h index 00ae59bde8..c99a2bbbff 100644 --- a/rpcs3/Emu/RSX/GSRender.h +++ b/rpcs3/Emu/RSX/GSRender.h @@ -90,7 +90,7 @@ public: virtual display_handle_t handle() const = 0; std::atomic screenshot_toggle = false; - virtual void take_screenshot(const std::vector sshot_data, const u32 sshot_width, const u32 sshot_height) = 0; + virtual void take_screenshot(const std::vector sshot_data, const u32 sshot_width, const u32 sshot_height, bool is_bgra) = 0; }; class GSRender : public rsx::thread diff --git a/rpcs3/Emu/RSX/VK/VKPresent.cpp b/rpcs3/Emu/RSX/VK/VKPresent.cpp index 8d8d3f79ac..2dd874f27e 100644 --- a/rpcs3/Emu/RSX/VK/VKPresent.cpp +++ b/rpcs3/Emu/RSX/VK/VKPresent.cpp @@ -659,7 +659,8 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info) memcpy(sshot_frame.data(), src, sshot_size); sshot_vkbuf.unmap(); - m_frame->take_screenshot(std::move(sshot_frame), buffer_width, buffer_height); + const bool is_bgra = image_to_flip->format() == VK_FORMAT_B8G8R8A8_UNORM; + m_frame->take_screenshot(std::move(sshot_frame), buffer_width, buffer_height, is_bgra); } } diff --git a/rpcs3/rpcs3qt/gs_frame.cpp b/rpcs3/rpcs3qt/gs_frame.cpp index dfad64572b..abf8336656 100644 --- a/rpcs3/rpcs3qt/gs_frame.cpp +++ b/rpcs3/rpcs3qt/gs_frame.cpp @@ -335,10 +335,10 @@ void gs_frame::flip(draw_context_t, bool /*skip_frame*/) } } -void gs_frame::take_screenshot(const std::vector sshot_data, const u32 sshot_width, const u32 sshot_height) +void gs_frame::take_screenshot(const std::vector sshot_data, const u32 sshot_width, const u32 sshot_height, bool is_bgra) { std::thread( - [sshot_width, sshot_height](const std::vector sshot_data) + [sshot_width, sshot_height, is_bgra](const std::vector sshot_data) { std::string screen_path = fs::get_config_dir() + "screenshots/"; @@ -361,9 +361,19 @@ void gs_frame::take_screenshot(const std::vector sshot_data, const u32 sshot const u32* sshot_ptr = reinterpret_cast(sshot_data.data()); u32* alpha_ptr = reinterpret_cast(sshot_data_alpha.data()); - for (size_t index = 0; index < sshot_data.size() / sizeof(u32); index++) + if (is_bgra) [[likely]] { - alpha_ptr[index] = ((sshot_ptr[index] & 0xFF) << 16) | (sshot_ptr[index] & 0xFF00) | ((sshot_ptr[index] & 0xFF0000) >> 16) | 0xFF000000; + for (size_t index = 0; index < sshot_data.size() / sizeof(u32); index++) + { + alpha_ptr[index] = ((sshot_ptr[index] & 0xFF) << 16) | (sshot_ptr[index] & 0xFF00) | ((sshot_ptr[index] & 0xFF0000) >> 16) | 0xFF000000; + } + } + else + { + for (size_t index = 0; index < sshot_data.size() / sizeof(u32); index++) + { + alpha_ptr[index] = sshot_ptr[index] | 0xFF000000; + } } std::vector encoded_png; diff --git a/rpcs3/rpcs3qt/gs_frame.h b/rpcs3/rpcs3qt/gs_frame.h index ca3e7366bf..becd0b8a5b 100644 --- a/rpcs3/rpcs3qt/gs_frame.h +++ b/rpcs3/rpcs3qt/gs_frame.h @@ -50,7 +50,7 @@ public: void progress_increment(int delta); void progress_set_limit(int limit); - void take_screenshot(const std::vector sshot_data, const u32 sshot_width, const u32 sshot_height) override; + void take_screenshot(const std::vector sshot_data, const u32 sshot_width, const u32 sshot_height, bool is_bgra) override; protected: virtual void paintEvent(QPaintEvent *event);