diff --git a/core/libs/prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp b/core/libs/prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp index 916de6b35..bd48aed75 100644 --- a/core/libs/prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp +++ b/core/libs/prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp @@ -222,7 +222,7 @@ public: // blit-submit times after the flip packet; noted in-place reads checked // (APS5_FLIP_READ_CHECK=1) and found overwritten before the blit's fence. struct PresentStatistics { - std::uint64_t presents, gpuUnread, batchesAheadOfBlit, batchesAfterFlip, readsChecked, readsOverwritten; + std::uint64_t presents, gpuUnread, batchesAheadOfBlit, batchesAfterFlip, readsChecked, readsOverwritten, acquireDrops; double gpuBusyMs, gpuGapMs, lastSubmitAfterFlipMs, blitSubmitAfterFlipMs; }; static PresentStatistics PresentCounts(); diff --git a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp index 83f0f25ae..d7566f1ef 100644 --- a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp +++ b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Presentation.cpp @@ -157,7 +157,7 @@ void Driver::reportPresents(double waitedMs, std::size_t inFlight) { const auto flips = flipsCounted.load() - previousFlips; const double perFlip = flips != 0 ? 1.0 / static_cast(flips) : 0.0; const auto serial = flipSerial.load(); - AgcDriver::ProfilePrint_nid_no_patch( "[present] %llu presents over 10 s (%zu may trail on the GPU); %s p50 %.2f ms, p90 %.2f ms, max %.2f ms over %zu; per present: GPU busy %.1f ms, idle gaps %.1f ms (%llu batches without a completion record); per flip: %.1f batches recorded (%.1f unsignaled at the flip); per present: %.1f batches ahead of the blit, %.1f after it; after the flip packet: last submit %.1f ms, blit submit %.1f ms; in-place reads overwritten before execution: %llu of %llu checked\n", static_cast(presents), inFlight, inFlight != 0 ? "inflight_wait" : "render_fence_wait", percentile(0.5), percentile(0.9), waits.empty() ? 0.0 : waits.back(), waits.size(), (counts.gpuBusyMs - previous.gpuBusyMs) * perPresent, (counts.gpuGapMs - previous.gpuGapMs) * perPresent, static_cast(counts.gpuUnread - previous.gpuUnread), static_cast(serial - windowSerial) * perFlip, static_cast(flipBatchesUnsignaled.load() - previousUnsignaled) * perFlip, static_cast(counts.batchesAheadOfBlit - previous.batchesAheadOfBlit) * perPresent, static_cast(counts.batchesAfterFlip - previous.batchesAfterFlip) * perPresent, (counts.lastSubmitAfterFlipMs - previous.lastSubmitAfterFlipMs) * perPresent, (counts.blitSubmitAfterFlipMs - previous.blitSubmitAfterFlipMs) * perPresent, static_cast(counts.readsOverwritten - previous.readsOverwritten), static_cast(counts.readsChecked - previous.readsChecked)); + AgcDriver::ProfilePrint_nid_no_patch( "[present] %llu presents over 10 s (%llu dropped: no free swapchain image; %zu may trail on the GPU); %s p50 %.2f ms, p90 %.2f ms, max %.2f ms over %zu; per present: GPU busy %.1f ms, idle gaps %.1f ms (%llu batches without a completion record); per flip: %.1f batches recorded (%.1f unsignaled at the flip); per present: %.1f batches ahead of the blit, %.1f after it; after the flip packet: last submit %.1f ms, blit submit %.1f ms; in-place reads overwritten before execution: %llu of %llu checked\n", static_cast(presents), static_cast(counts.acquireDrops - previous.acquireDrops), inFlight, inFlight != 0 ? "inflight_wait" : "render_fence_wait", percentile(0.5), percentile(0.9), waits.empty() ? 0.0 : waits.back(), waits.size(), (counts.gpuBusyMs - previous.gpuBusyMs) * perPresent, (counts.gpuGapMs - previous.gpuGapMs) * perPresent, static_cast(counts.gpuUnread - previous.gpuUnread), static_cast(serial - windowSerial) * perFlip, static_cast(flipBatchesUnsignaled.load() - previousUnsignaled) * perFlip, static_cast(counts.batchesAheadOfBlit - previous.batchesAheadOfBlit) * perPresent, static_cast(counts.batchesAfterFlip - previous.batchesAfterFlip) * perPresent, (counts.lastSubmitAfterFlipMs - previous.lastSubmitAfterFlipMs) * perPresent, (counts.blitSubmitAfterFlipMs - previous.blitSubmitAfterFlipMs) * perPresent, static_cast(counts.readsOverwritten - previous.readsOverwritten), static_cast(counts.readsChecked - previous.readsChecked)); previous = counts; previousFlips = flipsCounted.load(); previousUnsignaled = flipBatchesUnsignaled.load(); diff --git a/core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp b/core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp index b3a823fa8..cc6560fb4 100644 --- a/core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp +++ b/core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp @@ -2649,11 +2649,15 @@ bool VulkanDevice::AcquireImage() { std::uint32_t index = 0; timing.Mark("fence_reset"); // An out-of-date swapchain (the window changed) drops this frame; the next Resize recreates it. - const auto acquired = state->DeviceFunction("vkAcquireNextImageKHR")(state->device, state->swapchain, 5'000'000'000ULL, VK_NULL_HANDLE, state->acquireFence, &index); + const auto acquired = state->DeviceFunction("vkAcquireNextImageKHR")(state->device, state->swapchain, 0, VK_NULL_HANDLE, state->acquireFence, &index); if (acquired == VK_ERROR_OUT_OF_DATE_KHR) { state->extent = {0, 0}; return false; } + if (acquired == VK_NOT_READY || acquired == VK_TIMEOUT) { + ++presentCounters.acquireDrops; + return false; + } if (acquired != VK_SUBOPTIMAL_KHR) check(acquired, "vkAcquireNextImageKHR"); timing.Mark("acquire_image"); APS5_LOG_OUT_DEBUG("vkAcquireNextImageKHR index=%u imageCount=%zu", index, state->images.size());