diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-29 00:27:35 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-29 00:27:35 -0400 |
| commit | 934eeb0e6d82458048c94361b0d7b2db1b89f041 (patch) | |
| tree | ac13dba71747bb4f406bb823722c8fd931e6ff0d /src/video_core/gpu_thread.cpp | |
| parent | 863d3afa90f2dfde8e715b45f28fc75c1b472739 (diff) | |
nx2: poll pending channels briefly before sleeping; profile zones on the TSC
- A channel waiting on a semaphore the CPU releases slept 1 ms per poll
(~25 waits a second in title 1); poll for 0.5 ms first.
- The GPU profile zones read the wall clock (the TSC) instead of
QueryPerformanceCounter, which cost ~5% of the GPU thread when on.
Diffstat (limited to 'src/video_core/gpu_thread.cpp')
| -rw-r--r-- | src/video_core/gpu_thread.cpp | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index cf4e159806..72da1904e1 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp @@ -39,6 +39,8 @@ void ThreadManager::StartThread(VideoCore::RendererBase& renderer, Core::Fronten auto current_context = context.Acquire(); CommandDataContainer next; + // When a pending channel last moved or a command arrived (see the polling below). + auto last_progress = std::chrono::steady_clock::now(); namespace Profile = VideoCommon::Nx2Profile; while (!stop_token.stop_requested()) { Profile::Report(); @@ -49,8 +51,16 @@ void ThreadManager::StartThread(VideoCore::RendererBase& renderer, Core::Fronten scheduler.ResumePending(system.GPU()); } if (!state.queue.TryPop(next)) { + // The CPU usually releases the semaphore soon after: poll for half a + // millisecond before sleeping, or every wait also waits out a host sleep + // (title 1 waits ~25 times a second). Profile::Scope scope{Profile::Zone::PendingSleep}; - std::this_thread::sleep_for(std::chrono::milliseconds{1}); + if (std::chrono::steady_clock::now() - last_progress < + std::chrono::microseconds{500}) { + std::this_thread::yield(); + } else { + std::this_thread::sleep_for(std::chrono::milliseconds{1}); + } continue; } } else { @@ -60,6 +70,7 @@ void ThreadManager::StartThread(VideoCore::RendererBase& renderer, Core::Fronten if (stop_token.stop_requested()) { break; } + last_progress = std::chrono::steady_clock::now(); if (auto* submit_list = std::get_if<SubmitListCommand>(&next.data)) { Profile::Scope scope{Profile::Zone::Push}; scheduler.Push(system.GPU(), submit_list->channel, std::move(submit_list->entries)); |
