fix(agc-driver): delay storage writeback until queue activity settles
This commit is contained in:
parent
1acfa7f788
commit
afbc3c8eb5
|
|
@ -7,10 +7,17 @@
|
|||
#include "prx/libSceAgcDriver/Execution/include/WorkerSampler.hpp"
|
||||
#include "prx/libSceAgcDriver/Execution/include/PerformanceTimer.hpp"
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace AgcDriver::DriverDetail {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr auto IdleResultsQuietPeriod = std::chrono::milliseconds(50);
|
||||
|
||||
}
|
||||
|
||||
FrameTiming* Driver::frameTiming() {
|
||||
if (!APS5_ENABLE_TIMING_LOG) return nullptr;
|
||||
if (pendingFrameTiming == nullptr) pendingFrameTiming = std::make_shared<FrameTiming>(++frameSerial, true);
|
||||
|
|
@ -114,6 +121,9 @@ void Driver::run(std::uint32_t id) noexcept {
|
|||
return runningWorkers.load(std::memory_order_acquire) == 0
|
||||
&& std::all_of(workers.begin(), workers.end(), [](const auto& item) { return item.second.pending.empty(); });
|
||||
};
|
||||
const auto idleResultsPending = [&] {
|
||||
return id == 0 && Graphics::StorageTexture::AnyPending() && allQueuesIdle() && !completionsPending();
|
||||
};
|
||||
const auto poll = [&](const auto& done) {
|
||||
#ifdef _WIN32
|
||||
lock.unlock();
|
||||
|
|
@ -128,7 +138,21 @@ void Driver::run(std::uint32_t id) noexcept {
|
|||
while (!ready()) {
|
||||
if (!completionsPending() || (id != 0 && Graphics::Recorder::PendingCompletionLabels() == 0)) {
|
||||
const auto idleEpochAtCheck = idleEpoch.load(std::memory_order_acquire);
|
||||
const bool storeIdleResults = id == 0 && allQueuesIdle() && !completionsPending();
|
||||
const bool storeIdleResults = idleResultsPending();
|
||||
if (storeIdleResults) {
|
||||
queue0Dormant.store(true, std::memory_order_relaxed);
|
||||
const auto quietUntil = std::chrono::steady_clock::now() + IdleResultsQuietPeriod;
|
||||
const auto idleEpochAtWait = idleEpoch.load(std::memory_order_acquire);
|
||||
changed.wait_until(lock, quietUntil, [&] {
|
||||
return ready() || idleEpoch.load(std::memory_order_acquire) != idleEpochAtWait;
|
||||
});
|
||||
queue0Dormant.store(false, std::memory_order_relaxed);
|
||||
if (ready()) break;
|
||||
if (idleEpoch.load(std::memory_order_acquire) != idleEpochAtWait) {
|
||||
continue;
|
||||
}
|
||||
if (!idleResultsPending()) continue;
|
||||
}
|
||||
lock.unlock();
|
||||
if (storeIdleResults) {
|
||||
if (const auto localDevice = device.Load()) localDevice->StoreIdleResults();
|
||||
|
|
|
|||
Loading…
Reference in New Issue