rsx: Improve texture cache invalidate

- Bunch of improvements
- Properly signal renderer to rebind textures!
- TODO: Range checks, should be pretty easy
This commit is contained in:
kd-11 2021-01-28 21:53:49 +03:00 committed by kd-11
parent 52acc23ecf
commit 195fb1cf66
4 changed files with 52 additions and 20 deletions

View File

@ -53,6 +53,7 @@ namespace rsx
{
bool violation_handled = false;
bool flushed = false;
bool invalidate_samplers = false;
invalidation_cause cause;
std::vector<section_storage_type*> sections_to_flush; // Sections to be flushed
std::vector<section_storage_type*> sections_to_unprotect; // These sections are to be unpotected and discarded by caller
@ -683,13 +684,6 @@ namespace rsx
auto &tex = *It;
if (!tex.is_locked(true))
{
// Ignore hash sections, they are not involved in page faults
It++;
continue;
}
AUDIT(tex.is_locked()); // we should be iterating locked sections only, but just to make sure...
AUDIT(tex.cache_tag != cache_tag || last_dirty_block != UINT32_MAX); // cache tag should not match during the first loop
@ -799,6 +793,7 @@ namespace rsx
{
// Discard - this section won't be needed any more
tex.discard(/* set_dirty */ true);
result.invalidate_samplers = true;
}
else if (g_cfg.video.strict_texture_flushing && tex.is_flushable())
{
@ -807,6 +802,7 @@ namespace rsx
else
{
tex.set_dirty(true);
result.invalidate_samplers = true;
}
}
}
@ -821,6 +817,7 @@ namespace rsx
if (invalidate_range == fault_range)
{
result.violation_handled = true;
result.invalidate_samplers = true;
#ifdef TEXTURE_CACHE_DEBUG
// Post-check the result
result.check_post_sanity();
@ -840,7 +837,7 @@ namespace rsx
{
auto &tex = *obj;
if (!tex.is_locked(true))
if (!tex.is_locked())
continue;
const rsx::section_bounds bounds = tex.get_overlap_test_bounds();
@ -859,7 +856,11 @@ namespace rsx
)
{
// False positive
result.sections_to_exclude.push_back(&tex);
if (tex.is_locked(true))
{
// Do not exclude hashed pages from unprotect! They will cause protection holes
result.sections_to_exclude.push_back(&tex);
}
continue;
}
@ -894,7 +895,17 @@ namespace rsx
tex.set_dirty(true);
}
result.sections_to_unprotect.push_back(&tex);
if (tex.is_locked(true))
{
result.sections_to_unprotect.push_back(&tex);
}
else
{
// No need to waste resources on hashed section, just discard immediately
tex.discard(true);
result.invalidate_samplers = true;
}
continue;
}
@ -944,6 +955,8 @@ namespace rsx
result.violation_handled = false;
}
result.invalidate_samplers |= result.violation_handled;
#ifdef TEXTURE_CACHE_DEBUG
// Post-check the result
result.check_post_sanity();
@ -981,7 +994,6 @@ namespace rsx
for (auto It = m_storage.range_begin(test_range, full_range, check_unlocked); It != m_storage.range_end(); It++)
{
auto &tex = *It;
tex.sync_protection();
if (!tex.is_dirty() && (context_mask & static_cast<u32>(tex.get_context())))
{
@ -990,6 +1002,11 @@ namespace rsx
continue;
}
if (!tex.sync_protection())
{
continue;
}
results.push_back(&tex);
}
}
@ -1003,14 +1020,17 @@ namespace rsx
auto &block = m_storage.block_for(rsx_address);
for (auto &tex : block)
{
tex.sync_protection();
if constexpr (check_unlocked)
{
if (!tex.is_locked())
{
continue;
}
}
if (!tex.is_dirty() && tex.matches(rsx_address, format, width, height, depth, mipmaps))
if (!tex.is_dirty() &&
tex.matches(rsx_address, format, width, height, depth, mipmaps) &&
tex.sync_protection())
{
return &tex;
}
@ -1035,6 +1055,9 @@ namespace rsx
{
if (tex.matches(range))
{
// We must validate
tex.sync_protection();
if (allow_dirty || !tex.is_dirty())
{
if (!confirm_dimensions || tex.matches(attr.gcm_format, attr.width, attr.height, attr.depth, attr.mipmaps))

View File

@ -1480,13 +1480,16 @@ namespace rsx
flush_exclusions.clear();
}
void sync_protection()
bool sync_protection()
{
if (!buffered_section::sync())
{
discard(true);
ensure(is_dirty());
return false;
}
return true;
}

View File

@ -918,14 +918,17 @@ bool GLGSRender::on_access_violation(u32 address, bool is_writing)
auto cmd = can_flush ? gl::command_context{ gl_state } : gl::command_context{};
auto result = m_gl_texture_cache.invalidate_address(cmd, address, cause);
if (!result.violation_handled)
return false;
if (result.invalidate_samplers)
{
std::lock_guard lock(m_sampler_mutex);
m_samplers_dirty.store(true);
}
if (!result.violation_handled)
{
return false;
}
if (result.num_flushable > 0)
{
auto &task = post_flush_request(address, result);

View File

@ -660,14 +660,17 @@ bool VKGSRender::on_access_violation(u32 address, bool is_writing)
result = std::move(m_texture_cache.invalidate_address(m_secondary_command_buffer, address, cause));
}
if (!result.violation_handled)
return false;
if (result.invalidate_samplers)
{
std::lock_guard lock(m_sampler_mutex);
m_samplers_dirty.store(true);
}
if (!result.violation_handled)
{
return false;
}
if (result.num_flushable > 0)
{
if (g_fxo->get<rsx::dma_manager>()->is_current_thread())