video_core: Block in WaitFence.
This function is called rarely and blocks quite often for a long time. So don't waste power and let the CPU sleep. This might also increase the performance as the other cores might be allowed to clock higher.
This commit is contained in:
parent
f846e3d6d0
commit
cb9dd01ffd
3 changed files with 9 additions and 5 deletions
|
@ -192,7 +192,7 @@ void NVFlinger::Compose() {
|
||||||
|
|
||||||
const auto& igbp_buffer = buffer->get().igbp_buffer;
|
const auto& igbp_buffer = buffer->get().igbp_buffer;
|
||||||
|
|
||||||
const auto& gpu = system.GPU();
|
auto& gpu = system.GPU();
|
||||||
const auto& multi_fence = buffer->get().multi_fence;
|
const auto& multi_fence = buffer->get().multi_fence;
|
||||||
for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) {
|
for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) {
|
||||||
const auto& fence = multi_fence.fences[fence_id];
|
const auto& fence = multi_fence.fences[fence_id];
|
||||||
|
|
|
@ -66,19 +66,20 @@ const DmaPusher& GPU::DmaPusher() const {
|
||||||
return *dma_pusher;
|
return *dma_pusher;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU::WaitFence(u32 syncpoint_id, u32 value) const {
|
void GPU::WaitFence(u32 syncpoint_id, u32 value) {
|
||||||
// Synced GPU, is always in sync
|
// Synced GPU, is always in sync
|
||||||
if (!is_async) {
|
if (!is_async) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MICROPROFILE_SCOPE(GPU_wait);
|
MICROPROFILE_SCOPE(GPU_wait);
|
||||||
while (syncpoints[syncpoint_id].load(std::memory_order_relaxed) < value) {
|
std::unique_lock lock{sync_mutex};
|
||||||
}
|
sync_cv.wait(lock, [=]() { return syncpoints[syncpoint_id].load() >= value; });
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU::IncrementSyncPoint(const u32 syncpoint_id) {
|
void GPU::IncrementSyncPoint(const u32 syncpoint_id) {
|
||||||
syncpoints[syncpoint_id]++;
|
syncpoints[syncpoint_id]++;
|
||||||
std::lock_guard lock{sync_mutex};
|
std::lock_guard lock{sync_mutex};
|
||||||
|
sync_cv.notify_all();
|
||||||
if (!syncpt_interrupts[syncpoint_id].empty()) {
|
if (!syncpt_interrupts[syncpoint_id].empty()) {
|
||||||
u32 value = syncpoints[syncpoint_id].load();
|
u32 value = syncpoints[syncpoint_id].load();
|
||||||
auto it = syncpt_interrupts[syncpoint_id].begin();
|
auto it = syncpt_interrupts[syncpoint_id].begin();
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <condition_variable>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -181,7 +182,7 @@ public:
|
||||||
virtual void WaitIdle() const = 0;
|
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);
|
||||||
|
|
||||||
void IncrementSyncPoint(u32 syncpoint_id);
|
void IncrementSyncPoint(u32 syncpoint_id);
|
||||||
|
|
||||||
|
@ -312,6 +313,8 @@ private:
|
||||||
|
|
||||||
std::mutex sync_mutex;
|
std::mutex sync_mutex;
|
||||||
|
|
||||||
|
std::condition_variable sync_cv;
|
||||||
|
|
||||||
const bool is_async;
|
const bool is_async;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue