diff --git a/rpcs3/Emu/RSX/Common/surface_store.h b/rpcs3/Emu/RSX/Common/surface_store.h index 259b52960c..e397943667 100644 --- a/rpcs3/Emu/RSX/Common/surface_store.h +++ b/rpcs3/Emu/RSX/Common/surface_store.h @@ -81,6 +81,8 @@ namespace rsx template struct render_target_descriptor { + u64 last_use_tag = 0; // tag indicating when this block was last confirmed to have been written to + bool dirty = false; image_storage_type old_contents = nullptr; rsx::surface_antialiasing read_aa_mode = rsx::surface_antialiasing::center_1_sample; @@ -105,8 +107,14 @@ namespace rsx write_aa_mode = read_aa_mode = rsx::surface_antialiasing::center_1_sample; } - void on_write() + void on_write(u64 write_tag = 0) { + if (write_tag) + { + // Update use tag if requested + last_use_tag = write_tag; + } + read_aa_mode = write_aa_mode; dirty = false; old_contents = nullptr; @@ -1011,15 +1019,39 @@ namespace rsx process_list_function(m_render_targets_storage, false); process_list_function(m_depth_stencil_storage, true); + + if (result.size() > 1) + { + std::sort(result.begin(), result.end(), [](const auto &a, const auto &b) + { + if (a.surface->last_use_tag == b.surface->last_use_tag) + { + const auto area_a = a.width * a.height; + const auto area_b = b.width * b.height; + + return area_a < area_b; + } + + return a.surface->last_use_tag < b.surface->last_use_tag; + }); + } + return result; } void on_write(u32 address = 0) { - if (!address && write_tag == cache_tag) + if (!address) { - // Nothing to do - return; + if (write_tag == cache_tag) + { + // Nothing to do + return; + } + else + { + write_tag = cache_tag; + } } if (memory_tag != cache_tag) @@ -1053,7 +1085,7 @@ namespace rsx if (auto surface = std::get<1>(rtt)) { - surface->on_write(); + surface->on_write(write_tag); } } @@ -1061,14 +1093,9 @@ namespace rsx { if (!address || std::get<0>(m_bound_depth_stencil) == address) { - ds->on_write(); + ds->on_write(write_tag); } } - - if (!address) - { - write_tag = cache_tag; - } } void notify_memory_structure_changed() diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index 9d90d8a2fd..f3ef02884c 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -1602,8 +1602,25 @@ namespace rsx auto bpp = get_format_block_size_in_bytes(format); auto overlapping = m_rtts.get_merged_texture_memory_region(texaddr, tex_width, tex_height, tex_pitch, bpp); + bool requires_merging = false; if (overlapping.size() > 1) + { + // The returned values are sorted with oldest first and newest last + // This allows newer data to overwrite older memory when merging the list + if (overlapping.back().surface == texptr) + { + // The texture 'proposed' by the previous lookup is the newest one + // If it occupies the entire requested region, just use it as-is + requires_merging = (internal_width > surface_width || internal_height > surface_height); + } + else + { + requires_merging = true; + } + } + + if (requires_merging) { const auto w = rsx::apply_resolution_scale(internal_width, true); const auto h = rsx::apply_resolution_scale(internal_height, true);