mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 22:41:25 +12:00
rsx: Add code to detect instanced draw commands
This commit is contained in:
parent
43e04f3fc7
commit
e696d9b324
2 changed files with 45 additions and 2 deletions
|
@ -89,6 +89,45 @@ namespace rsx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool draw_clause::check_trivially_instanced() const
|
||||||
|
{
|
||||||
|
if (draw_command_ranges.size() <= 1)
|
||||||
|
{
|
||||||
|
// Cannot instance one draw call or less
|
||||||
|
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.
|
||||||
|
rsx_log.error("Instanced draw detected, but no command barriers found!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
// Only transform constant instancing is supported at the moment.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void draw_clause::reset(primitive_type type)
|
void draw_clause::reset(primitive_type type)
|
||||||
{
|
{
|
||||||
current_range_index = ~0u;
|
current_range_index = ~0u;
|
||||||
|
@ -97,6 +136,7 @@ namespace rsx
|
||||||
command = draw_command::none;
|
command = draw_command::none;
|
||||||
primitive = type;
|
primitive = type;
|
||||||
primitive_barrier_enable = false;
|
primitive_barrier_enable = false;
|
||||||
|
is_trivial_instanced_draw = false;
|
||||||
|
|
||||||
draw_command_ranges.clear();
|
draw_command_ranges.clear();
|
||||||
draw_command_barriers.clear();
|
draw_command_barriers.clear();
|
||||||
|
|
|
@ -51,6 +51,8 @@ namespace rsx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool check_trivially_instanced() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
primitive_type primitive{};
|
primitive_type primitive{};
|
||||||
draw_command command{};
|
draw_command command{};
|
||||||
|
@ -59,6 +61,7 @@ namespace rsx
|
||||||
bool is_disjoint_primitive{}; // Set if primitive type does not rely on adjacency information
|
bool is_disjoint_primitive{}; // Set if primitive type does not rely on adjacency information
|
||||||
bool primitive_barrier_enable{}; // Set once to signal that a primitive restart barrier can be inserted
|
bool primitive_barrier_enable{}; // Set once to signal that a primitive restart barrier can be inserted
|
||||||
bool is_rendering{}; // Set while we're actually pushing the draw calls to host GPU
|
bool is_rendering{}; // Set while we're actually pushing the draw calls to host GPU
|
||||||
|
bool is_trivial_instanced_draw{}; // Set if the draw call can be executed on the host GPU as a single instanced draw.
|
||||||
|
|
||||||
simple_array<u32> inline_vertex_array{};
|
simple_array<u32> inline_vertex_array{};
|
||||||
|
|
||||||
|
@ -73,8 +76,8 @@ namespace rsx
|
||||||
{
|
{
|
||||||
// End draw call append mode
|
// End draw call append mode
|
||||||
current_range_index = ~0u;
|
current_range_index = ~0u;
|
||||||
|
// Check if we can instance on host
|
||||||
// TODO
|
is_trivial_instanced_draw = check_trivially_instanced();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue