From 0ee15222c83157dc765a9fdeac614e1620f76d12 Mon Sep 17 00:00:00 2001 From: Bill Hollings Date: Fri, 8 Sep 2023 20:46:28 -0400 Subject: [PATCH] Ensure objects retained for life of MTLCommandBuffer. - vkCmdBlitImage() ensure swizzle texture view is retained for life of MTLCommandBuffer. - vkQueuePresentKHR() use MTLCommandBuffer that retains references. - Update MoltenVK version to 1.2.6. --- Docs/Whats_New.md | 1 + MoltenVK/MoltenVK/API/mvk_config.h | 2 +- MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm | 19 ++++++++----------- MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm | 5 ++++- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md index 836a60a9..605cda82 100644 --- a/Docs/Whats_New.md +++ b/Docs/Whats_New.md @@ -20,6 +20,7 @@ Released TBD - Fix rare case where vertex attribute buffers are not bound to Metal when no other bindings change between pipelines. +- Ensure objects retained for life of `MTLCommandBuffer` during `vkCmdBlitImage()` & `vkQueuePresentKHR()`. - Fix case where a `CAMetalDrawable` with invalid pixel format causes onscreen flickering. - Improve behavior of swapchain image presentation stalls caused by Metal regression. - Add several additional performance trackers, available via logging, or the `mvk_private_api.h` API. diff --git a/MoltenVK/MoltenVK/API/mvk_config.h b/MoltenVK/MoltenVK/API/mvk_config.h index 532d27db..f9702661 100644 --- a/MoltenVK/MoltenVK/API/mvk_config.h +++ b/MoltenVK/MoltenVK/API/mvk_config.h @@ -45,7 +45,7 @@ extern "C" { */ #define MVK_VERSION_MAJOR 1 #define MVK_VERSION_MINOR 2 -#define MVK_VERSION_PATCH 5 +#define MVK_VERSION_PATCH 6 #define MVK_MAKE_VERSION(major, minor, patch) (((major) * 10000) + ((minor) * 100) + (patch)) #define MVK_VERSION MVK_MAKE_VERSION(MVK_VERSION_MAJOR, MVK_VERSION_MINOR, MVK_VERSION_PATCH) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm index 2c0ef546..1c38d15a 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.mm @@ -504,11 +504,12 @@ void MVKCmdBlitImage::encode(MVKCommandEncoder* cmdEncoder, MVKCommandUse com if (cmdEncoder->getDevice()->_pMetalFeatures->nativeTextureSwizzle && _srcImage->needsSwizzle()) { // Use a view that has a swizzle on it. - srcMTLTex = [[srcMTLTex newTextureViewWithPixelFormat:srcMTLTex.pixelFormat - textureType:srcMTLTex.textureType - levels:NSMakeRange(0, srcMTLTex.mipmapLevelCount) - slices:NSMakeRange(0, srcMTLTex.arrayLength) - swizzle:_srcImage->getPixelFormats()->getMTLTextureSwizzleChannels(_srcImage->getVkFormat())] autorelease]; + srcMTLTex = [srcMTLTex newTextureViewWithPixelFormat:srcMTLTex.pixelFormat + textureType:srcMTLTex.textureType + levels:NSMakeRange(0, srcMTLTex.mipmapLevelCount) + slices:NSMakeRange(0, srcMTLTex.arrayLength) + swizzle:_srcImage->getPixelFormats()->getMTLTextureSwizzleChannels(_srcImage->getVkFormat())]; + [cmdEncoder->_mtlCmdBuffer addCompletedHandler: ^(id) { [srcMTLTex release]; }]; } cmdEncoder->endCurrentMetalEncoding(); @@ -551,9 +552,7 @@ void MVKCmdBlitImage::encode(MVKCommandEncoder* cmdEncoder, MVKCommandUse com textureType: MTLTextureType2DArray levels: NSMakeRange(0, srcMTLTex.mipmapLevelCount) slices: NSMakeRange(0, srcMTLTex.arrayLength)]; - [cmdEncoder->_mtlCmdBuffer addCompletedHandler: ^(id) { - [srcMTLTex release]; - }]; + [cmdEncoder->_mtlCmdBuffer addCompletedHandler: ^(id) { [srcMTLTex release]; }]; } blitKey.dstMTLPixelFormat = _dstImage->getMTLPixelFormat(dstPlaneIndex); blitKey.srcFilter = mvkMTLSamplerMinMagFilterFromVkFilter(_filter); @@ -655,9 +654,7 @@ void MVKCmdBlitImage::encode(MVKCommandEncoder* cmdEncoder, MVKCommandUse com #endif } id stencilMTLTex = [srcMTLTex newTextureViewWithPixelFormat: stencilFmt]; - [cmdEncoder->_mtlCmdBuffer addCompletedHandler: ^(id) { - [stencilMTLTex release]; - }]; + [cmdEncoder->_mtlCmdBuffer addCompletedHandler: ^(id) { [stencilMTLTex release]; }]; [mtlRendEnc setFragmentTexture: stencilMTLTex atIndex: 1]; } else { [mtlRendEnc setFragmentTexture: srcMTLTex atIndex: 1]; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm index f53cb71d..1c28f63f 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm @@ -622,7 +622,10 @@ MVKQueueFullCommandBufferSubmission::MVKQueueFullCommandBufferSubmission(MVKQ // If the semaphores are not encodable, wait on them inline after presenting. // The semaphores know what to do. VkResult MVKQueuePresentSurfaceSubmission::execute() { - id mtlCmdBuff = _queue->getMTLCommandBuffer(kMVKCommandUseQueuePresent); + // MTLCommandBuffer retain references to avoid rare case where objects are destroyed too early. + // Although testing could not determine which objects were being lost, queue present MTLCommandBuffers + // are used only once per frame, and retain so few objects, that blanket retention is still performant. + id mtlCmdBuff = _queue->getMTLCommandBuffer(kMVKCommandUseQueuePresent, true); for (auto& ws : _waitSemaphores) { auto& sem4 = ws.first;