Only update CAMetalLayer drawableSize property during swapchain creation.
Simplify structure of MVKQueue::submit() functions.
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index 5bea0fe..94ff4d8 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -174,7 +174,7 @@
CAMetalLayer* mtlLayer = surface->getCAMetalLayer();
if ( !mtlLayer ) { return surface->getConfigurationResult(); }
- VkExtent2D surfExtnt = mvkVkExtent2DFromCGSize(mtlLayer.updatedDrawableSizeMVK);
+ VkExtent2D surfExtnt = mvkVkExtent2DFromCGSize(mtlLayer.naturalDrawableSizeMVK);
// Metal supports 3 concurrent drawables, but if the swapchain is destroyed and
// rebuilt as part of resizing, one will be held by the current display image.
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h
index a4eccab..a2a28fc 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h
@@ -81,7 +81,7 @@
VkFence fence, MVKCommandUse cmdBuffUse);
/** Submits the specified presentation command to the queue. */
- VkResult submitPresentKHR(const VkPresentInfoKHR* pPresentInfo);
+ VkResult submit(const VkPresentInfoKHR* pPresentInfo);
/** Block the current thread until this queue is idle. */
VkResult waitIdle(MVKCommandUse cmdBuffUse);
@@ -145,7 +145,7 @@
void initExecQueue();
void initMTLCommandQueue();
void destroyExecQueue();
- void submit(MVKQueueSubmission* qSubmit);
+ VkResult submit(MVKQueueSubmission* qSubmit);
MVKQueueFamily* _queueFamily;
uint32_t _index;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm
index 93c3909..82612d1 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm
@@ -64,41 +64,37 @@
// Submissions to the execution queue are wrapped in a dedicated autorelease pool.
// Relying on the dispatch queue to find time to drain the autorelease pool can
// result in significant memory creep under heavy workloads.
-void MVKQueue::submit(MVKQueueSubmission* qSubmit) {
- if ( !qSubmit ) { return; } // Ignore nils
+VkResult MVKQueue::submit(MVKQueueSubmission* qSubmit) {
+ if ( !qSubmit ) { return VK_SUCCESS; } // Ignore nils
+ VkResult rslt = qSubmit->_submissionResult; // Extract result before submission to avoid race condition with early destruction
if (_execQueue) {
dispatch_async(_execQueue, ^{ @autoreleasepool { qSubmit->execute(); } } );
} else {
qSubmit->execute();
}
+ return rslt;
}
VkResult MVKQueue::submit(uint32_t submitCount, const VkSubmitInfo* pSubmits,
VkFence fence, MVKCommandUse cmdBuffUse) {
+
+ // Fence-only submission
+ if (submitCount == 0 && fence) {
+ return submit(new MVKQueueCommandBufferSubmission(_device, this, VK_NULL_HANDLE, fence, cmdBuffUse));
+ }
+
VkResult rslt = VK_SUCCESS;
for (uint32_t sIdx = 0; sIdx < submitCount; sIdx++) {
VkFence fenceOrNil = (sIdx == (submitCount - 1)) ? fence : VK_NULL_HANDLE; // last one gets the fence
- MVKQueueSubmission* qSub = new MVKQueueCommandBufferSubmission(_device, this, &pSubmits[sIdx], fenceOrNil, cmdBuffUse);
- if (rslt == VK_SUCCESS) { rslt = qSub->_submissionResult; } // Extract result before submission to avoid race condition with early destruction
- submit(qSub);
+ VkResult subRslt = submit(new MVKQueueCommandBufferSubmission(_device, this, &pSubmits[sIdx], fenceOrNil, cmdBuffUse));
+ if (rslt == VK_SUCCESS) { rslt = subRslt; }
}
-
- // Support fence-only submission
- if (submitCount == 0 && fence) {
- MVKQueueSubmission* qSub = new MVKQueueCommandBufferSubmission(_device, this, VK_NULL_HANDLE, fence, cmdBuffUse);
- if (rslt == VK_SUCCESS) { rslt = qSub->_submissionResult; } // Extract result before submission to avoid race condition with early destruction
- submit(qSub);
- }
-
return rslt;
}
-VkResult MVKQueue::submitPresentKHR(const VkPresentInfoKHR* pPresentInfo) {
- MVKQueueSubmission* qSub = new MVKQueuePresentSurfaceSubmission(_device, this, pPresentInfo);
- VkResult rslt = qSub->_submissionResult; // Extract result before submission to avoid race condition with early destruction
- submit(qSub);
- return rslt;
+VkResult MVKQueue::submit(const VkPresentInfoKHR* pPresentInfo) {
+ return submit(new MVKQueuePresentSurfaceSubmission(_device, this, pPresentInfo));
}
// Create an empty submit struct and fence, submit to queue and wait on fence.
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm
index aeed37c..7368e34 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm
@@ -83,7 +83,7 @@
}
bool MVKSwapchain::getHasSurfaceSizeChanged() {
- return !CGSizeEqualToSize(_mtlLayer.updatedDrawableSizeMVK, _mtlLayerOrigDrawSize);
+ return !CGSizeEqualToSize(_mtlLayer.naturalDrawableSizeMVK, _mtlLayerOrigDrawSize);
}
uint64_t MVKSwapchain::getNextAcquisitionID() { return ++_currentAcquisitionID; }
diff --git a/MoltenVK/MoltenVK/OS/CAMetalLayer+MoltenVK.h b/MoltenVK/MoltenVK/OS/CAMetalLayer+MoltenVK.h
index ad18bbf..bb6a599 100644
--- a/MoltenVK/MoltenVK/OS/CAMetalLayer+MoltenVK.h
+++ b/MoltenVK/MoltenVK/OS/CAMetalLayer+MoltenVK.h
@@ -24,8 +24,19 @@
@interface CAMetalLayer (MoltenVK)
/**
- * Ensures the drawableSize property of this layer is up to date, by combining the size
- * of the bounds property and the contentScale property, and returns the updated value.
+ * Returns the natural drawable size for this layer.
+ *
+ * The natural drawable size is the size of the bounds property of this layer, multiplied
+ * by the contentsScale property of this layer, and is the value that the drawableSize
+ * property will be set to when the updatedDrawableSizeMVK nethod is invoked.
+ */
+@property(nonatomic, readonly) CGSize naturalDrawableSizeMVK;
+
+/**
+ * Ensures the drawableSize property of this layer is up to date, by ensuring
+ * it is set to the value returned by the naturalDrawableSizeMVK property.
+ *
+ * Returns the updated drawableSize value.
*/
-(CGSize) updatedDrawableSizeMVK;
diff --git a/MoltenVK/MoltenVK/OS/CAMetalLayer+MoltenVK.m b/MoltenVK/MoltenVK/OS/CAMetalLayer+MoltenVK.m
index 726128f..3bbb860 100644
--- a/MoltenVK/MoltenVK/OS/CAMetalLayer+MoltenVK.m
+++ b/MoltenVK/MoltenVK/OS/CAMetalLayer+MoltenVK.m
@@ -22,18 +22,21 @@
@implementation CAMetalLayer (MoltenVK)
--(CGSize) updatedDrawableSizeMVK {
+-(CGSize) naturalDrawableSizeMVK {
CGSize drawSize = self.bounds.size;
CGFloat scaleFactor = self.contentsScale;
drawSize.width = trunc(drawSize.width * scaleFactor);
drawSize.height = trunc(drawSize.height * scaleFactor);
-
- // Only update property value if it needs to be, in case
- // updating to same value causes internal reconfigurations.
+ return drawSize;
+}
+
+// Only update drawableSize property value if it needs to be,
+// in case updating to same value causes internal reconfigurations.
+-(CGSize) updatedDrawableSizeMVK {
+ CGSize drawSize = self.naturalDrawableSizeMVK;
if ( !CGSizeEqualToSize(drawSize, self.drawableSize) ) {
self.drawableSize = drawSize;
}
-
return drawSize;
}
diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm
index d0ffe9c..28fa8a9 100644
--- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm
+++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm
@@ -1524,7 +1524,7 @@
const VkPresentInfoKHR* pPresentInfo) {
MVKQueue* mvkQ = MVKQueue::getMVKQueue(queue);
- return mvkQ->submitPresentKHR(pPresentInfo);
+ return mvkQ->submit(pPresentInfo);
}