rsx: Fix multidraw range splits again

rsx: Hotfix for disjoint range detection
This commit is contained in:
kd-11 2017-09-14 20:05:13 +03:00
parent 45d0e821dc
commit 10e25eb362
1 changed files with 41 additions and 39 deletions

View File

@ -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;