Core: Wait for GPU to be idle before shutting down.
This commit is contained in:
parent
69fa2e6525
commit
3f104464de
7 changed files with 19 additions and 0 deletions
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue