Add VISkip

This commit is contained in:
Sam Belliveau 2023-01-14 01:56:37 -05:00
parent 8a1cac9be1
commit 23ad07b368
15 changed files with 53 additions and 3 deletions

View File

@ -247,6 +247,7 @@ public enum BooleanSetting implements AbstractBooleanSetting
GFX_HACK_EFB_EMULATE_FORMAT_CHANGES(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, GFX_HACK_EFB_EMULATE_FORMAT_CHANGES(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS,
"EFBEmulateFormatChanges", false), "EFBEmulateFormatChanges", false),
GFX_HACK_VERTEX_ROUNDING(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, "VertexRounding", false), GFX_HACK_VERTEX_ROUNDING(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, "VertexRounding", false),
GFX_HACK_VI_SKIP(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, "VISkip", false),
GFX_HACK_FAST_TEXTURE_SAMPLING(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS, GFX_HACK_FAST_TEXTURE_SAMPLING(Settings.FILE_GFX, Settings.SECTION_GFX_HACKS,
"FastTextureSampling", true), "FastTextureSampling", true),

View File

@ -881,6 +881,8 @@ public final class SettingsFragmentPresenter
R.string.disable_bbox, R.string.disable_bbox_description)); R.string.disable_bbox, R.string.disable_bbox_description));
sl.add(new SwitchSetting(mContext, BooleanSetting.GFX_HACK_VERTEX_ROUNDING, sl.add(new SwitchSetting(mContext, BooleanSetting.GFX_HACK_VERTEX_ROUNDING,
R.string.vertex_rounding, R.string.vertex_rounding_description)); R.string.vertex_rounding, R.string.vertex_rounding_description));
sl.add(new SwitchSetting(mContext, BooleanSetting.GFX_HACK_VI_SKIP, R.string.vi_skip,
R.string.vi_skip_description));
sl.add(new SwitchSetting(mContext, BooleanSetting.GFX_SAVE_TEXTURE_CACHE_TO_STATE, sl.add(new SwitchSetting(mContext, BooleanSetting.GFX_SAVE_TEXTURE_CACHE_TO_STATE,
R.string.texture_cache_to_state, R.string.texture_cache_to_state_description)); R.string.texture_cache_to_state, R.string.texture_cache_to_state_description));
} }

View File

@ -309,6 +309,8 @@
<string name="disable_bbox_description">Disables bounding box emulation. This may improve GPU performance significantly, but some games will break. If unsure, leave this checked.</string> <string name="disable_bbox_description">Disables bounding box emulation. This may improve GPU performance significantly, but some games will break. If unsure, leave this checked.</string>
<string name="vertex_rounding">Vertex Rounding</string> <string name="vertex_rounding">Vertex Rounding</string>
<string name="vertex_rounding_description">Rounds 2D vertices to whole pixels and rounds the viewport size to a whole number. Fixes graphical problems in some games at higher internal resolutions. This setting has no effect when native internal resolution is used. If unsure, leave this unchecked.</string> <string name="vertex_rounding_description">Rounds 2D vertices to whole pixels and rounds the viewport size to a whole number. Fixes graphical problems in some games at higher internal resolutions. This setting has no effect when native internal resolution is used. If unsure, leave this unchecked.</string>
<string name="vi_skip">VI Skip</string>
<string name="vi_skip_description">Skips VI interrupts when lag is detected, allowing for smooth audio playback when emulation speed is not 100%. Can cause freezes and compatibility issues.</string>
<string name="texture_cache_to_state">Save Texture Cache to State</string> <string name="texture_cache_to_state">Save Texture Cache to State</string>
<string name="texture_cache_to_state_description">Includes the contents of the embedded frame buffer (EFB) and upscaled EFB copies in save states. Fixes missing and/or non-upscaled textures/objects when loading states at the cost of additional save/load time.</string> <string name="texture_cache_to_state_description">Includes the contents of the embedded frame buffer (EFB) and upscaled EFB copies in save states. Fixes missing and/or non-upscaled textures/objects when loading states at the cost of additional save/load time.</string>
<string name="aspect_ratio">Aspect Ratio</string> <string name="aspect_ratio">Aspect Ratio</string>

