mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-13 02:08:49 +12:00
rsx: Add duplicate section detection when there are too many sections in the surface cache
- Check for useless sections. Helps in games that create a bunch of sections randomly for one-time use
This commit is contained in:
parent
b8311caa6b
commit
eba7d3b172
2 changed files with 64 additions and 0 deletions
|
@ -956,6 +956,49 @@ namespace rsx
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void check_for_duplicates(std::vector<surface_overlap_info>& sections, const rsx::address_range& range)
|
||||||
|
{
|
||||||
|
// Generic painter's algorithm to detect obsolete sections
|
||||||
|
ensure(range.length() < 64 * 0x100000);
|
||||||
|
std::vector<u8> marker(range.length());
|
||||||
|
std::memset(marker.data(), 0, range.length());
|
||||||
|
|
||||||
|
for (auto it = sections.crbegin(); it != sections.crend(); ++it)
|
||||||
|
{
|
||||||
|
if (it->base_address < range.start)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto true_pitch_in_bytes = it->surface->get_surface_width(rsx::surface_metrics::bytes);
|
||||||
|
const auto true_height_in_rows = it->surface->get_surface_height(rsx::surface_metrics::samples);
|
||||||
|
|
||||||
|
bool valid = false;
|
||||||
|
auto addr = it->base_address - range.start;
|
||||||
|
auto data = marker.data();
|
||||||
|
|
||||||
|
for (usz row = 0; row < true_height_in_rows; ++row)
|
||||||
|
{
|
||||||
|
for (usz col = 0; col < true_pitch_in_bytes; ++col)
|
||||||
|
{
|
||||||
|
if (const auto loc = col + addr; !data[loc])
|
||||||
|
{
|
||||||
|
valid = true;
|
||||||
|
data[loc] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addr += true_pitch_in_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!valid)
|
||||||
|
{
|
||||||
|
rsx_log.error("Stale surface at address 0x%x will be deleted", it->base_address);
|
||||||
|
invalidate_surface_address(it->base_address, it->is_depth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void on_write(const bool* color, bool z)
|
void on_write(const bool* color, bool z)
|
||||||
{
|
{
|
||||||
if (write_tag == cache_tag && m_skip_write_updates)
|
if (write_tag == cache_tag && m_skip_write_updates)
|
||||||
|
|
|
@ -1783,6 +1783,26 @@ namespace rsx
|
||||||
|
|
||||||
if (result_is_valid)
|
if (result_is_valid)
|
||||||
{
|
{
|
||||||
|
// Check for possible duplicates
|
||||||
|
usz max_safe_sections = UINT32_MAX;
|
||||||
|
switch (result.external_subresource_desc.op)
|
||||||
|
{
|
||||||
|
case deferred_request_command::atlas_gather:
|
||||||
|
max_safe_sections = 8 + attr.mipmaps; break;
|
||||||
|
case deferred_request_command::cubemap_gather:
|
||||||
|
max_safe_sections = 8 * attr.mipmaps; break;
|
||||||
|
case deferred_request_command::_3d_gather:
|
||||||
|
max_safe_sections = (attr.depth * attr.mipmaps * 110) / 100; break; // 10% factor of safety
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overlapping_fbos.size() > max_safe_sections)
|
||||||
|
{
|
||||||
|
rsx_log.error("[Performance warning] Texture gather routine encountered too many objects!");
|
||||||
|
m_rtts.check_for_duplicates(overlapping_fbos, memory_range);
|
||||||
|
}
|
||||||
|
|
||||||
// Optionally disallow caching if resource is being written to as it is being read from
|
// Optionally disallow caching if resource is being written to as it is being read from
|
||||||
for (const auto& section : overlapping_fbos)
|
for (const auto& section : overlapping_fbos)
|
||||||
{
|
{
|
||||||
|
@ -1855,6 +1875,7 @@ namespace rsx
|
||||||
attributes.bpp = get_format_block_size_in_bytes(attributes.gcm_format);
|
attributes.bpp = get_format_block_size_in_bytes(attributes.gcm_format);
|
||||||
attributes.width = tex.width();
|
attributes.width = tex.width();
|
||||||
attributes.height = tex.height();
|
attributes.height = tex.height();
|
||||||
|
attributes.mipmaps = tex.get_exact_mipmap_count();
|
||||||
attributes.swizzled = !(tex.format() & CELL_GCM_TEXTURE_LN);
|
attributes.swizzled = !(tex.format() & CELL_GCM_TEXTURE_LN);
|
||||||
|
|
||||||
const bool is_unnormalized = !!(tex.format() & CELL_GCM_TEXTURE_UN);
|
const bool is_unnormalized = !!(tex.format() & CELL_GCM_TEXTURE_UN);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue