diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index e4b3165f7e..6bb359ffd1 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -952,7 +952,7 @@ namespace rsx if (vertex_push_buffers[index].vertex_count > 1) { - const rsx::register_vertex_data_info& info = state.register_vertex_info[index]; + const auto& info = vertex_push_buffers[index]; const u8 element_size = info.size * sizeof(u32); gsl::span vertex_src = { (const gsl::byte*)vertex_push_buffers[index].data.data(), vertex_push_buffers[index].vertex_count * element_size }; @@ -1406,11 +1406,11 @@ namespace rsx { current_vertex_program.rsx_vertex_inputs.push_back( { index, - rsx::method_registers.register_vertex_info[index].size, + vertex_push_buffers[index].size, 1, false, true, - is_int_type(rsx::method_registers.vertex_arrays_info[index].type()), 0 }); + is_int_type(vertex_push_buffers[index].type), 0 }); } else if (rsx::method_registers.register_vertex_info[index].size > 0) { @@ -1479,18 +1479,27 @@ namespace rsx //Check for interleaving const auto &info = state.vertex_arrays_info[index]; - if (rsx::method_registers.current_draw_clause.is_immediate_draw) + if (rsx::method_registers.current_draw_clause.is_immediate_draw && + rsx::method_registers.current_draw_clause.command != rsx::draw_command::indexed) { + // NOTE: In immediate rendering mode, all vertex setup is ignored + // Observed with GT5, immediate render bypasses array pointers completely, even falling back to fixed-function register defaults if (vertex_push_buffers[index].vertex_count > 1) { - //Read temp buffer (register array) + // Read temp buffer (register array) std::pair volatile_range_info = std::make_pair(index, static_cast(vertex_push_buffers[index].data.size() * sizeof(u32))); result.volatile_blocks.push_back(volatile_range_info); result.attribute_placement[index] = attribute_buffer_placement::transient; - continue; + } + else if (state.register_vertex_info[index].size > 0) + { + // Reads from register + result.referenced_registers.push_back(index); + result.attribute_placement[index] = attribute_buffer_placement::transient; } - //Might be an indexed immediate draw - real vertex arrays but glArrayElement style of IB declaration + // Fall back to the default register value if no source is specified via register + continue; } if (!info.size()) @@ -2100,7 +2109,7 @@ namespace rsx vertex_push_buffers[index].vertex_count > 1) { // Push buffer - const auto &info = rsx::method_registers.register_vertex_info[index]; + const auto &info = vertex_push_buffers[index]; type = info.type; size = info.size; diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index fbc4f0094a..cf6b499f62 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -247,8 +247,11 @@ namespace rsx if (rsx->in_begin_end) { - // Update to immediate mode register/array, aliasing with the register view + // Update to immediate mode register/array rsx->append_to_push_buffer(attribute_index, count, vertex_subreg, vtype, arg); + + // NOTE: one can update the register to update constant across primitive. Needs verification. + // Fall through } auto& info = rsx::method_registers.register_vertex_info[attribute_index]; diff --git a/rpcs3/Emu/RSX/rsx_utils.h b/rpcs3/Emu/RSX/rsx_utils.h index 96f3d1a5c8..22e838d13d 100644 --- a/rpcs3/Emu/RSX/rsx_utils.h +++ b/rpcs3/Emu/RSX/rsx_utils.h @@ -747,6 +747,12 @@ namespace rsx _capacity = size; } + void resize(u32 size) + { + reserve(size); + _size = size; + } + void push_back(const Ty& val) { if (_size >= _capacity) diff --git a/rpcs3/Emu/RSX/rsx_vertex_data.h b/rpcs3/Emu/RSX/rsx_vertex_data.h index 4ed65b94da..4593228988 100644 --- a/rpcs3/Emu/RSX/rsx_vertex_data.h +++ b/rpcs3/Emu/RSX/rsx_vertex_data.h @@ -3,6 +3,7 @@ #include "GCM.h" #include "Utilities/types.h" #include "Utilities/BEType.h" +#include "rsx_utils.h" namespace rsx { @@ -60,7 +61,7 @@ struct push_buffer_vertex_info u32 vertex_count = 0; u32 attribute_mask = ~0; - std::vector data; + rsx::simple_array data; void clear() { @@ -98,6 +99,8 @@ struct push_buffer_vertex_info const u32 element_mask = (1 << sub_index); const u8 vertex_size = get_vertex_size_in_dwords(type); + this->type = type; + if (attribute_mask & element_mask) { attribute_mask = 0; @@ -122,7 +125,6 @@ struct register_vertex_data_info register_vertex_data_info() {} std::array data; - }; }