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.