From e09141750bc9b2f64d7df7f93e50312a19ff2d13 Mon Sep 17 00:00:00 2001 From: yuzubot Date: Sat, 7 Dec 2019 13:01:22 +0000 Subject: [PATCH] "Merge Tagged PR 3166" --- src/video_core/gpu_thread.cpp | 37 +++++++++++++++++++---------------- src/video_core/gpu_thread.h | 2 ++ 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index 2cdf1aa7f..24a790aaf 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp @@ -19,8 +19,7 @@ static void RunThread(VideoCore::RendererBase& renderer, Tegra::DmaPusher& dma_p MicroProfileOnThreadCreate("GpuThread"); // Wait for first GPU command before acquiring the window context - while (state.queue.Empty()) - ; + state.sync_event.Wait(); // If emulation was stopped during disk shader loading, abort before trying to acquire context if (!state.is_running) { @@ -31,22 +30,25 @@ static void RunThread(VideoCore::RendererBase& renderer, Tegra::DmaPusher& dma_p CommandDataContainer next; while (state.is_running) { - next = state.queue.PopWait(); - if (const auto submit_list = std::get_if(&next.data)) { - dma_pusher.Push(std::move(submit_list->entries)); - dma_pusher.DispatchCalls(); - } else if (const auto data = std::get_if(&next.data)) { - renderer.SwapBuffers(data->framebuffer ? &*data->framebuffer : nullptr); - } else if (const auto data = std::get_if(&next.data)) { - renderer.Rasterizer().FlushRegion(data->addr, data->size); - } else if (const auto data = std::get_if(&next.data)) { - renderer.Rasterizer().InvalidateRegion(data->addr, data->size); - } else if (std::holds_alternative(next.data)) { - return; - } else { - UNREACHABLE(); + while (!state.queue.Empty()) { + state.queue.Pop(next); + if (const auto submit_list = std::get_if(&next.data)) { + dma_pusher.Push(std::move(submit_list->entries)); + dma_pusher.DispatchCalls(); + } else if (const auto data = std::get_if(&next.data)) { + renderer.SwapBuffers(data->framebuffer ? &*data->framebuffer : nullptr); + } else if (const auto data = std::get_if(&next.data)) { + renderer.Rasterizer().FlushRegion(data->addr, data->size); + } else if (const auto data = std::get_if(&next.data)) { + renderer.Rasterizer().InvalidateRegion(data->addr, data->size); + } else if (std::holds_alternative(next.data)) { + return; + } else { + UNREACHABLE(); + } + state.signaled_fence.store(next.fence); } - state.signaled_fence.store(next.fence); + state.sync_event.Wait(); } } @@ -95,6 +97,7 @@ void ThreadManager::WaitIdle() const { u64 ThreadManager::PushCommand(CommandData&& command_data) { const u64 fence{++state.last_fence}; state.queue.Push(CommandDataContainer(std::move(command_data), fence)); + state.sync_event.Set(); return fence; } diff --git a/src/video_core/gpu_thread.h b/src/video_core/gpu_thread.h index 08dc96bb3..4fd191002 100644 --- a/src/video_core/gpu_thread.h +++ b/src/video_core/gpu_thread.h @@ -11,6 +11,7 @@ #include #include +#include "common/thread.h" #include "common/threadsafe_queue.h" #include "video_core/gpu.h" @@ -90,6 +91,7 @@ struct SynchState final { CommandQueue queue; u64 last_fence{}; std::atomic signaled_fence{}; + Common::Event sync_event{}; }; /// Class used to manage the GPU thread