diff options
| author | 2020-06-28 12:37:50 -0400 | |
|---|---|---|
| committer | 2020-06-28 12:37:50 -0400 | |
| commit | b05795d704e0c194215f815a5703db09e524b59a (patch) | |
| tree | ecf4023b4ee0c91555c1d8263762fcb9dcb04a17 /src/core/hle/service | |
| parent | Merge pull request #4196 from ogniK5377/nrr-nro-fixes (diff) | |
| parent | Core/Common: Address Feedback. (diff) | |
| download | yuzu-b05795d704e0c194215f815a5703db09e524b59a.tar.gz yuzu-b05795d704e0c194215f815a5703db09e524b59a.tar.xz yuzu-b05795d704e0c194215f815a5703db09e524b59a.zip | |
Merge pull request #3955 from FernandoS27/prometheus-2b
Remake Kernel Scheduling, CPU Management & Boot Management (Prometheus)
Diffstat (limited to 'src/core/hle/service')
19 files changed, 103 insertions, 43 deletions
diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp index 1f2131ec8..cb35919e9 100644 --- a/src/core/hle/service/hid/controllers/debug_pad.cpp +++ b/src/core/hle/service/hid/controllers/debug_pad.cpp | |||
| @@ -23,7 +23,7 @@ void Controller_DebugPad::OnRelease() {} | |||
| 23 | 23 | ||
| 24 | void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 24 | void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, |
| 25 | std::size_t size) { | 25 | std::size_t size) { |
| 26 | shared_memory.header.timestamp = core_timing.GetTicks(); | 26 | shared_memory.header.timestamp = core_timing.GetCPUTicks(); |
| 27 | shared_memory.header.total_entry_count = 17; | 27 | shared_memory.header.total_entry_count = 17; |
| 28 | 28 | ||
| 29 | if (!IsControllerActivated()) { | 29 | if (!IsControllerActivated()) { |
diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp index 6e990dd00..b7b7bfeae 100644 --- a/src/core/hle/service/hid/controllers/gesture.cpp +++ b/src/core/hle/service/hid/controllers/gesture.cpp | |||
| @@ -19,7 +19,7 @@ void Controller_Gesture::OnRelease() {} | |||
| 19 | 19 | ||
| 20 | void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 20 | void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, |
| 21 | std::size_t size) { | 21 | std::size_t size) { |
| 22 | shared_memory.header.timestamp = core_timing.GetTicks(); | 22 | shared_memory.header.timestamp = core_timing.GetCPUTicks(); |
| 23 | shared_memory.header.total_entry_count = 17; | 23 | shared_memory.header.total_entry_count = 17; |
| 24 | 24 | ||
| 25 | if (!IsControllerActivated()) { | 25 | if (!IsControllerActivated()) { |
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp index 9a8d354ba..feae89525 100644 --- a/src/core/hle/service/hid/controllers/keyboard.cpp +++ b/src/core/hle/service/hid/controllers/keyboard.cpp | |||
| @@ -21,7 +21,7 @@ void Controller_Keyboard::OnRelease() {} | |||
| 21 | 21 | ||
| 22 | void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 22 | void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, |
| 23 | std::size_t size) { | 23 | std::size_t size) { |
| 24 | shared_memory.header.timestamp = core_timing.GetTicks(); | 24 | shared_memory.header.timestamp = core_timing.GetCPUTicks(); |
| 25 | shared_memory.header.total_entry_count = 17; | 25 | shared_memory.header.total_entry_count = 17; |
| 26 | 26 | ||
| 27 | if (!IsControllerActivated()) { | 27 | if (!IsControllerActivated()) { |
diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp index 93d88ea50..ac40989c5 100644 --- a/src/core/hle/service/hid/controllers/mouse.cpp +++ b/src/core/hle/service/hid/controllers/mouse.cpp | |||
| @@ -19,7 +19,7 @@ void Controller_Mouse::OnRelease() {} | |||
| 19 | 19 | ||
| 20 | void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 20 | void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, |
| 21 | std::size_t size) { | 21 | std::size_t size) { |
| 22 | shared_memory.header.timestamp = core_timing.GetTicks(); | 22 | shared_memory.header.timestamp = core_timing.GetCPUTicks(); |
| 23 | shared_memory.header.total_entry_count = 17; | 23 | shared_memory.header.total_entry_count = 17; |
| 24 | 24 | ||
| 25 | if (!IsControllerActivated()) { | 25 | if (!IsControllerActivated()) { |
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 6fbee7efa..ef67ad690 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -328,7 +328,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 328 | const auto& last_entry = | 328 | const auto& last_entry = |
| 329 | main_controller->npad[main_controller->common.last_entry_index]; | 329 | main_controller->npad[main_controller->common.last_entry_index]; |
| 330 | 330 | ||
| 331 | main_controller->common.timestamp = core_timing.GetTicks(); | 331 | main_controller->common.timestamp = core_timing.GetCPUTicks(); |
| 332 | main_controller->common.last_entry_index = | 332 | main_controller->common.last_entry_index = |
| 333 | (main_controller->common.last_entry_index + 1) % 17; | 333 | (main_controller->common.last_entry_index + 1) % 17; |
| 334 | 334 | ||
diff --git a/src/core/hle/service/hid/controllers/stubbed.cpp b/src/core/hle/service/hid/controllers/stubbed.cpp index 9e527d176..e7483bfa2 100644 --- a/src/core/hle/service/hid/controllers/stubbed.cpp +++ b/src/core/hle/service/hid/controllers/stubbed.cpp | |||
| @@ -23,7 +23,7 @@ void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing, u | |||
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | CommonHeader header{}; | 25 | CommonHeader header{}; |
| 26 | header.timestamp = core_timing.GetTicks(); | 26 | header.timestamp = core_timing.GetCPUTicks(); |
| 27 | header.total_entry_count = 17; | 27 | header.total_entry_count = 17; |
| 28 | header.entry_count = 0; | 28 | header.entry_count = 0; |
| 29 | header.last_entry_index = 0; | 29 | header.last_entry_index = 0; |
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index 1c6e55566..e326f8f5c 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp | |||
| @@ -22,7 +22,7 @@ void Controller_Touchscreen::OnRelease() {} | |||
| 22 | 22 | ||
| 23 | void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 23 | void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, |
| 24 | std::size_t size) { | 24 | std::size_t size) { |
| 25 | shared_memory.header.timestamp = core_timing.GetTicks(); | 25 | shared_memory.header.timestamp = core_timing.GetCPUTicks(); |
| 26 | shared_memory.header.total_entry_count = 17; | 26 | shared_memory.header.total_entry_count = 17; |
| 27 | 27 | ||
| 28 | if (!IsControllerActivated()) { | 28 | if (!IsControllerActivated()) { |
| @@ -49,7 +49,7 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin | |||
| 49 | touch_entry.diameter_x = Settings::values.touchscreen.diameter_x; | 49 | touch_entry.diameter_x = Settings::values.touchscreen.diameter_x; |
| 50 | touch_entry.diameter_y = Settings::values.touchscreen.diameter_y; | 50 | touch_entry.diameter_y = Settings::values.touchscreen.diameter_y; |
| 51 | touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle; | 51 | touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle; |
| 52 | const u64 tick = core_timing.GetTicks(); | 52 | const u64 tick = core_timing.GetCPUTicks(); |
| 53 | touch_entry.delta_time = tick - last_touch; | 53 | touch_entry.delta_time = tick - last_touch; |
| 54 | last_touch = tick; | 54 | last_touch = tick; |
| 55 | touch_entry.finger = Settings::values.touchscreen.finger; | 55 | touch_entry.finger = Settings::values.touchscreen.finger; |
diff --git a/src/core/hle/service/hid/controllers/xpad.cpp b/src/core/hle/service/hid/controllers/xpad.cpp index 27511b27b..2503ef241 100644 --- a/src/core/hle/service/hid/controllers/xpad.cpp +++ b/src/core/hle/service/hid/controllers/xpad.cpp | |||
| @@ -20,7 +20,7 @@ void Controller_XPad::OnRelease() {} | |||
| 20 | void Controller_XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, | 20 | void Controller_XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, |
| 21 | std::size_t size) { | 21 | std::size_t size) { |
| 22 | for (auto& xpad_entry : shared_memory.shared_memory_entries) { | 22 | for (auto& xpad_entry : shared_memory.shared_memory_entries) { |
| 23 | xpad_entry.header.timestamp = core_timing.GetTicks(); | 23 | xpad_entry.header.timestamp = core_timing.GetCPUTicks(); |
| 24 | xpad_entry.header.total_entry_count = 17; | 24 | xpad_entry.header.total_entry_count = 17; |
| 25 | 25 | ||
| 26 | if (!IsControllerActivated()) { | 26 | if (!IsControllerActivated()) { |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 57d5edea7..e9020e0dc 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -39,11 +39,9 @@ namespace Service::HID { | |||
| 39 | 39 | ||
| 40 | // Updating period for each HID device. | 40 | // Updating period for each HID device. |
| 41 | // TODO(ogniK): Find actual polling rate of hid | 41 | // TODO(ogniK): Find actual polling rate of hid |
| 42 | constexpr s64 pad_update_ticks = static_cast<s64>(Core::Hardware::BASE_CLOCK_RATE / 66); | 42 | constexpr s64 pad_update_ticks = static_cast<s64>(1000000000 / 66); |
| 43 | [[maybe_unused]] constexpr s64 accelerometer_update_ticks = | 43 | [[maybe_unused]] constexpr s64 accelerometer_update_ticks = static_cast<s64>(1000000000 / 100); |
| 44 | static_cast<s64>(Core::Hardware::BASE_CLOCK_RATE / 100); | 44 | [[maybe_unused]] constexpr s64 gyroscope_update_ticks = static_cast<s64>(1000000000 / 100); |
| 45 | [[maybe_unused]] constexpr s64 gyroscope_update_ticks = | ||
| 46 | static_cast<s64>(Core::Hardware::BASE_CLOCK_RATE / 100); | ||
| 47 | constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; | 45 | constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; |
| 48 | 46 | ||
| 49 | IAppletResource::IAppletResource(Core::System& system) | 47 | IAppletResource::IAppletResource(Core::System& system) |
| @@ -78,8 +76,8 @@ IAppletResource::IAppletResource(Core::System& system) | |||
| 78 | 76 | ||
| 79 | // Register update callbacks | 77 | // Register update callbacks |
| 80 | pad_update_event = | 78 | pad_update_event = |
| 81 | Core::Timing::CreateEvent("HID::UpdatePadCallback", [this](u64 userdata, s64 cycles_late) { | 79 | Core::Timing::CreateEvent("HID::UpdatePadCallback", [this](u64 userdata, s64 ns_late) { |
| 82 | UpdateControllers(userdata, cycles_late); | 80 | UpdateControllers(userdata, ns_late); |
| 83 | }); | 81 | }); |
| 84 | 82 | ||
| 85 | // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?) | 83 | // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?) |
| @@ -109,7 +107,7 @@ void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) { | |||
| 109 | rb.PushCopyObjects(shared_mem); | 107 | rb.PushCopyObjects(shared_mem); |
| 110 | } | 108 | } |
| 111 | 109 | ||
| 112 | void IAppletResource::UpdateControllers(u64 userdata, s64 cycles_late) { | 110 | void IAppletResource::UpdateControllers(u64 userdata, s64 ns_late) { |
| 113 | auto& core_timing = system.CoreTiming(); | 111 | auto& core_timing = system.CoreTiming(); |
| 114 | 112 | ||
| 115 | const bool should_reload = Settings::values.is_device_reload_pending.exchange(false); | 113 | const bool should_reload = Settings::values.is_device_reload_pending.exchange(false); |
| @@ -120,7 +118,7 @@ void IAppletResource::UpdateControllers(u64 userdata, s64 cycles_late) { | |||
| 120 | controller->OnUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE); | 118 | controller->OnUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE); |
| 121 | } | 119 | } |
| 122 | 120 | ||
| 123 | core_timing.ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event); | 121 | core_timing.ScheduleEvent(pad_update_ticks - ns_late, pad_update_event); |
| 124 | } | 122 | } |
| 125 | 123 | ||
| 126 | class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> { | 124 | class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> { |
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp index 36ed6f7da..e82fd031b 100644 --- a/src/core/hle/service/hid/irs.cpp +++ b/src/core/hle/service/hid/irs.cpp | |||
| @@ -98,7 +98,7 @@ void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) { | |||
| 98 | 98 | ||
| 99 | IPC::ResponseBuilder rb{ctx, 5}; | 99 | IPC::ResponseBuilder rb{ctx, 5}; |
| 100 | rb.Push(RESULT_SUCCESS); | 100 | rb.Push(RESULT_SUCCESS); |
| 101 | rb.PushRaw<u64>(system.CoreTiming().GetTicks()); | 101 | rb.PushRaw<u64>(system.CoreTiming().GetCPUTicks()); |
| 102 | rb.PushRaw<u32>(0); | 102 | rb.PushRaw<u32>(0); |
| 103 | } | 103 | } |
| 104 | 104 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index 0d913334e..fba89e7a6 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | |||
| @@ -200,8 +200,7 @@ u32 nvhost_ctrl_gpu::GetGpuTime(const std::vector<u8>& input, std::vector<u8>& o | |||
| 200 | 200 | ||
| 201 | IoctlGetGpuTime params{}; | 201 | IoctlGetGpuTime params{}; |
| 202 | std::memcpy(¶ms, input.data(), input.size()); | 202 | std::memcpy(¶ms, input.data(), input.size()); |
| 203 | const auto ns = Core::Timing::CyclesToNs(system.CoreTiming().GetTicks()); | 203 | params.gpu_time = static_cast<u64_le>(system.CoreTiming().GetGlobalTimeNs().count()); |
| 204 | params.gpu_time = static_cast<u64_le>(ns.count()); | ||
| 205 | std::memcpy(output.data(), ¶ms, output.size()); | 204 | std::memcpy(output.data(), ¶ms, output.size()); |
| 206 | return 0; | 205 | return 0; |
| 207 | } | 206 | } |
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 437bc5dee..2f44d3779 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "common/logging/log.h" | 9 | #include "common/logging/log.h" |
| 10 | #include "common/microprofile.h" | 10 | #include "common/microprofile.h" |
| 11 | #include "common/scope_exit.h" | 11 | #include "common/scope_exit.h" |
| 12 | #include "common/thread.h" | ||
| 12 | #include "core/core.h" | 13 | #include "core/core.h" |
| 13 | #include "core/core_timing.h" | 14 | #include "core/core_timing.h" |
| 14 | #include "core/core_timing_util.h" | 15 | #include "core/core_timing_util.h" |
| @@ -27,8 +28,35 @@ | |||
| 27 | 28 | ||
| 28 | namespace Service::NVFlinger { | 29 | namespace Service::NVFlinger { |
| 29 | 30 | ||
| 30 | constexpr s64 frame_ticks = static_cast<s64>(Core::Hardware::BASE_CLOCK_RATE / 60); | 31 | constexpr s64 frame_ticks = static_cast<s64>(1000000000 / 60); |
| 31 | constexpr s64 frame_ticks_30fps = static_cast<s64>(Core::Hardware::BASE_CLOCK_RATE / 30); | 32 | constexpr s64 frame_ticks_30fps = static_cast<s64>(1000000000 / 30); |
| 33 | |||
| 34 | void NVFlinger::VSyncThread(NVFlinger& nv_flinger) { | ||
| 35 | nv_flinger.SplitVSync(); | ||
| 36 | } | ||
| 37 | |||
| 38 | void NVFlinger::SplitVSync() { | ||
| 39 | system.RegisterHostThread(); | ||
| 40 | std::string name = "yuzu:VSyncThread"; | ||
| 41 | MicroProfileOnThreadCreate(name.c_str()); | ||
| 42 | Common::SetCurrentThreadName(name.c_str()); | ||
| 43 | Common::SetCurrentThreadPriority(Common::ThreadPriority::High); | ||
| 44 | s64 delay = 0; | ||
| 45 | while (is_running) { | ||
| 46 | guard->lock(); | ||
| 47 | const s64 time_start = system.CoreTiming().GetGlobalTimeNs().count(); | ||
| 48 | Compose(); | ||
| 49 | const auto ticks = GetNextTicks(); | ||
| 50 | const s64 time_end = system.CoreTiming().GetGlobalTimeNs().count(); | ||
| 51 | const s64 time_passed = time_end - time_start; | ||
| 52 | const s64 next_time = std::max<s64>(0, ticks - time_passed - delay); | ||
| 53 | guard->unlock(); | ||
| 54 | if (next_time > 0) { | ||
| 55 | wait_event->WaitFor(std::chrono::nanoseconds{next_time}); | ||
| 56 | } | ||
| 57 | delay = (system.CoreTiming().GetGlobalTimeNs().count() - time_end) - next_time; | ||
| 58 | } | ||
| 59 | } | ||
| 32 | 60 | ||
| 33 | NVFlinger::NVFlinger(Core::System& system) : system(system) { | 61 | NVFlinger::NVFlinger(Core::System& system) : system(system) { |
| 34 | displays.emplace_back(0, "Default", system); | 62 | displays.emplace_back(0, "Default", system); |
| @@ -36,22 +64,36 @@ NVFlinger::NVFlinger(Core::System& system) : system(system) { | |||
| 36 | displays.emplace_back(2, "Edid", system); | 64 | displays.emplace_back(2, "Edid", system); |
| 37 | displays.emplace_back(3, "Internal", system); | 65 | displays.emplace_back(3, "Internal", system); |
| 38 | displays.emplace_back(4, "Null", system); | 66 | displays.emplace_back(4, "Null", system); |
| 67 | guard = std::make_shared<std::mutex>(); | ||
| 39 | 68 | ||
| 40 | // Schedule the screen composition events | 69 | // Schedule the screen composition events |
| 41 | composition_event = | 70 | composition_event = |
| 42 | Core::Timing::CreateEvent("ScreenComposition", [this](u64 userdata, s64 cycles_late) { | 71 | Core::Timing::CreateEvent("ScreenComposition", [this](u64 userdata, s64 ns_late) { |
| 72 | Lock(); | ||
| 43 | Compose(); | 73 | Compose(); |
| 44 | const auto ticks = | 74 | const auto ticks = GetNextTicks(); |
| 45 | Settings::values.force_30fps_mode ? frame_ticks_30fps : GetNextTicks(); | 75 | this->system.CoreTiming().ScheduleEvent(std::max<s64>(0LL, ticks - ns_late), |
| 46 | this->system.CoreTiming().ScheduleEvent(std::max<s64>(0LL, ticks - cycles_late), | ||
| 47 | composition_event); | 76 | composition_event); |
| 48 | }); | 77 | }); |
| 49 | 78 | if (system.IsMulticore()) { | |
| 50 | system.CoreTiming().ScheduleEvent(frame_ticks, composition_event); | 79 | is_running = true; |
| 80 | wait_event = std::make_unique<Common::Event>(); | ||
| 81 | vsync_thread = std::make_unique<std::thread>(VSyncThread, std::ref(*this)); | ||
| 82 | } else { | ||
| 83 | system.CoreTiming().ScheduleEvent(frame_ticks, composition_event); | ||
| 84 | } | ||
| 51 | } | 85 | } |
| 52 | 86 | ||
| 53 | NVFlinger::~NVFlinger() { | 87 | NVFlinger::~NVFlinger() { |
| 54 | system.CoreTiming().UnscheduleEvent(composition_event, 0); | 88 | if (system.IsMulticore()) { |
| 89 | is_running = false; | ||
| 90 | wait_event->Set(); | ||
| 91 | vsync_thread->join(); | ||
| 92 | vsync_thread.reset(); | ||
| 93 | wait_event.reset(); | ||
| 94 | } else { | ||
| 95 | system.CoreTiming().UnscheduleEvent(composition_event, 0); | ||
| 96 | } | ||
| 55 | } | 97 | } |
| 56 | 98 | ||
| 57 | void NVFlinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) { | 99 | void NVFlinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) { |
| @@ -199,10 +241,12 @@ void NVFlinger::Compose() { | |||
| 199 | 241 | ||
| 200 | auto& gpu = system.GPU(); | 242 | auto& gpu = system.GPU(); |
| 201 | const auto& multi_fence = buffer->get().multi_fence; | 243 | const auto& multi_fence = buffer->get().multi_fence; |
| 244 | guard->unlock(); | ||
| 202 | for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) { | 245 | for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) { |
| 203 | const auto& fence = multi_fence.fences[fence_id]; | 246 | const auto& fence = multi_fence.fences[fence_id]; |
| 204 | gpu.WaitFence(fence.id, fence.value); | 247 | gpu.WaitFence(fence.id, fence.value); |
| 205 | } | 248 | } |
| 249 | guard->lock(); | ||
| 206 | 250 | ||
| 207 | MicroProfileFlip(); | 251 | MicroProfileFlip(); |
| 208 | 252 | ||
| @@ -223,7 +267,7 @@ void NVFlinger::Compose() { | |||
| 223 | 267 | ||
| 224 | s64 NVFlinger::GetNextTicks() const { | 268 | s64 NVFlinger::GetNextTicks() const { |
| 225 | constexpr s64 max_hertz = 120LL; | 269 | constexpr s64 max_hertz = 120LL; |
| 226 | return (Core::Hardware::BASE_CLOCK_RATE * (1LL << swap_interval)) / max_hertz; | 270 | return (1000000000 * (1LL << swap_interval)) / max_hertz; |
| 227 | } | 271 | } |
| 228 | 272 | ||
| 229 | } // namespace Service::NVFlinger | 273 | } // namespace Service::NVFlinger |
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h index 57a21f33b..e4959a9af 100644 --- a/src/core/hle/service/nvflinger/nvflinger.h +++ b/src/core/hle/service/nvflinger/nvflinger.h | |||
| @@ -4,15 +4,22 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <atomic> | ||
| 7 | #include <memory> | 8 | #include <memory> |
| 9 | #include <mutex> | ||
| 8 | #include <optional> | 10 | #include <optional> |
| 9 | #include <string> | 11 | #include <string> |
| 10 | #include <string_view> | 12 | #include <string_view> |
| 13 | #include <thread> | ||
| 11 | #include <vector> | 14 | #include <vector> |
| 12 | 15 | ||
| 13 | #include "common/common_types.h" | 16 | #include "common/common_types.h" |
| 14 | #include "core/hle/kernel/object.h" | 17 | #include "core/hle/kernel/object.h" |
| 15 | 18 | ||
| 19 | namespace Common { | ||
| 20 | class Event; | ||
| 21 | } // namespace Common | ||
| 22 | |||
| 16 | namespace Core::Timing { | 23 | namespace Core::Timing { |
| 17 | class CoreTiming; | 24 | class CoreTiming; |
| 18 | struct EventType; | 25 | struct EventType; |
| @@ -79,6 +86,10 @@ public: | |||
| 79 | 86 | ||
| 80 | s64 GetNextTicks() const; | 87 | s64 GetNextTicks() const; |
| 81 | 88 | ||
| 89 | std::unique_lock<std::mutex> Lock() { | ||
| 90 | return std::unique_lock{*guard}; | ||
| 91 | } | ||
| 92 | |||
| 82 | private: | 93 | private: |
| 83 | /// Finds the display identified by the specified ID. | 94 | /// Finds the display identified by the specified ID. |
| 84 | VI::Display* FindDisplay(u64 display_id); | 95 | VI::Display* FindDisplay(u64 display_id); |
| @@ -92,6 +103,10 @@ private: | |||
| 92 | /// Finds the layer identified by the specified ID in the desired display. | 103 | /// Finds the layer identified by the specified ID in the desired display. |
| 93 | const VI::Layer* FindLayer(u64 display_id, u64 layer_id) const; | 104 | const VI::Layer* FindLayer(u64 display_id, u64 layer_id) const; |
| 94 | 105 | ||
| 106 | static void VSyncThread(NVFlinger& nv_flinger); | ||
| 107 | |||
| 108 | void SplitVSync(); | ||
| 109 | |||
| 95 | std::shared_ptr<Nvidia::Module> nvdrv; | 110 | std::shared_ptr<Nvidia::Module> nvdrv; |
| 96 | 111 | ||
| 97 | std::vector<VI::Display> displays; | 112 | std::vector<VI::Display> displays; |
| @@ -108,7 +123,13 @@ private: | |||
| 108 | /// Event that handles screen composition. | 123 | /// Event that handles screen composition. |
| 109 | std::shared_ptr<Core::Timing::EventType> composition_event; | 124 | std::shared_ptr<Core::Timing::EventType> composition_event; |
| 110 | 125 | ||
| 126 | std::shared_ptr<std::mutex> guard; | ||
| 127 | |||
| 111 | Core::System& system; | 128 | Core::System& system; |
| 129 | |||
| 130 | std::unique_ptr<std::thread> vsync_thread; | ||
| 131 | std::unique_ptr<Common::Event> wait_event; | ||
| 132 | std::atomic<bool> is_running{}; | ||
| 112 | }; | 133 | }; |
| 113 | 134 | ||
| 114 | } // namespace Service::NVFlinger | 135 | } // namespace Service::NVFlinger |
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 6ada13be4..d872de16c 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp | |||
| @@ -142,7 +142,7 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { | |||
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | // Wake the threads waiting on the ServerPort | 144 | // Wake the threads waiting on the ServerPort |
| 145 | server_port->WakeupAllWaitingThreads(); | 145 | server_port->Signal(); |
| 146 | 146 | ||
| 147 | LOG_DEBUG(Service_SM, "called service={} -> session={}", name, client->GetObjectId()); | 147 | LOG_DEBUG(Service_SM, "called service={} -> session={}", name, client->GetObjectId()); |
| 148 | IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; | 148 | IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; |
diff --git a/src/core/hle/service/time/standard_steady_clock_core.cpp b/src/core/hle/service/time/standard_steady_clock_core.cpp index 1575f0b49..59a272f4a 100644 --- a/src/core/hle/service/time/standard_steady_clock_core.cpp +++ b/src/core/hle/service/time/standard_steady_clock_core.cpp | |||
| @@ -11,9 +11,8 @@ | |||
| 11 | namespace Service::Time::Clock { | 11 | namespace Service::Time::Clock { |
| 12 | 12 | ||
| 13 | TimeSpanType StandardSteadyClockCore::GetCurrentRawTimePoint(Core::System& system) { | 13 | TimeSpanType StandardSteadyClockCore::GetCurrentRawTimePoint(Core::System& system) { |
| 14 | const TimeSpanType ticks_time_span{TimeSpanType::FromTicks( | 14 | const TimeSpanType ticks_time_span{ |
| 15 | Core::Timing::CpuCyclesToClockCycles(system.CoreTiming().GetTicks()), | 15 | TimeSpanType::FromTicks(system.CoreTiming().GetClockTicks(), Core::Hardware::CNTFREQ)}; |
| 16 | Core::Hardware::CNTFREQ)}; | ||
| 17 | TimeSpanType raw_time_point{setup_value.nanoseconds + ticks_time_span.nanoseconds}; | 16 | TimeSpanType raw_time_point{setup_value.nanoseconds + ticks_time_span.nanoseconds}; |
| 18 | 17 | ||
| 19 | if (raw_time_point.nanoseconds < cached_raw_time_point.nanoseconds) { | 18 | if (raw_time_point.nanoseconds < cached_raw_time_point.nanoseconds) { |
diff --git a/src/core/hle/service/time/tick_based_steady_clock_core.cpp b/src/core/hle/service/time/tick_based_steady_clock_core.cpp index 44d5bc651..8baaa2a6a 100644 --- a/src/core/hle/service/time/tick_based_steady_clock_core.cpp +++ b/src/core/hle/service/time/tick_based_steady_clock_core.cpp | |||
| @@ -11,9 +11,8 @@ | |||
| 11 | namespace Service::Time::Clock { | 11 | namespace Service::Time::Clock { |
| 12 | 12 | ||
| 13 | SteadyClockTimePoint TickBasedSteadyClockCore::GetTimePoint(Core::System& system) { | 13 | SteadyClockTimePoint TickBasedSteadyClockCore::GetTimePoint(Core::System& system) { |
| 14 | const TimeSpanType ticks_time_span{TimeSpanType::FromTicks( | 14 | const TimeSpanType ticks_time_span{ |
| 15 | Core::Timing::CpuCyclesToClockCycles(system.CoreTiming().GetTicks()), | 15 | TimeSpanType::FromTicks(system.CoreTiming().GetClockTicks(), Core::Hardware::CNTFREQ)}; |
| 16 | Core::Hardware::CNTFREQ)}; | ||
| 17 | 16 | ||
| 18 | return {ticks_time_span.ToSeconds(), GetClockSourceId()}; | 17 | return {ticks_time_span.ToSeconds(), GetClockSourceId()}; |
| 19 | } | 18 | } |
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 67f1bbcf3..4cf58a61a 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp | |||
| @@ -234,9 +234,8 @@ void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERe | |||
| 234 | const auto current_time_point{steady_clock_core.GetCurrentTimePoint(system)}; | 234 | const auto current_time_point{steady_clock_core.GetCurrentTimePoint(system)}; |
| 235 | 235 | ||
| 236 | if (current_time_point.clock_source_id == context.steady_time_point.clock_source_id) { | 236 | if (current_time_point.clock_source_id == context.steady_time_point.clock_source_id) { |
| 237 | const auto ticks{Clock::TimeSpanType::FromTicks( | 237 | const auto ticks{Clock::TimeSpanType::FromTicks(system.CoreTiming().GetClockTicks(), |
| 238 | Core::Timing::CpuCyclesToClockCycles(system.CoreTiming().GetTicks()), | 238 | Core::Hardware::CNTFREQ)}; |
| 239 | Core::Hardware::CNTFREQ)}; | ||
| 240 | const s64 base_time_point{context.offset + current_time_point.time_point - | 239 | const s64 base_time_point{context.offset + current_time_point.time_point - |
| 241 | ticks.ToSeconds()}; | 240 | ticks.ToSeconds()}; |
| 242 | IPC::ResponseBuilder rb{ctx, (sizeof(s64) / 4) + 2}; | 241 | IPC::ResponseBuilder rb{ctx, (sizeof(s64) / 4) + 2}; |
diff --git a/src/core/hle/service/time/time_sharedmemory.cpp b/src/core/hle/service/time/time_sharedmemory.cpp index 999ec1e51..e0ae9f874 100644 --- a/src/core/hle/service/time/time_sharedmemory.cpp +++ b/src/core/hle/service/time/time_sharedmemory.cpp | |||
| @@ -30,8 +30,7 @@ void SharedMemory::SetupStandardSteadyClock(Core::System& system, | |||
| 30 | const Common::UUID& clock_source_id, | 30 | const Common::UUID& clock_source_id, |
| 31 | Clock::TimeSpanType current_time_point) { | 31 | Clock::TimeSpanType current_time_point) { |
| 32 | const Clock::TimeSpanType ticks_time_span{Clock::TimeSpanType::FromTicks( | 32 | const Clock::TimeSpanType ticks_time_span{Clock::TimeSpanType::FromTicks( |
| 33 | Core::Timing::CpuCyclesToClockCycles(system.CoreTiming().GetTicks()), | 33 | system.CoreTiming().GetClockTicks(), Core::Hardware::CNTFREQ)}; |
| 34 | Core::Hardware::CNTFREQ)}; | ||
| 35 | const Clock::SteadyClockContext context{ | 34 | const Clock::SteadyClockContext context{ |
| 36 | static_cast<u64>(current_time_point.nanoseconds - ticks_time_span.nanoseconds), | 35 | static_cast<u64>(current_time_point.nanoseconds - ticks_time_span.nanoseconds), |
| 37 | clock_source_id}; | 36 | clock_source_id}; |
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 46e14c2a3..157092074 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -511,6 +511,7 @@ private: | |||
| 511 | LOG_DEBUG(Service_VI, "called. id=0x{:08X} transaction={:X}, flags=0x{:08X}", id, | 511 | LOG_DEBUG(Service_VI, "called. id=0x{:08X} transaction={:X}, flags=0x{:08X}", id, |
| 512 | static_cast<u32>(transaction), flags); | 512 | static_cast<u32>(transaction), flags); |
| 513 | 513 | ||
| 514 | nv_flinger->Lock(); | ||
| 514 | auto& buffer_queue = nv_flinger->FindBufferQueue(id); | 515 | auto& buffer_queue = nv_flinger->FindBufferQueue(id); |
| 515 | 516 | ||
| 516 | switch (transaction) { | 517 | switch (transaction) { |
| @@ -550,6 +551,7 @@ private: | |||
| 550 | [=](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, | 551 | [=](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, |
| 551 | Kernel::ThreadWakeupReason reason) { | 552 | Kernel::ThreadWakeupReason reason) { |
| 552 | // Repeat TransactParcel DequeueBuffer when a buffer is available | 553 | // Repeat TransactParcel DequeueBuffer when a buffer is available |
| 554 | nv_flinger->Lock(); | ||
| 553 | auto& buffer_queue = nv_flinger->FindBufferQueue(id); | 555 | auto& buffer_queue = nv_flinger->FindBufferQueue(id); |
| 554 | auto result = buffer_queue.DequeueBuffer(width, height); | 556 | auto result = buffer_queue.DequeueBuffer(width, height); |
| 555 | ASSERT_MSG(result != std::nullopt, "Could not dequeue buffer."); | 557 | ASSERT_MSG(result != std::nullopt, "Could not dequeue buffer."); |