From 7233640cf00fcb0f9235589502a73068135ac2d8 Mon Sep 17 00:00:00 2001 From: Jake Date: Mon, 5 Mar 2018 21:28:52 -0600 Subject: [PATCH] rsx: add vertex data base to offset and mask before translating address --- rpcs3/Emu/RSX/RSXThread.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index dcab732f5a..8220af19bf 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -89,6 +89,13 @@ namespace rsx } } + // The rsx internally adds the 'data_base_offset' and the 'vert_offset' and masks it + // before actually attempting to translate to the internal address. Seen happening heavily in R&C games + u32 get_vertex_offset_from_base(u32 vert_data_base_offset, u32 vert_base_offset) + { + return ((u64)vert_data_base_offset + vert_base_offset) & 0xFFFFFFF; + } + u32 get_vertex_type_size_on_host(vertex_base_type type, u32 size) { switch (type) @@ -997,7 +1004,7 @@ namespace rsx gsl::span thread::get_raw_vertex_buffer(const rsx::data_array_format_info& vertex_array_info, u32 base_offset, const std::vector>& vertex_ranges) const { u32 offset = vertex_array_info.offset(); - u32 address = base_offset + rsx::get_address(offset & 0x7fffffff, offset >> 31); + u32 address = rsx::get_address(rsx::get_vertex_offset_from_base(base_offset, offset & 0x7fffffff), offset >> 31); u32 element_size = rsx::get_vertex_type_size_on_host(vertex_array_info.type(), vertex_array_info.size()); @@ -1384,7 +1391,7 @@ namespace rsx for (auto &info : result.interleaved_blocks) { //Calculate real data address to be used during upload - info.real_offset_address = state.vertex_data_base_offset() + rsx::get_address(info.base_offset, info.memory_location); + info.real_offset_address = rsx::get_address(rsx::get_vertex_offset_from_base(state.vertex_data_base_offset(), info.base_offset), info.memory_location); } return result;