diff options
| -rw-r--r-- | src/core/core.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 3 | ||||
| -rw-r--r-- | src/video_core/gpu_asynch.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/gpu_asynch.h | 1 | ||||
| -rw-r--r-- | src/video_core/gpu_synch.h | 1 | ||||
| -rw-r--r-- | src/video_core/gpu_thread.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/gpu_thread.h | 3 |
7 files changed, 19 insertions, 0 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index 75a7ffb97..8f68bdbad 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -252,6 +252,8 @@ struct System::Impl { | |||
| 252 | is_powered_on = false; | 252 | is_powered_on = false; |
| 253 | exit_lock = false; | 253 | exit_lock = false; |
| 254 | 254 | ||
| 255 | gpu_core->WaitIdle(); | ||
| 256 | |||
| 255 | // Shutdown emulation session | 257 | // Shutdown emulation session |
| 256 | renderer.reset(); | 258 | renderer.reset(); |
| 257 | GDBStub::Shutdown(); | 259 | GDBStub::Shutdown(); |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index e20b0687a..dbca19f35 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -177,6 +177,9 @@ public: | |||
| 177 | /// Returns a reference to the GPU DMA pusher. | 177 | /// Returns a reference to the GPU DMA pusher. |
| 178 | Tegra::DmaPusher& DmaPusher(); | 178 | Tegra::DmaPusher& DmaPusher(); |
| 179 | 179 | ||
| 180 | // Waits for the GPU to finish working | ||
| 181 | virtual void WaitIdle() const = 0; | ||
| 182 | |||
| 180 | /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame. | 183 | /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame. |
| 181 | void WaitFence(u32 syncpoint_id, u32 value) const; | 184 | void WaitFence(u32 syncpoint_id, u32 value) const; |
| 182 | 185 | ||
diff --git a/src/video_core/gpu_asynch.cpp b/src/video_core/gpu_asynch.cpp index f2a3a390e..04222d060 100644 --- a/src/video_core/gpu_asynch.cpp +++ b/src/video_core/gpu_asynch.cpp | |||
| @@ -44,4 +44,8 @@ void GPUAsynch::TriggerCpuInterrupt(const u32 syncpoint_id, const u32 value) con | |||
| 44 | interrupt_manager.GPUInterruptSyncpt(syncpoint_id, value); | 44 | interrupt_manager.GPUInterruptSyncpt(syncpoint_id, value); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | void GPUAsynch::WaitIdle() const { | ||
| 48 | gpu_thread.WaitIdle(); | ||
| 49 | } | ||
| 50 | |||
| 47 | } // namespace VideoCommon | 51 | } // namespace VideoCommon |
diff --git a/src/video_core/gpu_asynch.h b/src/video_core/gpu_asynch.h index a12f9bac4..1241ade1d 100644 --- a/src/video_core/gpu_asynch.h +++ b/src/video_core/gpu_asynch.h | |||
| @@ -25,6 +25,7 @@ public: | |||
| 25 | void FlushRegion(CacheAddr addr, u64 size) override; | 25 | void FlushRegion(CacheAddr addr, u64 size) override; |
| 26 | void InvalidateRegion(CacheAddr addr, u64 size) override; | 26 | void InvalidateRegion(CacheAddr addr, u64 size) override; |
| 27 | void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override; | 27 | void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override; |
| 28 | void WaitIdle() const override; | ||
| 28 | 29 | ||
| 29 | protected: | 30 | protected: |
| 30 | void TriggerCpuInterrupt(u32 syncpoint_id, u32 value) const override; | 31 | void TriggerCpuInterrupt(u32 syncpoint_id, u32 value) const override; |
diff --git a/src/video_core/gpu_synch.h b/src/video_core/gpu_synch.h index 5eb1c461c..c71baee89 100644 --- a/src/video_core/gpu_synch.h +++ b/src/video_core/gpu_synch.h | |||
| @@ -24,6 +24,7 @@ public: | |||
| 24 | void FlushRegion(CacheAddr addr, u64 size) override; | 24 | void FlushRegion(CacheAddr addr, u64 size) override; |
| 25 | void InvalidateRegion(CacheAddr addr, u64 size) override; | 25 | void InvalidateRegion(CacheAddr addr, u64 size) override; |
| 26 | void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override; | 26 | void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override; |
| 27 | void WaitIdle() const override {} | ||
| 27 | 28 | ||
| 28 | protected: | 29 | protected: |
| 29 | void TriggerCpuInterrupt([[maybe_unused]] u32 syncpoint_id, | 30 | void TriggerCpuInterrupt([[maybe_unused]] u32 syncpoint_id, |
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index d7048b6ae..4a42634d2 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp | |||
| @@ -90,6 +90,11 @@ void ThreadManager::FlushAndInvalidateRegion(CacheAddr addr, u64 size) { | |||
| 90 | InvalidateRegion(addr, size); | 90 | InvalidateRegion(addr, size); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | void ThreadManager::WaitIdle() const { | ||
| 94 | while (state.last_fence > state.signaled_fence.load()) { | ||
| 95 | } | ||
| 96 | } | ||
| 97 | |||
| 93 | u64 ThreadManager::PushCommand(CommandData&& command_data) { | 98 | u64 ThreadManager::PushCommand(CommandData&& command_data) { |
| 94 | const u64 fence{++state.last_fence}; | 99 | const u64 fence{++state.last_fence}; |
| 95 | state.queue.Push(CommandDataContainer(std::move(command_data), fence)); | 100 | state.queue.Push(CommandDataContainer(std::move(command_data), fence)); |
diff --git a/src/video_core/gpu_thread.h b/src/video_core/gpu_thread.h index 108f456bd..08dc96bb3 100644 --- a/src/video_core/gpu_thread.h +++ b/src/video_core/gpu_thread.h | |||
| @@ -116,6 +116,9 @@ public: | |||
| 116 | /// Notify rasterizer that any caches of the specified region should be flushed and invalidated | 116 | /// Notify rasterizer that any caches of the specified region should be flushed and invalidated |
| 117 | void FlushAndInvalidateRegion(CacheAddr addr, u64 size); | 117 | void FlushAndInvalidateRegion(CacheAddr addr, u64 size); |
| 118 | 118 | ||
| 119 | // Wait until the gpu thread is idle. | ||
| 120 | void WaitIdle() const; | ||
| 121 | |||
| 119 | private: | 122 | private: |
| 120 | /// Pushes a command to be executed by the GPU thread | 123 | /// Pushes a command to be executed by the GPU thread |
| 121 | u64 PushCommand(CommandData&& command_data); | 124 | u64 PushCommand(CommandData&& command_data); |