rsx: Forcefully disable writes to channels disabled on host

- Some formats may have dummy channels on host. Never write to them!
- This means that XRGB formats correctly only write 24 bits, not 32.
This commit is contained in:
kd-11 2024-01-20 02:17:31 +03:00 committed by kd-11
parent 0971636c07
commit 9a9b5860df
3 changed files with 52 additions and 3 deletions

View file

@ -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.

View file

@ -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;

View file

@ -870,6 +870,38 @@ namespace rsx
return result;
}
static inline const std::array<bool, 4> get_write_output_mask(rsx::surface_color_format format)
{
const std::array<bool, 4> rgba = { true, true, true, true };
const std::array<bool, 4> rgb = { true, true, true, false };
const std::array<bool, 4> rg = { true, true, false, false };
const std::array<bool, 4> 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<int>(format));
}
}
template <uint integer, uint frac, bool sign = true, typename To = f32>
static inline To decode_fxp(u32 bits)
{