diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.cpp | 3 | ||||
| -rw-r--r-- | src/video_core/gpu.cpp | 19 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 3 |
3 files changed, 10 insertions, 15 deletions
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index a22811ec1..396cc5afa 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp | |||
| @@ -266,10 +266,11 @@ void NVFlinger::Compose() { | |||
| 266 | 266 | ||
| 267 | auto& gpu = system.GPU(); | 267 | auto& gpu = system.GPU(); |
| 268 | const auto& multi_fence = buffer->get().multi_fence; | 268 | const auto& multi_fence = buffer->get().multi_fence; |
| 269 | const auto stop_token = vsync_thread.get_stop_token(); | ||
| 269 | guard->unlock(); | 270 | guard->unlock(); |
| 270 | for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) { | 271 | for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) { |
| 271 | const auto& fence = multi_fence.fences[fence_id]; | 272 | const auto& fence = multi_fence.fences[fence_id]; |
| 272 | gpu.WaitFence(fence.id, fence.value); | 273 | gpu.WaitFence(fence.id, fence.value, stop_token); |
| 273 | } | 274 | } |
| 274 | guard->lock(); | 275 | guard->lock(); |
| 275 | 276 | ||
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 8788f5148..d98874150 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) { | 209 | void WaitFence(u32 syncpoint_id, u32 value, std::stop_token stop_token = {}) { |
| 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,13 +218,8 @@ 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, [=, this] { | 221 | sync_cv.wait(lock, stop_token, |
| 222 | if (shutting_down.load(std::memory_order_relaxed)) { | 222 | [=, this] { return syncpoints.at(syncpoint_id).load() >= value; }); |
| 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 | }); | ||
| 228 | } | 223 | } |
| 229 | 224 | ||
| 230 | void IncrementSyncPoint(u32 syncpoint_id) { | 225 | void IncrementSyncPoint(u32 syncpoint_id) { |
| @@ -670,8 +665,6 @@ struct GPU::Impl { | |||
| 670 | std::unique_ptr<Engines::KeplerMemory> kepler_memory; | 665 | std::unique_ptr<Engines::KeplerMemory> kepler_memory; |
| 671 | /// Shader build notifier | 666 | /// Shader build notifier |
| 672 | std::unique_ptr<VideoCore::ShaderNotify> shader_notify; | 667 | std::unique_ptr<VideoCore::ShaderNotify> shader_notify; |
| 673 | /// When true, we are about to shut down emulation session, so terminate outstanding tasks | ||
| 674 | std::atomic_bool shutting_down{}; | ||
| 675 | 668 | ||
| 676 | std::array<std::atomic<u32>, Service::Nvidia::MaxSyncPoints> syncpoints{}; | 669 | std::array<std::atomic<u32>, Service::Nvidia::MaxSyncPoints> syncpoints{}; |
| 677 | 670 | ||
| @@ -680,7 +673,7 @@ struct GPU::Impl { | |||
| 680 | std::mutex sync_mutex; | 673 | std::mutex sync_mutex; |
| 681 | std::mutex device_mutex; | 674 | std::mutex device_mutex; |
| 682 | 675 | ||
| 683 | std::condition_variable sync_cv; | 676 | std::condition_variable_any sync_cv; |
| 684 | 677 | ||
| 685 | struct FlushRequest { | 678 | struct FlushRequest { |
| 686 | explicit FlushRequest(u64 fence_, VAddr addr_, std::size_t size_) | 679 | explicit FlushRequest(u64 fence_, VAddr addr_, std::size_t size_) |
| @@ -819,8 +812,8 @@ const VideoCore::ShaderNotify& GPU::ShaderNotify() const { | |||
| 819 | return impl->ShaderNotify(); | 812 | return impl->ShaderNotify(); |
| 820 | } | 813 | } |
| 821 | 814 | ||
| 822 | void GPU::WaitFence(u32 syncpoint_id, u32 value) { | 815 | void GPU::WaitFence(u32 syncpoint_id, u32 value, std::stop_token stop_token) { |
| 823 | impl->WaitFence(syncpoint_id, value); | 816 | impl->WaitFence(syncpoint_id, value, stop_token); |
| 824 | } | 817 | } |
| 825 | 818 | ||
| 826 | void GPU::IncrementSyncPoint(u32 syncpoint_id) { | 819 | void GPU::IncrementSyncPoint(u32 syncpoint_id) { |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 500411176..cc65a7870 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <stop_token> | ||
| 8 | 9 | ||
| 9 | #include "common/bit_field.h" | 10 | #include "common/bit_field.h" |
| 10 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| @@ -209,7 +210,7 @@ public: | |||
| 209 | [[nodiscard]] const VideoCore::ShaderNotify& ShaderNotify() const; | 210 | [[nodiscard]] const VideoCore::ShaderNotify& ShaderNotify() const; |
| 210 | 211 | ||
| 211 | /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame. | 212 | /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame. |
| 212 | void WaitFence(u32 syncpoint_id, u32 value); | 213 | void WaitFence(u32 syncpoint_id, u32 value, std::stop_token stop_token = {}); |
| 213 | 214 | ||
| 214 | void IncrementSyncPoint(u32 syncpoint_id); | 215 | void IncrementSyncPoint(u32 syncpoint_id); |
| 215 | 216 | ||