View File

@ -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{ const Info<bool> GFX_HACK_EFB_EMULATE_FORMAT_CHANGES{
{System::GFX, "Hacks", "EFBEmulateFormatChanges"}, false}; {System::GFX, "Hacks", "EFBEmulateFormatChanges"}, false};
const Info<bool> GFX_HACK_VERTEX_ROUNDING{{System::GFX, "Hacks", "VertexRounding"}, 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"}, const Info<u32> GFX_HACK_MISSING_COLOR_VALUE{{System::GFX, "Hacks", "MissingColorValue"},
0xFFFFFFFF}; 0xFFFFFFFF};
const Info<bool> GFX_HACK_FAST_TEXTURE_SAMPLING{{System::GFX, "Hacks", "FastTextureSampling"}, const Info<bool> GFX_HACK_FAST_TEXTURE_SAMPLING{{System::GFX, "Hacks", "FastTextureSampling"},

View File

@ -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_COPY_EFB_SCALED;
extern const Info<bool> GFX_HACK_EFB_EMULATE_FORMAT_CHANGES; extern const Info<bool> GFX_HACK_EFB_EMULATE_FORMAT_CHANGES;
extern const Info<bool> GFX_HACK_VERTEX_ROUNDING; 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<u32> GFX_HACK_MISSING_COLOR_VALUE;
extern const Info<bool> GFX_HACK_FAST_TEXTURE_SAMPLING; extern const Info<bool> GFX_HACK_FAST_TEXTURE_SAMPLING;
#ifdef __APPLE__ #ifdef __APPLE__

View File

@ -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_FASTMEM{{System::Main, "Core", "Fastmem"}, true};
const Info<bool> MAIN_ACCURATE_CPU_CACHE{{System::Main, "Core", "AccurateCPUCache"}, false}; 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<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<int> MAIN_TIMING_VARIANCE{{System::Main, "Core", "TimingVariance"}, 40};
const Info<bool> MAIN_CPU_THREAD{{System::Main, "Core", "CPUThread"}, true}; const Info<bool> MAIN_CPU_THREAD{{System::Main, "Core", "CPUThread"}, true};
const Info<bool> MAIN_SYNC_ON_SKIP_IDLE{{System::Main, "Core", "SyncOnSkipIdle"}, true}; const Info<bool> MAIN_SYNC_ON_SKIP_IDLE{{System::Main, "Core", "SyncOnSkipIdle"}, true};

View File

@ -58,6 +58,7 @@ extern const Info<bool> MAIN_FASTMEM;
extern const Info<bool> MAIN_ACCURATE_CPU_CACHE; 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. // 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<bool> MAIN_DSP_HLE;
extern const Info<int> MAIN_MAX_FALLBACK;
extern const Info<int> MAIN_TIMING_VARIANCE; extern const Info<int> MAIN_TIMING_VARIANCE;
extern const Info<bool> MAIN_CPU_THREAD; extern const Info<bool> MAIN_CPU_THREAD;
extern const Info<bool> MAIN_SYNC_ON_SKIP_IDLE; extern const Info<bool> MAIN_SYNC_ON_SKIP_IDLE;

View File

@ -111,6 +111,7 @@ bool IsSettingSaveable(const Config::Location& config_location)
&Config::MAIN_SYNC_ON_SKIP_IDLE.GetLocation(), &Config::MAIN_SYNC_ON_SKIP_IDLE.GetLocation(),
&Config::MAIN_FASTMEM.GetLocation(), &Config::MAIN_FASTMEM.GetLocation(),
&Config::MAIN_TIMING_VARIANCE.GetLocation(), &Config::MAIN_TIMING_VARIANCE.GetLocation(),
&Config::MAIN_MAX_FALLBACK.GetLocation(),
&Config::MAIN_WII_SD_CARD.GetLocation(), &Config::MAIN_WII_SD_CARD.GetLocation(),
&Config::MAIN_WII_SD_CARD_ENABLE_FOLDER_SYNC.GetLocation(), &Config::MAIN_WII_SD_CARD_ENABLE_FOLDER_SYNC.GetLocation(),
&Config::MAIN_WII_KEYBOARD.GetLocation(), &Config::MAIN_WII_KEYBOARD.GetLocation(),

View File

@ -24,6 +24,7 @@
#include "VideoCommon/Fifo.h" #include "VideoCommon/Fifo.h"
#include "VideoCommon/PerformanceMetrics.h" #include "VideoCommon/PerformanceMetrics.h"
#include "VideoCommon/VideoBackendBase.h" #include "VideoCommon/VideoBackendBase.h"
#include "VideoCommon/VideoConfig.h"
namespace CoreTiming namespace CoreTiming
{ {
@ -354,7 +355,7 @@ void CoreTimingManager::Throttle(const s64 target_cycle)
// A maximum fallback is used to prevent the system from sleeping for // 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. // too long or going full speed in an attempt to catch up to timings.
const DT max_fallback = 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 time = Clock::now();
const TimePoint min_deadline = time - max_fallback; const TimePoint min_deadline = time - max_fallback;
@ -371,6 +372,13 @@ void CoreTimingManager::Throttle(const s64 target_cycle)
m_throttle_deadline = min_deadline; 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 // Only sleep if we are behind the deadline
if (time < m_throttle_deadline) if (time < m_throttle_deadline)
{ {
@ -388,6 +396,11 @@ TimePoint CoreTimingManager::GetCPUTimePoint(s64 cyclesLate) const
m_throttle_clock_per_sec)); m_throttle_clock_per_sec));
} }
bool CoreTimingManager::GetVISkip() const
{
return m_throttle_disable_vi_int && g_ActiveConfig.bVISkip && !Core::WantsDeterminism();
}
void CoreTimingManager::LogPendingEvents() const void CoreTimingManager::LogPendingEvents() const
{ {
auto clone = m_event_queue; auto clone = m_event_queue;

View File

@ -146,6 +146,7 @@ public:
void Throttle(const s64 target_cycle); void Throttle(const s64 target_cycle);
TimePoint GetCPUTimePoint(s64 cyclesLate) const; // Used by Dolphin Analytics TimePoint GetCPUTimePoint(s64 cyclesLate) const; // Used by Dolphin Analytics
bool GetVISkip() const; // Used By VideoInterface
private: private:
Globals m_globals; Globals m_globals;
@ -184,6 +185,7 @@ private:
TimePoint m_throttle_deadline = Clock::now(); TimePoint m_throttle_deadline = Clock::now();
s64 m_throttle_clock_per_sec; s64 m_throttle_clock_per_sec;
s64 m_throttle_min_clock_per_sleep; s64 m_throttle_min_clock_per_sleep;
bool m_throttle_disable_vi_int = false;
int DowncountToCycles(int downcount) const; int DowncountToCycles(int downcount) const;
int CyclesToDowncount(int cycles) const; int CyclesToDowncount(int cycles) const;

View File

@ -952,6 +952,10 @@ void Update(u64 ticks)
state.ticks_last_line_start = system.GetCoreTiming().GetTicks(); 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 // Check if we need to assert IR_INT. Note that the granularity of our current horizontal
// position is limited to half-lines. // position is limited to half-lines.

View File

@ -106,11 +106,13 @@ void HacksWidget::CreateWidgets()
m_vertex_rounding = new GraphicsBool(tr("Vertex Rounding"), Config::GFX_HACK_VERTEX_ROUNDING); m_vertex_rounding = new GraphicsBool(tr("Vertex Rounding"), Config::GFX_HACK_VERTEX_ROUNDING);
m_save_texture_cache_state = m_save_texture_cache_state =
new GraphicsBool(tr("Save Texture Cache to State"), Config::GFX_SAVE_TEXTURE_CACHE_TO_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_fast_depth_calculation, 0, 0);
other_layout->addWidget(m_disable_bounding_box, 0, 1); other_layout->addWidget(m_disable_bounding_box, 0, 1);
other_layout->addWidget(m_vertex_rounding, 1, 0); other_layout->addWidget(m_vertex_rounding, 1, 0);
other_layout->addWidget(m_save_texture_cache_state, 1, 1); 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(efb_box);
main_layout->addWidget(texture_cache_box); main_layout->addWidget(texture_cache_box);
@ -148,6 +150,8 @@ void HacksWidget::ConnectWidgets()
[this](int) { UpdateDeferEFBCopiesEnabled(); }); [this](int) { UpdateDeferEFBCopiesEnabled(); });
connect(m_immediate_xfb, &QCheckBox::stateChanged, connect(m_immediate_xfb, &QCheckBox::stateChanged,
[this](int) { UpdateSkipPresentingDuplicateFramesEnabled(); }); [this](int) { UpdateSkipPresentingDuplicateFramesEnabled(); });
connect(m_vi_skip, &QCheckBox::stateChanged,
[this](int) { UpdateSkipPresentingDuplicateFramesEnabled(); });
} }
void HacksWidget::LoadSettings() void HacksWidget::LoadSettings()
@ -280,6 +284,12 @@ void HacksWidget::AddDescriptions()
"Fixes graphical problems in some games at higher internal resolutions. This setting has no " "Fixes graphical problems in some games at higher internal resolutions. This setting has no "
"effect when native internal resolution is used.<br><br>" "effect when native internal resolution is used.<br><br>"
"<dolphin_emphasis>If unsure, leave this unchecked.</dolphin_emphasis>"); "<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_skip_efb_cpu->SetDescription(tr(TR_SKIP_EFB_CPU_ACCESS_DESCRIPTION));
m_ignore_format_changes->SetDescription(tr(TR_IGNORE_FORMAT_CHANGE_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_disable_bounding_box->SetDescription(tr(TR_DISABLE_BOUNDINGBOX_DESCRIPTION));
m_save_texture_cache_state->SetDescription(tr(TR_SAVE_TEXTURE_CACHE_TO_STATE_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_vertex_rounding->SetDescription(tr(TR_VERTEX_ROUNDING_DESCRIPTION));
m_vi_skip->SetDescription(tr(TR_VI_SKIP_DESCRIPTION));
} }
void HacksWidget::UpdateDeferEFBCopiesEnabled() 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 // 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. // 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);
} }

View File

@ -42,6 +42,7 @@ private:
GraphicsBool* m_fast_depth_calculation; GraphicsBool* m_fast_depth_calculation;
GraphicsBool* m_disable_bounding_box; GraphicsBool* m_disable_bounding_box;
GraphicsBool* m_vertex_rounding; GraphicsBool* m_vertex_rounding;
GraphicsBool* m_vi_skip;
GraphicsBool* m_save_texture_cache_state; GraphicsBool* m_save_texture_cache_state;
void CreateWidgets(); void CreateWidgets();

View File

@ -140,7 +140,8 @@ void VideoConfig::Refresh()
bDisableCopyToVRAM = Config::Get(Config::GFX_HACK_DISABLE_COPY_TO_VRAM); bDisableCopyToVRAM = Config::Get(Config::GFX_HACK_DISABLE_COPY_TO_VRAM);
bDeferEFBCopies = Config::Get(Config::GFX_HACK_DEFER_EFB_COPIES); bDeferEFBCopies = Config::Get(Config::GFX_HACK_DEFER_EFB_COPIES);
bImmediateXFB = Config::Get(Config::GFX_HACK_IMMEDIATE_XFB); 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); bCopyEFBScaled = Config::Get(Config::GFX_HACK_COPY_EFB_SCALED);
bEFBEmulateFormatChanges = Config::Get(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES); bEFBEmulateFormatChanges = Config::Get(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES);
bVertexRounding = Config::Get(Config::GFX_HACK_VERTEX_ROUNDING); bVertexRounding = Config::Get(Config::GFX_HACK_VERTEX_ROUNDING);

View File

@ -153,6 +153,7 @@ struct VideoConfig final
bool bEnablePixelLighting = false; bool bEnablePixelLighting = false;
bool bFastDepthCalc = false; bool bFastDepthCalc = false;
bool bVertexRounding = false; bool bVertexRounding = false;
bool bVISkip = false;
int iEFBAccessTileSize = 0; int iEFBAccessTileSize = 0;
int iSaveTargetId = 0; // TODO: Should be dropped int iSaveTargetId = 0; // TODO: Should be dropped
u32 iMissingColorValue = 0; u32 iMissingColorValue = 0;