summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorPierre Bourdon <delroth@gmail.com>2023-01-19 01:20:01 +0100
committerGitHub <noreply@github.com>2023-01-19 01:20:01 +0100
commit8d5edb13a9ac48c20e1f448644b8a50e8971d421 (patch)
tree754bcd5aaca21d9edf15e03336e7c9e0cfd310ba /Source/Core
parent1cd11b8f3abe54672f4f92349688ad1998cecdcd (diff)
parent23ad07b3688a1145c22ac72dfc35b0d2f9f834ff (diff)
Merge pull request #11367 from Sam-Belliveau/lagbegone
VideoCommon: VI Skip
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Config/GraphicsSettings.cpp1
-rw-r--r--Source/Core/Core/Config/GraphicsSettings.h1
-rw-r--r--Source/Core/Core/Config/MainSettings.cpp1
-rw-r--r--Source/Core/Core/Config/MainSettings.h1
-rw-r--r--Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp1
-rw-r--r--Source/Core/Core/CoreTiming.cpp15
-rw-r--r--Source/Core/Core/CoreTiming.h2
-rw-r--r--Source/Core/Core/HW/VideoInterface.cpp4
-rw-r--r--Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp20
-rw-r--r--Source/Core/DolphinQt/Config/Graphics/HacksWidget.h1
-rw-r--r--Source/Core/VideoCommon/VideoConfig.cpp3
-rw-r--r--Source/Core/VideoCommon/VideoConfig.h1
12 files changed, 48 insertions, 3 deletions
diff --git a/Source/Core/Core/Config/GraphicsSettings.cpp b/Source/Core/Core/Config/GraphicsSettings.cpp
index c52403d476..816179a565 100644
--- a/Source/Core/Core/Config/GraphicsSettings.cpp
+++ b/Source/Core/Core/Config/GraphicsSettings.cpp
@@ -156,6 +156,7 @@ const Info<bool> GFX_HACK_COPY_EFB_SCALED{{System::GFX, "Hacks", "EFBScaledCopy"
const Info<bool> GFX_HACK_EFB_EMULATE_FORMAT_CHANGES{
{System::GFX, "Hacks", "EFBEmulateFormatChanges"}, false};
const Info<bool> GFX_HACK_VERTEX_ROUNDING{{System::GFX, "Hacks", "VertexRounding"}, false};
+const Info<bool> GFX_HACK_VI_SKIP{{System::GFX, "Hacks", "VISkip"}, false};
const Info<u32> GFX_HACK_MISSING_COLOR_VALUE{{System::GFX, "Hacks", "MissingColorValue"},
0xFFFFFFFF};
const Info<bool> GFX_HACK_FAST_TEXTURE_SAMPLING{{System::GFX, "Hacks", "FastTextureSampling"},
diff --git a/Source/Core/Core/Config/GraphicsSettings.h b/Source/Core/Core/Config/GraphicsSettings.h
index df97bd12c2..f53248995d 100644
--- a/Source/Core/Core/Config/GraphicsSettings.h
+++ b/Source/Core/Core/Config/GraphicsSettings.h
@@ -135,6 +135,7 @@ extern const Info<bool> GFX_HACK_EARLY_XFB_OUTPUT;
extern const Info<bool> GFX_HACK_COPY_EFB_SCALED;
extern const Info<bool> GFX_HACK_EFB_EMULATE_FORMAT_CHANGES;
extern const Info<bool> GFX_HACK_VERTEX_ROUNDING;
+extern const Info<bool> GFX_HACK_VI_SKIP;
extern const Info<u32> GFX_HACK_MISSING_COLOR_VALUE;
extern const Info<bool> GFX_HACK_FAST_TEXTURE_SAMPLING;
#ifdef __APPLE__
diff --git a/Source/Core/Core/Config/MainSettings.cpp b/Source/Core/Core/Config/MainSettings.cpp
index a6f3a890aa..c3f1456f60 100644
--- a/Source/Core/Core/Config/MainSettings.cpp
+++ b/Source/Core/Core/Config/MainSettings.cpp
@@ -39,6 +39,7 @@ const Info<bool> MAIN_JIT_FOLLOW_BRANCH{{System::Main, "Core", "JITFollowBranch"
const Info<bool> MAIN_FASTMEM{{System::Main, "Core", "Fastmem"}, true};
const Info<bool> MAIN_ACCURATE_CPU_CACHE{{System::Main, "Core", "AccurateCPUCache"}, false};
const Info<bool> MAIN_DSP_HLE{{System::Main, "Core", "DSPHLE"}, true};
+const Info<int> MAIN_MAX_FALLBACK{{System::Main, "Core", "MaxFallback"}, 100};
const Info<int> MAIN_TIMING_VARIANCE{{System::Main, "Core", "TimingVariance"}, 40};
const Info<bool> MAIN_CPU_THREAD{{System::Main, "Core", "CPUThread"}, true};
const Info<bool> MAIN_SYNC_ON_SKIP_IDLE{{System::Main, "Core", "SyncOnSkipIdle"}, true};
diff --git a/Source/Core/Core/Config/MainSettings.h b/Source/Core/Core/Config/MainSettings.h
index 92b909adf5..d6a8d058f5 100644
--- a/Source/Core/Core/Config/MainSettings.h
+++ b/Source/Core/Core/Config/MainSettings.h
@@ -58,6 +58,7 @@ extern const Info<bool> MAIN_FASTMEM;
extern const Info<bool> MAIN_ACCURATE_CPU_CACHE;
// Should really be in the DSP section, but we're kind of stuck with bad decisions made in the past.
extern const Info<bool> MAIN_DSP_HLE;
+extern const Info<int> MAIN_MAX_FALLBACK;
extern const Info<int> MAIN_TIMING_VARIANCE;
extern const Info<bool> MAIN_CPU_THREAD;
extern const Info<bool> MAIN_SYNC_ON_SKIP_IDLE;
diff --git a/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp b/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp
index fedf6c6078..86c0ffc5fb 100644
--- a/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp
+++ b/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp
@@ -111,6 +111,7 @@ bool IsSettingSaveable(const Config::Location& config_location)
&Config::MAIN_SYNC_ON_SKIP_IDLE.GetLocation(),
&Config::MAIN_FASTMEM.GetLocation(),
&Config::MAIN_TIMING_VARIANCE.GetLocation(),
+ &Config::MAIN_MAX_FALLBACK.GetLocation(),
&Config::MAIN_WII_SD_CARD.GetLocation(),
&Config::MAIN_WII_SD_CARD_ENABLE_FOLDER_SYNC.GetLocation(),
&Config::MAIN_WII_KEYBOARD.GetLocation(),
diff --git a/Source/Core/Core/CoreTiming.cpp b/Source/Core/Core/CoreTiming.cpp
index d4c695b27f..bd95f42b59 100644
--- a/Source/Core/Core/CoreTiming.cpp
+++ b/Source/Core/Core/CoreTiming.cpp
@@ -24,6 +24,7 @@
#include "VideoCommon/Fifo.h"
#include "VideoCommon/PerformanceMetrics.h"
#include "VideoCommon/VideoBackendBase.h"
+#include "VideoCommon/VideoConfig.h"
namespace CoreTiming
{
@@ -359,7 +360,7 @@ void CoreTimingManager::Throttle(const s64 target_cycle)
// A maximum fallback is used to prevent the system from sleeping for
// too long or going full speed in an attempt to catch up to timings.
const DT max_fallback =
- std::chrono::duration_cast<DT>(DT_ms(Config::Get(Config::MAIN_TIMING_VARIANCE)));
+ std::chrono::duration_cast<DT>(DT_ms(Config::Get(Config::MAIN_MAX_FALLBACK)));
const TimePoint time = Clock::now();
const TimePoint min_deadline = time - max_fallback;
@@ -376,6 +377,13 @@ void CoreTimingManager::Throttle(const s64 target_cycle)
m_throttle_deadline = min_deadline;
}
+ // Skip the VI interrupt if the CPU is lagging by a certain amount.
+ // It doesn't matter what amount of lag we skip VI at, as long as it's constant.
+ const DT max_variance =
+ std::chrono::duration_cast<DT>(DT_ms(Config::Get(Config::MAIN_TIMING_VARIANCE)));
+ const TimePoint vi_deadline = time - max_variance;
+ m_throttle_disable_vi_int = 0.0 < speed && m_throttle_deadline < vi_deadline;
+
// Only sleep if we are behind the deadline
if (time < m_throttle_deadline)
{
@@ -399,6 +407,11 @@ TimePoint CoreTimingManager::GetCPUTimePoint(s64 cyclesLate) const
m_throttle_clock_per_sec));
}
+bool CoreTimingManager::GetVISkip() const
+{
+ return m_throttle_disable_vi_int && g_ActiveConfig.bVISkip && !Core::WantsDeterminism();
+}
+
void CoreTimingManager::LogPendingEvents() const
{
auto clone = m_event_queue;
diff --git a/Source/Core/Core/CoreTiming.h b/Source/Core/Core/CoreTiming.h
index 6bf5f908c3..54b2b54e2e 100644
--- a/Source/Core/Core/CoreTiming.h
+++ b/Source/Core/Core/CoreTiming.h
@@ -146,6 +146,7 @@ public:
void Throttle(const s64 target_cycle);
TimePoint GetCPUTimePoint(s64 cyclesLate) const; // Used by Dolphin Analytics
+ bool GetVISkip() const; // Used By VideoInterface
private:
Globals m_globals;
@@ -184,6 +185,7 @@ private:
TimePoint m_throttle_deadline = Clock::now();
s64 m_throttle_clock_per_sec;
s64 m_throttle_min_clock_per_sleep;
+ bool m_throttle_disable_vi_int = false;
void ResetThrottle(s64 cycle);
diff --git a/Source/Core/Core/HW/VideoInterface.cpp b/Source/Core/Core/HW/VideoInterface.cpp
index f40f475c4d..cb5b6bcfa2 100644
--- a/Source/Core/Core/HW/VideoInterface.cpp
+++ b/Source/Core/Core/HW/VideoInterface.cpp
@@ -952,6 +952,10 @@ void Update(u64 ticks)
state.ticks_last_line_start = system.GetCoreTiming().GetTicks();
}
+ // TODO: Findout why skipping interrupts acts as a frameskip
+ if (system.GetCoreTiming().GetVISkip())
+ return;
+
// Check if we need to assert IR_INT. Note that the granularity of our current horizontal
// position is limited to half-lines.
diff --git a/Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp b/Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp
index 0519631b77..484a1089b5 100644
--- a/Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp
+++ b/Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp
@@ -106,11 +106,13 @@ void HacksWidget::CreateWidgets()
m_vertex_rounding = new GraphicsBool(tr("Vertex Rounding"), Config::GFX_HACK_VERTEX_ROUNDING);
m_save_texture_cache_state =
new GraphicsBool(tr("Save Texture Cache to State"), Config::GFX_SAVE_TEXTURE_CACHE_TO_STATE);
+ m_vi_skip = new GraphicsBool(tr("VI Skip"), Config::GFX_HACK_VI_SKIP);
other_layout->addWidget(m_fast_depth_calculation, 0, 0);
other_layout->addWidget(m_disable_bounding_box, 0, 1);
other_layout->addWidget(m_vertex_rounding, 1, 0);
other_layout->addWidget(m_save_texture_cache_state, 1, 1);
+ other_layout->addWidget(m_vi_skip, 2, 0);
main_layout->addWidget(efb_box);
main_layout->addWidget(texture_cache_box);
@@ -148,6 +150,8 @@ void HacksWidget::ConnectWidgets()
[this](int) { UpdateDeferEFBCopiesEnabled(); });
connect(m_immediate_xfb, &QCheckBox::stateChanged,
[this](int) { UpdateSkipPresentingDuplicateFramesEnabled(); });
+ connect(m_vi_skip, &QCheckBox::stateChanged,
+ [this](int) { UpdateSkipPresentingDuplicateFramesEnabled(); });
}
void HacksWidget::LoadSettings()
@@ -280,6 +284,12 @@ void HacksWidget::AddDescriptions()
"Fixes graphical problems in some games at higher internal resolutions. This setting has no "
"effect when native internal resolution is used.<br><br>"
"<dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>");
+ static const char TR_VI_SKIP_DESCRIPTION[] =
+ QT_TR_NOOP("Skips VI interrupts when lag is detected, allowing for "
+ "smooth audio playback when emulation speed is not 100%. <br><br>"
+ "<dolphin_emphasis>WARNING: Can cause freezes and compatibility "
+ "issues.</dolphin_emphasis> <br><br>"
+ "<dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>");
m_skip_efb_cpu->SetDescription(tr(TR_SKIP_EFB_CPU_ACCESS_DESCRIPTION));
m_ignore_format_changes->SetDescription(tr(TR_IGNORE_FORMAT_CHANGE_DESCRIPTION));
@@ -295,6 +305,7 @@ void HacksWidget::AddDescriptions()
m_disable_bounding_box->SetDescription(tr(TR_DISABLE_BOUNDINGBOX_DESCRIPTION));
m_save_texture_cache_state->SetDescription(tr(TR_SAVE_TEXTURE_CACHE_TO_STATE_DESCRIPTION));
m_vertex_rounding->SetDescription(tr(TR_VERTEX_ROUNDING_DESCRIPTION));
+ m_vi_skip->SetDescription(tr(TR_VI_SKIP_DESCRIPTION));
}
void HacksWidget::UpdateDeferEFBCopiesEnabled()
@@ -309,5 +320,12 @@ void HacksWidget::UpdateSkipPresentingDuplicateFramesEnabled()
{
// If Immediate XFB is on, there's no point to skipping duplicate XFB copies as immediate presents
// when the XFB is created, therefore all XFB copies will be unique.
- m_skip_duplicate_xfbs->setEnabled(!m_immediate_xfb->isChecked());
+ // This setting is also required for VI skip to work.
+
+ const bool disabled = m_immediate_xfb->isChecked() || m_vi_skip->isChecked();
+
+ if (disabled)
+ m_skip_duplicate_xfbs->setChecked(true);
+
+ m_skip_duplicate_xfbs->setEnabled(!disabled);
}
diff --git a/Source/Core/DolphinQt/Config/Graphics/HacksWidget.h b/Source/Core/DolphinQt/Config/Graphics/HacksWidget.h
index 490a5b4f7e..296a467444 100644
--- a/Source/Core/DolphinQt/Config/Graphics/HacksWidget.h
+++ b/Source/Core/DolphinQt/Config/Graphics/HacksWidget.h
@@ -42,6 +42,7 @@ private:
GraphicsBool* m_fast_depth_calculation;
GraphicsBool* m_disable_bounding_box;
GraphicsBool* m_vertex_rounding;
+ GraphicsBool* m_vi_skip;
GraphicsBool* m_save_texture_cache_state;
void CreateWidgets();
diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp
index 66ba09c581..5314e352ad 100644
--- a/Source/Core/VideoCommon/VideoConfig.cpp
+++ b/Source/Core/VideoCommon/VideoConfig.cpp
@@ -140,7 +140,8 @@ void VideoConfig::Refresh()
bDisableCopyToVRAM = Config::Get(Config::GFX_HACK_DISABLE_COPY_TO_VRAM);
bDeferEFBCopies = Config::Get(Config::GFX_HACK_DEFER_EFB_COPIES);
bImmediateXFB = Config::Get(Config::GFX_HACK_IMMEDIATE_XFB);
- bSkipPresentingDuplicateXFBs = Config::Get(Config::GFX_HACK_SKIP_DUPLICATE_XFBS);
+ bVISkip = Config::Get(Config::GFX_HACK_VI_SKIP);
+ bSkipPresentingDuplicateXFBs = bVISkip || Config::Get(Config::GFX_HACK_SKIP_DUPLICATE_XFBS);
bCopyEFBScaled = Config::Get(Config::GFX_HACK_COPY_EFB_SCALED);
bEFBEmulateFormatChanges = Config::Get(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES);
bVertexRounding = Config::Get(Config::GFX_HACK_VERTEX_ROUNDING);
diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h
index 34a0063013..8140eb27eb 100644
--- a/Source/Core/VideoCommon/VideoConfig.h
+++ b/Source/Core/VideoCommon/VideoConfig.h
@@ -153,6 +153,7 @@ struct VideoConfig final
bool bEnablePixelLighting = false;
bool bFastDepthCalc = false;
bool bVertexRounding = false;
+ bool bVISkip = false;
int iEFBAccessTileSize = 0;
int iSaveTargetId = 0; // TODO: Should be dropped
u32 iMissingColorValue = 0;