summaryrefslogtreecommitdiff
path: root/src/video_core/gpu_thread.cpp
diff options
context:
space:
mode:
authorGravatar ameerj2021-09-15 20:32:54 -0400
committerGravatar ameerj2021-09-15 20:49:07 -0400
commit877cd60b00a3f827062fdaff93183b52174ec134 (patch)
treeddcd7153dade611b9200c1867cfa643719696e25 /src/video_core/gpu_thread.cpp
parentthreadsafe_queue: Add std::stop_token overload to PopWait (diff)
downloadyuzu-877cd60b00a3f827062fdaff93183b52174ec134.tar.gz
yuzu-877cd60b00a3f827062fdaff93183b52174ec134.tar.xz
yuzu-877cd60b00a3f827062fdaff93183b52174ec134.zip
gpu: Use std::jthread for async gpu thread
Diffstat (limited to 'src/video_core/gpu_thread.cpp')
-rw-r--r--src/video_core/gpu_thread.cpp57
1 files changed, 13 insertions, 44 deletions
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp
index 46f642b19..9547f277a 100644
--- a/src/video_core/gpu_thread.cpp
+++ b/src/video_core/gpu_thread.cpp
@@ -17,9 +17,9 @@
17namespace VideoCommon::GPUThread { 17namespace VideoCommon::GPUThread {
18 18
19/// Runs the GPU thread 19/// Runs the GPU thread
20static void RunThread(Core::System& system, VideoCore::RendererBase& renderer, 20static void RunThread(std::stop_token stop_token, Core::System& system,
21 Core::Frontend::GraphicsContext& context, Tegra::DmaPusher& dma_pusher, 21 VideoCore::RendererBase& renderer, Core::Frontend::GraphicsContext& context,
22 SynchState& state) { 22 Tegra::DmaPusher& dma_pusher, SynchState& state) {
23 std::string name = "yuzu:GPU"; 23 std::string name = "yuzu:GPU";
24 MicroProfileOnThreadCreate(name.c_str()); 24 MicroProfileOnThreadCreate(name.c_str());
25 SCOPE_EXIT({ MicroProfileOnThreadExit(); }); 25 SCOPE_EXIT({ MicroProfileOnThreadExit(); });
@@ -28,20 +28,14 @@ static void RunThread(Core::System& system, VideoCore::RendererBase& renderer,
28 Common::SetCurrentThreadPriority(Common::ThreadPriority::High); 28 Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
29 system.RegisterHostThread(); 29 system.RegisterHostThread();
30 30
31 // Wait for first GPU command before acquiring the window context
32 state.queue.Wait();
33
34 // If emulation was stopped during disk shader loading, abort before trying to acquire context
35 if (!state.is_running) {
36 return;
37 }
38
39 auto current_context = context.Acquire(); 31 auto current_context = context.Acquire();
40 VideoCore::RasterizerInterface* const rasterizer = renderer.ReadRasterizer(); 32 VideoCore::RasterizerInterface* const rasterizer = renderer.ReadRasterizer();
41 33
42 CommandDataContainer next; 34 while (!stop_token.stop_requested()) {
43 while (state.is_running) { 35 CommandDataContainer next = state.queue.PopWait(stop_token);
44 next = state.queue.PopWait(); 36 if (stop_token.stop_requested()) {
37 break;
38 }
45 if (auto* submit_list = std::get_if<SubmitListCommand>(&next.data)) { 39 if (auto* submit_list = std::get_if<SubmitListCommand>(&next.data)) {
46 dma_pusher.Push(std::move(submit_list->entries)); 40 dma_pusher.Push(std::move(submit_list->entries));
47 dma_pusher.DispatchCalls(); 41 dma_pusher.DispatchCalls();
@@ -55,8 +49,6 @@ static void RunThread(Core::System& system, VideoCore::RendererBase& renderer,
55 rasterizer->FlushRegion(flush->addr, flush->size); 49 rasterizer->FlushRegion(flush->addr, flush->size);
56 } else if (const auto* invalidate = std::get_if<InvalidateRegionCommand>(&next.data)) { 50 } else if (const auto* invalidate = std::get_if<InvalidateRegionCommand>(&next.data)) {
57 rasterizer->OnCPUWrite(invalidate->addr, invalidate->size); 51 rasterizer->OnCPUWrite(invalidate->addr, invalidate->size);
58 } else if (std::holds_alternative<EndProcessingCommand>(next.data)) {
59 ASSERT(state.is_running == false);
60 } else { 52 } else {
61 UNREACHABLE(); 53 UNREACHABLE();
62 } 54 }
@@ -73,16 +65,14 @@ static void RunThread(Core::System& system, VideoCore::RendererBase& renderer,
73ThreadManager::ThreadManager(Core::System& system_, bool is_async_) 65ThreadManager::ThreadManager(Core::System& system_, bool is_async_)
74 : system{system_}, is_async{is_async_} {} 66 : system{system_}, is_async{is_async_} {}
75 67
76ThreadManager::~ThreadManager() { 68ThreadManager::~ThreadManager() = default;
77 ShutDown();
78}
79 69
80void ThreadManager::StartThread(VideoCore::RendererBase& renderer, 70void ThreadManager::StartThread(VideoCore::RendererBase& renderer,
81 Core::Frontend::GraphicsContext& context, 71 Core::Frontend::GraphicsContext& context,
82 Tegra::DmaPusher& dma_pusher) { 72 Tegra::DmaPusher& dma_pusher) {
83 rasterizer = renderer.ReadRasterizer(); 73 rasterizer = renderer.ReadRasterizer();
84 thread = std::thread(RunThread, std::ref(system), std::ref(renderer), std::ref(context), 74 thread = std::jthread(RunThread, std::ref(system), std::ref(renderer), std::ref(context),
85 std::ref(dma_pusher), std::ref(state)); 75 std::ref(dma_pusher), std::ref(state));
86} 76}
87 77
88void ThreadManager::SubmitList(Tegra::CommandList&& entries) { 78void ThreadManager::SubmitList(Tegra::CommandList&& entries) {
@@ -117,26 +107,6 @@ void ThreadManager::FlushAndInvalidateRegion(VAddr addr, u64 size) {
117 rasterizer->OnCPUWrite(addr, size); 107 rasterizer->OnCPUWrite(addr, size);
118} 108}
119 109
120void ThreadManager::ShutDown() {
121 if (!state.is_running) {
122 return;
123 }
124
125 {
126 std::lock_guard lk(state.write_lock);
127 state.is_running = false;
128 state.cv.notify_all();
129 }
130
131 if (!thread.joinable()) {
132 return;
133 }
134
135 // Notify GPU thread that a shutdown is pending
136 PushCommand(EndProcessingCommand());
137 thread.join();
138}
139
140void ThreadManager::OnCommandListEnd() { 110void ThreadManager::OnCommandListEnd() {
141 PushCommand(OnCommandListEndCommand()); 111 PushCommand(OnCommandListEndCommand());
142} 112}
@@ -152,9 +122,8 @@ u64 ThreadManager::PushCommand(CommandData&& command_data, bool block) {
152 state.queue.Push(CommandDataContainer(std::move(command_data), fence, block)); 122 state.queue.Push(CommandDataContainer(std::move(command_data), fence, block));
153 123
154 if (block) { 124 if (block) {
155 state.cv.wait(lk, [this, fence] { 125 state.cv.wait(lk, thread.get_stop_token(), [this, fence] {
156 return fence <= state.signaled_fence.load(std::memory_order_relaxed) || 126 return fence <= state.signaled_fence.load(std::memory_order_relaxed);
157 !state.is_running;
158 }); 127 });
159 } 128 }
160 129