From 3a4083263e221ef3c76e832f2294619c3ed3960a Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 11 Mar 2019 23:22:04 +0300 Subject: [PATCH] rsx: Fix texture transfer when pitch does not match exactly --- rpcs3/Emu/RSX/Common/texture_cache_utils.h | 26 +++++++++++++++++++++- rpcs3/Emu/RSX/GL/GLTextureCache.h | 1 + 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/Common/texture_cache_utils.h b/rpcs3/Emu/RSX/Common/texture_cache_utils.h index fe773b5251..a045d1780a 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache_utils.h +++ b/rpcs3/Emu/RSX/Common/texture_cache_utils.h @@ -1397,8 +1397,32 @@ namespace rsx const auto valid_offset = valid_range.start - get_section_base(); AUDIT(valid_length > 0); + // In case of pitch mismatch, match the offset point to the correct point + u32 mapped_offset, mapped_length; + if (real_pitch != rsx_pitch) + { + if (LIKELY(!valid_offset)) + { + mapped_offset = 0; + } + else if (valid_offset) + { + const u32 offset_in_x = valid_offset % rsx_pitch; + const u32 offset_in_y = valid_offset / rsx_pitch; + mapped_offset = (offset_in_y * real_pitch) + offset_in_x; + } + + const u32 available_vmem = (get_section_size() / rsx_pitch) * real_pitch + std::min(get_section_size() % rsx_pitch, real_pitch); + mapped_length = std::min(available_vmem - mapped_offset, valid_length); + } + else + { + mapped_offset = valid_offset; + mapped_length = valid_length; + } + // Obtain pointers to the source and destination memory regions - u8 *src = static_cast(derived()->map_synchronized(valid_offset, valid_length)); + u8 *src = static_cast(derived()->map_synchronized(mapped_offset, mapped_length)); u32 dst = valid_range.start; ASSERT(src != nullptr); diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 83f6d1307b..fe08587a1c 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -387,6 +387,7 @@ namespace gl { AUDIT(synchronized); + verify(HERE), (offset + size) <= pbo_size; glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo_id); return glMapBufferRange(GL_PIXEL_PACK_BUFFER, offset, size, GL_MAP_READ_BIT); }