diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/gpu_thread.cpp | 11 | ||||
| -rw-r--r-- | src/video_core/gpu_thread.h | 7 |
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 |
| 71 | struct SynchState final { | 71 | struct 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 | ||