rsx: Skip framebufferless draws if we have no side-effects

This commit is contained in:
kd-11
2026-10-10 10:30:35 +03:00
committed by kd-11
parent 66ba732829
commit 78f27eaad6
7 changed files with 37 additions and 11 deletions
+1 -1
View File
@@ -133,7 +133,7 @@ namespace rsx
m_data |= mask;
}
bool test(T mask)
bool test(T mask) const
{
return !!(m_data & static_cast<bitmask_type>(mask));
}
+6 -5
View File
@@ -36,14 +36,15 @@ namespace rsx
rtt_config_dirty = (1 << 21), // Render target configuration changed
rtt_config_contested = (1 << 22), // Render target configuration is indeterminate
rtt_config_valid = (1 << 23), // Render target configuration is valid
rtt_cache_state_dirty = (1 << 24), // Texture cache state is indeterminate
rtt_config_no_attachments = (1 << 24), // Render target configuration has no attachments
rtt_cache_state_dirty = (1 << 25), // Texture cache state is indeterminate
xform_instancing_state_dirty = (1 << 25), // Transform instancing state has changed
xform_instancing_state_dirty = (1 << 26), // Transform instancing state has changed
zeta_address_is_cyclic = (1 << 26), // The currently bound Z buffer is active for R/W in a cyclic manner
zeta_address_cyclic_barrier = (1 << 27), // A memory barrier is required to "end" the Z buffer cyclic state
zeta_address_is_cyclic = (1 << 27), // The currently bound Z buffer is active for R/W in a cyclic manner
zeta_address_cyclic_barrier = (1 << 28), // A memory barrier is required to "end" the Z buffer cyclic state
blend_config_dirty = (1 << 28), // Blending configuration has been updated. Only matters when programmable blending is in use.
blend_config_dirty = (1 << 29), // Blending configuration has been updated. Only matters when programmable blending is in use.
// TODO - Should signal that we simply need to do a FP compare before the next draw call and invalidate the ucode if the content has changed.
// Marking as dirty to invalidate hot cache also works, it's not like there's tons of barriers per frame anyway.
+1 -1
View File
@@ -929,7 +929,7 @@ void GLGSRender::end()
{
m_profiler.start();
if (skip_current_frame || !m_graphics_state.test(rsx::rtt_config_valid) || cond_render_ctrl.disable_rendering())
if (should_skip_draw())
{
execute_nop_draw();
rsx::thread::end();
+1 -2
View File
@@ -268,8 +268,7 @@ void GLGSRender::init_buffers(rsx::framebuffer_creation_context context, bool /*
ensure(m_draw_fbo);
if (!depth_stencil_target &&
std::all_of(color_targets.begin(), color_targets.end(), FN(x == GL_NONE)))
if (m_graphics_state.test(rsx::rtt_config_no_attachments))
{
// Framebufferless rendering. Raster dimensions must be supplied explicitly and match what real surfaces would have used.
const auto [raster_width, raster_height] = rsx::apply_resolution_scale<true>(
+18 -2
View File
@@ -1005,6 +1005,22 @@ namespace rsx
while (method_registers.current_draw_clause.next());
}
bool thread::should_skip_draw() const
{
if (skip_current_frame || !m_graphics_state.test(rsx::rtt_config_valid) || cond_render_ctrl.disable_rendering())
{
return true;
}
if (m_graphics_state.test(rsx::rtt_config_no_attachments) &&
(g_cfg.video.disable_zcull_queries || !zcull_ctrl->has_active_queries()))
{
return true;
}
return false;
}
void thread::cpu_task()
{
while (Emu.IsReady())
@@ -1461,7 +1477,7 @@ namespace rsx
layout.width = rsx::method_registers.surface_clip_width();
layout.height = rsx::method_registers.surface_clip_height();
m_graphics_state.clear(rsx::rtt_config_contested | rsx::rtt_config_valid);
m_graphics_state.clear(rsx::rtt_config_contested | rsx::rtt_config_valid | rsx::rtt_config_no_attachments);
m_current_framebuffer_context = context;
if (layout.width == 0 || layout.height == 0)
@@ -1785,7 +1801,7 @@ namespace rsx
}
// Context must be draw now...
// TODO: Also disable rendering if ZPASS stat counting is not enabled (side-effect)
m_graphics_state.set(rsx::rtt_config_no_attachments);
}
// At least one attachment exists
+1
View File
@@ -365,6 +365,7 @@ namespace rsx
virtual void begin();
virtual void end();
virtual void execute_nop_draw();
bool should_skip_draw() const;
virtual void on_init_thread() = 0;
virtual void on_frame_end(u32 buffer, bool forced = false);
+9
View File
@@ -187,6 +187,15 @@ namespace rsx
// Check for pending writes
bool has_pending() const { return !m_pending_writes.empty(); }
// Check if queries are currently active
bool has_active_queries() const { return host_queries_active; }
// Check if ZPASS_COUNT stats are running
bool is_zpass_count_active() const { return zpass_count_enabled; }
// Grab the currently active query block
occlusion_query_info* get_current_query_task() const { return m_current_task; }
// Search for query synchronized at address
query_search_result find_query(vm::addr_t sink_address, bool all);