mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-13 02:08:49 +12:00
rsx: Implement dynamic vertex offset updates
- Vertex offsets can be updated mid-draw to dynamically render different meshes without breaking up draws
This commit is contained in:
parent
9b050a33e4
commit
194bfc54d1
4 changed files with 130 additions and 88 deletions
|
@ -779,6 +779,24 @@ namespace rsx
|
|||
}
|
||||
}
|
||||
|
||||
template<u32 index>
|
||||
struct set_vertex_array_offset
|
||||
{
|
||||
static void impl(thread* rsx, u32 reg, u32 arg)
|
||||
{
|
||||
if (rsx->in_begin_end &&
|
||||
!rsx::method_registers.current_draw_clause.empty() &&
|
||||
reg != method_registers.register_previous_value)
|
||||
{
|
||||
// Revert change to queue later
|
||||
method_registers.decode(reg, method_registers.register_previous_value);
|
||||
|
||||
// Insert offset mofifier barrier
|
||||
method_registers.current_draw_clause.insert_command_barrier(vertex_array_offset_modifier_barrier, arg, index);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void check_index_array_dma(thread* rsx, u32 reg, u32 arg)
|
||||
{
|
||||
// Check if either location or index type are invalid
|
||||
|
@ -2637,6 +2655,56 @@ namespace rsx
|
|||
return registers[reg] == value;
|
||||
}
|
||||
|
||||
void draw_clause::insert_command_barrier(command_barrier_type type, u32 arg, u32 index)
|
||||
{
|
||||
ensure(!draw_command_ranges.empty());
|
||||
|
||||
auto _do_barrier_insert = [this](barrier_t&& val)
|
||||
{
|
||||
if (draw_command_barriers.empty() || draw_command_barriers.back() < val)
|
||||
{
|
||||
draw_command_barriers.push_back(val);
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto it = draw_command_barriers.begin(); it != draw_command_barriers.end(); it++)
|
||||
{
|
||||
if (*it < val)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
draw_command_barriers.insert(it, val);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
if (type == primitive_restart_barrier)
|
||||
{
|
||||
// Rasterization flow barrier
|
||||
const auto& last = draw_command_ranges[current_range_index];
|
||||
const auto address = last.first + last.count;
|
||||
|
||||
_do_barrier_insert({ current_range_index, 0, address, index, arg, 0, type });
|
||||
}
|
||||
else
|
||||
{
|
||||
// Execution dependency barrier. Requires breaking the current draw call sequence and start another.
|
||||
if (draw_command_ranges.back().count > 0)
|
||||
{
|
||||
append_draw_command({});
|
||||
}
|
||||
else
|
||||
{
|
||||
// In case of back-to-back modifiers, do not add duplicates
|
||||
current_range_index = draw_command_ranges.size() - 1;
|
||||
}
|
||||
|
||||
_do_barrier_insert({ current_range_index, get_system_time(), ~0u, index, arg, 0, type });
|
||||
last_execution_barrier_index = current_range_index;
|
||||
}
|
||||
}
|
||||
|
||||
void draw_clause::reset(primitive_type type)
|
||||
{
|
||||
current_range_index = ~0u;
|
||||
|
@ -2676,6 +2744,11 @@ namespace rsx
|
|||
method_registers.decode(NV4097_SET_VERTEX_DATA_BASE_OFFSET, barrier.arg);
|
||||
result |= vertex_base_changed;
|
||||
break;
|
||||
case vertex_array_offset_modifier_barrier:
|
||||
// Change vertex array offset
|
||||
method_registers.decode(NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + barrier.index, barrier.arg);
|
||||
result |= vertex_arrays_changed;
|
||||
break;
|
||||
default:
|
||||
fmt::throw_exception("Unreachable");
|
||||
}
|
||||
|
@ -3187,6 +3260,7 @@ namespace rsx
|
|||
bind<NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK, nv4097::set_vertex_attribute_output_mask>();
|
||||
bind<NV4097_SET_VERTEX_DATA_BASE_OFFSET, nv4097::set_vertex_base_offset>();
|
||||
bind<NV4097_SET_VERTEX_DATA_BASE_INDEX, nv4097::set_index_base_offset>();
|
||||
bind_range<NV4097_SET_VERTEX_DATA_ARRAY_OFFSET, 1, 16, nv4097::set_vertex_array_offset>();
|
||||
bind<NV4097_SET_USER_CLIP_PLANE_CONTROL, nv4097::notify_state_changed<vertex_state_dirty>>();
|
||||
bind<NV4097_SET_TRANSFORM_BRANCH_BITS, nv4097::notify_state_changed<vertex_state_dirty>>();
|
||||
bind<NV4097_SET_CLIP_MIN, nv4097::notify_state_changed<invalidate_zclip_bits>>();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue