summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/gpu_thread.cpp11
-rw-r--r--src/video_core/gpu_thread.h7
2 files changed, 11 insertions, 7 deletions
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp
index 4c25380eb..c5bdd2a17 100644
--- a/src/video_core/gpu_thread.cpp
+++ b/src/video_core/gpu_thread.cpp
@@ -40,7 +40,7 @@ static void RunThread(VideoCore::RendererBase& renderer, Tegra::DmaPusher& dma_p
40 40
41 auto WaitForWakeup = [&]() { 41 auto WaitForWakeup = [&]() {
42 std::unique_lock<std::mutex> lock{state.signal_mutex}; 42 std::unique_lock<std::mutex> lock{state.signal_mutex};
43 state.signal_condition.wait(lock, [&] { return !state.IsIdle() || !state.is_running; }); 43 state.signal_condition.wait(lock, [&] { return !state.is_idle || !state.is_running; });
44 }; 44 };
45 45
46 // Wait for first GPU command before acquiring the window context 46 // Wait for first GPU command before acquiring the window context
@@ -70,8 +70,10 @@ static void RunThread(VideoCore::RendererBase& renderer, Tegra::DmaPusher& dma_p
70 state.pop_queue->pop(); 70 state.pop_queue->pop();
71 } 71 }
72 72
73 state.UpdateIdleState();
74
73 // Signal that the GPU thread has finished processing commands 75 // Signal that the GPU thread has finished processing commands
74 if (state.IsIdle()) { 76 if (state.is_idle) {
75 state.idle_condition.notify_one(); 77 state.idle_condition.notify_one();
76 } 78 }
77 79
@@ -126,13 +128,14 @@ void ThreadManager::PushCommand(CommandData&& command_data, bool wait_for_idle,
126 { 128 {
127 std::lock_guard<std::mutex> lock{state.signal_mutex}; 129 std::lock_guard<std::mutex> lock{state.signal_mutex};
128 130
129 if ((allow_on_cpu && state.IsIdle()) || IsGpuThread()) { 131 if ((allow_on_cpu && state.is_idle) || IsGpuThread()) {
130 // Execute the command synchronously on the current thread 132 // Execute the command synchronously on the current thread
131 ExecuteCommand(&command_data, renderer, dma_pusher); 133 ExecuteCommand(&command_data, renderer, dma_pusher);
132 return; 134 return;
133 } 135 }
134 136
135 // Push the command to the GPU thread 137 // Push the command to the GPU thread
138 state.UpdateIdleState();
136 state.push_queue->emplace(command_data); 139 state.push_queue->emplace(command_data);
137 } 140 }
138 141
@@ -142,7 +145,7 @@ void ThreadManager::PushCommand(CommandData&& command_data, bool wait_for_idle,
142 if (wait_for_idle) { 145 if (wait_for_idle) {
143 // Wait for the GPU to be idle (all commands to be executed) 146 // Wait for the GPU to be idle (all commands to be executed)
144 std::unique_lock<std::mutex> lock{state.idle_mutex}; 147 std::unique_lock<std::mutex> lock{state.idle_mutex};
145 state.idle_condition.wait(lock, [this] { return state.IsIdle(); }); 148 state.idle_condition.wait(lock, [this] { return static_cast<bool>(state.is_idle); });
146 } 149 }
147} 150}
148 151
diff --git a/src/video_core/gpu_thread.h b/src/video_core/gpu_thread.h
index ad9f9462b..2ad8214cc 100644
--- a/src/video_core/gpu_thread.h
+++ b/src/video_core/gpu_thread.h
@@ -70,6 +70,7 @@ using CommandData = std::variant<SubmitListCommand, SwapBuffersCommand, FlushReg
70/// Struct used to synchronize the GPU thread 70/// Struct used to synchronize the GPU thread
71struct SynchState final { 71struct SynchState final {
72 std::atomic<bool> is_running{true}; 72 std::atomic<bool> is_running{true};
73 std::atomic<bool> is_idle{true};
73 std::condition_variable signal_condition; 74 std::condition_variable signal_condition;
74 std::mutex signal_mutex; 75 std::mutex signal_mutex;
75 std::condition_variable idle_condition; 76 std::condition_variable idle_condition;
@@ -84,9 +85,9 @@ struct SynchState final {
84 CommandQueue* push_queue{&command_queues[0]}; 85 CommandQueue* push_queue{&command_queues[0]};
85 CommandQueue* pop_queue{&command_queues[1]}; 86 CommandQueue* pop_queue{&command_queues[1]};
86 87
87 /// Returns true if the GPU thread should be idle, meaning there are no commands to process 88 void UpdateIdleState() {
88 bool IsIdle() const { 89 std::lock_guard<std::mutex> lock{idle_mutex};
89 return command_queues[0].empty() && command_queues[1].empty(); 90 is_idle = command_queues[0].empty() && command_queues[1].empty();
90 } 91 }
91}; 92};
92 93