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.
This commit is contained in:
Bill Hollings 2023-09-08 20:46:28 -04:00
parent 473ea0c2f1
commit 0ee15222c8
4 changed files with 14 additions and 13 deletions

View File

@ -20,6 +20,7 @@ Released TBD
- Fix rare case where vertex attribute buffers are not bound to Metal - Fix rare case where vertex attribute buffers are not bound to Metal
when no other bindings change between pipelines. 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. - Fix case where a `CAMetalDrawable` with invalid pixel format causes onscreen flickering.
- Improve behavior of swapchain image presentation stalls caused by Metal regression. - 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. - Add several additional performance trackers, available via logging, or the `mvk_private_api.h` API.

View File

@ -45,7 +45,7 @@ extern "C" {
*/ */
#define MVK_VERSION_MAJOR 1 #define MVK_VERSION_MAJOR 1
#define MVK_VERSION_MINOR 2 #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_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) #define MVK_VERSION MVK_MAKE_VERSION(MVK_VERSION_MAJOR, MVK_VERSION_MINOR, MVK_VERSION_PATCH)

View File

@ -504,11 +504,12 @@ void MVKCmdBlitImage<N>::encode(MVKCommandEncoder* cmdEncoder, MVKCommandUse com
if (cmdEncoder->getDevice()->_pMetalFeatures->nativeTextureSwizzle && if (cmdEncoder->getDevice()->_pMetalFeatures->nativeTextureSwizzle &&
_srcImage->needsSwizzle()) { _srcImage->needsSwizzle()) {
// Use a view that has a swizzle on it. // Use a view that has a swizzle on it.
srcMTLTex = [[srcMTLTex newTextureViewWithPixelFormat:srcMTLTex.pixelFormat srcMTLTex = [srcMTLTex newTextureViewWithPixelFormat:srcMTLTex.pixelFormat
textureType:srcMTLTex.textureType textureType:srcMTLTex.textureType
levels:NSMakeRange(0, srcMTLTex.mipmapLevelCount) levels:NSMakeRange(0, srcMTLTex.mipmapLevelCount)
slices:NSMakeRange(0, srcMTLTex.arrayLength) slices:NSMakeRange(0, srcMTLTex.arrayLength)
swizzle:_srcImage->getPixelFormats()->getMTLTextureSwizzleChannels(_srcImage->getVkFormat())] autorelease]; swizzle:_srcImage->getPixelFormats()->getMTLTextureSwizzleChannels(_srcImage->getVkFormat())];
[cmdEncoder->_mtlCmdBuffer addCompletedHandler: ^(id<MTLCommandBuffer>) { [srcMTLTex release]; }];
} }
cmdEncoder->endCurrentMetalEncoding(); cmdEncoder->endCurrentMetalEncoding();
@ -551,9 +552,7 @@ void MVKCmdBlitImage<N>::encode(MVKCommandEncoder* cmdEncoder, MVKCommandUse com
textureType: MTLTextureType2DArray textureType: MTLTextureType2DArray
levels: NSMakeRange(0, srcMTLTex.mipmapLevelCount) levels: NSMakeRange(0, srcMTLTex.mipmapLevelCount)
slices: NSMakeRange(0, srcMTLTex.arrayLength)]; slices: NSMakeRange(0, srcMTLTex.arrayLength)];
[cmdEncoder->_mtlCmdBuffer addCompletedHandler: ^(id<MTLCommandBuffer>) { [cmdEncoder->_mtlCmdBuffer addCompletedHandler: ^(id<MTLCommandBuffer>) { [srcMTLTex release]; }];
[srcMTLTex release];
}];
} }
blitKey.dstMTLPixelFormat = _dstImage->getMTLPixelFormat(dstPlaneIndex); blitKey.dstMTLPixelFormat = _dstImage->getMTLPixelFormat(dstPlaneIndex);
blitKey.srcFilter = mvkMTLSamplerMinMagFilterFromVkFilter(_filter); blitKey.srcFilter = mvkMTLSamplerMinMagFilterFromVkFilter(_filter);
@ -655,9 +654,7 @@ void MVKCmdBlitImage<N>::encode(MVKCommandEncoder* cmdEncoder, MVKCommandUse com
#endif #endif
} }
id<MTLTexture> stencilMTLTex = [srcMTLTex newTextureViewWithPixelFormat: stencilFmt]; id<MTLTexture> stencilMTLTex = [srcMTLTex newTextureViewWithPixelFormat: stencilFmt];
[cmdEncoder->_mtlCmdBuffer addCompletedHandler: ^(id<MTLCommandBuffer>) { [cmdEncoder->_mtlCmdBuffer addCompletedHandler: ^(id<MTLCommandBuffer>) { [stencilMTLTex release]; }];
[stencilMTLTex release];
}];
[mtlRendEnc setFragmentTexture: stencilMTLTex atIndex: 1]; [mtlRendEnc setFragmentTexture: stencilMTLTex atIndex: 1];
} else { } else {
[mtlRendEnc setFragmentTexture: srcMTLTex atIndex: 1]; [mtlRendEnc setFragmentTexture: srcMTLTex atIndex: 1];

View File

@ -622,7 +622,10 @@ MVKQueueFullCommandBufferSubmission<N>::MVKQueueFullCommandBufferSubmission(MVKQ
// If the semaphores are not encodable, wait on them inline after presenting. // If the semaphores are not encodable, wait on them inline after presenting.
// The semaphores know what to do. // The semaphores know what to do.
VkResult MVKQueuePresentSurfaceSubmission::execute() { VkResult MVKQueuePresentSurfaceSubmission::execute() {
id<MTLCommandBuffer> 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<MTLCommandBuffer> mtlCmdBuff = _queue->getMTLCommandBuffer(kMVKCommandUseQueuePresent, true);
for (auto& ws : _waitSemaphores) { for (auto& ws : _waitSemaphores) {
auto& sem4 = ws.first; auto& sem4 = ws.first;