diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index a7f4ac1b2d..79e0f349bd 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -568,6 +568,11 @@ void GLGSRender::clear_surface(u32 arg) if (auto colormask = (arg & 0xf0)) { + u8 clear_a = rsx::method_registers.clear_color_a(); + u8 clear_r = rsx::method_registers.clear_color_r(); + u8 clear_g = rsx::method_registers.clear_color_g(); + u8 clear_b = rsx::method_registers.clear_color_b(); + switch (rsx::method_registers.surface_color()) { case rsx::surface_color_format::x32: @@ -579,16 +584,22 @@ void GLGSRender::clear_surface(u32 arg) } case rsx::surface_color_format::g8b8: { + rsx::get_g8b8_clear_color(clear_r, clear_g, clear_b, clear_a); colormask = rsx::get_g8b8_r8g8_colormask(colormask); - [[fallthrough]]; + break; } - default: + case rsx::surface_color_format::a8b8g8r8: + case rsx::surface_color_format::x8b8g8r8_o8b8g8r8: + case rsx::surface_color_format::x8b8g8r8_z8b8g8r8: { - u8 clear_a = rsx::method_registers.clear_color_a(); - u8 clear_r = rsx::method_registers.clear_color_r(); - u8 clear_g = rsx::method_registers.clear_color_g(); - u8 clear_b = rsx::method_registers.clear_color_b(); + rsx::get_abgr8_clear_color(clear_r, clear_g, clear_b, clear_a); + colormask = rsx::get_abgr8_colormask(colormask); + break; + } + } + if (colormask) + { gl_state.clear_color(clear_r, clear_g, clear_b, clear_a); mask |= GLenum(gl::buffers::color); @@ -601,8 +612,6 @@ void GLGSRender::clear_surface(u32 arg) } update_color = true; - break; - } } } diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index ca4e84fc7c..f78ece4875 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -1130,33 +1130,45 @@ void VKGSRender::clear_surface(u32 mask) if (!m_draw_buffers.empty()) { bool use_fast_clear = false; - bool ignore_clear = false; + u8 clear_a = rsx::method_registers.clear_color_a(); + u8 clear_r = rsx::method_registers.clear_color_r(); + u8 clear_g = rsx::method_registers.clear_color_g(); + u8 clear_b = rsx::method_registers.clear_color_b(); + switch (rsx::method_registers.surface_color()) { case rsx::surface_color_format::x32: case rsx::surface_color_format::w16z16y16x16: case rsx::surface_color_format::w32z32y32x32: + { //NOP - ignore_clear = true; + colormask = 0; break; + } case rsx::surface_color_format::g8b8: + { + rsx::get_g8b8_clear_color(clear_r, clear_g, clear_b, clear_a); colormask = rsx::get_g8b8_r8g8_colormask(colormask); use_fast_clear = (colormask == (0x10 | 0x20)); - ignore_clear = (colormask == 0); - colormask |= (0x40 | 0x80); break; + } + case rsx::surface_color_format::a8b8g8r8: + case rsx::surface_color_format::x8b8g8r8_o8b8g8r8: + case rsx::surface_color_format::x8b8g8r8_z8b8g8r8: + { + rsx::get_abgr8_clear_color(clear_r, clear_g, clear_b, clear_a); + colormask = rsx::get_abgr8_colormask(colormask); + break; + } default: + { use_fast_clear = (colormask == (0x10 | 0x20 | 0x40 | 0x80)); break; } + } - if (!ignore_clear) + if (colormask) { - u8 clear_a = rsx::method_registers.clear_color_a(); - u8 clear_r = rsx::method_registers.clear_color_r(); - u8 clear_g = rsx::method_registers.clear_color_g(); - u8 clear_b = rsx::method_registers.clear_color_b(); - color_clear_values.color.float32[0] = static_cast(clear_r) / 255; color_clear_values.color.float32[1] = static_cast(clear_g) / 255; color_clear_values.color.float32[2] = static_cast(clear_b) / 255; diff --git a/rpcs3/Emu/RSX/rsx_utils.h b/rpcs3/Emu/RSX/rsx_utils.h index c3c8bea18f..6ee52250c0 100644 --- a/rpcs3/Emu/RSX/rsx_utils.h +++ b/rpcs3/Emu/RSX/rsx_utils.h @@ -737,14 +737,38 @@ namespace rsx return result; } - static inline void get_g8b8_r8g8_colormask(bool &red, bool &green, bool &blue, bool &alpha) + static inline void get_g8b8_r8g8_colormask(bool &red, bool &/*green*/, bool &blue, bool &alpha) { red = blue; - green = green; blue = false; alpha = false; } + static inline void get_g8b8_clear_color(u8& red, u8& /*green*/, u8& blue, u8& /*alpha*/) + { + red = blue; + } + + static inline u32 get_abgr8_colormask(u32 mask) + { + u32 result = 0; + if (mask & 0x10) result |= 0x40; + if (mask & 0x20) result |= 0x20; + if (mask & 0x40) result |= 0x10; + if (mask & 0x80) result |= 0x80; + return result; + } + + static inline void get_abgr8_colormask(bool& red, bool& /*green*/, bool& blue, bool& /*alpha*/) + { + std::swap(red, blue); + } + + static inline void get_abgr8_clear_color(u8& red, u8& /*green*/, u8& blue, u8& /*alpha*/) + { + std::swap(red, blue); + } + static inline color4f decode_border_color(u32 colorref) { color4f result;