summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/core.cpp2
-rw-r--r--src/video_core/gpu.h3
-rw-r--r--src/video_core/gpu_asynch.cpp4
-rw-r--r--src/video_core/gpu_asynch.h1
-rw-r--r--src/video_core/gpu_synch.h1
-rw-r--r--src/video_core/gpu_thread.cpp5
-rw-r--r--src/video_core/gpu_thread.h3
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
47void 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
29protected: 30protected:
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
28protected: 29protected:
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
93void ThreadManager::WaitIdle() const {
94 while (state.last_fence > state.signaled_fence.load()) {
95 }
96}
97
93u64 ThreadManager::PushCommand(CommandData&& command_data) { 98u64 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
119private: 122private:
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);