diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h index a7b81b80..4dab04b9 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h @@ -402,6 +402,8 @@ public: MVKSwapchain* swapchain, uint32_t swapchainIndex); + ~MVKSwapchainImage() override; + protected: friend class MVKPeerSwapchainImage; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm index 8b07945d..52e2e8d5 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm @@ -1115,6 +1115,12 @@ MVKSwapchainImage::MVKSwapchainImage(MVKDevice* device, uint32_t swapchainIndex) : MVKImage(device, pCreateInfo) { _swapchain = swapchain; _swapchainIndex = swapchainIndex; + + _swapchain->retain(); +} + +MVKSwapchainImage::~MVKSwapchainImage() { + if (_swapchain) { _swapchain->release(); } } @@ -1275,11 +1281,13 @@ void MVKPresentableSwapchainImage::presentCAMetalDrawable(id m _swapchain->recordPresentTime(presentID, desiredPresentTime, desiredPresentTime); #else if ([_mtlDrawable respondsToSelector: @selector(addPresentedHandler:)]) { + retain(); // Ensure this image is not destroyed while awaiting presentation [_mtlDrawable addPresentedHandler: ^(id drawable) { // Record the presentation time CFTimeInterval presentedTimeSeconds = drawable.presentedTime; uint64_t presentedTimeNanoseconds = (uint64_t)(presentedTimeSeconds * 1.0e9); _swapchain->recordPresentTime(presentID, desiredPresentTime, presentedTimeNanoseconds); + release(); }]; } else { // If MTLDrawable.presentedTime/addPresentedHandler isn't supported, just treat it as if the