1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2025-03-15 04:21:01 +00:00

rsx: Refactor surface inheritance logic

This commit is contained in:
kd-11 2021-04-18 21:42:34 +03:00 committed by Ivan
parent 24e4a43ec4
commit 78972cd611
2 changed files with 52 additions and 42 deletions
rpcs3/Emu/RSX/Common

@ -279,6 +279,7 @@ namespace rsx
}
result.push_back({ e.first, surface });
ensure(e.first == surface->base_addr);
}
return result;
@ -327,10 +328,6 @@ namespace rsx
}
// TODO: Modify deferred_clip_region::direct_copy() to take a few more things into account!
const areau child_region = new_surface->get_normalized_memory_area();
const auto child_w = child_region.width();
const auto child_h = child_region.height();
const auto pitch = new_surface->get_rsx_pitch();
for (const auto &e: surface_info)
{
@ -367,41 +364,8 @@ namespace rsx
ensure(this_address);
}
const auto parent_region = surface->get_normalized_memory_area();
const auto parent_w = parent_region.width();
const auto parent_h = parent_region.height();
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 dst_offset = std::get<1>(rect);
const auto size = std::get<2>(rect);
if (src_offset.x >= parent_w || src_offset.y >= parent_h)
{
continue;
}
if (dst_offset.x >= child_w || dst_offset.y >= child_h)
{
continue;
}
// TODO: Eventually need to stack all the overlapping regions, but for now just do the latest rect in the space
deferred_clipped_region<surface_type> region;
region.src_x = src_offset.x;
region.src_y = src_offset.y;
region.dst_x = dst_offset.x;
region.dst_y = dst_offset.y;
region.width = size.width;
region.height = size.height;
region.source = surface;
region.target = new_surface;
new_surface->set_old_contents_region(region, true);
if (surface->memory_usage_flags == surface_usage_flags::storage &&
region.width == parent_w &&
region.height == parent_h &&
if (new_surface->inherit_surface_contents(surface) == surface_inheritance_result::full &&
surface->memory_usage_flags == surface_usage_flags::storage &&
surface != prev_surface &&
surface == e.second)
{
@ -409,8 +373,6 @@ namespace rsx
auto &storage = surface->is_depth_surface() ? m_depth_stencil_storage : m_render_targets_storage;
auto &object = storage[e.first];
ensure(!src_offset.x);
ensure(!src_offset.y);
ensure(object);
if (!surface->old_contents.empty()) [[unlikely]]
{

@ -19,12 +19,19 @@ namespace rsx
require_unresolve = 4
};
enum surface_sample_layout : u32
enum class surface_sample_layout : u32
{
null = 0,
ps3 = 1
};
enum class surface_inheritance_result : u32
{
none = 0,
partial,
full
};
template <typename surface_type>
struct surface_overlap_info_t
{
@ -504,6 +511,47 @@ namespace rsx
}
}
template <typename T>
surface_inheritance_result inherit_surface_contents(T* surface)
{
const auto child_w = get_surface_width(rsx::surface_metrics::bytes);
const auto child_h = get_surface_height(rsx::surface_metrics::bytes);
const auto parent_w = surface->get_surface_width(rsx::surface_metrics::bytes);
const auto parent_h = surface->get_surface_height(rsx::surface_metrics::bytes);
const auto rect = rsx::intersect_region(surface->base_addr, parent_w, parent_h, 1, base_addr, child_w, child_h, 1, get_rsx_pitch());
const auto src_offset = std::get<0>(rect);
const auto dst_offset = std::get<1>(rect);
const auto size = std::get<2>(rect);
if (src_offset.x >= parent_w || src_offset.y >= parent_h)
{
return surface_inheritance_result::none;
}
if (dst_offset.x >= child_w || dst_offset.y >= child_h)
{
return surface_inheritance_result::none;
}
// TODO: Eventually need to stack all the overlapping regions, but for now just do the latest rect in the space
deferred_clipped_region<T*> region;
region.src_x = src_offset.x;
region.src_y = src_offset.y;
region.dst_x = dst_offset.x;
region.dst_y = dst_offset.y;
region.width = size.width;
region.height = size.height;
region.source = surface;
region.target = static_cast<T*>(this);
set_old_contents_region(region, true);
return (region.width == parent_w && region.height == parent_h) ?
surface_inheritance_result::full :
surface_inheritance_result::partial;
}
void on_write(u64 write_tag = 0,
rsx::surface_state_flags resolve_flags = surface_state_flags::require_resolve,
surface_raster_type type = rsx::surface_raster_type::undefined)