rsx: Fix immediate indexed drawing

This commit is contained in:
kd-11 2017-08-17 00:10:06 +03:00
commit 142bfb5250

View file

@ -1258,23 +1258,26 @@ namespace rsx
volatile_memory_size += (u32)layout.referenced_registers.size() * 16u; volatile_memory_size += (u32)layout.referenced_registers.size() * 16u;
if (rsx::method_registers.current_draw_clause.is_immediate_draw) if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::inlined_array)
{ {
for (auto &info : layout.volatile_blocks) for (const auto &block : layout.interleaved_blocks)
{
volatile_memory_size += info.second;
}
}
else if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::inlined_array)
{
for (auto &block : layout.interleaved_blocks)
{ {
volatile_memory_size += block.attribute_stride * vertex_count; volatile_memory_size += block.attribute_stride * vertex_count;
} }
} }
else else
{ {
for (auto &block : layout.interleaved_blocks) //NOTE: Immediate commands can be index array only or both index array and vertex data
//Check both - but only check volatile blocks if immediate_draw flag is set
if (rsx::method_registers.current_draw_clause.is_immediate_draw)
{
for (const auto &info : layout.volatile_blocks)
{
volatile_memory_size += info.second;
}
}
for (const auto &block : layout.interleaved_blocks)
{ {
u32 unique_verts; u32 unique_verts;
@ -1306,13 +1309,13 @@ namespace rsx
void thread::fill_vertex_layout_state(vertex_input_layout& layout, const u32 vertex_count, s32* buffer) void thread::fill_vertex_layout_state(vertex_input_layout& layout, const u32 vertex_count, s32* buffer)
{ {
std::array<u32, 16> offset_in_block = {}; std::array<s32, 16> offset_in_block = {};
u32 volatile_offset = 0; u32 volatile_offset = 0;
u32 persistent_offset = 0; u32 persistent_offset = 0;
if (rsx::method_registers.current_draw_clause.is_immediate_draw) if (rsx::method_registers.current_draw_clause.is_immediate_draw)
{ {
for (auto &info : layout.volatile_blocks) for (const auto &info : layout.volatile_blocks)
{ {
offset_in_block[info.first] = volatile_offset; offset_in_block[info.first] = volatile_offset;
volatile_offset += info.second; volatile_offset += info.second;
@ -1327,8 +1330,8 @@ namespace rsx
if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::inlined_array) if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::inlined_array)
{ {
auto &block = layout.interleaved_blocks[0]; const auto &block = layout.interleaved_blocks[0];
for (u8 index : block.locations) for (const u8 index : block.locations)
{ {
auto &info = rsx::method_registers.vertex_arrays_info[index]; auto &info = rsx::method_registers.vertex_arrays_info[index];
@ -1338,7 +1341,7 @@ namespace rsx
} }
else else
{ {
for (auto &block : layout.interleaved_blocks) for (const auto &block : layout.interleaved_blocks)
{ {
for (u8 index : block.locations) for (u8 index : block.locations)
{ {
@ -1400,18 +1403,23 @@ namespace rsx
{ {
auto &info = rsx::method_registers.vertex_arrays_info[index]; auto &info = rsx::method_registers.vertex_arrays_info[index];
type = info.type(); type = info.type();
size = (s32)info.size(); size = info.size();
attributes = layout.interleaved_blocks[0].attribute_stride; attributes = layout.interleaved_blocks[0].attribute_stride;
attributes |= default_frequency_mask | volatile_storage_mask; attributes |= default_frequency_mask | volatile_storage_mask;
is_be_type = false; is_be_type = false;
} }
else if (rsx::method_registers.current_draw_clause.is_immediate_draw) else
{ {
auto &info = rsx::method_registers.register_vertex_info[index]; //Data is either from an immediate render or register input
//Immediate data overrides register input
if (rsx::method_registers.current_draw_clause.is_immediate_draw && vertex_push_buffers[index].size > 0)
{
const auto &info = rsx::method_registers.register_vertex_info[index];
type = info.type; type = info.type;
size = (s32)info.size; size = info.size;
attributes = rsx::get_vertex_type_size_on_host(type, size); attributes = rsx::get_vertex_type_size_on_host(type, size);
attributes |= default_frequency_mask | volatile_storage_mask; attributes |= default_frequency_mask | volatile_storage_mask;
@ -1421,9 +1429,9 @@ namespace rsx
else else
{ {
//Register //Register
auto& info = rsx::method_registers.register_vertex_info[index]; const auto& info = rsx::method_registers.register_vertex_info[index];
type = info.type; type = info.type;
size = (s32)info.size; size = info.size;
attributes = rsx::get_vertex_type_size_on_host(type, size); attributes = rsx::get_vertex_type_size_on_host(type, size);
attributes |= volatile_storage_mask; attributes |= volatile_storage_mask;
@ -1431,6 +1439,7 @@ namespace rsx
is_be_type = false; is_be_type = false;
} }
} }
}
else else
{ {
auto &info = rsx::method_registers.vertex_arrays_info[index]; auto &info = rsx::method_registers.vertex_arrays_info[index];
@ -1475,9 +1484,9 @@ namespace rsx
break; break;
} }
buffer[index * 4 + 0] = (s32)type; buffer[index * 4 + 0] = static_cast<s32>(type);
buffer[index * 4 + 1] = size; buffer[index * 4 + 1] = size;
buffer[index * 4 + 2] = (s32)offset_in_block[index]; buffer[index * 4 + 2] = offset_in_block[index];
buffer[index * 4 + 3] = attributes; buffer[index * 4 + 3] = attributes;
} }
} }
@ -1498,7 +1507,7 @@ namespace rsx
return; return;
} }
for (u8 index : layout.referenced_registers) for (const u8 index : layout.referenced_registers)
{ {
memcpy(transient, rsx::method_registers.register_vertex_info[index].data.data(), 16); memcpy(transient, rsx::method_registers.register_vertex_info[index].data.data(), 16);
transient += 16; transient += 16;
@ -1506,19 +1515,18 @@ namespace rsx
if (draw_call.is_immediate_draw) if (draw_call.is_immediate_draw)
{ {
for (auto &info : layout.volatile_blocks) //NOTE: It is possible for immediate draw to only contain index data, so vertex data can be in persistent memory
for (const auto &info : layout.volatile_blocks)
{ {
memcpy(transient, vertex_push_buffers[info.first].data.data(), info.second); memcpy(transient, vertex_push_buffers[info.first].data.data(), info.second);
transient += info.second; transient += info.second;
} }
return;
} }
} }
if (persistent != nullptr) if (persistent != nullptr)
{ {
for (auto &block : layout.interleaved_blocks) for (const auto &block : layout.interleaved_blocks)
{ {
u32 unique_verts; u32 unique_verts;
u32 vertex_base = first_vertex * block.attribute_stride; u32 vertex_base = first_vertex * block.attribute_stride;