From f413996362d348747fad97fe76eae24085ac8907 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 10 Sep 2018 13:22:24 +0300 Subject: [PATCH] rsx: Minor texture cache fixes - Retag resources reprotected under flush_always rules - Properly check for blit resource fitting taking into account format mismatch, pitch mismatch and typeless transfers --- rpcs3/Emu/RSX/Common/texture_cache.h | 54 +++++++++++++++------------- rpcs3/Emu/RSX/GL/GLTextureCache.h | 6 +++- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index 620b93a12a..b6e6f882b5 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -2222,7 +2222,7 @@ namespace rsx if (!dst_is_render_target) { - //Check for any available region that will fit this one + // Check for any available region that will fit this one auto overlapping_surfaces = find_texture_from_range(dst_address, dst.pitch * dst.clip_height); for (const auto &surface : overlapping_surfaces) @@ -2230,6 +2230,9 @@ namespace rsx if (surface->get_context() != rsx::texture_upload_context::blit_engine_dst) continue; + if (surface->rsx_pitch != dst.pitch) + continue; + const auto old_dst_area = dst_area; if (const u32 address_offset = dst_address - surface->get_section_base()) { @@ -2244,17 +2247,15 @@ namespace rsx dst_area.y2 += offset_y; } - //Validate clipping region + // Validate clipping region if ((unsigned)dst_area.x2 <= surface->get_width() && (unsigned)dst_area.y2 <= surface->get_height()) { cached_dest = surface; break; } - else - { - dst_area = old_dst_area; - } + + dst_area = old_dst_area; } if (cached_dest) @@ -2299,9 +2300,12 @@ namespace rsx surface->get_context() == rsx::texture_upload_context::framebuffer_storage) continue; + if (surface->rsx_pitch != src.pitch) + continue; + if (const u32 address_offset = src_address - surface->get_section_base()) { - const u16 bpp = dst_is_argb8 ? 4 : 2; + const u16 bpp = src_is_argb8 ? 4 : 2; const u16 offset_y = address_offset / src.pitch; const u16 offset_x = address_offset % src.pitch; const u16 offset_x_in_block = offset_x / bpp; @@ -2412,17 +2416,6 @@ namespace rsx if (format_mismatch) { lock.upgrade(); - - //Mark for removal as the memory is not reusable now - if (cached_dest->is_locked()) - { - cached_dest->unprotect(); - m_cache[get_block_address(cached_dest->get_section_base())].remove_one(); - } - - cached_dest->set_dirty(true); - m_unreleased_texture_objects++; - invalidate_range_impl_base(cached_dest->get_section_base(), cached_dest->get_section_size(), true, false, true, std::forward(extras)...); dest_texture = 0; @@ -2488,16 +2481,11 @@ namespace rsx if (cached_dest) { - const bool notify = !cached_dest->is_locked(); - const u32 mem_base = dst_area.y1 * dst.pitch; - const u32 mem_length = (dst.clip_height == 1)? - dst.clip_width * (dst_is_argb8? 4 : 2) : // Lock full rows if its a rectangular section - dst.pitch * dst.clip_height; // Lock only part of fist row if simple 1D array - lock.upgrade(); - if (notify) + if (!cached_dest->is_locked()) { + // Notify m_cache[get_block_address(cached_dest->get_section_base())].notify(); } else if (cached_dest->is_synchronized()) @@ -2506,6 +2494,21 @@ namespace rsx m_num_cache_mispredictions++; } + u32 mem_length; + const u32 mem_base = dst_address - cached_dest->get_section_base(); + + if (dst.clip_height == 1) + { + mem_length = dst.clip_width * (dst_is_argb8 ? 4 : 2); + } + else + { + const u32 mem_excess = mem_base % dst.pitch; + mem_length = (dst.pitch * dst.clip_height) - mem_excess; + } + + verify(HERE), (mem_base + mem_length) <= cached_dest->get_section_size(); + cached_dest->reprotect(utils::protection::no, { mem_base, mem_length }); cached_dest->touch(); } @@ -2587,6 +2590,7 @@ namespace rsx { //NOTE: find_cached_texture will increment block ctr section.reprotect(utils::protection::no); + tag_framebuffer(It.first); update_tag = true; } else diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 5428814d64..e3d8d1115e 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -285,9 +285,13 @@ namespace gl synchronized = false; sync_timestamp = 0ull; + if (rsx_pitch > 0) + this->rsx_pitch = rsx_pitch; + else + this->rsx_pitch = cpu_address_range / height; + this->width = w; this->height = h; - this->rsx_pitch = rsx_pitch; this->real_pitch = 0; this->depth = depth; this->mipmaps = mipmaps;