Only update CAMetalLayer drawableSize property during swapchain creation.
Simplify structure of MVKQueue::submit() functions.
This commit is contained in:
parent
d2aea464de
commit
e39d7e6394
@ -174,7 +174,7 @@ VkResult MVKPhysicalDevice::getSurfaceCapabilities(MVKSurface* surface,
|
||||
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.
|
||||
|
@ -81,7 +81,7 @@ public:
|
||||
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 @@ protected:
|
||||
void initExecQueue();
|
||||
void initMTLCommandQueue();
|
||||
void destroyExecQueue();
|
||||
void submit(MVKQueueSubmission* qSubmit);
|
||||
VkResult submit(MVKQueueSubmission* qSubmit);
|
||||
|
||||
MVKQueueFamily* _queueFamily;
|
||||
uint32_t _index;
|
||||
|
@ -64,41 +64,37 @@ MVKQueueFamily::~MVKQueueFamily() {
|
||||
// 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.
|
||||
|
@ -83,7 +83,7 @@ VkResult MVKSwapchain::acquireNextImageKHR(uint64_t timeout,
|
||||
}
|
||||
|
||||
bool MVKSwapchain::getHasSurfaceSizeChanged() {
|
||||
return !CGSizeEqualToSize(_mtlLayer.updatedDrawableSizeMVK, _mtlLayerOrigDrawSize);
|
||||
return !CGSizeEqualToSize(_mtlLayer.naturalDrawableSizeMVK, _mtlLayerOrigDrawSize);
|
||||
}
|
||||
|
||||
uint64_t MVKSwapchain::getNextAcquisitionID() { return ++_currentAcquisitionID; }
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
return drawSize;
|
||||
}
|
||||
|
||||
// Only update property value if it needs to be, in case
|
||||
// updating to same value causes internal reconfigurations.
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -1524,7 +1524,7 @@ MVK_PUBLIC_SYMBOL VkResult vkQueuePresentKHR(
|
||||
const VkPresentInfoKHR* pPresentInfo) {
|
||||
|
||||
MVKQueue* mvkQ = MVKQueue::getMVKQueue(queue);
|
||||
return mvkQ->submitPresentKHR(pPresentInfo);
|
||||
return mvkQ->submit(pPresentInfo);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user