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:
parent
24e4a43ec4
commit
78972cd611
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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user