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:
parent
998717659f
commit
34b06453f9
@ -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);
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user