Compare commits
1 Commits
android-96
...
android-95
Author | SHA1 | Date | |
---|---|---|---|
3f71b85569 |
@ -1,6 +1,5 @@
|
|||||||
| Pull Request | Commit | Title | Author | Merged? |
|
| Pull Request | Commit | Title | Author | Merged? |
|
||||||
|----|----|----|----|----|
|
|----|----|----|----|----|
|
||||||
| [11718](https://github.com/yuzu-emu/yuzu//pull/11718) | [`21bc2c14b`](https://github.com/yuzu-emu/yuzu//pull/11718/files) | common: add arm64 native clock | [liamwhite](https://github.com/liamwhite/) | Yes |
|
|
||||||
|
|
||||||
|
|
||||||
End of merge log. You can find the original README.md below the break.
|
End of merge log. You can find the original README.md below the break.
|
||||||
|
@ -189,14 +189,6 @@ if(ARCHITECTURE_x86_64)
|
|||||||
target_link_libraries(common PRIVATE xbyak::xbyak)
|
target_link_libraries(common PRIVATE xbyak::xbyak)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ARCHITECTURE_arm64 AND (ANDROID OR LINUX))
|
|
||||||
target_sources(common
|
|
||||||
PRIVATE
|
|
||||||
arm64/native_clock.cpp
|
|
||||||
arm64/native_clock.h
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
target_compile_definitions(common PRIVATE
|
target_compile_definitions(common PRIVATE
|
||||||
# The standard library doesn't provide any replacement for codecvt yet
|
# The standard library doesn't provide any replacement for codecvt yet
|
||||||
|
@ -1,72 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "common/arm64/native_clock.h"
|
|
||||||
|
|
||||||
namespace Common::Arm64 {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
NativeClock::FactorType GetFixedPointFactor(u64 num, u64 den) {
|
|
||||||
return (static_cast<NativeClock::FactorType>(num) << 64) / den;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 MultiplyHigh(u64 m, NativeClock::FactorType factor) {
|
|
||||||
return static_cast<u64>((m * factor) >> 64);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
NativeClock::NativeClock() {
|
|
||||||
const u64 host_cntfrq = GetHostCNTFRQ();
|
|
||||||
ns_cntfrq_factor = GetFixedPointFactor(NsRatio::den, host_cntfrq);
|
|
||||||
us_cntfrq_factor = GetFixedPointFactor(UsRatio::den, host_cntfrq);
|
|
||||||
ms_cntfrq_factor = GetFixedPointFactor(MsRatio::den, host_cntfrq);
|
|
||||||
guest_cntfrq_factor = GetFixedPointFactor(CNTFRQ, host_cntfrq);
|
|
||||||
gputick_cntfrq_factor = GetFixedPointFactor(GPUTickFreq, host_cntfrq);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::chrono::nanoseconds NativeClock::GetTimeNS() const {
|
|
||||||
return std::chrono::nanoseconds{MultiplyHigh(GetHostTicksElapsed(), ns_cntfrq_factor)};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::chrono::microseconds NativeClock::GetTimeUS() const {
|
|
||||||
return std::chrono::microseconds{MultiplyHigh(GetHostTicksElapsed(), us_cntfrq_factor)};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::chrono::milliseconds NativeClock::GetTimeMS() const {
|
|
||||||
return std::chrono::milliseconds{MultiplyHigh(GetHostTicksElapsed(), ms_cntfrq_factor)};
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 NativeClock::GetCNTPCT() const {
|
|
||||||
return MultiplyHigh(GetHostTicksElapsed(), guest_cntfrq_factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 NativeClock::GetGPUTick() const {
|
|
||||||
return MultiplyHigh(GetHostTicksElapsed(), gputick_cntfrq_factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 NativeClock::GetHostTicksNow() const {
|
|
||||||
u64 cntvct_el0 = 0;
|
|
||||||
asm volatile("dsb ish\n\t"
|
|
||||||
"mrs %[cntvct_el0], cntvct_el0\n\t"
|
|
||||||
"dsb ish\n\t"
|
|
||||||
: [cntvct_el0] "=r"(cntvct_el0));
|
|
||||||
return cntvct_el0;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 NativeClock::GetHostTicksElapsed() const {
|
|
||||||
return GetHostTicksNow();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NativeClock::IsNative() const {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 NativeClock::GetHostCNTFRQ() {
|
|
||||||
u64 cntfrq_el0 = 0;
|
|
||||||
asm("mrs %[cntfrq_el0], cntfrq_el0" : [cntfrq_el0] "=r"(cntfrq_el0));
|
|
||||||
return cntfrq_el0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Common::Arm64
|
|
@ -1,47 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/wall_clock.h"
|
|
||||||
|
|
||||||
namespace Common::Arm64 {
|
|
||||||
|
|
||||||
class NativeClock final : public WallClock {
|
|
||||||
public:
|
|
||||||
explicit NativeClock();
|
|
||||||
|
|
||||||
std::chrono::nanoseconds GetTimeNS() const override;
|
|
||||||
|
|
||||||
std::chrono::microseconds GetTimeUS() const override;
|
|
||||||
|
|
||||||
std::chrono::milliseconds GetTimeMS() const override;
|
|
||||||
|
|
||||||
u64 GetCNTPCT() const override;
|
|
||||||
|
|
||||||
u64 GetGPUTick() const override;
|
|
||||||
|
|
||||||
u64 GetHostTicksNow() const override;
|
|
||||||
|
|
||||||
u64 GetHostTicksElapsed() const override;
|
|
||||||
|
|
||||||
bool IsNative() const override;
|
|
||||||
|
|
||||||
static u64 GetHostCNTFRQ();
|
|
||||||
|
|
||||||
public:
|
|
||||||
using FactorType = unsigned __int128;
|
|
||||||
|
|
||||||
FactorType GetGuestCNTFRQFactor() const {
|
|
||||||
return guest_cntfrq_factor;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
FactorType ns_cntfrq_factor;
|
|
||||||
FactorType us_cntfrq_factor;
|
|
||||||
FactorType ms_cntfrq_factor;
|
|
||||||
FactorType guest_cntfrq_factor;
|
|
||||||
FactorType gputick_cntfrq_factor;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Common::Arm64
|
|
@ -10,10 +10,6 @@
|
|||||||
#include "common/x64/rdtsc.h"
|
#include "common/x64/rdtsc.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ARCHITECTURE_arm64) && defined(__linux__)
|
|
||||||
#include "common/arm64/native_clock.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
class StandardWallClock final : public WallClock {
|
class StandardWallClock final : public WallClock {
|
||||||
@ -57,7 +53,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<WallClock> CreateOptimalClock() {
|
std::unique_ptr<WallClock> CreateOptimalClock() {
|
||||||
#if defined(ARCHITECTURE_x86_64)
|
#ifdef ARCHITECTURE_x86_64
|
||||||
const auto& caps = GetCPUCaps();
|
const auto& caps = GetCPUCaps();
|
||||||
|
|
||||||
if (caps.invariant_tsc && caps.tsc_frequency >= std::nano::den) {
|
if (caps.invariant_tsc && caps.tsc_frequency >= std::nano::den) {
|
||||||
@ -68,8 +64,6 @@ std::unique_ptr<WallClock> CreateOptimalClock() {
|
|||||||
// - Is not more precise than 1 GHz (1ns resolution)
|
// - Is not more precise than 1 GHz (1ns resolution)
|
||||||
return std::make_unique<StandardWallClock>();
|
return std::make_unique<StandardWallClock>();
|
||||||
}
|
}
|
||||||
#elif defined(ARCHITECTURE_arm64) && defined(__linux__)
|
|
||||||
return std::make_unique<Arm64::NativeClock>();
|
|
||||||
#else
|
#else
|
||||||
return std::make_unique<StandardWallClock>();
|
return std::make_unique<StandardWallClock>();
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user