diff options
| -rw-r--r-- | src/core/core.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/gpu.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 4 | ||||
| -rw-r--r-- | src/video_core/gpu_thread.cpp | 26 | ||||
| -rw-r--r-- | src/video_core/gpu_thread.h | 7 |
5 files changed, 28 insertions, 15 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index 305f56ff1..56b47e671 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -296,7 +296,7 @@ struct System::Impl { | |||
| 296 | exit_lock = false; | 296 | exit_lock = false; |
| 297 | 297 | ||
| 298 | if (gpu_core) { | 298 | if (gpu_core) { |
| 299 | gpu_core->WaitIdle(); | 299 | gpu_core->ShutDown(); |
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | services.reset(); | 302 | services.reset(); |
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index c61f44619..009c6f574 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -517,8 +517,8 @@ void GPU::TriggerCpuInterrupt(const u32 syncpoint_id, const u32 value) const { | |||
| 517 | interrupt_manager.GPUInterruptSyncpt(syncpoint_id, value); | 517 | interrupt_manager.GPUInterruptSyncpt(syncpoint_id, value); |
| 518 | } | 518 | } |
| 519 | 519 | ||
| 520 | void GPU::WaitIdle() const { | 520 | void GPU::ShutDown() { |
| 521 | gpu_thread.WaitIdle(); | 521 | gpu_thread.ShutDown(); |
| 522 | } | 522 | } |
| 523 | 523 | ||
| 524 | void GPU::OnCommandListEnd() { | 524 | void GPU::OnCommandListEnd() { |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index b2ee45496..ecab35d3b 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -219,8 +219,8 @@ public: | |||
| 219 | return *shader_notify; | 219 | return *shader_notify; |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | // Waits for the GPU to finish working | 222 | // Stops the GPU execution and waits for the GPU to finish working |
| 223 | void WaitIdle() const; | 223 | void ShutDown(); |
| 224 | 224 | ||
| 225 | /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame. | 225 | /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame. |
| 226 | void WaitFence(u32 syncpoint_id, u32 value); | 226 | void WaitFence(u32 syncpoint_id, u32 value); |
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index cd59a7faf..6b8f06f78 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp | |||
| @@ -68,13 +68,7 @@ ThreadManager::ThreadManager(Core::System& system_, bool is_async_) | |||
| 68 | : system{system_}, is_async{is_async_} {} | 68 | : system{system_}, is_async{is_async_} {} |
| 69 | 69 | ||
| 70 | ThreadManager::~ThreadManager() { | 70 | ThreadManager::~ThreadManager() { |
| 71 | if (!thread.joinable()) { | 71 | ShutDown(); |
| 72 | return; | ||
| 73 | } | ||
| 74 | |||
| 75 | // Notify GPU thread that a shutdown is pending | ||
| 76 | PushCommand(EndProcessingCommand()); | ||
| 77 | thread.join(); | ||
| 78 | } | 72 | } |
| 79 | 73 | ||
| 80 | void ThreadManager::StartThread(VideoCore::RendererBase& renderer, | 74 | void ThreadManager::StartThread(VideoCore::RendererBase& renderer, |
| @@ -132,10 +126,26 @@ void ThreadManager::FlushAndInvalidateRegion(VAddr addr, u64 size) { | |||
| 132 | 126 | ||
| 133 | void ThreadManager::WaitIdle() const { | 127 | void ThreadManager::WaitIdle() const { |
| 134 | while (state.last_fence > state.signaled_fence.load(std::memory_order_relaxed) && | 128 | while (state.last_fence > state.signaled_fence.load(std::memory_order_relaxed) && |
| 135 | system.IsPoweredOn()) { | 129 | state.is_running) { |
| 136 | } | 130 | } |
| 137 | } | 131 | } |
| 138 | 132 | ||
| 133 | void ThreadManager::ShutDown() { | ||
| 134 | if (!state.is_running) { | ||
| 135 | return; | ||
| 136 | } | ||
| 137 | |||
| 138 | state.is_running = false; | ||
| 139 | |||
| 140 | if (!thread.joinable()) { | ||
| 141 | return; | ||
| 142 | } | ||
| 143 | |||
| 144 | // Notify GPU thread that a shutdown is pending | ||
| 145 | PushCommand(EndProcessingCommand()); | ||
| 146 | thread.join(); | ||
| 147 | } | ||
| 148 | |||
| 139 | void ThreadManager::OnCommandListEnd() { | 149 | void ThreadManager::OnCommandListEnd() { |
| 140 | PushCommand(OnCommandListEndCommand()); | 150 | PushCommand(OnCommandListEndCommand()); |
| 141 | } | 151 | } |
diff --git a/src/video_core/gpu_thread.h b/src/video_core/gpu_thread.h index 18269e51c..d384164de 100644 --- a/src/video_core/gpu_thread.h +++ b/src/video_core/gpu_thread.h | |||
| @@ -132,8 +132,8 @@ public: | |||
| 132 | /// Notify rasterizer that any caches of the specified region should be flushed and invalidated | 132 | /// Notify rasterizer that any caches of the specified region should be flushed and invalidated |
| 133 | void FlushAndInvalidateRegion(VAddr addr, u64 size); | 133 | void FlushAndInvalidateRegion(VAddr addr, u64 size); |
| 134 | 134 | ||
| 135 | // Wait until the gpu thread is idle. | 135 | // Stops the GPU execution and waits for the GPU to finish working |
| 136 | void WaitIdle() const; | 136 | void ShutDown(); |
| 137 | 137 | ||
| 138 | void OnCommandListEnd(); | 138 | void OnCommandListEnd(); |
| 139 | 139 | ||
| @@ -141,6 +141,9 @@ private: | |||
| 141 | /// Pushes a command to be executed by the GPU thread | 141 | /// Pushes a command to be executed by the GPU thread |
| 142 | u64 PushCommand(CommandData&& command_data); | 142 | u64 PushCommand(CommandData&& command_data); |
| 143 | 143 | ||
| 144 | // Wait until the gpu thread is idle. | ||
| 145 | void WaitIdle() const; | ||
| 146 | |||
| 144 | Core::System& system; | 147 | Core::System& system; |
| 145 | const bool is_async; | 148 | const bool is_async; |
| 146 | VideoCore::RasterizerInterface* rasterizer = nullptr; | 149 | VideoCore::RasterizerInterface* rasterizer = nullptr; |