diff options
| author | 2022-01-04 14:16:24 +0100 | |
|---|---|---|
| committer | 2022-01-04 14:16:24 +0100 | |
| commit | 118d5fa3b0fdc070f57916203dbbb999fe7e3c69 (patch) | |
| tree | dcea9a661fb5595fd255fa62e81d82c9a3aef822 /src/video_core/gpu.cpp | |
| parent | Merge pull request #7251 from FernandoS27/shader-dump (diff) | |
| parent | gpu: Add shut down method to synchronize threads before destruction (diff) | |
| download | yuzu-118d5fa3b0fdc070f57916203dbbb999fe7e3c69.tar.gz yuzu-118d5fa3b0fdc070f57916203dbbb999fe7e3c69.tar.xz yuzu-118d5fa3b0fdc070f57916203dbbb999fe7e3c69.zip | |
Merge pull request #7670 from ameerj/vsync-block
gpu: Add shut down method to synchronize threads before destruction
Diffstat (limited to 'src/video_core/gpu.cpp')
| -rw-r--r-- | src/video_core/gpu.cpp | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index d98874150..44fda27ef 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -206,7 +206,7 @@ struct GPU::Impl { | |||
| 206 | } | 206 | } |
| 207 | 207 | ||
| 208 | /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame. | 208 | /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame. |
| 209 | void WaitFence(u32 syncpoint_id, u32 value, std::stop_token stop_token = {}) { | 209 | void WaitFence(u32 syncpoint_id, u32 value) { |
| 210 | // Synced GPU, is always in sync | 210 | // Synced GPU, is always in sync |
| 211 | if (!is_async) { | 211 | if (!is_async) { |
| 212 | return; | 212 | return; |
| @@ -218,8 +218,13 @@ struct GPU::Impl { | |||
| 218 | } | 218 | } |
| 219 | MICROPROFILE_SCOPE(GPU_wait); | 219 | MICROPROFILE_SCOPE(GPU_wait); |
| 220 | std::unique_lock lock{sync_mutex}; | 220 | std::unique_lock lock{sync_mutex}; |
| 221 | sync_cv.wait(lock, stop_token, | 221 | sync_cv.wait(lock, [=, this] { |
| 222 | [=, this] { return syncpoints.at(syncpoint_id).load() >= value; }); | 222 | if (shutting_down.load(std::memory_order_relaxed)) { |
| 223 | // We're shutting down, ensure no threads continue to wait for the next syncpoint | ||
| 224 | return true; | ||
| 225 | } | ||
| 226 | return syncpoints.at(syncpoint_id).load() >= value; | ||
| 227 | }); | ||
| 223 | } | 228 | } |
| 224 | 229 | ||
| 225 | void IncrementSyncPoint(u32 syncpoint_id) { | 230 | void IncrementSyncPoint(u32 syncpoint_id) { |
| @@ -307,6 +312,12 @@ struct GPU::Impl { | |||
| 307 | cpu_context->MakeCurrent(); | 312 | cpu_context->MakeCurrent(); |
| 308 | } | 313 | } |
| 309 | 314 | ||
| 315 | void NotifyShutdown() { | ||
| 316 | std::unique_lock lk{sync_mutex}; | ||
| 317 | shutting_down.store(true, std::memory_order::relaxed); | ||
| 318 | sync_cv.notify_all(); | ||
| 319 | } | ||
| 320 | |||
| 310 | /// Obtain the CPU Context | 321 | /// Obtain the CPU Context |
| 311 | void ObtainContext() { | 322 | void ObtainContext() { |
| 312 | cpu_context->MakeCurrent(); | 323 | cpu_context->MakeCurrent(); |
| @@ -665,6 +676,8 @@ struct GPU::Impl { | |||
| 665 | std::unique_ptr<Engines::KeplerMemory> kepler_memory; | 676 | std::unique_ptr<Engines::KeplerMemory> kepler_memory; |
| 666 | /// Shader build notifier | 677 | /// Shader build notifier |
| 667 | std::unique_ptr<VideoCore::ShaderNotify> shader_notify; | 678 | std::unique_ptr<VideoCore::ShaderNotify> shader_notify; |
| 679 | /// When true, we are about to shut down emulation session, so terminate outstanding tasks | ||
| 680 | std::atomic_bool shutting_down{}; | ||
| 668 | 681 | ||
| 669 | std::array<std::atomic<u32>, Service::Nvidia::MaxSyncPoints> syncpoints{}; | 682 | std::array<std::atomic<u32>, Service::Nvidia::MaxSyncPoints> syncpoints{}; |
| 670 | 683 | ||
| @@ -673,7 +686,7 @@ struct GPU::Impl { | |||
| 673 | std::mutex sync_mutex; | 686 | std::mutex sync_mutex; |
| 674 | std::mutex device_mutex; | 687 | std::mutex device_mutex; |
| 675 | 688 | ||
| 676 | std::condition_variable_any sync_cv; | 689 | std::condition_variable sync_cv; |
| 677 | 690 | ||
| 678 | struct FlushRequest { | 691 | struct FlushRequest { |
| 679 | explicit FlushRequest(u64 fence_, VAddr addr_, std::size_t size_) | 692 | explicit FlushRequest(u64 fence_, VAddr addr_, std::size_t size_) |
| @@ -812,8 +825,8 @@ const VideoCore::ShaderNotify& GPU::ShaderNotify() const { | |||
| 812 | return impl->ShaderNotify(); | 825 | return impl->ShaderNotify(); |
| 813 | } | 826 | } |
| 814 | 827 | ||
| 815 | void GPU::WaitFence(u32 syncpoint_id, u32 value, std::stop_token stop_token) { | 828 | void GPU::WaitFence(u32 syncpoint_id, u32 value) { |
| 816 | impl->WaitFence(syncpoint_id, value, stop_token); | 829 | impl->WaitFence(syncpoint_id, value); |
| 817 | } | 830 | } |
| 818 | 831 | ||
| 819 | void GPU::IncrementSyncPoint(u32 syncpoint_id) { | 832 | void GPU::IncrementSyncPoint(u32 syncpoint_id) { |
| @@ -852,6 +865,10 @@ void GPU::Start() { | |||
| 852 | impl->Start(); | 865 | impl->Start(); |
| 853 | } | 866 | } |
| 854 | 867 | ||
| 868 | void GPU::NotifyShutdown() { | ||
| 869 | impl->NotifyShutdown(); | ||
| 870 | } | ||
| 871 | |||
| 855 | void GPU::ObtainContext() { | 872 | void GPU::ObtainContext() { |
| 856 | impl->ObtainContext(); | 873 | impl->ObtainContext(); |
| 857 | } | 874 | } |