diff options
author | bunnei <bunneidev@gmail.com> | 2022-07-17 08:14:38 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-17 08:14:38 +0200 |
commit | 8ca8281f4f2d4050ec4eb67db422d5ceb3cabb3a (patch) | |
tree | 10fc191d058f7d057cbe41bc875054080774893d /src | |
parent | Merge pull request #8593 from merryhime/ranged-setting-T (diff) | |
parent | guard against div-by-zero (diff) | |
download | yuzu-8ca8281f4f2d4050ec4eb67db422d5ceb3cabb3a.tar yuzu-8ca8281f4f2d4050ec4eb67db422d5ceb3cabb3a.tar.gz yuzu-8ca8281f4f2d4050ec4eb67db422d5ceb3cabb3a.tar.bz2 yuzu-8ca8281f4f2d4050ec4eb67db422d5ceb3cabb3a.tar.lz yuzu-8ca8281f4f2d4050ec4eb67db422d5ceb3cabb3a.tar.xz yuzu-8ca8281f4f2d4050ec4eb67db422d5ceb3cabb3a.tar.zst yuzu-8ca8281f4f2d4050ec4eb67db422d5ceb3cabb3a.zip |
Diffstat (limited to 'src')
-rw-r--r-- | src/common/wall_clock.cpp | 2 | ||||
-rw-r--r-- | src/common/x64/cpu_detect.cpp | 16 | ||||
-rw-r--r-- | src/common/x64/cpu_detect.h | 5 |
3 files changed, 22 insertions, 1 deletions
diff --git a/src/common/wall_clock.cpp b/src/common/wall_clock.cpp index b4fb3a59f..ae07f2811 100644 --- a/src/common/wall_clock.cpp +++ b/src/common/wall_clock.cpp @@ -67,7 +67,7 @@ std::unique_ptr<WallClock> CreateBestMatchingClock(u64 emulated_cpu_frequency, const auto& caps = GetCPUCaps(); u64 rtsc_frequency = 0; if (caps.invariant_tsc) { - rtsc_frequency = EstimateRDTSCFrequency(); + rtsc_frequency = caps.tsc_frequency ? caps.tsc_frequency : EstimateRDTSCFrequency(); } // Fallback to StandardWallClock if the hardware TSC does not have the precision greater than: diff --git a/src/common/x64/cpu_detect.cpp b/src/common/x64/cpu_detect.cpp index 322aa1f08..1a27532d4 100644 --- a/src/common/x64/cpu_detect.cpp +++ b/src/common/x64/cpu_detect.cpp @@ -161,6 +161,22 @@ static CPUCaps Detect() { caps.invariant_tsc = Common::Bit<8>(cpu_id[3]); } + if (max_std_fn >= 0x15) { + __cpuid(cpu_id, 0x15); + caps.tsc_crystal_ratio_denominator = cpu_id[0]; + caps.tsc_crystal_ratio_numerator = cpu_id[1]; + caps.crystal_frequency = cpu_id[2]; + // Some CPU models might not return a crystal frequency. + // The CPU model can be detected to use the values from turbostat + // https://github.com/torvalds/linux/blob/master/tools/power/x86/turbostat/turbostat.c#L5569 + // but it's easier to just estimate the TSC tick rate for these cases. + if (caps.tsc_crystal_ratio_denominator) { + caps.tsc_frequency = static_cast<u64>(caps.crystal_frequency) * + caps.tsc_crystal_ratio_numerator / + caps.tsc_crystal_ratio_denominator; + } + } + if (max_std_fn >= 0x16) { __cpuid(cpu_id, 0x16); caps.base_frequency = cpu_id[0]; diff --git a/src/common/x64/cpu_detect.h b/src/common/x64/cpu_detect.h index 9bdc9dbfa..6830f3795 100644 --- a/src/common/x64/cpu_detect.h +++ b/src/common/x64/cpu_detect.h @@ -30,6 +30,11 @@ struct CPUCaps { u32 max_frequency; u32 bus_frequency; + u32 tsc_crystal_ratio_denominator; + u32 tsc_crystal_ratio_numerator; + u32 crystal_frequency; + u64 tsc_frequency; // Derived from the above three values + bool sse : 1; bool sse2 : 1; bool sse3 : 1; |