aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/gpu_thread.cpp
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-29 00:27:35 -0400
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-29 00:27:35 -0400
commit934eeb0e6d82458048c94361b0d7b2db1b89f041 (patch)
treeac13dba71747bb4f406bb823722c8fd931e6ff0d /src/video_core/gpu_thread.cpp
parent863d3afa90f2dfde8e715b45f28fc75c1b472739 (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.cpp13
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));