Skip to content

Commit

Permalink
Add VBI Overclock
Browse files Browse the repository at this point in the history
  • Loading branch information
Sam-Belliveau authored and SuperSamus committed Sep 4, 2024
1 parent 7d08377 commit ffdae15
Show file tree
Hide file tree
Showing 18 changed files with 175 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ enum class BooleanSetting(
"OverclockEnable",
false
),
MAIN_VI_OVERCLOCK_ENABLE(
Settings.FILE_DOLPHIN,
Settings.SECTION_INI_CORE,
"VIOverclockEnable",
false
),
MAIN_RAM_OVERRIDE_ENABLE(
Settings.FILE_DOLPHIN,
Settings.SECTION_INI_CORE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ enum class FloatSetting(
// These entries have the same names and order as in C++, just for consistency.
MAIN_EMULATION_SPEED(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "EmulationSpeed", 1.0f),
MAIN_OVERCLOCK(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "Overclock", 1.0f),
MAIN_VI_OVERCLOCK(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "VIOverclock", 1.0f),
GFX_CC_GAME_GAMMA(Settings.FILE_GFX, Settings.SECTION_GFX_COLOR_CORRECTION, "GameGamma", 2.35f);

override val isOverridden: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,27 @@ class SettingsFragmentPresenter(
false
)
)
sl.add(
SwitchSetting(
context,
BooleanSetting.MAIN_VI_OVERCLOCK_ENABLE,
R.string.vi_overclock_enable,
R.string.vi_overclock_enable_description
)
)
sl.add(
PercentSliderSetting(
context,
FloatSetting.MAIN_VI_OVERCLOCK,
R.string.vi_overclock_title,
R.string.vi_overclock_title_description,
0f,
400f,
"%",
1f,
false
)
)

val mem1Size = ScaledIntSetting(1024 * 1024, IntSetting.MAIN_MEM1_SIZE)
val mem2Size = ScaledIntSetting(1024 * 1024, IntSetting.MAIN_MEM2_SIZE)
Expand Down
6 changes: 5 additions & 1 deletion Source/Android/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@
<string name="enable_cpu_cache_description">Enables emulation of the CPU write-back cache. Enabling will have a significant impact on performance. This should be left disabled unless absolutely needed.</string>
<string name="clock_override">Clock Override</string>
<string name="overclock_enable">Override Emulated CPU Clock Speed</string>
<string name="overclock_enable_description">Higher values can make variable-framerate games run at a higher framerate, requiring a powerful device. Lower values make games run at a lower framerate, increasing emulation speed, but reducing the emulated console\'s performance.</string>
<string name="overclock_enable_description">Higher values can make games run at a higher framerate if they lagged on original hardware, requiring a powerful device. Lower values improve performance by causing lag, but will slow down the game (without affecting audio) if its physics ignore the framerate.</string>
<string name="overclock_title">Emulated CPU Clock Speed</string>
<string name="overclock_title_description">Adjusts the emulated CPU\'s clock rate if \"Override Emulated CPU Clock Speed\" is enabled.</string>
<string name="memory_override">Memory Override</string>
Expand All @@ -375,6 +375,10 @@
<string name="main_mem1_size">MEM1 Size</string>
<string name="main_mem2_size">MEM2 Size</string>
<string name="gpu_options">GPU Options</string>
<string name="vi_overclock_enable">Override VBI Clock Speed</string>
<string name="vi_overclock_enable_description">Makes the game run at a different framerate without impacting audio, making the emulation less demanding when lowered, or improving smoothness when increased. Because many games\' physics ignore the framerate, this may affect game speed.</string>
<string name="vi_overclock_title">Emulated VBI Clock Speed</string>
<string name="vi_overclock_title_description">Adjusts the emulated VBI clock rate if \"Override VBI Clock Speed\" is enabled.\nAlso adjusts the emulated CPU\'s clock rate, to keep it relatively the same.</string>
<string name="synchronize_gpu_thread">Synchronize GPU Thread</string>
<string name="synchronize_gpu_thread_description">Synchronizing the GPU thread reduces the risk of games crashing or becoming unstable with dual core enabled, but can also reduce the performance gain of dual core. If unsure, select \"On Idle Skipping\". Selecting \"Never\" is risky and not recommended!</string>
<string name="custom_rtc_options">Custom RTC Options</string>
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Core/Config/MainSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ const Info<bool> MAIN_DISABLE_ICACHE{{System::Main, "Core", "DisableICache"}, fa
const Info<float> MAIN_EMULATION_SPEED{{System::Main, "Core", "EmulationSpeed"}, 1.0f};
const Info<float> MAIN_OVERCLOCK{{System::Main, "Core", "Overclock"}, 1.0f};
const Info<bool> MAIN_OVERCLOCK_ENABLE{{System::Main, "Core", "OverclockEnable"}, false};
const Info<float> MAIN_VI_OVERCLOCK{{System::Main, "Core", "VIOverclock"}, 1.0f};
const Info<bool> MAIN_VI_OVERCLOCK_ENABLE{{System::Main, "Core", "VIOverclockEnable"}, false};
const Info<bool> MAIN_RAM_OVERRIDE_ENABLE{{System::Main, "Core", "RAMOverrideEnable"}, false};
const Info<u32> MAIN_MEM1_SIZE{{System::Main, "Core", "MEM1Size"}, Memory::MEM1_SIZE_RETAIL};
const Info<u32> MAIN_MEM2_SIZE{{System::Main, "Core", "MEM2Size"}, Memory::MEM2_SIZE_RETAIL};
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Core/Config/MainSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ extern const Info<bool> MAIN_DISABLE_ICACHE;
extern const Info<float> MAIN_EMULATION_SPEED;
extern const Info<float> MAIN_OVERCLOCK;
extern const Info<bool> MAIN_OVERCLOCK_ENABLE;
extern const Info<float> MAIN_VI_OVERCLOCK;
extern const Info<bool> MAIN_VI_OVERCLOCK_ENABLE;
extern const Info<bool> MAIN_RAM_OVERRIDE_ENABLE;
extern const Info<u32> MAIN_MEM1_SIZE;
extern const Info<u32> MAIN_MEM2_SIZE;
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Core/ConfigLoaders/NetPlayConfigLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class NetPlayConfigLayerLoader final : public Config::ConfigLayerLoader
layer->Set(Config::MAIN_DSP_HLE, m_settings.dsp_hle);
layer->Set(Config::MAIN_OVERCLOCK_ENABLE, m_settings.oc_enable);
layer->Set(Config::MAIN_OVERCLOCK, m_settings.oc_factor);
layer->Set(Config::MAIN_VI_OVERCLOCK_ENABLE, m_settings.vi_oc_enable);
layer->Set(Config::MAIN_VI_OVERCLOCK, m_settings.vi_oc_factor);
for (ExpansionInterface::Slot slot : ExpansionInterface::SLOTS)
layer->Set(Config::GetInfoForEXIDevice(slot), m_settings.exi_device[slot]);
layer->Set(Config::MAIN_MEMORY_CARD_SIZE, m_settings.memcard_size_override);
Expand Down
9 changes: 8 additions & 1 deletion Source/Core/Core/CoreTiming.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ void CoreTimingManager::Shutdown()
void CoreTimingManager::RefreshConfig()
{
m_config_oc_factor =
Config::Get(Config::MAIN_OVERCLOCK_ENABLE) ? Config::Get(Config::MAIN_OVERCLOCK) : 1.0f;
(Config::Get(Config::MAIN_OVERCLOCK_ENABLE) ? Config::Get(Config::MAIN_OVERCLOCK) : 1.0f) *
(Config::Get(Config::MAIN_VI_OVERCLOCK_ENABLE) ? Config::Get(Config::MAIN_VI_OVERCLOCK) :
1.0f);
m_config_oc_inv_factor = 1.0f / m_config_oc_factor;
m_config_sync_on_skip_idle = Config::Get(Config::MAIN_SYNC_ON_SKIP_IDLE);

Expand Down Expand Up @@ -432,6 +434,11 @@ bool CoreTimingManager::GetVISkip() const
return m_throttle_disable_vi_int && g_ActiveConfig.bVISkip && !Core::WantsDeterminism();
}

float CoreTimingManager::GetOverclock() const
{
return m_config_oc_factor;
}

bool CoreTimingManager::UseSyncOnSkipIdle() const
{
return m_config_sync_on_skip_idle;
Expand Down
1 change: 1 addition & 0 deletions Source/Core/Core/CoreTiming.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ class CoreTimingManager

TimePoint GetCPUTimePoint(s64 cyclesLate) const; // Used by Dolphin Analytics
bool GetVISkip() const; // Used By VideoInterface
float GetOverclock() const;

bool UseSyncOnSkipIdle() const;

Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Core/DolphinAnalytics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,8 @@ void DolphinAnalytics::MakePerGameBuilder()
builder.AddData("cfg-audio-backend", Config::Get(Config::MAIN_AUDIO_BACKEND));
builder.AddData("cfg-oc-enable", Config::Get(Config::MAIN_OVERCLOCK_ENABLE));
builder.AddData("cfg-oc-factor", Config::Get(Config::MAIN_OVERCLOCK));
builder.AddData("cfg-vi-oc-enable", Config::Get(Config::MAIN_VI_OVERCLOCK_ENABLE));
builder.AddData("cfg-vi-oc-factor", Config::Get(Config::MAIN_VI_OVERCLOCK));
builder.AddData("cfg-render-to-main", Config::Get(Config::MAIN_RENDER_TO_MAIN));
if (g_video_backend)
{
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/Core/HW/SystemTimers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ void SystemTimersManager::VICallback(Core::System& system, u64 userdata, s64 cyc
auto& core_timing = system.GetCoreTiming();
auto& vi = system.GetVideoInterface();
vi.Update(core_timing.GetTicks() - cycles_late);
core_timing.ScheduleEvent(vi.GetTicksPerHalfLine() - cycles_late,
core_timing.ScheduleEvent(vi.GetTicksPerViCallback() - cycles_late,
system.GetSystemTimers().m_event_type_vi);
}

Expand Down Expand Up @@ -296,7 +296,7 @@ void SystemTimersManager::Init()

core_timing.ScheduleEvent(0, m_event_type_perf_tracker);
core_timing.ScheduleEvent(0, m_event_type_gpu_sleeper);
core_timing.ScheduleEvent(vi.GetTicksPerHalfLine(), m_event_type_vi);
core_timing.ScheduleEvent(vi.GetTicksPerViCallback(), m_event_type_vi);
core_timing.ScheduleEvent(0, m_event_type_dsp);

const int audio_dma_callback_period = GetAudioDMACallbackPeriod(
Expand Down
27 changes: 26 additions & 1 deletion Source/Core/Core/HW/VideoInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
#include "Common/Config/Config.h"
#include "Common/Logging/Log.h"

#include "VideoCommon/OnScreenDisplay.h"
#include "VideoCommon/PerformanceMetrics.h"

#include "Core/AchievementManager.h"
#include "Core/Config/GraphicsSettings.h"
#include "Core/Config/MainSettings.h"
#include "Core/Config/SYSCONFSettings.h"
Expand All @@ -41,7 +43,10 @@ VideoInterfaceManager::VideoInterfaceManager(Core::System& system) : m_system(sy
{
}

VideoInterfaceManager::~VideoInterfaceManager() = default;
VideoInterfaceManager::~VideoInterfaceManager()
{
Config::RemoveConfigChangedCallback(m_config_changed_callback_id);
}

static constexpr std::array<u32, 2> CLOCK_FREQUENCIES{{
27000000,
Expand Down Expand Up @@ -173,6 +178,21 @@ void VideoInterfaceManager::Preset(bool _bNTSC)
void VideoInterfaceManager::Init()
{
Preset(true);

m_config_changed_callback_id = Config::AddConfigChangedCallback([this] { RefreshConfig(); });
RefreshConfig();
}

void VideoInterfaceManager::RefreshConfig()
{
m_config_vi_oc_factor =
Config::Get(Config::MAIN_VI_OVERCLOCK_ENABLE) ? Config::Get(Config::MAIN_VI_OVERCLOCK) : 1.0f;
if (AchievementManager::GetInstance().IsHardcoreModeActive() && m_config_vi_oc_factor < 1.0f)
{
Config::SetCurrent(Config::MAIN_VI_OVERCLOCK, 1.0f);
m_config_vi_oc_factor = 1.0f;
OSD::AddMessage("Minimum VBI overclock is 100% in Hardcore Mode");
}
}

void VideoInterfaceManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
Expand Down Expand Up @@ -731,6 +751,11 @@ u32 VideoInterfaceManager::GetTicksPerField() const
return GetTicksPerEvenField();
}

u32 VideoInterfaceManager::GetTicksPerViCallback() const
{
return static_cast<u32>(GetTicksPerHalfLine() / m_config_vi_oc_factor);
}

void VideoInterfaceManager::LogField(FieldType field, u32 xfb_address) const
{
static constexpr std::array<const char*, 2> field_type_names{{"Odd", "Even"}};
Expand Down
7 changes: 7 additions & 0 deletions Source/Core/Core/HW/VideoInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <memory>

#include "Common/CommonTypes.h"
#include "Common/Config/Config.h"

enum class FieldType;
class PointerWrap;
Expand Down Expand Up @@ -387,6 +388,7 @@ class VideoInterfaceManager
u32 GetTicksPerSample() const;
u32 GetTicksPerHalfLine() const;
u32 GetTicksPerField() const;
u32 GetTicksPerViCallback() const;

// Get the aspect ratio of VI's active area (rarely matching pure 4:3).
// This function only deals with standard aspect ratios. For widescreen aspect ratios, multiply
Expand All @@ -407,6 +409,8 @@ class VideoInterfaceManager
void BeginField(FieldType field, u64 ticks);
void EndField(FieldType field, u64 ticks);

void RefreshConfig();

// Registers listed in order:
UVIVerticalTimingRegister m_vertical_timing_register;
UVIDisplayControlRegister m_display_control_register;
Expand Down Expand Up @@ -447,6 +451,9 @@ class VideoInterfaceManager
u32 m_even_field_last_hl = 0; // index last halfline of the even field
u32 m_odd_field_last_hl = 0; // index last halfline of the odd field

float m_config_vi_oc_factor = 0.0f;

Config::ConfigChangedCallbackID m_config_changed_callback_id;
Core::System& m_system;
};
} // namespace VideoInterface
4 changes: 1 addition & 3 deletions Source/Core/Core/IOS/DolphinDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,7 @@ IPCReply GetCPUSpeed(Core::System& system, const IOCtlVRequest& request)
return IPCReply(IPC_EINVAL);
}

const bool overclock_enabled = Config::Get(Config::MAIN_OVERCLOCK_ENABLE);
const float oc = overclock_enabled ? Config::Get(Config::MAIN_OVERCLOCK) : 1.0f;

const bool oc = system.GetCoreTiming().GetOverclock();
const u32 core_clock = u32(float(system.GetSystemTimers().GetTicksPerSecond()) * oc);

auto& memory = system.GetMemory();
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Core/NetPlayProto.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ struct NetSettings
bool allow_sd_writes = false;
bool oc_enable = false;
float oc_factor = 0;
bool vi_oc_enable = false;
float vi_oc_factor = 0;
Common::EnumMap<ExpansionInterface::EXIDeviceType, ExpansionInterface::MAX_SLOT> exi_device{};
int memcard_size_override = -1;

Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Core/NetPlayServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1369,6 +1369,8 @@ bool NetPlayServer::SetupNetSettings()
settings.allow_sd_writes = Config::Get(Config::MAIN_ALLOW_SD_WRITES);
settings.oc_enable = Config::Get(Config::MAIN_OVERCLOCK_ENABLE);
settings.oc_factor = Config::Get(Config::MAIN_OVERCLOCK);
settings.vi_oc_enable = Config::Get(Config::MAIN_VI_OVERCLOCK_ENABLE);
settings.vi_oc_factor = Config::Get(Config::MAIN_VI_OVERCLOCK);

for (ExpansionInterface::Slot slot : ExpansionInterface::SLOTS)
{
Expand Down
Loading

0 comments on commit ffdae15

Please sign in to comment.