rsx: Avoid false surface match rejection when data is uploaded into the surface cache during RTT scan

This commit is contained in:
kd-11
2026-08-28 14:55:44 +03:00
committed by kd-11
parent 7d1b67b17a
commit 124462fbab
3 changed files with 28 additions and 2 deletions
+4
View File
@@ -1260,6 +1260,9 @@ namespace rsx
// Drop any excess subpixels on the requester side if any. Ensures division generates a perfect fitting rect without rounding bugs.
width_in_bytes -= (width_in_bytes % required_bpp);
// We need to track if this surface is reloaded from CPU during this next step.
const bool needs_reload = surface->needs_cpu_upload();
// Delay this as much as possible to avoid side-effects of spamming barrier
if (surface->memory_barrier(cmd, access); !surface->test())
{
@@ -1272,6 +1275,7 @@ namespace rsx
info.base_address = range.start;
info.is_depth = is_depth;
info.is_clipped = (width_in_bytes < required_width_in_bytes || height < required_height);
info.is_reloaded = needs_reload;
// Decode source
info.src_area.x = src_x / surface_bpp;
+18
View File
@@ -39,6 +39,7 @@ namespace rsx
u32 base_address = 0;
bool is_depth = false;
bool is_clipped = false;
bool is_reloaded = false;
coordu src_area; //<- Always computed in source image coordinates
coordu dst_area; //<- Always computed in destination (requester) image coordinates
@@ -357,6 +358,23 @@ namespace rsx
return (state_flags & rsx::surface_state_flags::erase_bkgnd) && old_contents.empty();
}
inline bool needs_cpu_upload() const
{
if ((state_flags & rsx::surface_state_flags::erase_bkgnd) == 0) [[ likely ]]
{
return false;
}
if (state_flags & rsx::surface_state_flags::force_data_load)
{
return true;
}
return is_depth_surface()
? !!g_cfg.video.read_depth_buffer
: !!g_cfg.video.read_color_buffers;
}
#if (ENABLE_SURFACE_CACHE_DEBUG)
u64 hash_block() const
{
+6 -2
View File
@@ -3399,13 +3399,17 @@ namespace rsx
// FBO re-validation. It is common for GPU and CPU data to desync as we do not have a way to share memory pages directly between the two (in most setups)
// To avoid losing data, we need to do some gymnastics
if (src_is_render_target && !blit_engine_internals::validate_fbo_integrity(this, src_subres.surface->get_memory_range(), src_subres.is_depth))
if (src_is_render_target &&
!src_subres.is_reloaded &&
!blit_engine_internals::validate_fbo_integrity(this, src_subres.surface->get_memory_range(), src_subres.is_depth))
{
src_is_render_target = false;
src_subres.surface = nullptr;
}
if (dst_is_render_target && !blit_engine_internals::validate_fbo_integrity(this, dst_subres.surface->get_memory_range(), dst_subres.is_depth))
if (dst_is_render_target &&
!dst_subres.is_reloaded &&
!blit_engine_internals::validate_fbo_integrity(this, dst_subres.surface->get_memory_range(), dst_subres.is_depth))
{
// This is a lot more serious that the src case. We have to signal surface cache to reload the memory and discard what we have GPU-side.
// Do the transfer CPU side and we should eventually "read" the data on RCB/RDB barrier.