mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-09 16:31:28 +12:00
rsx: Improve surface options invalidation
This commit is contained in:
parent
5430892052
commit
3663a8ab4d
3 changed files with 152 additions and 8 deletions
|
@ -1037,9 +1037,9 @@ namespace rsx
|
|||
if ((!mask || !active_write_op) && rsx::method_registers.two_sided_stencil_test_enabled())
|
||||
{
|
||||
mask |= rsx::method_registers.back_stencil_mask();
|
||||
active_write_op |= (rsx::method_registers.stencil_op_zpass() != rsx::stencil_op::keep ||
|
||||
rsx::method_registers.stencil_op_fail() != rsx::stencil_op::keep ||
|
||||
rsx::method_registers.stencil_op_zfail() != rsx::stencil_op::keep);
|
||||
active_write_op |= (rsx::method_registers.back_stencil_op_zpass() != rsx::stencil_op::keep ||
|
||||
rsx::method_registers.back_stencil_op_fail() != rsx::stencil_op::keep ||
|
||||
rsx::method_registers.back_stencil_op_zfail() != rsx::stencil_op::keep);
|
||||
}
|
||||
|
||||
layout.zeta_write_enabled = (mask && active_write_op);
|
||||
|
@ -1300,6 +1300,136 @@ namespace rsx
|
|||
layout.ignore_change = false;
|
||||
}
|
||||
|
||||
void thread::on_framebuffer_options_changed(u32 opt)
|
||||
{
|
||||
auto evaluate_depth_buffer_state = [&]()
|
||||
{
|
||||
m_framebuffer_layout.zeta_write_enabled =
|
||||
(rsx::method_registers.depth_test_enabled() && rsx::method_registers.depth_write_enabled());
|
||||
};
|
||||
|
||||
auto evaluate_stencil_buffer_state = [&]()
|
||||
{
|
||||
if (!m_framebuffer_layout.zeta_write_enabled &&
|
||||
rsx::method_registers.stencil_test_enabled() &&
|
||||
m_framebuffer_layout.depth_format == rsx::surface_depth_format::z24s8)
|
||||
{
|
||||
// Check if stencil data is modified
|
||||
auto mask = rsx::method_registers.stencil_mask();
|
||||
bool active_write_op = (rsx::method_registers.stencil_op_zpass() != rsx::stencil_op::keep ||
|
||||
rsx::method_registers.stencil_op_fail() != rsx::stencil_op::keep ||
|
||||
rsx::method_registers.stencil_op_zfail() != rsx::stencil_op::keep);
|
||||
|
||||
if ((!mask || !active_write_op) && rsx::method_registers.two_sided_stencil_test_enabled())
|
||||
{
|
||||
mask |= rsx::method_registers.back_stencil_mask();
|
||||
active_write_op |= (rsx::method_registers.back_stencil_op_zpass() != rsx::stencil_op::keep ||
|
||||
rsx::method_registers.back_stencil_op_fail() != rsx::stencil_op::keep ||
|
||||
rsx::method_registers.back_stencil_op_zfail() != rsx::stencil_op::keep);
|
||||
}
|
||||
|
||||
m_framebuffer_layout.zeta_write_enabled = (mask && active_write_op);
|
||||
}
|
||||
};
|
||||
|
||||
auto evaluate_color_buffer_state = [&]() -> bool
|
||||
{
|
||||
const auto mrt_buffers = rsx::utility::get_rtt_indexes(m_framebuffer_layout.target);
|
||||
bool any_found = false;
|
||||
|
||||
for (uint i = 0; i < mrt_buffers.size(); ++i)
|
||||
{
|
||||
if (rsx::method_registers.color_write_enabled(i))
|
||||
{
|
||||
const auto real_index = mrt_buffers[i];
|
||||
m_framebuffer_layout.color_write_enabled[real_index] = true;
|
||||
any_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
return any_found;
|
||||
};
|
||||
|
||||
if (m_rtts_dirty)
|
||||
{
|
||||
// Nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
switch (opt)
|
||||
{
|
||||
case NV4097_SET_DEPTH_TEST_ENABLE:
|
||||
case NV4097_SET_DEPTH_MASK:
|
||||
{
|
||||
auto old_state = m_framebuffer_layout.zeta_write_enabled;
|
||||
evaluate_depth_buffer_state();
|
||||
|
||||
if (m_framebuffer_state_contested &&
|
||||
!old_state && m_framebuffer_layout.zeta_write_enabled)
|
||||
{
|
||||
// Z buffer needs to be recreated
|
||||
m_rtts_dirty = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE:
|
||||
case NV4097_SET_STENCIL_TEST_ENABLE:
|
||||
case NV4097_SET_STENCIL_MASK:
|
||||
case NV4097_SET_STENCIL_OP_ZPASS:
|
||||
case NV4097_SET_STENCIL_OP_FAIL:
|
||||
case NV4097_SET_STENCIL_OP_ZFAIL:
|
||||
case NV4097_SET_BACK_STENCIL_MASK:
|
||||
case NV4097_SET_BACK_STENCIL_OP_ZPASS:
|
||||
case NV4097_SET_BACK_STENCIL_OP_FAIL:
|
||||
case NV4097_SET_BACK_STENCIL_OP_ZFAIL:
|
||||
{
|
||||
// Stencil takes a back seat to depth buffer stuff
|
||||
bool old_state = m_framebuffer_layout.zeta_write_enabled;
|
||||
evaluate_depth_buffer_state();
|
||||
|
||||
if (!m_framebuffer_layout.zeta_write_enabled)
|
||||
{
|
||||
evaluate_stencil_buffer_state();
|
||||
}
|
||||
|
||||
if (m_framebuffer_state_contested &&
|
||||
!old_state && m_framebuffer_layout.zeta_write_enabled)
|
||||
{
|
||||
// Z|S buffer needs to be recreated
|
||||
m_rtts_dirty = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NV4097_SET_COLOR_MASK:
|
||||
case NV4097_SET_COLOR_MASK_MRT:
|
||||
{
|
||||
if (!m_framebuffer_state_contested) [[likely]]
|
||||
{
|
||||
// Update write masks and continue
|
||||
evaluate_color_buffer_state();
|
||||
}
|
||||
else
|
||||
{
|
||||
bool old_state = false;
|
||||
for (const auto& enabled : m_framebuffer_layout.color_write_enabled)
|
||||
{
|
||||
if (old_state = enabled) break;
|
||||
}
|
||||
|
||||
const auto new_state = evaluate_color_buffer_state();
|
||||
if (!old_state && new_state)
|
||||
{
|
||||
// Color buffers now in use
|
||||
m_rtts_dirty = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rsx_log.fatal("Unhandled framebuffer option changed 0x%x", opt);
|
||||
}
|
||||
}
|
||||
|
||||
bool thread::get_scissor(areau& region, bool clip_viewport)
|
||||
{
|
||||
if (!(m_graphics_state & rsx::pipeline_state::scissor_config_state_dirty))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue