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:
kd-11 2018-08-14 22:58:50 +03:00 committed by kd-11
parent ec31157bc7
commit 4b2b662c3a
2 changed files with 55 additions and 11 deletions

View file

@ -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,16 +1019,40 @@ 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)
{
if (write_tag == cache_tag)
{ {
// Nothing to do // Nothing to do
return; 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()

View file

@ -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);