mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-16 11:48:36 +12:00
Reimplement overlapping fbo "hack"
To avoid the need (and performance hit) of Read Color/Depth Buffers, we may not invalidate overlapping fbos inside lock_memory_region unless they are guaranteed to be superseded by the new one. This avoids e.g. issues with overblooming, among others.
This commit is contained in:
parent
5ab7296665
commit
18b9ee4541
1 changed files with 22 additions and 12 deletions
|
@ -272,7 +272,7 @@ namespace rsx
|
||||||
std::atomic<u32> m_misses_this_frame = { 0 };
|
std::atomic<u32> m_misses_this_frame = { 0 };
|
||||||
std::atomic<u32> m_speculations_this_frame = { 0 };
|
std::atomic<u32> m_speculations_this_frame = { 0 };
|
||||||
std::atomic<u32> m_unavoidable_hard_faults_this_frame = { 0 };
|
std::atomic<u32> m_unavoidable_hard_faults_this_frame = { 0 };
|
||||||
static const u32 m_predict_max_flushes_per_frame = 100; // Above this number the predictions are disabled
|
static const u32 m_predict_max_flushes_per_frame = 50; // Above this number the predictions are disabled
|
||||||
|
|
||||||
// Invalidation
|
// Invalidation
|
||||||
static const bool invalidation_ignore_unsynchronized = true; // If true, unsynchronized sections don't get forcefully flushed unless they overlap the fault range
|
static const bool invalidation_ignore_unsynchronized = true; // If true, unsynchronized sections don't get forcefully flushed unless they overlap the fault range
|
||||||
|
@ -502,7 +502,7 @@ namespace rsx
|
||||||
|
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
AUDIT(exclusion_range.is_page_range());
|
AUDIT(exclusion_range.is_page_range());
|
||||||
AUDIT(data.cause.is_read() && !excluded->is_flushable() || !exclusion_range.overlaps(data.fault_range));
|
AUDIT(data.cause.is_read() && !excluded->is_flushable() || data.cause == invalidation_cause::superseded_by_fbo || !exclusion_range.overlaps(data.fault_range));
|
||||||
|
|
||||||
// Apply exclusion
|
// Apply exclusion
|
||||||
ranges_to_unprotect.exclude(exclusion_range);
|
ranges_to_unprotect.exclude(exclusion_range);
|
||||||
|
@ -691,14 +691,21 @@ namespace rsx
|
||||||
for (auto &obj : trampled_set.sections)
|
for (auto &obj : trampled_set.sections)
|
||||||
{
|
{
|
||||||
auto &tex = *obj;
|
auto &tex = *obj;
|
||||||
if (tex.inside(fault_range, section_bounds::locked_range))
|
if (tex.overlaps(fault_range, section_bounds::locked_range))
|
||||||
{
|
{
|
||||||
// Discard - this section won't be needed any more
|
if (cause == invalidation_cause::superseded_by_fbo &&
|
||||||
tex.discard(/* set_dirty */ true);
|
tex.get_context() == texture_upload_context::framebuffer_storage &&
|
||||||
}
|
tex.get_section_base() != fault_range_in.start)
|
||||||
else if (tex.overlaps(fault_range, section_bounds::locked_range))
|
{
|
||||||
{
|
// HACK: When being superseded by an fbo, we preserve other overlapped fbos unless the start addresses match
|
||||||
if (g_cfg.video.strict_texture_flushing && tex.is_flushable())
|
continue;
|
||||||
|
}
|
||||||
|
else if (tex.inside(fault_range, section_bounds::locked_range))
|
||||||
|
{
|
||||||
|
// Discard - this section won't be needed any more
|
||||||
|
tex.discard(/* set_dirty */ true);
|
||||||
|
}
|
||||||
|
else if (g_cfg.video.strict_texture_flushing && tex.is_flushable())
|
||||||
{
|
{
|
||||||
tex.add_flush_exclusion(fault_range);
|
tex.add_flush_exclusion(fault_range);
|
||||||
}
|
}
|
||||||
|
@ -742,6 +749,7 @@ namespace rsx
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const rsx::section_bounds bounds = tex.get_overlap_test_bounds();
|
const rsx::section_bounds bounds = tex.get_overlap_test_bounds();
|
||||||
|
const bool overlaps_fault_range = tex.overlaps(fault_range, bounds);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
// RO sections during a read invalidation can be ignored (unless there are flushables in trampled_set, since those could overwrite RO data)
|
// RO sections during a read invalidation can be ignored (unless there are flushables in trampled_set, since those could overwrite RO data)
|
||||||
|
@ -749,7 +757,9 @@ namespace rsx
|
||||||
// Sections that are not fully contained in invalidate_range can be ignored
|
// Sections that are not fully contained in invalidate_range can be ignored
|
||||||
!tex.inside(trampled_set.invalidate_range, bounds) ||
|
!tex.inside(trampled_set.invalidate_range, bounds) ||
|
||||||
// Unsynchronized sections (or any flushable when skipping flushes) that do not overlap the fault range directly can also be ignored
|
// Unsynchronized sections (or any flushable when skipping flushes) that do not overlap the fault range directly can also be ignored
|
||||||
(invalidation_ignore_unsynchronized && tex.is_flushable() && (cause.skip_flush() || !tex.is_synchronized()) && !tex.overlaps(fault_range, bounds))
|
(invalidation_ignore_unsynchronized && tex.is_flushable() && (cause.skip_flush() || !tex.is_synchronized()) && !overlaps_fault_range) ||
|
||||||
|
// HACK: When being superseded by an fbo, we preserve other overlapped fbos unless the start addresses match
|
||||||
|
(overlaps_fault_range && cause == invalidation_cause::superseded_by_fbo && tex.get_context() == texture_upload_context::framebuffer_storage && tex.get_section_base() != fault_range_in.start)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// False positive
|
// False positive
|
||||||
|
@ -830,8 +840,8 @@ namespace rsx
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// This is a read and all overlapping sections were RO and were excluded
|
// This is a read and all overlapping sections were RO and were excluded (except for cause == superseded_by_fbo)
|
||||||
AUDIT(cause.is_read() && !result.sections_to_exclude.empty());
|
AUDIT(cause == invalidation_cause::superseded_by_fbo || cause.is_read() && !result.sections_to_exclude.empty());
|
||||||
|
|
||||||
// We did not handle this violation
|
// We did not handle this violation
|
||||||
result.clear_sections();
|
result.clear_sections();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue