Merge pull request #1410 from billhollings/swapchain-image-acquisition-order
Fix issue where swapchain images were acquired out of order under heavy load.
diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md
index 26b7e76..2683e1c 100644
--- a/Docs/Whats_New.md
+++ b/Docs/Whats_New.md
@@ -19,6 +19,7 @@
Released TBD
- Vulkan timestamp query pools use Metal GPU counters when available.
+- Fix issue where swapchain images were acquired out of order under heavy load.
- Fix incorrect translation of clear color values on Apple Silicon.
- Fix swizzle of depth and stencil values into RGBA (`float4`) variable in shaders.
- Disable `VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT` for
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
index 0f1b596..1a4f78e 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm
@@ -1185,19 +1185,18 @@
void MVKPresentableSwapchainImage::makeAvailable(const MVKSwapchainSignaler& signaler) {
lock_guard<mutex> lock(_availabilityLock);
- // Mark when this event happened, relative to that of other images
- _availability.acquisitionID = _swapchain->getNextAcquisitionID();
-
// Signal the semaphore and fence, and let them know they are no longer being tracked.
signal(signaler, nil);
unmarkAsTracked(signaler);
-
-// MVKLogDebug("Signaling%s swapchain image %p semaphore %p from present, with %lu remaining semaphores.", (_availability.isAvailable ? " pre-signaled" : ""), this, signaler.first, _availabilitySignalers.size());
}
void MVKPresentableSwapchainImage::acquireAndSignalWhenAvailable(MVKSemaphore* semaphore, MVKFence* fence) {
lock_guard<mutex> lock(_availabilityLock);
+ // Upon acquisition, update acquisition ID immediately, to move it to the back of the chain,
+ // so other images will be preferred if either all images are available or no images are available.
+ _availability.acquisitionID = _swapchain->getNextAcquisitionID();
+
// Now that this image is being acquired, release the existing drawable and its texture.
// This is not done earlier so the texture is retained for any post-processing such as screen captures, etc.
releaseMetalDrawable();
@@ -1223,8 +1222,6 @@
_availabilitySignalers.push_back(signaler);
}
markAsTracked(signaler);
-
-// MVKLogDebug("%s swapchain image %p semaphore %p in acquire with %lu other semaphores.", (_availability.isAvailable ? "Signaling" : "Tracking"), this, semaphore, _availabilitySignalers.size());
}
// If present, signal the semaphore for the first waiter for the given image.