mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-10 00:41:26 +12:00
Refactor get_intersecting_set
The existing implementation restarts the loop immediately after finding a range_data instance that updates the trampled_range. This commit refactors this method to continue the loop with the updated trampled_range, and then repeat only those range_data instances that were iterated through before the trampled_range was last updated. As a result, the number of total iterations required is reduced.
This commit is contained in:
parent
b534d49e48
commit
fa6a5761b3
1 changed files with 38 additions and 39 deletions
|
@ -567,66 +567,65 @@ namespace rsx
|
||||||
{
|
{
|
||||||
std::vector<std::pair<section_storage_type*, ranged_storage*>> result;
|
std::vector<std::pair<section_storage_type*, ranged_storage*>> result;
|
||||||
u32 last_dirty_block = UINT32_MAX;
|
u32 last_dirty_block = UINT32_MAX;
|
||||||
|
bool repeat_loop = false;
|
||||||
const u64 cache_tag = get_system_time();
|
const u64 cache_tag = get_system_time();
|
||||||
|
|
||||||
std::pair<u32, u32> trampled_range = std::make_pair(address, address + range);
|
std::pair<u32, u32> trampled_range = std::make_pair(address, address + range);
|
||||||
const bool strict_range_check = g_cfg.video.write_color_buffers || g_cfg.video.write_depth_buffer;
|
const bool strict_range_check = g_cfg.video.write_color_buffers || g_cfg.video.write_depth_buffer;
|
||||||
|
|
||||||
auto It = m_cache.begin();
|
auto It = m_cache.begin();
|
||||||
while(It != m_cache.end())
|
while (It != m_cache.end())
|
||||||
{
|
{
|
||||||
auto &range_data = It->second;
|
|
||||||
const u32 base = It->first;
|
const u32 base = It->first;
|
||||||
bool range_reset = false;
|
auto &range_data = It->second;
|
||||||
|
|
||||||
if (base == last_dirty_block && range_data.valid_count == 0)
|
// Ignore invalid or empty sets
|
||||||
continue;
|
if (trampled_range.first <= trampled_range.second &&
|
||||||
|
!(trampled_range.first >= (range_data.max_addr + range_data.max_range) || range_data.min_addr >= trampled_range.second))
|
||||||
if (trampled_range.first <= trampled_range.second)
|
|
||||||
{
|
{
|
||||||
//Only if a valid range, ignore empty sets
|
|
||||||
if (trampled_range.first >= (range_data.max_addr + range_data.max_range) || range_data.min_addr >= trampled_range.second)
|
for (int i = 0; i < range_data.data.size(); i++)
|
||||||
{
|
{
|
||||||
It++;
|
auto &tex = range_data.data[i];
|
||||||
continue;
|
if (tex.cache_tag == cache_tag) continue; //already processed
|
||||||
}
|
if (!tex.is_locked()) continue; //flushable sections can be 'clean' but unlocked. TODO: Handle this better
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < range_data.data.size(); i++)
|
const auto bounds_test = (strict_range_check || tex.get_context() == rsx::texture_upload_context::blit_engine_dst) ?
|
||||||
{
|
rsx::overlap_test_bounds::full_range :
|
||||||
auto &tex = range_data.data[i];
|
rsx::overlap_test_bounds::protected_range;
|
||||||
if (tex.cache_tag == cache_tag) continue; //already processed
|
|
||||||
if (!tex.is_locked()) continue; //flushable sections can be 'clean' but unlocked. TODO: Handle this better
|
|
||||||
|
|
||||||
const auto bounds_test = (strict_range_check || tex.get_context() == rsx::texture_upload_context::blit_engine_dst) ?
|
auto overlapped = tex.overlaps_page(trampled_range, address, bounds_test);
|
||||||
rsx::overlap_test_bounds::full_range :
|
if (std::get<0>(overlapped))
|
||||||
rsx::overlap_test_bounds::protected_range;
|
|
||||||
|
|
||||||
auto overlapped = tex.overlaps_page(trampled_range, address, bounds_test);
|
|
||||||
if (std::get<0>(overlapped))
|
|
||||||
{
|
|
||||||
auto &new_range = std::get<1>(overlapped);
|
|
||||||
|
|
||||||
if (new_range.first != trampled_range.first ||
|
|
||||||
new_range.second != trampled_range.second)
|
|
||||||
{
|
{
|
||||||
i = 0;
|
auto &new_range = std::get<1>(overlapped);
|
||||||
trampled_range = new_range;
|
|
||||||
range_reset = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
tex.cache_tag = cache_tag;
|
if (new_range.first != trampled_range.first ||
|
||||||
result.push_back({&tex, &range_data});
|
new_range.second != trampled_range.second)
|
||||||
|
{
|
||||||
|
trampled_range = new_range;
|
||||||
|
repeat_loop = true; // we will need to repeat the loop again
|
||||||
|
last_dirty_block = base; // stop the repeat loop once we finish this block
|
||||||
|
}
|
||||||
|
|
||||||
|
tex.cache_tag = cache_tag;
|
||||||
|
result.push_back({ &tex, &range_data });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (range_reset)
|
// On the last loop, we stop once we're done with the last dirty block
|
||||||
|
if (!repeat_loop && base == last_dirty_block)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Iterate
|
||||||
|
It++;
|
||||||
|
|
||||||
|
// repeat_loop==true means some blocks are still dirty and we need to repeat the loop again
|
||||||
|
if (repeat_loop && It == m_cache.end())
|
||||||
{
|
{
|
||||||
last_dirty_block = base;
|
|
||||||
It = m_cache.begin();
|
It = m_cache.begin();
|
||||||
|
repeat_loop = false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
It++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue