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,
"EFBEmulateFormatChanges", 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,
"FastTextureSampling", true),

View File

@ -881,6 +881,8 @@ public final class SettingsFragmentPresenter
R.string.disable_bbox, R.string.disable_bbox_description));
sl.add(new SwitchSetting(mContext, BooleanSetting.GFX_HACK_VERTEX_ROUNDING,
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,
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="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="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_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>

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{
{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"},

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_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__

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_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};

View File

@ -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;

View File

@ -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(),

View File

@ -24,6 +24,7 @@
#include "VideoCommon/Fifo.h"
#include "VideoCommon/PerformanceMetrics.h"
#include "VideoCommon/VideoBackendBase.h"
#include "VideoCommon/VideoConfig.h"
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
// 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;
@ -371,6 +372,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)
{
@ -388,6 +396,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;

View File

@ -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;
int DowncountToCycles(int downcount) const;
int CyclesToDowncount(int cycles) const;

View File

@ -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.

View File

@ -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);
}

View File

@ -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();

View File

@ -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);

View File

@ -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;