mirror of https://github.com/RPCS3/rpcs3.git
rsx: Fix multidraw range splits again
rsx: Hotfix for disjoint range detection
This commit is contained in:
parent
45d0e821dc
commit
10e25eb362
|
@ -394,63 +394,65 @@ namespace rsx
|
||||||
// Deferred calls are used to batch draws together
|
// Deferred calls are used to batch draws together
|
||||||
u32 deferred_primitive_type = 0;
|
u32 deferred_primitive_type = 0;
|
||||||
u32 deferred_call_size = 0;
|
u32 deferred_call_size = 0;
|
||||||
|
std::vector<u32> deferred_stack;
|
||||||
bool has_deferred_call = false;
|
bool has_deferred_call = false;
|
||||||
|
|
||||||
auto flush_command_queue = [&]()
|
auto flush_command_queue = [&]()
|
||||||
{
|
{
|
||||||
//TODO: Split first-count pairs if not consecutive
|
const auto num_draws = method_registers.current_draw_clause.first_count_commands.size();
|
||||||
bool split_command = false;
|
bool emit_begin = false;
|
||||||
std::vector <std::pair<u32, u32>> split_ranges;
|
bool emit_end = true;
|
||||||
auto first_count_cmds = method_registers.current_draw_clause.first_count_commands;
|
|
||||||
|
|
||||||
if (method_registers.current_draw_clause.first_count_commands.size() > 1 &&
|
if (num_draws > 1)
|
||||||
method_registers.current_draw_clause.is_disjoint_primitive)
|
|
||||||
{
|
{
|
||||||
u32 next = method_registers.current_draw_clause.first_count_commands.front().first;
|
auto& first_counts = method_registers.current_draw_clause.first_count_commands;
|
||||||
u32 last_head = 0;
|
deferred_stack.resize(0);
|
||||||
|
|
||||||
for (int n = 0; n < first_count_cmds.size(); ++n)
|
u32 last = first_counts.front().first;
|
||||||
|
u32 last_index = 0;
|
||||||
|
|
||||||
|
for (size_t draw = 0; draw < num_draws; draw++)
|
||||||
{
|
{
|
||||||
const auto &v = first_count_cmds[n];
|
if (first_counts[draw].first != last)
|
||||||
if (v.first != next)
|
|
||||||
{
|
{
|
||||||
split_command = true;
|
//Disjoint
|
||||||
split_ranges.push_back(std::make_pair(last_head, n));
|
deferred_stack.push_back(draw);
|
||||||
last_head = n + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next = v.first + v.second;
|
last = first_counts[draw].first + first_counts[draw].second;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (split_command)
|
if (deferred_stack.size() > 0)
|
||||||
split_ranges.push_back(std::make_pair(last_head, first_count_cmds.size() - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!split_command)
|
|
||||||
{
|
|
||||||
methods[NV4097_SET_BEGIN_END](this, NV4097_SET_BEGIN_END, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::vector<std::pair<u32, u32>> tmp;
|
|
||||||
auto list_head = first_count_cmds.begin();
|
|
||||||
bool emit_begin = false;
|
|
||||||
|
|
||||||
for (auto &range : split_ranges)
|
|
||||||
{
|
{
|
||||||
tmp.resize(range.second - range.first + 1);
|
//TODO: Verify this works correctly
|
||||||
std::copy(list_head + range.first, list_head + range.second, tmp.begin());
|
LOG_ERROR(RSX, "Disjoint draw range detected");
|
||||||
|
|
||||||
if (emit_begin)
|
deferred_stack.push_back(num_draws - 1); //Append last pair
|
||||||
methods[NV4097_SET_BEGIN_END](this, NV4097_SET_BEGIN_END, deferred_primitive_type);
|
std::vector<std::pair<u32, u32>> temp_range = first_counts;
|
||||||
else
|
|
||||||
emit_begin = true;
|
|
||||||
|
|
||||||
method_registers.current_draw_clause.first_count_commands = tmp;
|
u32 last_index = 0;
|
||||||
methods[NV4097_SET_BEGIN_END](this, NV4097_SET_BEGIN_END, 0);
|
|
||||||
|
for (const u32 draw : deferred_stack)
|
||||||
|
{
|
||||||
|
first_counts.resize(draw - last_index);
|
||||||
|
std::copy(temp_range.begin() + last_index, temp_range.begin() + draw, first_counts.begin());
|
||||||
|
|
||||||
|
if (emit_begin)
|
||||||
|
methods[NV4097_SET_BEGIN_END](this, NV4097_SET_BEGIN_END, deferred_primitive_type);
|
||||||
|
else
|
||||||
|
emit_begin = true;
|
||||||
|
|
||||||
|
methods[NV4097_SET_BEGIN_END](this, NV4097_SET_BEGIN_END, 0);
|
||||||
|
last_index = draw;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit_end = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (emit_end)
|
||||||
|
methods[NV4097_SET_BEGIN_END](this, NV4097_SET_BEGIN_END, 0);
|
||||||
|
|
||||||
deferred_primitive_type = 0;
|
deferred_primitive_type = 0;
|
||||||
deferred_call_size = 0;
|
deferred_call_size = 0;
|
||||||
has_deferred_call = false;
|
has_deferred_call = false;
|
||||||
|
@ -577,7 +579,7 @@ namespace rsx
|
||||||
|
|
||||||
deferred_call_size++;
|
deferred_call_size++;
|
||||||
|
|
||||||
if (method_registers.current_draw_clause.is_disjoint_primitive)
|
if (!method_registers.current_draw_clause.is_disjoint_primitive)
|
||||||
{
|
{
|
||||||
// Combine all calls since the last one
|
// Combine all calls since the last one
|
||||||
auto &first_count = method_registers.current_draw_clause.first_count_commands;
|
auto &first_count = method_registers.current_draw_clause.first_count_commands;
|
||||||
|
|
Loading…
Reference in New Issue