aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/gpu_thread.cpp
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-28 23:07:49 -0400
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-28 23:07:49 -0400
commit571f9b58eb8a9c102a91a5d26cd32ebae4330232 (patch)
tree989c5032c268044452d7ad7c324b147c964227e9 /src/video_core/gpu_thread.cpp
parent808039e5806dc841a30ef7d887462635860ae291 (diff)
nx2: GPU-thread zone timers and an in-process sampling profiler
EDEN_NX2_GPU_PROFILE=1 times the GPU thread's stages (command parsing, macros, draw setup by step, compute, texture uploads) and logs each one's share of every second. EDEN_NX2_SAMPLE=<thread names> (Windows) pauses the named threads about 600 times a second for EDEN_NX2_SAMPLE_SECONDS, walks their stacks and writes per-function counts plus folded stacks (EDEN_NX2_SAMPLE_OUT).
Diffstat (limited to 'src/video_core/gpu_thread.cpp')
-rw-r--r--src/video_core/gpu_thread.cpp15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp
index 793e8e9eeb..cf4e159806 100644
--- a/src/video_core/gpu_thread.cpp
+++ b/src/video_core/gpu_thread.cpp
@@ -17,6 +17,7 @@
#include "video_core/dma_pusher.h"
#include "video_core/gpu.h"
#include "video_core/gpu_thread.h"
+#include "video_core/nx2_profile.h"
#include "video_core/host1x/host1x.h"
#include "video_core/renderer_base.h"
@@ -38,29 +39,41 @@ void ThreadManager::StartThread(VideoCore::RendererBase& renderer, Core::Fronten
auto current_context = context.Acquire();
CommandDataContainer next;
+ namespace Profile = VideoCommon::Nx2Profile;
while (!stop_token.stop_requested()) {
+ Profile::Report();
if (scheduler.HasPendingChannels()) {
// Suspended channels wait on semaphores the CPU releases: poll them meanwhile.
- scheduler.ResumePending(system.GPU());
+ {
+ Profile::Scope scope{Profile::Zone::ResumePending};
+ scheduler.ResumePending(system.GPU());
+ }
if (!state.queue.TryPop(next)) {
+ Profile::Scope scope{Profile::Zone::PendingSleep};
std::this_thread::sleep_for(std::chrono::milliseconds{1});
continue;
}
} else {
+ Profile::Scope scope{Profile::Zone::Idle};
state.queue.PopWait(next, stop_token);
}
if (stop_token.stop_requested()) {
break;
}
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));
} else if (std::holds_alternative<GPUTickCommand>(next.data)) {
+ Profile::Scope scope{Profile::Zone::Tick};
system.GPU().TickWork();
} else if (auto* run = std::get_if<RunCommand>(&next.data)) {
+ Profile::Scope scope{Profile::Zone::Run};
run->func();
} else if (const auto* flush = std::get_if<FlushRegionCommand>(&next.data)) {
+ Profile::Scope scope{Profile::Zone::FlushInvalidate};
renderer.ReadRasterizer()->FlushRegion(flush->addr, flush->size);
} else if (const auto* invalidate = std::get_if<InvalidateRegionCommand>(&next.data)) {
+ Profile::Scope scope{Profile::Zone::FlushInvalidate};
renderer.ReadRasterizer()->OnCacheInvalidation(invalidate->addr, invalidate->size);
} else {
ASSERT(false);