diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 3ecfbd5921..4a11952ef9 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -496,14 +496,14 @@ void GLGSRender::clear_surface(u32 arg) if (skip_current_frame) return; // If stencil write mask is disabled, remove clear_stencil bit - if (!rsx::method_registers.stencil_mask()) arg &= ~0x2u; + if (!rsx::method_registers.stencil_mask()) arg &= ~RSX_GCM_CLEAR_STENCIL_BIT; // Ignore invalid clear flags - if ((arg & 0xf3) == 0) return; + if ((arg & RSX_GCM_CLEAR_ANY_MASK) == 0) return; u8 ctx = rsx::framebuffer_creation_context::context_draw; - if (arg & 0xF0) ctx |= rsx::framebuffer_creation_context::context_clear_color; - if (arg & 0x3) ctx |= rsx::framebuffer_creation_context::context_clear_depth; + if (arg & RSX_GCM_CLEAR_COLOR_MASK) ctx |= rsx::framebuffer_creation_context::context_clear_color; + if (arg & RSX_GCM_CLEAR_DEPTH_STENCIL_MASK) ctx |= rsx::framebuffer_creation_context::context_clear_depth; init_buffers(static_cast(ctx), true); @@ -521,9 +521,9 @@ void GLGSRender::clear_surface(u32 arg) bool update_color = false, update_z = false; rsx::surface_depth_format2 surface_depth_format = rsx::method_registers.surface_depth_fmt(); - if (auto ds = std::get<1>(m_rtts.m_bound_depth_stencil); arg & 0x3) + if (auto ds = std::get<1>(m_rtts.m_bound_depth_stencil); arg & RSX_GCM_CLEAR_DEPTH_STENCIL_MASK) { - if (arg & 0x1) + if (arg & RSX_GCM_CLEAR_DEPTH_BIT) { u32 max_depth_value = get_max_depth_value(surface_depth_format); u32 clear_depth = rsx::method_registers.z_clear_value(is_depth_stencil_format(surface_depth_format)); @@ -535,7 +535,7 @@ void GLGSRender::clear_surface(u32 arg) if (is_depth_stencil_format(surface_depth_format)) { - if (arg & 0x2) + if (arg & RSX_GCM_CLEAR_STENCIL_BIT) { u8 clear_stencil = rsx::method_registers.stencil_clear_value(); @@ -544,7 +544,8 @@ void GLGSRender::clear_surface(u32 arg) mask |= GLenum(gl::buffers::stencil); } - if ((arg & 0x3) != 0x3 || !full_frame) + if (const auto ds_mask = (arg & RSX_GCM_CLEAR_DEPTH_STENCIL_MASK); + ds_mask != RSX_GCM_CLEAR_DEPTH_STENCIL_MASK || !full_frame) { ensure(mask); @@ -552,14 +553,14 @@ void GLGSRender::clear_surface(u32 arg) ds->old_contents.empty() && !g_cfg.video.read_depth_buffer) // No way to load data from memory, so no initialization given { // Only one aspect was cleared. Make sure to memory initialize the other before removing dirty flag - if (arg == 1) + if (ds_mask == RSX_GCM_CLEAR_DEPTH_BIT) { // Depth was cleared, initialize stencil gl_state.stencil_mask(0xFF); gl_state.clear_stencil(0xFF); mask |= GLenum(gl::buffers::stencil); } - else + else if (ds_mask == RSX_GCM_CLEAR_STENCIL_BIT) { // Stencil was cleared, initialize depth gl_state.depth_mask(GL_TRUE); diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index dcdfc4370f..043f421cc5 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -1197,14 +1197,14 @@ void VKGSRender::clear_surface(u32 mask) if (skip_current_frame || swapchain_unavailable) return; // If stencil write mask is disabled, remove clear_stencil bit - if (!rsx::method_registers.stencil_mask()) mask &= ~0x2u; + if (!rsx::method_registers.stencil_mask()) mask &= ~RSX_GCM_CLEAR_STENCIL_BIT; // Ignore invalid clear flags - if (!(mask & 0xF3)) return; + if (!(mask & RSX_GCM_CLEAR_ANY_MASK)) return; u8 ctx = rsx::framebuffer_creation_context::context_draw; - if (mask & 0xF0) ctx |= rsx::framebuffer_creation_context::context_clear_color; - if (mask & 0x3) ctx |= rsx::framebuffer_creation_context::context_clear_depth; + if (mask & RSX_GCM_CLEAR_COLOR_MASK) ctx |= rsx::framebuffer_creation_context::context_clear_color; + if (mask & RSX_GCM_CLEAR_DEPTH_STENCIL_MASK) ctx |= rsx::framebuffer_creation_context::context_clear_depth; init_buffers(rsx::framebuffer_creation_context{ctx}); if (!framebuffer_status_valid) return; @@ -1232,9 +1232,9 @@ void VKGSRender::clear_surface(u32 mask) bool update_color = false, update_z = false; auto surface_depth_format = rsx::method_registers.surface_depth_fmt(); - if (auto ds = std::get<1>(m_rtts.m_bound_depth_stencil); mask & 0x3) + if (auto ds = std::get<1>(m_rtts.m_bound_depth_stencil); mask & RSX_GCM_CLEAR_DEPTH_STENCIL_MASK) { - if (mask & 0x1) + if (mask & RSX_GCM_CLEAR_DEPTH_BIT) { u32 max_depth_value = get_max_depth_value(surface_depth_format); @@ -1249,7 +1249,7 @@ void VKGSRender::clear_surface(u32 mask) if (is_depth_stencil_format(surface_depth_format)) { - if (mask & 0x2) + if (mask & RSX_GCM_CLEAR_STENCIL_BIT) { u8 clear_stencil = rsx::method_registers.stencil_clear_value(); depth_stencil_clear_values.depthStencil.stencil = clear_stencil; @@ -1273,13 +1273,14 @@ void VKGSRender::clear_surface(u32 mask) ds->old_contents.empty() && !g_cfg.video.read_depth_buffer) // No way to load data from memory, so no initialization given { // Only one aspect was cleared. Make sure to memory initialize the other before removing dirty flag - if (mask == 1) + const auto ds_mask = (mask & RSX_GCM_CLEAR_DEPTH_STENCIL_MASK); + if (ds_mask == RSX_GCM_CLEAR_DEPTH_BIT && (ds->aspect() & VK_IMAGE_ASPECT_STENCIL_BIT)) { // Depth was cleared, initialize stencil depth_stencil_clear_values.depthStencil.stencil = 0xFF; depth_stencil_mask |= VK_IMAGE_ASPECT_STENCIL_BIT; } - else + else if (ds_mask == RSX_GCM_CLEAR_STENCIL_BIT) { // Stencil was cleared, initialize depth depth_stencil_clear_values.depthStencil.depth = 1.f; @@ -1294,7 +1295,7 @@ void VKGSRender::clear_surface(u32 mask) } } - if (auto colormask = (mask & 0xF0)) + if (auto colormask = (mask & RSX_GCM_CLEAR_COLOR_MASK)) { if (!m_draw_buffers.empty()) { @@ -1318,7 +1319,7 @@ void VKGSRender::clear_surface(u32 mask) { 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)); + use_fast_clear = (colormask == (RSX_GCM_CLEAR_RED_BIT | RSX_GCM_CLEAR_GREEN_BIT)); break; } case rsx::surface_color_format::a8b8g8r8: @@ -1331,7 +1332,7 @@ void VKGSRender::clear_surface(u32 mask) } default: { - use_fast_clear = (colormask == (0x10 | 0x20 | 0x40 | 0x80)); + use_fast_clear = (colormask == RSX_GCM_CLEAR_COLOR_MASK); break; } } diff --git a/rpcs3/Emu/RSX/gcm_enums.h b/rpcs3/Emu/RSX/gcm_enums.h index 24b0536e43..3c60bdab47 100644 --- a/rpcs3/Emu/RSX/gcm_enums.h +++ b/rpcs3/Emu/RSX/gcm_enums.h @@ -1177,3 +1177,18 @@ enum CELL_GCM_FOG_MODE_EXP2_ABS = 0x0803, CELL_GCM_FOG_MODE_LINEAR_ABS = 0x0804, }; + +// Surface clear bitfields (aggregates) +enum +{ + RSX_GCM_CLEAR_DEPTH_BIT = 0x01, + RSX_GCM_CLEAR_STENCIL_BIT = 0x02, + RSX_GCM_CLEAR_RED_BIT = 0x10, + RSX_GCM_CLEAR_GREEN_BIT = 0x20, + RSX_GCM_CLEAR_BLUE_BIT = 0x40, + RSX_GCM_CLEAR_ALPHA_BIT = 0x80, + + RSX_GCM_CLEAR_COLOR_MASK = 0xF0, + RSX_GCM_CLEAR_DEPTH_STENCIL_MASK = (RSX_GCM_CLEAR_DEPTH_BIT | RSX_GCM_CLEAR_STENCIL_BIT), + RSX_GCM_CLEAR_ANY_MASK = (RSX_GCM_CLEAR_COLOR_MASK | RSX_GCM_CLEAR_DEPTH_STENCIL_MASK) +};