From 1fd9d338cf252e6f66f590dfdc9310ef4f50629f Mon Sep 17 00:00:00 2001 From: kd-11 Date: Tue, 8 Apr 2025 01:53:01 +0300 Subject: [PATCH] rsx: Track command barrier types during recording for faster instancing compatibility checks --- rpcs3/Emu/RSX/NV47/FW/draw_call.cpp | 38 ++++++++++------------------- rpcs3/Emu/RSX/NV47/FW/draw_call.hpp | 3 +++ 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/rpcs3/Emu/RSX/NV47/FW/draw_call.cpp b/rpcs3/Emu/RSX/NV47/FW/draw_call.cpp index 640db9c762..96b1910ae9 100644 --- a/rpcs3/Emu/RSX/NV47/FW/draw_call.cpp +++ b/rpcs3/Emu/RSX/NV47/FW/draw_call.cpp @@ -44,6 +44,8 @@ namespace rsx } }; + draw_command_barrier_mask |= (1u << type); + if (type == primitive_restart_barrier) { // Rasterization flow barrier @@ -97,16 +99,6 @@ namespace rsx return false; } - // For instancing all draw calls must be identical - const auto& ref = draw_command_ranges.front(); - for (const auto& range : draw_command_ranges) - { - if (range.first != ref.first || range.count != ref.count) - { - return false; - } - } - if (draw_command_barriers.empty()) { // Raise alarm here for investigation, we may be missing a corner case. @@ -115,30 +107,26 @@ namespace rsx } // Barriers must exist, but can only involve updating transform constants (for now) - for (const auto& barrier : draw_command_barriers) - { - if (barrier.type != rsx::transform_constant_load_modifier_barrier && - barrier.type != rsx::transform_constant_update_barrier) - { - ensure(barrier.draw_id < ::size32(draw_command_ranges)); - if (draw_command_ranges[barrier.draw_id].count == 0) - { - // Dangling command barriers are ignored. We're also at the end of the command, so abort. - break; - } + const u32 compatible_barrier_mask = + (1u << rsx::transform_constant_load_modifier_barrier) | + (1u << rsx::transform_constant_update_barrier); - // Fail. Only transform constant instancing is supported at the moment. - return false; - } + if (draw_command_barrier_mask & ~compatible_barrier_mask) + { + return false; } - return true; + // For instancing all draw calls must be identical + // FIXME: This requirement can be easily lifted by chunking contiguous chunks. + const auto& ref = draw_command_ranges.front(); + return !draw_command_ranges.any(FN(x.first != ref.first || x.count != ref.count)); } void draw_clause::reset(primitive_type type) { current_range_index = ~0u; last_execution_barrier_index = 0; + draw_command_barrier_mask = 0; command = draw_command::none; primitive = type; diff --git a/rpcs3/Emu/RSX/NV47/FW/draw_call.hpp b/rpcs3/Emu/RSX/NV47/FW/draw_call.hpp index 4e350e985d..416a82fbae 100644 --- a/rpcs3/Emu/RSX/NV47/FW/draw_call.hpp +++ b/rpcs3/Emu/RSX/NV47/FW/draw_call.hpp @@ -29,6 +29,9 @@ namespace rsx // Location of last execution barrier u32 last_execution_barrier_index{}; + // Mask of all active barriers + u32 draw_command_barrier_mask = 0; + // Draw-time iterator to the draw_command_barriers struct mutable simple_array::iterator current_barrier_it;