mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-29 22:20:48 +00:00
rsx: Refactor surface inheritance logic
This commit is contained in:
parent
24e4a43ec4
commit
78972cd611
@ -279,6 +279,7 @@ namespace rsx
|
|||||||
}
|
}
|
||||||
|
|
||||||
result.push_back({ e.first, surface });
|
result.push_back({ e.first, surface });
|
||||||
|
ensure(e.first == surface->base_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -327,10 +328,6 @@ namespace rsx
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Modify deferred_clip_region::direct_copy() to take a few more things into account!
|
// 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();
|
const auto pitch = new_surface->get_rsx_pitch();
|
||||||
for (const auto &e: surface_info)
|
for (const auto &e: surface_info)
|
||||||
{
|
{
|
||||||
@ -367,41 +364,8 @@ namespace rsx
|
|||||||
ensure(this_address);
|
ensure(this_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto parent_region = surface->get_normalized_memory_area();
|
if (new_surface->inherit_surface_contents(surface) == surface_inheritance_result::full &&
|
||||||
const auto parent_w = parent_region.width();
|
surface->memory_usage_flags == surface_usage_flags::storage &&
|
||||||
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 &&
|
|
||||||
surface != prev_surface &&
|
surface != prev_surface &&
|
||||||
surface == e.second)
|
surface == e.second)
|
||||||
{
|
{
|
||||||
@ -409,8 +373,6 @@ namespace rsx
|
|||||||
auto &storage = surface->is_depth_surface() ? m_depth_stencil_storage : m_render_targets_storage;
|
auto &storage = surface->is_depth_surface() ? m_depth_stencil_storage : m_render_targets_storage;
|
||||||
auto &object = storage[e.first];
|
auto &object = storage[e.first];
|
||||||
|
|
||||||
ensure(!src_offset.x);
|
|
||||||
ensure(!src_offset.y);
|
|
||||||
ensure(object);
|
ensure(object);
|
||||||
if (!surface->old_contents.empty()) [[unlikely]]
|
if (!surface->old_contents.empty()) [[unlikely]]
|
||||||
{
|
{
|
||||||
|
@ -19,12 +19,19 @@ namespace rsx
|
|||||||
require_unresolve = 4
|
require_unresolve = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
enum surface_sample_layout : u32
|
enum class surface_sample_layout : u32
|
||||||
{
|
{
|
||||||
null = 0,
|
null = 0,
|
||||||
ps3 = 1
|
ps3 = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class surface_inheritance_result : u32
|
||||||
|
{
|
||||||
|
none = 0,
|
||||||
|
partial,
|
||||||
|
full
|
||||||
|
};
|
||||||
|
|
||||||
template <typename surface_type>
|
template <typename surface_type>
|
||||||
struct surface_overlap_info_t
|
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,
|
void on_write(u64 write_tag = 0,
|
||||||
rsx::surface_state_flags resolve_flags = surface_state_flags::require_resolve,
|
rsx::surface_state_flags resolve_flags = surface_state_flags::require_resolve,
|
||||||
surface_raster_type type = rsx::surface_raster_type::undefined)
|
surface_raster_type type = rsx::surface_raster_type::undefined)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user