diff --git a/rpcs3/Emu/RSX/GL/GLDraw.cpp b/rpcs3/Emu/RSX/GL/GLDraw.cpp index 3a8e47f4a7..fce7c2a650 100644 --- a/rpcs3/Emu/RSX/GL/GLDraw.cpp +++ b/rpcs3/Emu/RSX/GL/GLDraw.cpp @@ -188,6 +188,7 @@ void GLGSRender::update_draw_state() if (m_rtts.get_color_surface_count()) { // Color buffer is active + const auto host_write_mask = rsx::get_write_output_mask(rsx::method_registers.surface_color()); for (int index = 0; index < m_rtts.get_color_surface_count(); ++index) { bool color_mask_b = rsx::method_registers.color_mask_b(index); @@ -207,7 +208,12 @@ void GLGSRender::update_draw_state() break; } - gl_state.color_maski(index, color_mask_r, color_mask_g, color_mask_b, color_mask_a); + gl_state.color_maski( + index, + color_mask_r && host_write_mask[0], + color_mask_g && host_write_mask[1], + color_mask_b && host_write_mask[2], + color_mask_a && host_write_mask[3]); } // LogicOp and Blend are mutually exclusive. If both are enabled, LogicOp takes precedence. diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 824ce6d666..70edf8175d 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -265,8 +265,11 @@ namespace vk } if (rsx::method_registers.cull_face_enabled()) + { properties.state.enable_cull_face(vk::get_cull_face(rsx::method_registers.cull_face_mode())); + } + const auto host_write_mask = rsx::get_write_output_mask(rsx::method_registers.surface_color()); for (uint index = 0; index < num_draw_buffers; ++index) { bool color_mask_b = rsx::method_registers.color_mask_b(index); @@ -286,7 +289,12 @@ namespace vk break; } - properties.state.set_color_mask(index, color_mask_r, color_mask_g, color_mask_b, color_mask_a); + properties.state.set_color_mask( + index, + color_mask_r && host_write_mask[0], + color_mask_g && host_write_mask[1], + color_mask_b && host_write_mask[2], + color_mask_a && host_write_mask[3]); } // LogicOp and Blend are mutually exclusive. If both are enabled, LogicOp takes precedence. @@ -1482,7 +1490,10 @@ void VKGSRender::clear_surface(u32 mask) if (mask & RSX_GCM_CLEAR_DEPTH_STENCIL_MASK) ctx |= rsx::framebuffer_creation_context::context_clear_depth; init_buffers(rsx::framebuffer_creation_context{ctx}); - if (!m_graphics_state.test(rsx::rtt_config_valid)) return; + if (!m_graphics_state.test(rsx::rtt_config_valid)) + { + return; + } //float depth_clear = 1.f; u32 stencil_clear = 0; diff --git a/rpcs3/Emu/RSX/rsx_utils.h b/rpcs3/Emu/RSX/rsx_utils.h index 1bfbadc742..c38eb7d8ed 100644 --- a/rpcs3/Emu/RSX/rsx_utils.h +++ b/rpcs3/Emu/RSX/rsx_utils.h @@ -870,6 +870,38 @@ namespace rsx return result; } + static inline const std::array get_write_output_mask(rsx::surface_color_format format) + { + const std::array rgba = { true, true, true, true }; + const std::array rgb = { true, true, true, false }; + const std::array rg = { true, true, false, false }; + const std::array r = { true, false, false, false }; + + switch (format) + { + case rsx::surface_color_format::a8r8g8b8: + case rsx::surface_color_format::a8b8g8r8: + case rsx::surface_color_format::w16z16y16x16: + case rsx::surface_color_format::w32z32y32x32: + return rgba; + case rsx::surface_color_format::x1r5g5b5_z1r5g5b5: + case rsx::surface_color_format::x1r5g5b5_o1r5g5b5: + case rsx::surface_color_format::r5g6b5: + case rsx::surface_color_format::x8r8g8b8_z8r8g8b8: + case rsx::surface_color_format::x8r8g8b8_o8r8g8b8: + case rsx::surface_color_format::x8b8g8r8_z8b8g8r8: + case rsx::surface_color_format::x8b8g8r8_o8b8g8r8: + return rgb; + case rsx::surface_color_format::g8b8: + return rg; + case rsx::surface_color_format::b8: + case rsx::surface_color_format::x32: + return r; + default: + fmt::throw_exception("Unknown surface format 0x%x", static_cast(format)); + } + } + template static inline To decode_fxp(u32 bits) {