rsx: Resync excluded memory regions to avoid memory tests failing after flush events

- This is a mostly correct fix, but a corner case exists that can leak old data to the surface cache
This commit is contained in:
kd-11 2020-10-20 23:38:05 +03:00 committed by Ivan
parent 78972cd611
commit 966aec7ad7
4 changed files with 51 additions and 0 deletions

View File

@ -374,6 +374,7 @@ namespace rsx
auto &object = storage[e.first];
ensure(object);
if (!surface->old_contents.empty()) [[unlikely]]
{
surface->read_barrier(cmd);

View File

@ -515,6 +515,34 @@ namespace rsx
}
}
// Resync any exclusions that do not require flushing
std::vector<section_storage_type*> surfaces_to_inherit;
for (auto& surface : data.sections_to_exclude)
{
if (surface->get_context() != texture_upload_context::framebuffer_storage)
{
continue;
}
// Check for any 'newer' flushed overlaps. Memory must be re-acquired to avoid holding stale contents
// Note that the surface cache inheritance will minimize the impact
surfaces_to_inherit.clear();
for (auto& flushed_surface : data.sections_to_flush)
{
if (flushed_surface->get_context() != texture_upload_context::framebuffer_storage ||
flushed_surface->last_write_tag <= surface->last_write_tag ||
!flushed_surface->get_confirmed_range().overlaps(surface->get_confirmed_range()))
{
continue;
}
surfaces_to_inherit.push_back(flushed_surface);
}
surface->sync_surface_memory(surfaces_to_inherit);
}
data.flushed = true;
}

View File

@ -350,6 +350,17 @@ namespace gl
baseclass::on_section_resources_destroyed();
}
void sync_surface_memory(const std::vector<cached_texture_section*>& surfaces)
{
auto rtt = gl::as_rtt(vram_texture);
rtt->sync_tag();
for (auto& surface : surfaces)
{
rtt->inherit_surface_contents(gl::as_rtt(surface->vram_texture));
}
}
bool exists() const
{
return (vram_texture != nullptr);

View File

@ -321,6 +321,17 @@ namespace vk
rsx_pitch = pitch;
}
void sync_surface_memory(const std::vector<cached_texture_section*>& surfaces)
{
auto rtt = vk::as_rtt(vram_texture);
rtt->sync_tag();
for (auto& surface : surfaces)
{
rtt->inherit_surface_contents(vk::as_rtt(surface->vram_texture));
}
}
bool is_synchronized() const
{
return synchronized;