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:
Rui Pinheiro 2018-08-12 00:30:23 +01:00 committed by kd-11
parent b534d49e48
commit fa6a5761b3

View file

@ -567,6 +567,7 @@ namespace rsx
{
std::vector<std::pair<section_storage_type*, ranged_storage*>> result;
u32 last_dirty_block = UINT32_MAX;
bool repeat_loop = false;
const u64 cache_tag = get_system_time();
std::pair<u32, u32> trampled_range = std::make_pair(address, address + range);
@ -575,22 +576,13 @@ namespace rsx
auto It = m_cache.begin();
while (It != m_cache.end())
{
auto &range_data = It->second;
const u32 base = It->first;
bool range_reset = false;
auto &range_data = It->second;
if (base == last_dirty_block && range_data.valid_count == 0)
continue;
if (trampled_range.first <= trampled_range.second)
// Ignore invalid or empty sets
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))
{
//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)
{
It++;
continue;
}
}
for (int i = 0; i < range_data.data.size(); i++)
{
@ -610,23 +602,30 @@ namespace rsx
if (new_range.first != trampled_range.first ||
new_range.second != trampled_range.second)
{
i = 0;
trampled_range = new_range;
range_reset = true;
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)
{
last_dirty_block = base;
It = m_cache.begin();
}
else
// 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())
{
It = m_cache.begin();
repeat_loop = false;
}
}
return result;