mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-10 00:41:26 +12:00
rsx: Followup to the memory inheritance hierachy patch
- Tags framebuffer resources on first use (when on_write is called to verify memory) - Texture cache now selects the best match and even sorts atlas writes with memory write order to avoid older data showing over newer one
This commit is contained in:
parent
ec31157bc7
commit
4b2b662c3a
2 changed files with 55 additions and 11 deletions
|
@ -81,6 +81,8 @@ namespace rsx
|
||||||
template <typename image_storage_type>
|
template <typename image_storage_type>
|
||||||
struct render_target_descriptor
|
struct render_target_descriptor
|
||||||
{
|
{
|
||||||
|
u64 last_use_tag = 0; // tag indicating when this block was last confirmed to have been written to
|
||||||
|
|
||||||
bool dirty = false;
|
bool dirty = false;
|
||||||
image_storage_type old_contents = nullptr;
|
image_storage_type old_contents = nullptr;
|
||||||
rsx::surface_antialiasing read_aa_mode = rsx::surface_antialiasing::center_1_sample;
|
rsx::surface_antialiasing read_aa_mode = rsx::surface_antialiasing::center_1_sample;
|
||||||
|
@ -105,8 +107,14 @@ namespace rsx
|
||||||
write_aa_mode = read_aa_mode = rsx::surface_antialiasing::center_1_sample;
|
write_aa_mode = read_aa_mode = rsx::surface_antialiasing::center_1_sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_write()
|
void on_write(u64 write_tag = 0)
|
||||||
{
|
{
|
||||||
|
if (write_tag)
|
||||||
|
{
|
||||||
|
// Update use tag if requested
|
||||||
|
last_use_tag = write_tag;
|
||||||
|
}
|
||||||
|
|
||||||
read_aa_mode = write_aa_mode;
|
read_aa_mode = write_aa_mode;
|
||||||
dirty = false;
|
dirty = false;
|
||||||
old_contents = nullptr;
|
old_contents = nullptr;
|
||||||
|
@ -1011,15 +1019,39 @@ namespace rsx
|
||||||
|
|
||||||
process_list_function(m_render_targets_storage, false);
|
process_list_function(m_render_targets_storage, false);
|
||||||
process_list_function(m_depth_stencil_storage, true);
|
process_list_function(m_depth_stencil_storage, true);
|
||||||
|
|
||||||
|
if (result.size() > 1)
|
||||||
|
{
|
||||||
|
std::sort(result.begin(), result.end(), [](const auto &a, const auto &b)
|
||||||
|
{
|
||||||
|
if (a.surface->last_use_tag == b.surface->last_use_tag)
|
||||||
|
{
|
||||||
|
const auto area_a = a.width * a.height;
|
||||||
|
const auto area_b = b.width * b.height;
|
||||||
|
|
||||||
|
return area_a < area_b;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a.surface->last_use_tag < b.surface->last_use_tag;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_write(u32 address = 0)
|
void on_write(u32 address = 0)
|
||||||
{
|
{
|
||||||
if (!address && write_tag == cache_tag)
|
if (!address)
|
||||||
{
|
{
|
||||||
// Nothing to do
|
if (write_tag == cache_tag)
|
||||||
return;
|
{
|
||||||
|
// Nothing to do
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
write_tag = cache_tag;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memory_tag != cache_tag)
|
if (memory_tag != cache_tag)
|
||||||
|
@ -1053,7 +1085,7 @@ namespace rsx
|
||||||
|
|
||||||
if (auto surface = std::get<1>(rtt))
|
if (auto surface = std::get<1>(rtt))
|
||||||
{
|
{
|
||||||
surface->on_write();
|
surface->on_write(write_tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1061,14 +1093,9 @@ namespace rsx
|
||||||
{
|
{
|
||||||
if (!address || std::get<0>(m_bound_depth_stencil) == address)
|
if (!address || std::get<0>(m_bound_depth_stencil) == address)
|
||||||
{
|
{
|
||||||
ds->on_write();
|
ds->on_write(write_tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!address)
|
|
||||||
{
|
|
||||||
write_tag = cache_tag;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void notify_memory_structure_changed()
|
void notify_memory_structure_changed()
|
||||||
|
|
|
@ -1602,8 +1602,25 @@ namespace rsx
|
||||||
|
|
||||||
auto bpp = get_format_block_size_in_bytes(format);
|
auto bpp = get_format_block_size_in_bytes(format);
|
||||||
auto overlapping = m_rtts.get_merged_texture_memory_region(texaddr, tex_width, tex_height, tex_pitch, bpp);
|
auto overlapping = m_rtts.get_merged_texture_memory_region(texaddr, tex_width, tex_height, tex_pitch, bpp);
|
||||||
|
bool requires_merging = false;
|
||||||
|
|
||||||
if (overlapping.size() > 1)
|
if (overlapping.size() > 1)
|
||||||
|
{
|
||||||
|
// The returned values are sorted with oldest first and newest last
|
||||||
|
// This allows newer data to overwrite older memory when merging the list
|
||||||
|
if (overlapping.back().surface == texptr)
|
||||||
|
{
|
||||||
|
// The texture 'proposed' by the previous lookup is the newest one
|
||||||
|
// If it occupies the entire requested region, just use it as-is
|
||||||
|
requires_merging = (internal_width > surface_width || internal_height > surface_height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
requires_merging = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requires_merging)
|
||||||
{
|
{
|
||||||
const auto w = rsx::apply_resolution_scale(internal_width, true);
|
const auto w = rsx::apply_resolution_scale(internal_width, true);
|
||||||
const auto h = rsx::apply_resolution_scale(internal_height, true);
|
const auto h = rsx::apply_resolution_scale(internal_height, true);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue