diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/core.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.h | 5 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/gpu.cpp | 30 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 6 |
6 files changed, 39 insertions, 14 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index aa96f709b..3f9a7f44b 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -317,6 +317,8 @@ struct System::Impl { | |||
| 317 | is_powered_on = false; | 317 | is_powered_on = false; |
| 318 | exit_lock = false; | 318 | exit_lock = false; |
| 319 | 319 | ||
| 320 | gpu_core->NotifyShutdown(); | ||
| 321 | |||
| 320 | services.reset(); | 322 | services.reset(); |
| 321 | service_manager.reset(); | 323 | service_manager.reset(); |
| 322 | cheat_engine.reset(); | 324 | cheat_engine.reset(); |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index b4c3a6099..5fead6d1b 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp | |||
| @@ -186,6 +186,10 @@ u32 BufferQueue::Query(QueryType type) { | |||
| 186 | case QueryType::NativeWindowWidth: | 186 | case QueryType::NativeWindowWidth: |
| 187 | case QueryType::NativeWindowHeight: | 187 | case QueryType::NativeWindowHeight: |
| 188 | break; | 188 | break; |
| 189 | case QueryType::NativeWindowMinUndequeuedBuffers: | ||
| 190 | return 0; | ||
| 191 | case QueryType::NativeWindowConsumerUsageBits: | ||
| 192 | return 0; | ||
| 189 | } | 193 | } |
| 190 | UNIMPLEMENTED_MSG("Unimplemented query type={}", type); | 194 | UNIMPLEMENTED_MSG("Unimplemented query type={}", type); |
| 191 | return 0; | 195 | return 0; |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index 7b7baeaea..f2a579133 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h | |||
| @@ -57,6 +57,11 @@ public: | |||
| 57 | NativeWindowWidth = 0, | 57 | NativeWindowWidth = 0, |
| 58 | NativeWindowHeight = 1, | 58 | NativeWindowHeight = 1, |
| 59 | NativeWindowFormat = 2, | 59 | NativeWindowFormat = 2, |
| 60 | /// The minimum number of buffers that must remain un-dequeued after a buffer has been | ||
| 61 | /// queued | ||
| 62 | NativeWindowMinUndequeuedBuffers = 3, | ||
| 63 | /// The consumer gralloc usage bits currently set by the consumer | ||
| 64 | NativeWindowConsumerUsageBits = 10, | ||
| 60 | }; | 65 | }; |
| 61 | 66 | ||
| 62 | explicit BufferQueue(Kernel::KernelCore& kernel, u32 id_, u64 layer_id_, | 67 | explicit BufferQueue(Kernel::KernelCore& kernel, u32 id_, u64 layer_id_, |
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 396cc5afa..01e69de30 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp | |||
| @@ -100,9 +100,6 @@ std::optional<u64> NVFlinger::OpenDisplay(std::string_view name) { | |||
| 100 | 100 | ||
| 101 | LOG_DEBUG(Service, "Opening \"{}\" display", name); | 101 | LOG_DEBUG(Service, "Opening \"{}\" display", name); |
| 102 | 102 | ||
| 103 | // TODO(Subv): Currently we only support the Default display. | ||
| 104 | ASSERT(name == "Default"); | ||
| 105 | |||
| 106 | const auto itr = | 103 | const auto itr = |
| 107 | std::find_if(displays.begin(), displays.end(), | 104 | std::find_if(displays.begin(), displays.end(), |
| 108 | [&](const VI::Display& display) { return display.GetName() == name; }); | 105 | [&](const VI::Display& display) { return display.GetName() == name; }); |
| @@ -266,11 +263,10 @@ void NVFlinger::Compose() { | |||
| 266 | 263 | ||
| 267 | auto& gpu = system.GPU(); | 264 | auto& gpu = system.GPU(); |
| 268 | const auto& multi_fence = buffer->get().multi_fence; | 265 | const auto& multi_fence = buffer->get().multi_fence; |
| 269 | const auto stop_token = vsync_thread.get_stop_token(); | ||
| 270 | guard->unlock(); | 266 | guard->unlock(); |
| 271 | for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) { | 267 | for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) { |
| 272 | const auto& fence = multi_fence.fences[fence_id]; | 268 | const auto& fence = multi_fence.fences[fence_id]; |
| 273 | gpu.WaitFence(fence.id, fence.value, stop_token); | 269 | gpu.WaitFence(fence.id, fence.value); |
| 274 | } | 270 | } |
| 275 | guard->lock(); | 271 | guard->lock(); |
| 276 | 272 | ||
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index d98874150..705765c99 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -17,7 +17,6 @@ | |||
| 17 | #include "core/frontend/emu_window.h" | 17 | #include "core/frontend/emu_window.h" |
| 18 | #include "core/hardware_interrupt_manager.h" | 18 | #include "core/hardware_interrupt_manager.h" |
| 19 | #include "core/hle/service/nvdrv/nvdata.h" | 19 | #include "core/hle/service/nvdrv/nvdata.h" |
| 20 | #include "core/hle/service/nvflinger/buffer_queue.h" | ||
| 21 | #include "core/perf_stats.h" | 20 | #include "core/perf_stats.h" |
| 22 | #include "video_core/cdma_pusher.h" | 21 | #include "video_core/cdma_pusher.h" |
| 23 | #include "video_core/dma_pusher.h" | 22 | #include "video_core/dma_pusher.h" |
| @@ -206,7 +205,7 @@ struct GPU::Impl { | |||
| 206 | } | 205 | } |
| 207 | 206 | ||
| 208 | /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame. | 207 | /// 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 = {}) { | 208 | void WaitFence(u32 syncpoint_id, u32 value) { |
| 210 | // Synced GPU, is always in sync | 209 | // Synced GPU, is always in sync |
| 211 | if (!is_async) { | 210 | if (!is_async) { |
| 212 | return; | 211 | return; |
| @@ -218,8 +217,13 @@ struct GPU::Impl { | |||
| 218 | } | 217 | } |
| 219 | MICROPROFILE_SCOPE(GPU_wait); | 218 | MICROPROFILE_SCOPE(GPU_wait); |
| 220 | std::unique_lock lock{sync_mutex}; | 219 | std::unique_lock lock{sync_mutex}; |
| 221 | sync_cv.wait(lock, stop_token, | 220 | sync_cv.wait(lock, [=, this] { |
| 222 | [=, this] { return syncpoints.at(syncpoint_id).load() >= value; }); | 221 | if (shutting_down.load(std::memory_order_relaxed)) { |
| 222 | // We're shutting down, ensure no threads continue to wait for the next syncpoint | ||
| 223 | return true; | ||
| 224 | } | ||
| 225 | return syncpoints.at(syncpoint_id).load() >= value; | ||
| 226 | }); | ||
| 223 | } | 227 | } |
| 224 | 228 | ||
| 225 | void IncrementSyncPoint(u32 syncpoint_id) { | 229 | void IncrementSyncPoint(u32 syncpoint_id) { |
| @@ -307,6 +311,12 @@ struct GPU::Impl { | |||
| 307 | cpu_context->MakeCurrent(); | 311 | cpu_context->MakeCurrent(); |
| 308 | } | 312 | } |
| 309 | 313 | ||
| 314 | void NotifyShutdown() { | ||
| 315 | std::unique_lock lk{sync_mutex}; | ||
| 316 | shutting_down.store(true, std::memory_order::relaxed); | ||
| 317 | sync_cv.notify_all(); | ||
| 318 | } | ||
| 319 | |||
| 310 | /// Obtain the CPU Context | 320 | /// Obtain the CPU Context |
| 311 | void ObtainContext() { | 321 | void ObtainContext() { |
| 312 | cpu_context->MakeCurrent(); | 322 | cpu_context->MakeCurrent(); |
| @@ -665,6 +675,8 @@ struct GPU::Impl { | |||
| 665 | std::unique_ptr<Engines::KeplerMemory> kepler_memory; | 675 | std::unique_ptr<Engines::KeplerMemory> kepler_memory; |
| 666 | /// Shader build notifier | 676 | /// Shader build notifier |
| 667 | std::unique_ptr<VideoCore::ShaderNotify> shader_notify; | 677 | std::unique_ptr<VideoCore::ShaderNotify> shader_notify; |
| 678 | /// When true, we are about to shut down emulation session, so terminate outstanding tasks | ||
| 679 | std::atomic_bool shutting_down{}; | ||
| 668 | 680 | ||
| 669 | std::array<std::atomic<u32>, Service::Nvidia::MaxSyncPoints> syncpoints{}; | 681 | std::array<std::atomic<u32>, Service::Nvidia::MaxSyncPoints> syncpoints{}; |
| 670 | 682 | ||
| @@ -673,7 +685,7 @@ struct GPU::Impl { | |||
| 673 | std::mutex sync_mutex; | 685 | std::mutex sync_mutex; |
| 674 | std::mutex device_mutex; | 686 | std::mutex device_mutex; |
| 675 | 687 | ||
| 676 | std::condition_variable_any sync_cv; | 688 | std::condition_variable sync_cv; |
| 677 | 689 | ||
| 678 | struct FlushRequest { | 690 | struct FlushRequest { |
| 679 | explicit FlushRequest(u64 fence_, VAddr addr_, std::size_t size_) | 691 | explicit FlushRequest(u64 fence_, VAddr addr_, std::size_t size_) |
| @@ -812,8 +824,8 @@ const VideoCore::ShaderNotify& GPU::ShaderNotify() const { | |||
| 812 | return impl->ShaderNotify(); | 824 | return impl->ShaderNotify(); |
| 813 | } | 825 | } |
| 814 | 826 | ||
| 815 | void GPU::WaitFence(u32 syncpoint_id, u32 value, std::stop_token stop_token) { | 827 | void GPU::WaitFence(u32 syncpoint_id, u32 value) { |
| 816 | impl->WaitFence(syncpoint_id, value, stop_token); | 828 | impl->WaitFence(syncpoint_id, value); |
| 817 | } | 829 | } |
| 818 | 830 | ||
| 819 | void GPU::IncrementSyncPoint(u32 syncpoint_id) { | 831 | void GPU::IncrementSyncPoint(u32 syncpoint_id) { |
| @@ -852,6 +864,10 @@ void GPU::Start() { | |||
| 852 | impl->Start(); | 864 | impl->Start(); |
| 853 | } | 865 | } |
| 854 | 866 | ||
| 867 | void GPU::NotifyShutdown() { | ||
| 868 | impl->NotifyShutdown(); | ||
| 869 | } | ||
| 870 | |||
| 855 | void GPU::ObtainContext() { | 871 | void GPU::ObtainContext() { |
| 856 | impl->ObtainContext(); | 872 | impl->ObtainContext(); |
| 857 | } | 873 | } |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index cc65a7870..3188b83ed 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <stop_token> | ||
| 9 | 8 | ||
| 10 | #include "common/bit_field.h" | 9 | #include "common/bit_field.h" |
| 11 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| @@ -210,7 +209,7 @@ public: | |||
| 210 | [[nodiscard]] const VideoCore::ShaderNotify& ShaderNotify() const; | 209 | [[nodiscard]] const VideoCore::ShaderNotify& ShaderNotify() const; |
| 211 | 210 | ||
| 212 | /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame. | 211 | /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame. |
| 213 | void WaitFence(u32 syncpoint_id, u32 value, std::stop_token stop_token = {}); | 212 | void WaitFence(u32 syncpoint_id, u32 value); |
| 214 | 213 | ||
| 215 | void IncrementSyncPoint(u32 syncpoint_id); | 214 | void IncrementSyncPoint(u32 syncpoint_id); |
| 216 | 215 | ||
| @@ -233,6 +232,9 @@ public: | |||
| 233 | /// core timing events. | 232 | /// core timing events. |
| 234 | void Start(); | 233 | void Start(); |
| 235 | 234 | ||
| 235 | /// Performs any additional necessary steps to shutdown GPU emulation. | ||
| 236 | void NotifyShutdown(); | ||
| 237 | |||
| 236 | /// Obtain the CPU Context | 238 | /// Obtain the CPU Context |
| 237 | void ObtainContext(); | 239 | void ObtainContext(); |
| 238 | 240 | ||