diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 5ac05c7ed..906f0bfb7 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -1258,23 +1258,26 @@ namespace rsx 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) - { - 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) + for (const auto &block : layout.interleaved_blocks) { volatile_memory_size += block.attribute_stride * vertex_count; } } 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; @@ -1306,13 +1309,13 @@ namespace rsx void thread::fill_vertex_layout_state(vertex_input_layout& layout, const u32 vertex_count, s32* buffer) { - std::array offset_in_block = {}; + std::array offset_in_block = {}; u32 volatile_offset = 0; u32 persistent_offset = 0; 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; volatile_offset += info.second; @@ -1327,8 +1330,8 @@ namespace rsx if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::inlined_array) { - auto &block = layout.interleaved_blocks[0]; - for (u8 index : block.locations) + const auto &block = layout.interleaved_blocks[0]; + for (const u8 index : block.locations) { auto &info = rsx::method_registers.vertex_arrays_info[index]; @@ -1338,7 +1341,7 @@ namespace rsx } else { - for (auto &block : layout.interleaved_blocks) + for (const auto &block : layout.interleaved_blocks) { for (u8 index : block.locations) { @@ -1400,35 +1403,41 @@ namespace rsx { auto &info = rsx::method_registers.vertex_arrays_info[index]; type = info.type(); - size = (s32)info.size(); + size = info.size(); attributes = layout.interleaved_blocks[0].attribute_stride; attributes |= default_frequency_mask | volatile_storage_mask; is_be_type = false; } - else if (rsx::method_registers.current_draw_clause.is_immediate_draw) - { - auto &info = rsx::method_registers.register_vertex_info[index]; - type = info.type; - size = (s32)info.size; - - attributes = rsx::get_vertex_type_size_on_host(type, size); - attributes |= default_frequency_mask | volatile_storage_mask; - - is_be_type = true; - } else { - //Register - auto& info = rsx::method_registers.register_vertex_info[index]; - type = info.type; - size = (s32)info.size; + //Data is either from an immediate render or register input + //Immediate data overrides register input - attributes = rsx::get_vertex_type_size_on_host(type, size); - attributes |= volatile_storage_mask; + 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; + size = info.size; - is_be_type = false; + attributes = rsx::get_vertex_type_size_on_host(type, size); + attributes |= default_frequency_mask | volatile_storage_mask; + + is_be_type = true; + } + else + { + //Register + const auto& info = rsx::method_registers.register_vertex_info[index]; + type = info.type; + size = info.size; + + attributes = rsx::get_vertex_type_size_on_host(type, size); + attributes |= volatile_storage_mask; + + is_be_type = false; + } } } else @@ -1475,9 +1484,9 @@ namespace rsx break; } - buffer[index * 4 + 0] = (s32)type; + buffer[index * 4 + 0] = static_cast(type); 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; } } @@ -1498,7 +1507,7 @@ namespace rsx 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); transient += 16; @@ -1506,19 +1515,18 @@ namespace rsx 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); transient += info.second; } - - return; } } if (persistent != nullptr) { - for (auto &block : layout.interleaved_blocks) + for (const auto &block : layout.interleaved_blocks) { u32 unique_verts; u32 vertex_base = first_vertex * block.attribute_stride;