Somewhat functional clock timing setting
Some checks failed
eden-build / windows (msvc) (pull_request) Successful in 35m58s
eden-build / source (pull_request) Has been cancelled
eden-build / linux (pull_request) Has been cancelled
eden-build / android (pull_request) Has been cancelled
eden-license / license-header (pull_request_target) Has been cancelled
Some checks failed
eden-build / windows (msvc) (pull_request) Successful in 35m58s
eden-build / source (pull_request) Has been cancelled
eden-build / linux (pull_request) Has been cancelled
eden-build / android (pull_request) Has been cancelled
eden-license / license-header (pull_request_target) Has been cancelled
hangs when clock timing or both is set Signed-off-by: swurl <swurl@swurl.xyz>
This commit is contained in:
parent
449edd5224
commit
ec60d21616
10 changed files with 64 additions and 60 deletions
|
@ -231,11 +231,16 @@ struct Values {
|
|||
CpuAccuracy::Auto, CpuAccuracy::Paranoid,
|
||||
"cpu_accuracy", Category::Cpu};
|
||||
|
||||
SwitchableSetting<u32, true> cpu_clock_rate{linkage, 1020,
|
||||
500, 1785,
|
||||
SwitchableSetting<u32, true> cpu_clock_rate{linkage, 1,
|
||||
1, 6,
|
||||
"cpu_clock_rate", Category::Cpu,
|
||||
Specialization::Scalar};
|
||||
|
||||
SwitchableSetting<CpuClockStrategy, true> cpu_clock_strategy{linkage, CpuClockStrategy::Clock,
|
||||
CpuClockStrategy::None, CpuClockStrategy::Both,
|
||||
"cpu_clock_strategy", Category::Cpu};
|
||||
|
||||
|
||||
SwitchableSetting<bool> cpu_debug_mode{linkage, false, "cpu_debug_mode", Category::CpuDebug};
|
||||
|
||||
Setting<bool> cpuopt_page_tables{linkage, true, "cpuopt_page_tables", Category::CpuDebug};
|
||||
|
|
|
@ -134,6 +134,8 @@ ENUM(CpuBackend, Dynarmic, Nce);
|
|||
|
||||
ENUM(CpuAccuracy, Auto, Accurate, Unsafe, Paranoid);
|
||||
|
||||
ENUM(CpuClockStrategy, None, Clock, Timing, Both)
|
||||
|
||||
ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb);
|
||||
|
||||
ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never);
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include <ratio>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/hardware_properties.h"
|
||||
|
||||
namespace Common {
|
||||
|
||||
|
@ -16,9 +15,7 @@ class WallClock {
|
|||
public:
|
||||
static constexpr u64 CNTFRQ = 19'200'000; // CNTPCT_EL0 Frequency = 19.2 MHz
|
||||
static constexpr u64 GPUTickFreq = 614'400'000; // GM20B GPU Tick Frequency = 614.4 MHz
|
||||
static inline u64 CPUTickFreq() {
|
||||
return Core::Hardware::BASE_CLOCK_RATE();
|
||||
}
|
||||
static constexpr u64 CPUTickFreq = 1'020'000; // CPU Frequency = 1020.0MHz
|
||||
|
||||
virtual ~WallClock() = default;
|
||||
|
||||
|
@ -54,19 +51,19 @@ public:
|
|||
// Cycle Timing
|
||||
|
||||
static inline u64 CPUTickToNS(u64 cpu_tick) {
|
||||
return cpu_tick * CPUTickToNsRatio::num / CPUTickToNsRatio::den();
|
||||
return cpu_tick * CPUTickToNsRatio::num / CPUTickToNsRatio::den;
|
||||
}
|
||||
|
||||
static inline u64 CPUTickToUS(u64 cpu_tick) {
|
||||
return cpu_tick * CPUTickToUsRatio::num / CPUTickToUsRatio::den();
|
||||
return cpu_tick * CPUTickToUsRatio::num / CPUTickToUsRatio::den;
|
||||
}
|
||||
|
||||
static inline u64 CPUTickToCNTPCT(u64 cpu_tick) {
|
||||
return cpu_tick * CPUTickToCNTPCTRatio::num / CPUTickToCNTPCTRatio::den();
|
||||
return cpu_tick * CPUTickToCNTPCTRatio::num / CPUTickToCNTPCTRatio::den;
|
||||
}
|
||||
|
||||
static inline u64 CPUTickToGPUTick(u64 cpu_tick) {
|
||||
return cpu_tick * CPUTickToGPUTickRatio::num / CPUTickToGPUTickRatio::den();
|
||||
return cpu_tick * CPUTickToGPUTickRatio::num / CPUTickToGPUTickRatio::den;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -80,34 +77,10 @@ protected:
|
|||
using NsToGPUTickRatio = std::ratio<GPUTickFreq, std::nano::den>;
|
||||
|
||||
// Cycle Timing
|
||||
|
||||
struct CPUTickToNsRatio {
|
||||
static inline std::intmax_t num = std::nano::den;
|
||||
static inline std::intmax_t den() {
|
||||
return CPUTickFreq();
|
||||
}
|
||||
};
|
||||
|
||||
struct CPUTickToUsRatio {
|
||||
static inline std::intmax_t num = std::micro::den;
|
||||
static inline std::intmax_t den() {
|
||||
return CPUTickFreq();
|
||||
}
|
||||
};
|
||||
|
||||
struct CPUTickToCNTPCTRatio {
|
||||
static inline std::intmax_t num = CNTFRQ;
|
||||
static inline std::intmax_t den() {
|
||||
return CPUTickFreq();
|
||||
}
|
||||
};
|
||||
|
||||
struct CPUTickToGPUTickRatio {
|
||||
static inline std::intmax_t num = GPUTickFreq;
|
||||
static inline std::intmax_t den() {
|
||||
return CPUTickFreq();
|
||||
}
|
||||
};
|
||||
using CPUTickToNsRatio = std::ratio<std::nano::den, CPUTickFreq>;
|
||||
using CPUTickToUsRatio = std::ratio<std::micro::den, CPUTickFreq>;
|
||||
using CPUTickToCNTPCTRatio = std::ratio<CNTFRQ, CPUTickFreq>;
|
||||
using CPUTickToGPUTickRatio = std::ratio<GPUTickFreq, CPUTickFreq>;
|
||||
};
|
||||
|
||||
std::unique_ptr<WallClock> CreateOptimalClock();
|
||||
|
|
|
@ -1,25 +1,28 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include <iostream>
|
||||
#include "common/settings.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "common/windows/timer_resolution.h"
|
||||
#endif
|
||||
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
#include "common/x64/cpu_wait.h"
|
||||
#endif
|
||||
|
||||
#include "common/microprofile.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hardware_properties.h"
|
||||
|
||||
namespace Core::Timing {
|
||||
|
||||
int CoreTiming::rate_multiplier = 1;
|
||||
int CoreTiming::time_multiplier = 1;
|
||||
|
||||
constexpr s64 MAX_SLICE_LENGTH = 10000;
|
||||
|
||||
std::shared_ptr<EventType> CreateEvent(std::string name, TimedCallback&& callback) {
|
||||
|
@ -185,14 +188,14 @@ void CoreTiming::ResetTicks() {
|
|||
|
||||
u64 CoreTiming::GetClockTicks() const {
|
||||
if (is_multicore) [[likely]] {
|
||||
return clock->GetCNTPCT();
|
||||
return clock->GetCNTPCT() * rate_multiplier;
|
||||
}
|
||||
return Common::WallClock::CPUTickToCNTPCT(cpu_ticks);
|
||||
}
|
||||
|
||||
u64 CoreTiming::GetGPUTicks() const {
|
||||
if (is_multicore) [[likely]] {
|
||||
return clock->GetGPUTick();
|
||||
return clock->GetGPUTick() * rate_multiplier;
|
||||
}
|
||||
return Common::WallClock::CPUTickToGPUTick(cpu_ticks);
|
||||
}
|
||||
|
@ -302,6 +305,7 @@ void CoreTiming::ThreadLoop() {
|
|||
}
|
||||
|
||||
void CoreTiming::Reset() {
|
||||
std::cout << "reset called" << std::endl;
|
||||
paused = true;
|
||||
shutting_down = true;
|
||||
pause_event.Set();
|
||||
|
@ -311,18 +315,27 @@ void CoreTiming::Reset() {
|
|||
}
|
||||
timer_thread.reset();
|
||||
has_started = false;
|
||||
|
||||
auto clock_strategy = Settings::values.cpu_clock_strategy.GetValue();
|
||||
auto multiplier = Settings::values.cpu_clock_rate.GetValue();
|
||||
|
||||
time_multiplier = (clock_strategy == Settings::CpuClockStrategy::Timing || clock_strategy == Settings::CpuClockStrategy::Both) ? multiplier : 1;
|
||||
rate_multiplier = (clock_strategy == Settings::CpuClockStrategy::Clock || clock_strategy == Settings::CpuClockStrategy::Both) ? multiplier : 1;
|
||||
|
||||
std::cout << "reset finished " << time_multiplier << " " << rate_multiplier << " " << (int) clock_strategy << " " << multiplier << " " << this << std::endl;
|
||||
}
|
||||
|
||||
std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const {
|
||||
if (is_multicore) [[likely]] {
|
||||
return clock->GetTimeNS();
|
||||
LOG_INFO(Core, "GLOBAL TIME MULTIPLIER {:X}", time_multiplier);
|
||||
return clock->GetTimeNS() * CoreTiming::time_multiplier;
|
||||
}
|
||||
return std::chrono::nanoseconds{Common::WallClock::CPUTickToNS(cpu_ticks)};
|
||||
}
|
||||
|
||||
std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const {
|
||||
if (is_multicore) [[likely]] {
|
||||
return clock->GetTimeUS();
|
||||
return clock->GetTimeUS() * time_multiplier;
|
||||
}
|
||||
return std::chrono::microseconds{Common::WallClock::CPUTickToUS(cpu_ticks)};
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <boost/heap/fibonacci_heap.hpp>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/settings_enums.h"
|
||||
#include "common/thread.h"
|
||||
#include "common/wall_clock.h"
|
||||
|
||||
|
@ -178,6 +179,10 @@ private:
|
|||
/// Cycle timing
|
||||
u64 cpu_ticks{};
|
||||
s64 downcount{};
|
||||
|
||||
// Clock multipliers
|
||||
static int rate_multiplier;
|
||||
static int time_multiplier;
|
||||
};
|
||||
|
||||
/// Creates a core timing event with the given name and callback.
|
||||
|
|
|
@ -5,22 +5,15 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
|
||||
#include "common/bit_util.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/logging/log.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
namespace Hardware {
|
||||
|
||||
inline u64 BASE_CLOCK_RATE() {
|
||||
LOG_DEBUG(Core, "Settings reported clock rate={:08X}", Settings::values.cpu_clock_rate.GetValue());
|
||||
// std::cout << Settings::values.cpu_clock_rate.GetValue() << std::endl;
|
||||
return Settings::values.cpu_clock_rate.GetValue() * 1'000'000;
|
||||
}
|
||||
constexpr u64 BASE_CLOCK_RATE = 1'020'000; // CPU Frequency = 1020.0 MHz
|
||||
constexpr u64 CNTFREQ = 19'200'000; // CNTPCT_EL0 Frequency = 19.2 MHz
|
||||
constexpr u32 NUM_CPU_CORES = 4; // Number of CPU Cores
|
||||
|
||||
|
|
|
@ -80,10 +80,6 @@ PerformanceConfiguration Controller::GetCurrentPerformanceConfiguration(Performa
|
|||
|
||||
void Controller::SetClockSpeed(u32 mhz) {
|
||||
LOG_DEBUG(Service_APM, "called, mhz={:08X}", mhz);
|
||||
|
||||
// TODO: needs to be verified
|
||||
// Settings::values.cpu_clock_rate.SetGlobal(false);
|
||||
// Settings::values.cpu_clock_rate.SetValue(mhz);
|
||||
}
|
||||
|
||||
} // namespace Service::APM
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "core/hle/service/vi/display_list.h"
|
||||
#include "core/hle/service/vi/vsync_manager.h"
|
||||
|
||||
constexpr auto FrameNs = std::chrono::nanoseconds{1000000000 / 60};
|
||||
constexpr auto FrameNs = std::chrono::nanoseconds{1'000'000'000 / 60};
|
||||
|
||||
namespace Service::VI {
|
||||
|
||||
|
|
|
@ -74,7 +74,8 @@ void ConfigureCpu::Setup(const ConfigurationShared::Builder& builder) {
|
|||
} else if (setting->Id() == Settings::values.cpu_backend.Id()) {
|
||||
backend_layout->addWidget(widget);
|
||||
backend_combobox = widget->combobox;
|
||||
} else if (setting->Id() == Settings::values.cpu_clock_rate.Id()) {
|
||||
} else if (setting->Id() == Settings::values.cpu_clock_rate.Id()
|
||||
|| setting->Id() == Settings::values.cpu_clock_strategy.Id()) {
|
||||
clock_layout->addWidget(widget);
|
||||
} else {
|
||||
// Presently, all other settings here are unsafe checkboxes
|
||||
|
|
|
@ -77,8 +77,14 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
|
|||
tr("This setting controls the accuracy of the emulated CPU.\nDon't change this unless "
|
||||
"you know what you are doing."));
|
||||
INSERT(Settings, cpu_backend, tr("Backend:"), QStringLiteral());
|
||||
INSERT(Settings, cpu_clock_rate, tr("CPU Clock Rate (MHz):"), tr("Increasing CPU clock rate may "
|
||||
INSERT(Settings, cpu_clock_rate, tr("CPU Clock Multiplier:"), tr("Increasing CPU clock speed may "
|
||||
"improve performance, but may also reduce stability."));
|
||||
INSERT(Settings, cpu_clock_strategy, tr("Clock Strategy:"),
|
||||
tr("Some games use clock rate for timings, others use clock timing, and some even use both.\n"
|
||||
"Generally, this setting will increase a game's default FPS, but may cause unintended\n"
|
||||
"speedups or gameplay issues; for this reason, dedicated mods that unlock VSync and\n"
|
||||
"enable dynamic FPS are preferred over this setting.\nOnly change if you know what you're "
|
||||
"doing."));
|
||||
|
||||
// Cpu Debug
|
||||
|
||||
|
@ -356,6 +362,16 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent) {
|
|||
PAIR(CpuAccuracy, Unsafe, tr("Unsafe")),
|
||||
PAIR(CpuAccuracy, Paranoid, tr("Paranoid (disables most optimizations)")),
|
||||
}});
|
||||
|
||||
translations->insert(
|
||||
{Settings::EnumMetadata<Settings::CpuClockStrategy>::Index(),
|
||||
{
|
||||
PAIR(CpuClockStrategy, None, tr("None")),
|
||||
PAIR(CpuClockStrategy, Clock, tr("Clock Rate")),
|
||||
PAIR(CpuClockStrategy, Timing, tr("Clock Timing")),
|
||||
PAIR(CpuClockStrategy, Both, tr("Both")),
|
||||
}});
|
||||
|
||||
translations->insert({Settings::EnumMetadata<Settings::CpuBackend>::Index(),
|
||||
{
|
||||
PAIR(CpuBackend, Dynarmic, tr("Dynarmic")),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue