Core: Wait for GPU to be idle before shutting down.

This commit is contained in:
Fernando Sahmkow 2019-09-26 19:08:22 -04:00 committed by FernandoS27
parent 69fa2e6525
commit 3f104464de
7 changed files with 19 additions and 0 deletions

View File

@ -252,6 +252,8 @@ struct System::Impl {
is_powered_on = false; is_powered_on = false;
exit_lock = false; exit_lock = false;
gpu_core->WaitIdle();
// Shutdown emulation session // Shutdown emulation session
renderer.reset(); renderer.reset();
GDBStub::Shutdown(); GDBStub::Shutdown();

View File

@ -177,6 +177,9 @@ public:
/// Returns a reference to the GPU DMA pusher. /// Returns a reference to the GPU DMA pusher.
Tegra::DmaPusher& DmaPusher(); Tegra::DmaPusher& DmaPusher();
// Waits for the GPU to finish working
virtual void WaitIdle() const = 0;
/// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame. /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame.
void WaitFence(u32 syncpoint_id, u32 value) const; void WaitFence(u32 syncpoint_id, u32 value) const;

View File

@ -44,4 +44,8 @@ void GPUAsynch::TriggerCpuInterrupt(const u32 syncpoint_id, const u32 value) con
interrupt_manager.GPUInterruptSyncpt(syncpoint_id, value); interrupt_manager.GPUInterruptSyncpt(syncpoint_id, value);
} }
void GPUAsynch::WaitIdle() const {
gpu_thread.WaitIdle();
}
} // namespace VideoCommon } // namespace VideoCommon

View File

@ -25,6 +25,7 @@ public:
void FlushRegion(CacheAddr addr, u64 size) override; void FlushRegion(CacheAddr addr, u64 size) override;
void InvalidateRegion(CacheAddr addr, u64 size) override; void InvalidateRegion(CacheAddr addr, u64 size) override;
void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override; void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override;
void WaitIdle() const override;
protected: protected:
void TriggerCpuInterrupt(u32 syncpoint_id, u32 value) const override; void TriggerCpuInterrupt(u32 syncpoint_id, u32 value) const override;

View File

@ -24,6 +24,7 @@ public:
void FlushRegion(CacheAddr addr, u64 size) override; void FlushRegion(CacheAddr addr, u64 size) override;
void InvalidateRegion(CacheAddr addr, u64 size) override; void InvalidateRegion(CacheAddr addr, u64 size) override;
void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override; void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override;
void WaitIdle() const override {}
protected: protected:
void TriggerCpuInterrupt([[maybe_unused]] u32 syncpoint_id, void TriggerCpuInterrupt([[maybe_unused]] u32 syncpoint_id,

View File

@ -90,6 +90,11 @@ void ThreadManager::FlushAndInvalidateRegion(CacheAddr addr, u64 size) {
InvalidateRegion(addr, size); InvalidateRegion(addr, size);
} }
void ThreadManager::WaitIdle() const {
while (state.last_fence > state.signaled_fence.load()) {
}
}
u64 ThreadManager::PushCommand(CommandData&& command_data) { u64 ThreadManager::PushCommand(CommandData&& command_data) {
const u64 fence{++state.last_fence}; const u64 fence{++state.last_fence};
state.queue.Push(CommandDataContainer(std::move(command_data), fence)); state.queue.Push(CommandDataContainer(std::move(command_data), fence));

View File

@ -116,6 +116,9 @@ public:
/// Notify rasterizer that any caches of the specified region should be flushed and invalidated /// Notify rasterizer that any caches of the specified region should be flushed and invalidated
void FlushAndInvalidateRegion(CacheAddr addr, u64 size); void FlushAndInvalidateRegion(CacheAddr addr, u64 size);
// Wait until the gpu thread is idle.
void WaitIdle() const;
private: private:
/// Pushes a command to be executed by the GPU thread /// Pushes a command to be executed by the GPU thread
u64 PushCommand(CommandData&& command_data); u64 PushCommand(CommandData&& command_data);