mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-14 01:27:00 +00:00
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:
parent
52acc23ecf
commit
195fb1cf66
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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())
|
||||
|
Loading…
x
Reference in New Issue
Block a user