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);
 }