diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h index 9fe33b661..e42150838 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h @@ -448,7 +448,6 @@ typedef struct { uint64_t desiredPresentTime; // VK_GOOGLE_display_timing desired presentation time in nanoseconds uint32_t presentID; // VK_GOOGLE_display_timing presentID VkPresentModeKHR presentMode; // VK_EXT_swapchain_maintenance1 present mode specialization - bool hasPresentTime; // Keep track of whether presentation included VK_GOOGLE_display_timing } MVKImagePresentInfo; /** Tracks a semaphore and fence for later signaling. */ @@ -505,6 +504,7 @@ class MVKPresentableSwapchainImage : public MVKSwapchainImage { MVKSmallVector _availabilitySignalers; MVKSwapchainSignaler _preSignaler = {}; std::mutex _availabilityLock; + uint64_t _beginPresentTime = 0; uint64_t _presentationStartTime = 0; }; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm index fa48391d9..107b1d8d8 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm @@ -1634,6 +1634,7 @@ static void signalAndUntrack(const MVKSwapchainSignaler& signaler) { void MVKPresentableSwapchainImage::beginPresentation(const MVKImagePresentInfo& presentInfo) { retain(); _swapchain->beginPresentation(presentInfo); + _beginPresentTime = mvkGetRuntimeNanoseconds(); _presentationStartTime = getPerformanceTimestamp(); } @@ -1652,7 +1653,7 @@ static void signalAndUntrack(const MVKSwapchainSignaler& signaler) { // VkDevice, have been destroyed by the time of this callback, so do not reference them. lock_guard lock(_detachmentLock); if (_device) { addPerformanceInterval(getPerformanceStats().queue.presentSwapchains, _presentationStartTime); } - if (_swapchain) { _swapchain->endPresentation(presentInfo, actualPresentTime); } + if (_swapchain) { _swapchain->endPresentation(presentInfo, _beginPresentTime, actualPresentTime); } } // Makes an image available for acquisition by the app. diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm index aab47cffb..2dea507fd 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm @@ -771,7 +771,7 @@ // Populate the array of swapchain images, testing each one for status uint32_t scCnt = pPresentInfo->swapchainCount; const VkPresentTimeGOOGLE* pPresentTimes = nullptr; - if (pPresentTimesInfo && pPresentTimesInfo->pTimes) { + if (pPresentTimesInfo) { pPresentTimes = pPresentTimesInfo->pTimes; MVKAssert(pPresentTimesInfo->swapchainCount == scCnt, "VkPresentTimesInfoGOOGLE swapchainCount must match VkPresentInfo swapchainCount."); } @@ -800,7 +800,6 @@ presentInfo.presentMode = pPresentModes ? pPresentModes[scIdx] : VK_PRESENT_MODE_MAX_ENUM_KHR; presentInfo.fence = pFences ? (MVKFence*)pFences[scIdx] : nullptr; if (pPresentTimes) { - presentInfo.hasPresentTime = true; presentInfo.presentID = pPresentTimes[scIdx].presentID; presentInfo.desiredPresentTime = pPresentTimes[scIdx].desiredPresentTime; } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h index 4e24ed36e..407065793 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h @@ -119,7 +119,7 @@ class MVKSwapchain : public MVKVulkanAPIDeviceObject { void renderWatermark(id mtlTexture, id mtlCmdBuff); void markFrameInterval(); void beginPresentation(const MVKImagePresentInfo& presentInfo); - void endPresentation(const MVKImagePresentInfo& presentInfo, uint64_t actualPresentTime = 0); + void endPresentation(const MVKImagePresentInfo& presentInfo, uint64_t beginPresentTime, uint64_t actualPresentTime = 0); void forceUnpresentedImageCompletion(); MVKSurface* _surface = nullptr; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm index 973f5b0b8..084cd0d59 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm @@ -251,7 +251,7 @@ _unpresentedImageCount++; } -void MVKSwapchain::endPresentation(const MVKImagePresentInfo& presentInfo, uint64_t actualPresentTime) { +void MVKSwapchain::endPresentation(const MVKImagePresentInfo& presentInfo, uint64_t beginPresentTime, uint64_t actualPresentTime) { _unpresentedImageCount--; std::lock_guard lock(_presentHistoryLock); @@ -266,9 +266,9 @@ _presentTimingHistory[_presentHistoryIndex].presentID = presentInfo.presentID; _presentTimingHistory[_presentHistoryIndex].desiredPresentTime = presentInfo.desiredPresentTime; _presentTimingHistory[_presentHistoryIndex].actualPresentTime = actualPresentTime; - // These details are not available in Metal + // These details are not available in Metal, but can estimate earliestPresentTime by using actualPresentTime instead _presentTimingHistory[_presentHistoryIndex].earliestPresentTime = actualPresentTime; - _presentTimingHistory[_presentHistoryIndex].presentMargin = 0; + _presentTimingHistory[_presentHistoryIndex].presentMargin = actualPresentTime > beginPresentTime ? actualPresentTime - beginPresentTime : 0; _presentHistoryIndex = (_presentHistoryIndex + 1) % kMaxPresentationHistory; }