mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-29 22:20:48 +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 violation_handled = false;
|
||||||
bool flushed = false;
|
bool flushed = false;
|
||||||
|
bool invalidate_samplers = false;
|
||||||
invalidation_cause cause;
|
invalidation_cause cause;
|
||||||
std::vector<section_storage_type*> sections_to_flush; // Sections to be flushed
|
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
|
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;
|
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.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
|
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
|
// Discard - this section won't be needed any more
|
||||||
tex.discard(/* set_dirty */ true);
|
tex.discard(/* set_dirty */ true);
|
||||||
|
result.invalidate_samplers = true;
|
||||||
}
|
}
|
||||||
else if (g_cfg.video.strict_texture_flushing && tex.is_flushable())
|
else if (g_cfg.video.strict_texture_flushing && tex.is_flushable())
|
||||||
{
|
{
|
||||||
@ -807,6 +802,7 @@ namespace rsx
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
tex.set_dirty(true);
|
tex.set_dirty(true);
|
||||||
|
result.invalidate_samplers = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -821,6 +817,7 @@ namespace rsx
|
|||||||
if (invalidate_range == fault_range)
|
if (invalidate_range == fault_range)
|
||||||
{
|
{
|
||||||
result.violation_handled = true;
|
result.violation_handled = true;
|
||||||
|
result.invalidate_samplers = true;
|
||||||
#ifdef TEXTURE_CACHE_DEBUG
|
#ifdef TEXTURE_CACHE_DEBUG
|
||||||
// Post-check the result
|
// Post-check the result
|
||||||
result.check_post_sanity();
|
result.check_post_sanity();
|
||||||
@ -840,7 +837,7 @@ namespace rsx
|
|||||||
{
|
{
|
||||||
auto &tex = *obj;
|
auto &tex = *obj;
|
||||||
|
|
||||||
if (!tex.is_locked(true))
|
if (!tex.is_locked())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const rsx::section_bounds bounds = tex.get_overlap_test_bounds();
|
const rsx::section_bounds bounds = tex.get_overlap_test_bounds();
|
||||||
@ -859,7 +856,11 @@ namespace rsx
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
// False positive
|
// 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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -894,7 +895,17 @@ namespace rsx
|
|||||||
tex.set_dirty(true);
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -944,6 +955,8 @@ namespace rsx
|
|||||||
result.violation_handled = false;
|
result.violation_handled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result.invalidate_samplers |= result.violation_handled;
|
||||||
|
|
||||||
#ifdef TEXTURE_CACHE_DEBUG
|
#ifdef TEXTURE_CACHE_DEBUG
|
||||||
// Post-check the result
|
// Post-check the result
|
||||||
result.check_post_sanity();
|
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++)
|
for (auto It = m_storage.range_begin(test_range, full_range, check_unlocked); It != m_storage.range_end(); It++)
|
||||||
{
|
{
|
||||||
auto &tex = *It;
|
auto &tex = *It;
|
||||||
tex.sync_protection();
|
|
||||||
|
|
||||||
if (!tex.is_dirty() && (context_mask & static_cast<u32>(tex.get_context())))
|
if (!tex.is_dirty() && (context_mask & static_cast<u32>(tex.get_context())))
|
||||||
{
|
{
|
||||||
@ -990,6 +1002,11 @@ namespace rsx
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!tex.sync_protection())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
results.push_back(&tex);
|
results.push_back(&tex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1003,14 +1020,17 @@ namespace rsx
|
|||||||
auto &block = m_storage.block_for(rsx_address);
|
auto &block = m_storage.block_for(rsx_address);
|
||||||
for (auto &tex : block)
|
for (auto &tex : block)
|
||||||
{
|
{
|
||||||
tex.sync_protection();
|
|
||||||
if constexpr (check_unlocked)
|
if constexpr (check_unlocked)
|
||||||
{
|
{
|
||||||
if (!tex.is_locked())
|
if (!tex.is_locked())
|
||||||
|
{
|
||||||
continue;
|
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;
|
return &tex;
|
||||||
}
|
}
|
||||||
@ -1035,6 +1055,9 @@ namespace rsx
|
|||||||
{
|
{
|
||||||
if (tex.matches(range))
|
if (tex.matches(range))
|
||||||
{
|
{
|
||||||
|
// We must validate
|
||||||
|
tex.sync_protection();
|
||||||
|
|
||||||
if (allow_dirty || !tex.is_dirty())
|
if (allow_dirty || !tex.is_dirty())
|
||||||
{
|
{
|
||||||
if (!confirm_dimensions || tex.matches(attr.gcm_format, attr.width, attr.height, attr.depth, attr.mipmaps))
|
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();
|
flush_exclusions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sync_protection()
|
bool sync_protection()
|
||||||
{
|
{
|
||||||
if (!buffered_section::sync())
|
if (!buffered_section::sync())
|
||||||
{
|
{
|
||||||
discard(true);
|
discard(true);
|
||||||
ensure(is_dirty());
|
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 cmd = can_flush ? gl::command_context{ gl_state } : gl::command_context{};
|
||||||
auto result = m_gl_texture_cache.invalidate_address(cmd, address, cause);
|
auto result = m_gl_texture_cache.invalidate_address(cmd, address, cause);
|
||||||
|
|
||||||
if (!result.violation_handled)
|
if (result.invalidate_samplers)
|
||||||
return false;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard lock(m_sampler_mutex);
|
std::lock_guard lock(m_sampler_mutex);
|
||||||
m_samplers_dirty.store(true);
|
m_samplers_dirty.store(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!result.violation_handled)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (result.num_flushable > 0)
|
if (result.num_flushable > 0)
|
||||||
{
|
{
|
||||||
auto &task = post_flush_request(address, result);
|
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));
|
result = std::move(m_texture_cache.invalidate_address(m_secondary_command_buffer, address, cause));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result.violation_handled)
|
if (result.invalidate_samplers)
|
||||||
return false;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard lock(m_sampler_mutex);
|
std::lock_guard lock(m_sampler_mutex);
|
||||||
m_samplers_dirty.store(true);
|
m_samplers_dirty.store(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!result.violation_handled)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (result.num_flushable > 0)
|
if (result.num_flushable > 0)
|
||||||
{
|
{
|
||||||
if (g_fxo->get<rsx::dma_manager>()->is_current_thread())
|
if (g_fxo->get<rsx::dma_manager>()->is_current_thread())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user