Compare commits
5 Commits
android-20
...
android-20
Author | SHA1 | Date | |
---|---|---|---|
486c3db222 | |||
f286c2fde3 | |||
34fb9081e7 | |||
1fc82b84c7 | |||
3ab0600904 |
@ -1,7 +1,9 @@
|
|||||||
| Pull Request | Commit | Title | Author | Merged? |
|
| Pull Request | Commit | Title | Author | Merged? |
|
||||||
|----|----|----|----|----|
|
|----|----|----|----|----|
|
||||||
| [12499](https://github.com/yuzu-emu/yuzu-android//pull/12499) | [`fc30a84fc`](https://github.com/yuzu-emu/yuzu-android//pull/12499/files) | Rework time services | [Kelebek1](https://github.com/Kelebek1/) | Yes |
|
| [12499](https://github.com/yuzu-emu/yuzu-android//pull/12499) | [`e4915fb7d`](https://github.com/yuzu-emu/yuzu-android//pull/12499/files) | Rework time services | [Kelebek1](https://github.com/Kelebek1/) | Yes |
|
||||||
| [12749](https://github.com/yuzu-emu/yuzu-android//pull/12749) | [`e3171486d`](https://github.com/yuzu-emu/yuzu-android//pull/12749/files) | general: workarounds for SMMU syncing issues | [liamwhite](https://github.com/liamwhite/) | Yes |
|
| [12749](https://github.com/yuzu-emu/yuzu-android//pull/12749) | [`e3171486d`](https://github.com/yuzu-emu/yuzu-android//pull/12749/files) | general: workarounds for SMMU syncing issues | [liamwhite](https://github.com/liamwhite/) | Yes |
|
||||||
|
| [12759](https://github.com/yuzu-emu/yuzu-android//pull/12759) | [`a120f8ff4`](https://github.com/yuzu-emu/yuzu-android//pull/12759/files) | core: miscellaneous fixes | [liamwhite](https://github.com/liamwhite/) | Yes |
|
||||||
|
| [12769](https://github.com/yuzu-emu/yuzu-android//pull/12769) | [`ad4622da2`](https://github.com/yuzu-emu/yuzu-android//pull/12769/files) | core: hid: Reduce controller requests | [german77](https://github.com/german77/) | 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.
|
||||||
|
@ -29,10 +29,6 @@ NativeClock::NativeClock() {
|
|||||||
gputick_cntfrq_factor = GetFixedPointFactor(GPUTickFreq, host_cntfrq);
|
gputick_cntfrq_factor = GetFixedPointFactor(GPUTickFreq, host_cntfrq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeClock::Reset() {
|
|
||||||
start_ticks = GetUptime();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::chrono::nanoseconds NativeClock::GetTimeNS() const {
|
std::chrono::nanoseconds NativeClock::GetTimeNS() const {
|
||||||
return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_cntfrq_factor)};
|
return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_cntfrq_factor)};
|
||||||
}
|
}
|
||||||
@ -46,11 +42,11 @@ std::chrono::milliseconds NativeClock::GetTimeMS() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s64 NativeClock::GetCNTPCT() const {
|
s64 NativeClock::GetCNTPCT() const {
|
||||||
return MultiplyHigh(GetUptime() - start_ticks, guest_cntfrq_factor);
|
return MultiplyHigh(GetUptime(), guest_cntfrq_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 NativeClock::GetGPUTick() const {
|
s64 NativeClock::GetGPUTick() const {
|
||||||
return MultiplyHigh(GetUptime() - start_ticks, gputick_cntfrq_factor);
|
return MultiplyHigh(GetUptime(), gputick_cntfrq_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 NativeClock::GetUptime() const {
|
s64 NativeClock::GetUptime() const {
|
||||||
|
@ -11,8 +11,6 @@ class NativeClock final : public WallClock {
|
|||||||
public:
|
public:
|
||||||
explicit NativeClock();
|
explicit NativeClock();
|
||||||
|
|
||||||
void Reset() override;
|
|
||||||
|
|
||||||
std::chrono::nanoseconds GetTimeNS() const override;
|
std::chrono::nanoseconds GetTimeNS() const override;
|
||||||
|
|
||||||
std::chrono::microseconds GetTimeUS() const override;
|
std::chrono::microseconds GetTimeUS() const override;
|
||||||
@ -42,7 +40,6 @@ private:
|
|||||||
FactorType ms_cntfrq_factor;
|
FactorType ms_cntfrq_factor;
|
||||||
FactorType guest_cntfrq_factor;
|
FactorType guest_cntfrq_factor;
|
||||||
FactorType gputick_cntfrq_factor;
|
FactorType gputick_cntfrq_factor;
|
||||||
s64 start_ticks;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Common::Arm64
|
} // namespace Common::Arm64
|
||||||
|
@ -20,10 +20,6 @@ class StandardWallClock final : public WallClock {
|
|||||||
public:
|
public:
|
||||||
explicit StandardWallClock() {}
|
explicit StandardWallClock() {}
|
||||||
|
|
||||||
void Reset() override {
|
|
||||||
start_time = std::chrono::system_clock::now();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::chrono::nanoseconds GetTimeNS() const override {
|
std::chrono::nanoseconds GetTimeNS() const override {
|
||||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(
|
return std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||||
std::chrono::system_clock::now().time_since_epoch());
|
std::chrono::system_clock::now().time_since_epoch());
|
||||||
@ -49,16 +45,13 @@ public:
|
|||||||
|
|
||||||
s64 GetUptime() const override {
|
s64 GetUptime() const override {
|
||||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(
|
return std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||||
std::chrono::system_clock::now() - start_time)
|
std::chrono::steady_clock::now().time_since_epoch())
|
||||||
.count();
|
.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsNative() const override {
|
bool IsNative() const override {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
std::chrono::system_clock::time_point start_time{};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<WallClock> CreateOptimalClock() {
|
std::unique_ptr<WallClock> CreateOptimalClock() {
|
||||||
|
@ -19,8 +19,6 @@ public:
|
|||||||
|
|
||||||
virtual ~WallClock() = default;
|
virtual ~WallClock() = default;
|
||||||
|
|
||||||
virtual void Reset() = 0;
|
|
||||||
|
|
||||||
/// @returns The time in nanoseconds since the construction of this clock.
|
/// @returns The time in nanoseconds since the construction of this clock.
|
||||||
virtual std::chrono::nanoseconds GetTimeNS() const = 0;
|
virtual std::chrono::nanoseconds GetTimeNS() const = 0;
|
||||||
|
|
||||||
|
@ -15,10 +15,6 @@ NativeClock::NativeClock(u64 rdtsc_frequency_)
|
|||||||
cntpct_rdtsc_factor{GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency)},
|
cntpct_rdtsc_factor{GetFixedPoint64Factor(CNTFRQ, rdtsc_frequency)},
|
||||||
gputick_rdtsc_factor{GetFixedPoint64Factor(GPUTickFreq, rdtsc_frequency)} {}
|
gputick_rdtsc_factor{GetFixedPoint64Factor(GPUTickFreq, rdtsc_frequency)} {}
|
||||||
|
|
||||||
void NativeClock::Reset() {
|
|
||||||
start_ticks = FencedRDTSC();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::chrono::nanoseconds NativeClock::GetTimeNS() const {
|
std::chrono::nanoseconds NativeClock::GetTimeNS() const {
|
||||||
return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_rdtsc_factor)};
|
return std::chrono::nanoseconds{MultiplyHigh(GetUptime(), ns_rdtsc_factor)};
|
||||||
}
|
}
|
||||||
@ -32,11 +28,11 @@ std::chrono::milliseconds NativeClock::GetTimeMS() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s64 NativeClock::GetCNTPCT() const {
|
s64 NativeClock::GetCNTPCT() const {
|
||||||
return MultiplyHigh(GetUptime() - start_ticks, cntpct_rdtsc_factor);
|
return MultiplyHigh(GetUptime(), cntpct_rdtsc_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 NativeClock::GetGPUTick() const {
|
s64 NativeClock::GetGPUTick() const {
|
||||||
return MultiplyHigh(GetUptime() - start_ticks, gputick_rdtsc_factor);
|
return MultiplyHigh(GetUptime(), gputick_rdtsc_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 NativeClock::GetUptime() const {
|
s64 NativeClock::GetUptime() const {
|
||||||
|
@ -11,8 +11,6 @@ class NativeClock final : public WallClock {
|
|||||||
public:
|
public:
|
||||||
explicit NativeClock(u64 rdtsc_frequency_);
|
explicit NativeClock(u64 rdtsc_frequency_);
|
||||||
|
|
||||||
void Reset() override;
|
|
||||||
|
|
||||||
std::chrono::nanoseconds GetTimeNS() const override;
|
std::chrono::nanoseconds GetTimeNS() const override;
|
||||||
|
|
||||||
std::chrono::microseconds GetTimeUS() const override;
|
std::chrono::microseconds GetTimeUS() const override;
|
||||||
@ -28,7 +26,6 @@ public:
|
|||||||
bool IsNative() const override;
|
bool IsNative() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u64 start_ticks;
|
|
||||||
u64 rdtsc_frequency;
|
u64 rdtsc_frequency;
|
||||||
|
|
||||||
u64 ns_rdtsc_factor;
|
u64 ns_rdtsc_factor;
|
||||||
|
@ -66,7 +66,6 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
|
|||||||
event_fifo_id = 0;
|
event_fifo_id = 0;
|
||||||
shutting_down = false;
|
shutting_down = false;
|
||||||
cpu_ticks = 0;
|
cpu_ticks = 0;
|
||||||
clock->Reset();
|
|
||||||
if (is_multicore) {
|
if (is_multicore) {
|
||||||
timer_thread = std::make_unique<std::jthread>(ThreadEntry, std::ref(*this));
|
timer_thread = std::make_unique<std::jthread>(ThreadEntry, std::ref(*this));
|
||||||
}
|
}
|
||||||
|
@ -69,9 +69,14 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename AddressType>
|
template <typename AddressType>
|
||||||
void InvalidateInstructionCache(KernelCore& kernel, AddressType addr, u64 size) {
|
void InvalidateInstructionCache(KernelCore& kernel, KPageTableBase* table, AddressType addr,
|
||||||
|
u64 size) {
|
||||||
// TODO: lock the process list
|
// TODO: lock the process list
|
||||||
for (auto& process : kernel.GetProcessList()) {
|
for (auto& process : kernel.GetProcessList()) {
|
||||||
|
if (std::addressof(process->GetPageTable().GetBasePageTable()) != table) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
|
for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
|
||||||
auto* interface = process->GetArmInterface(i);
|
auto* interface = process->GetArmInterface(i);
|
||||||
if (interface) {
|
if (interface) {
|
||||||
@ -1302,7 +1307,7 @@ Result KPageTableBase::UnmapCodeMemory(KProcessAddress dst_address, KProcessAddr
|
|||||||
bool reprotected_pages = false;
|
bool reprotected_pages = false;
|
||||||
SCOPE_EXIT({
|
SCOPE_EXIT({
|
||||||
if (reprotected_pages && any_code_pages) {
|
if (reprotected_pages && any_code_pages) {
|
||||||
InvalidateInstructionCache(m_kernel, dst_address, size);
|
InvalidateInstructionCache(m_kernel, this, dst_address, size);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2036,7 +2041,7 @@ Result KPageTableBase::SetProcessMemoryPermission(KProcessAddress addr, size_t s
|
|||||||
for (const auto& block : pg) {
|
for (const auto& block : pg) {
|
||||||
StoreDataCache(GetHeapVirtualPointer(m_kernel, block.GetAddress()), block.GetSize());
|
StoreDataCache(GetHeapVirtualPointer(m_kernel, block.GetAddress()), block.GetSize());
|
||||||
}
|
}
|
||||||
InvalidateInstructionCache(m_kernel, addr, size);
|
InvalidateInstructionCache(m_kernel, this, addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
@ -3277,7 +3282,7 @@ Result KPageTableBase::WriteDebugMemory(KProcessAddress dst_address, KProcessAdd
|
|||||||
R_TRY(PerformCopy());
|
R_TRY(PerformCopy());
|
||||||
|
|
||||||
// Invalidate the instruction cache, as this svc allows modifying executable pages.
|
// Invalidate the instruction cache, as this svc allows modifying executable pages.
|
||||||
InvalidateInstructionCache(m_kernel, dst_address, size);
|
InvalidateInstructionCache(m_kernel, this, dst_address, size);
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,7 @@ SessionId Container::OpenSession(Kernel::KProcess* process) {
|
|||||||
|
|
||||||
void Container::CloseSession(SessionId session_id) {
|
void Container::CloseSession(SessionId session_id) {
|
||||||
std::scoped_lock lk(impl->session_guard);
|
std::scoped_lock lk(impl->session_guard);
|
||||||
|
impl->file.UnmapAllHandles(session_id);
|
||||||
auto& session = impl->sessions[session_id.id];
|
auto& session = impl->sessions[session_id.id];
|
||||||
auto& smmu = impl->host1x.MemoryManager();
|
auto& smmu = impl->host1x.MemoryManager();
|
||||||
if (session.has_preallocated_area) {
|
if (session.has_preallocated_area) {
|
||||||
|
@ -326,4 +326,17 @@ std::optional<NvMap::FreeInfo> NvMap::FreeHandle(Handle::Id handle, bool interna
|
|||||||
return freeInfo;
|
return freeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NvMap::UnmapAllHandles(NvCore::SessionId session_id) {
|
||||||
|
auto handles_copy = [&] {
|
||||||
|
std::scoped_lock lk{handles_lock};
|
||||||
|
return handles;
|
||||||
|
}();
|
||||||
|
|
||||||
|
for (auto& [id, handle] : handles_copy) {
|
||||||
|
if (handle->session_id.id == session_id.id) {
|
||||||
|
FreeHandle(id, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Service::Nvidia::NvCore
|
} // namespace Service::Nvidia::NvCore
|
||||||
|
@ -152,6 +152,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
std::optional<FreeInfo> FreeHandle(Handle::Id handle, bool internal_session);
|
std::optional<FreeInfo> FreeHandle(Handle::Id handle, bool internal_session);
|
||||||
|
|
||||||
|
void UnmapAllHandles(NvCore::SessionId session_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::list<std::shared_ptr<Handle>> unmap_queue{};
|
std::list<std::shared_ptr<Handle>> unmap_queue{};
|
||||||
std::mutex unmap_queue_lock{}; //!< Protects access to `unmap_queue`
|
std::mutex unmap_queue_lock{}; //!< Protects access to `unmap_queue`
|
||||||
|
@ -110,7 +110,11 @@ void EmulatedController::ReloadFromSettings() {
|
|||||||
original_npad_type = npad_type;
|
original_npad_type = npad_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetPollingMode(EmulatedDeviceIndex::RightIndex, Common::Input::PollingMode::Active);
|
// Disable special features before disconnecting
|
||||||
|
if (controller.right_polling_mode != Common::Input::PollingMode::Active) {
|
||||||
|
SetPollingMode(EmulatedDeviceIndex::RightIndex, Common::Input::PollingMode::Active);
|
||||||
|
}
|
||||||
|
|
||||||
Disconnect();
|
Disconnect();
|
||||||
if (player.connected) {
|
if (player.connected) {
|
||||||
Connect();
|
Connect();
|
||||||
@ -1241,7 +1245,12 @@ bool EmulatedController::SetVibration(DeviceIndex device_index, const VibrationV
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_vibration_value = vibration;
|
// Skip duplicated vibrations
|
||||||
|
if (last_vibration_value[index] == vibration) {
|
||||||
|
return Settings::values.vibration_enabled.GetValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
last_vibration_value[index] = vibration;
|
||||||
|
|
||||||
if (!Settings::values.vibration_enabled) {
|
if (!Settings::values.vibration_enabled) {
|
||||||
return false;
|
return false;
|
||||||
@ -1272,7 +1281,10 @@ bool EmulatedController::SetVibration(DeviceIndex device_index, const VibrationV
|
|||||||
}
|
}
|
||||||
|
|
||||||
VibrationValue EmulatedController::GetActualVibrationValue(DeviceIndex device_index) const {
|
VibrationValue EmulatedController::GetActualVibrationValue(DeviceIndex device_index) const {
|
||||||
return last_vibration_value;
|
if (device_index >= DeviceIndex::MaxDeviceIndex) {
|
||||||
|
return Core::HID::DEFAULT_VIBRATION_VALUE;
|
||||||
|
}
|
||||||
|
return last_vibration_value[static_cast<std::size_t>(device_index)];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
|
bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
|
||||||
|
@ -581,7 +581,8 @@ private:
|
|||||||
f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard};
|
f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard};
|
||||||
u32 turbo_button_state{0};
|
u32 turbo_button_state{0};
|
||||||
std::size_t nfc_handles{0};
|
std::size_t nfc_handles{0};
|
||||||
VibrationValue last_vibration_value{DEFAULT_VIBRATION_VALUE};
|
std::array<VibrationValue, 2> last_vibration_value{DEFAULT_VIBRATION_VALUE,
|
||||||
|
DEFAULT_VIBRATION_VALUE};
|
||||||
|
|
||||||
// Temporary values to avoid doing changes while the controller is in configuring mode
|
// Temporary values to avoid doing changes while the controller is in configuring mode
|
||||||
NpadStyleIndex tmp_npad_type{NpadStyleIndex::None};
|
NpadStyleIndex tmp_npad_type{NpadStyleIndex::None};
|
||||||
|
@ -639,6 +639,15 @@ struct VibrationValue {
|
|||||||
f32 low_frequency{};
|
f32 low_frequency{};
|
||||||
f32 high_amplitude{};
|
f32 high_amplitude{};
|
||||||
f32 high_frequency{};
|
f32 high_frequency{};
|
||||||
|
bool operator==(const VibrationValue& b) {
|
||||||
|
if (low_amplitude != b.low_amplitude || high_amplitude != b.high_amplitude) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (low_frequency != b.low_amplitude || high_frequency != b.high_frequency) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
static_assert(sizeof(VibrationValue) == 0x10, "VibrationValue has incorrect size.");
|
static_assert(sizeof(VibrationValue) == 0x10, "VibrationValue has incorrect size.");
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user