Browse Source

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

nce_cpp
Fernando Sahmkow 6 years ago
committed by FernandoS27
parent
commit
ded3d555e1
  1. 2
      src/core/core.cpp
  2. 3
      src/video_core/gpu.h
  3. 4
      src/video_core/gpu_asynch.cpp
  4. 1
      src/video_core/gpu_asynch.h
  5. 1
      src/video_core/gpu_synch.h
  6. 5
      src/video_core/gpu_thread.cpp
  7. 3
      src/video_core/gpu_thread.h

2
src/core/core.cpp

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

3
src/video_core/gpu.h

@ -177,6 +177,9 @@ public:
/// Returns a reference to the GPU DMA pusher.
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.
void WaitFence(u32 syncpoint_id, u32 value) const;

4
src/video_core/gpu_asynch.cpp

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

1
src/video_core/gpu_asynch.h

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

1
src/video_core/gpu_synch.h

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

5
src/video_core/gpu_thread.cpp

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

3
src/video_core/gpu_thread.h

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

Loading…
Cancel
Save