1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 18:53:28 +01:00

rsx: Handle lost data due to unused data sections

- After splitting, the sections may not be referenced at all for anything other than just pixel storage
- In such cases, either merge down or sample from the upstream source instead
This commit is contained in:
kd-11 2019-07-15 21:48:21 +03:00 committed by kd-11
parent 998717659f
commit 34b06453f9
2 changed files with 30 additions and 8 deletions

View File

@ -198,8 +198,7 @@ namespace rsx
if (new_surface->last_use_tag > surface->last_use_tag || if (new_surface->last_use_tag > surface->last_use_tag ||
new_surface == surface || new_surface == surface ||
address == e.first || address == e.first)
e.second->dirty())
{ {
// Do not bother synchronizing with uninitialized data // Do not bother synchronizing with uninitialized data
continue; continue;
@ -292,10 +291,36 @@ namespace rsx
const auto pitch = new_surface->get_rsx_pitch(); const auto pitch = new_surface->get_rsx_pitch();
for (const auto &e: surface_info) for (const auto &e: surface_info)
{ {
const auto parent_region = e.second->get_normalized_memory_area(); auto this_address = e.first;
auto surface = e.second;
if (UNLIKELY(surface->old_contents.size() == 1))
{
// Dirty zombies are possible with unused pixel storage subslices and are valid
// Avoid double transfer if possible
// This is an optional optimization that can be safely disabled
surface = dynamic_cast<decltype(surface)>(surface->old_contents[0].source);
this_address = surface->memory_tag_samples[0].first;
verify(HERE), surface, this_address;
// If this surface has already been added via another descendant, just ignore it
bool ignore = false;
for (auto &slice : new_surface->old_contents)
{
if (slice.source == surface)
{
ignore = true;
break;
}
}
if (ignore) continue;
}
const auto parent_region = surface->get_normalized_memory_area();
const auto parent_w = parent_region.width(); const auto parent_w = parent_region.width();
const auto parent_h = parent_region.height(); const auto parent_h = parent_region.height();
const auto rect = rsx::intersect_region(e.first, parent_w, parent_h, 1, address, child_w, child_h, 1, pitch); const auto rect = rsx::intersect_region(this_address, parent_w, parent_h, 1, address, child_w, child_h, 1, pitch);
const auto src_offset = std::get<0>(rect); const auto src_offset = std::get<0>(rect);
const auto dst_offset = std::get<1>(rect); const auto dst_offset = std::get<1>(rect);
@ -325,7 +350,7 @@ namespace rsx
region.dst_y = dst_offset.y; region.dst_y = dst_offset.y;
region.width = size.width; region.width = size.width;
region.height = size.height; region.height = size.height;
region.source = e.second; region.source = surface;
region.target = new_surface; region.target = new_surface;
new_surface->set_old_contents_region(region, true); new_surface->set_old_contents_region(region, true);

View File

@ -51,9 +51,6 @@ namespace rsx
template <typename surface_type> template <typename surface_type>
struct deferred_clipped_region struct deferred_clipped_region
{ {
// Chain
deferred_clipped_region<surface_type>* next_ptr = nullptr;
u16 src_x, src_y, dst_x, dst_y, width, height; u16 src_x, src_y, dst_x, dst_y, width, height;
f32 transfer_scale_x, transfer_scale_y; f32 transfer_scale_x, transfer_scale_y;
surface_type target; surface_type target;