Fix memory leak where swapchains and images were not destroyed due to a retention loop.

Add Cube app iOS device rotation support, to test swapchain destruction on iOS.
This commit is contained in:
Bill Hollings 2021-03-26 17:45:16 -04:00
parent 79ba1d8e1e
commit d4844490f4
4 changed files with 17 additions and 1 deletions

View File

@ -62,6 +62,12 @@
demo_draw(&demo);
}
// Allow device rotation to resize the swapchain
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
demo_resize(&demo);
}
@end

View File

@ -22,6 +22,7 @@ Released TBD
- Always explicitly set `CAMetalLayer` colorspace property based on _Vulkan_ parameters,
and don't rely on _Metal_ default values.
- Avoid use of _Metal_ renderpass load and store actions on memoryless attachments.
- Fix memory leak on swapchain destruction.
- Remove project qualifiers from references to `SPIRV-Cross` header files.
- `MVKDescriptorPool` pools its descriptor sets.
- Enable `MVKConfiguration::preallocateDescriptors` and `MVK_CONFIG_PREALLOCATE_DESCRIPTORS`

View File

@ -97,6 +97,8 @@ public:
/** VK_GOOGLE_display_timing - returns past presentation times */
VkResult getPastPresentationTiming(uint32_t *pCount, VkPastPresentationTimingGOOGLE *pPresentationTimings);
void destroy() override;
#pragma mark Construction
MVKSwapchain(MVKDevice* device, const VkSwapchainCreateInfoKHR* pCreateInfo);

View File

@ -464,9 +464,16 @@ void MVKSwapchain::recordPresentTime(MVKPresentTimingInfo presentTimingInfo, uin
_presentHistoryIndex = (_presentHistoryIndex + 1) % kMaxPresentationHistory;
}
MVKSwapchain::~MVKSwapchain() {
// A retention loop exists between the swapchain and its images. The swapchain images
// retain the swapchain because they can be in flight when the app destroys the swapchain.
// Release the images now, when the app destroys the swapchain, so they will be destroyed when
// no longer held by the presentation flow, and will in turn release the swapchain for destruction.
void MVKSwapchain::destroy() {
for (auto& img : _presentableImages) { _device->destroyPresentableSwapchainImage(img, NULL); }
MVKVulkanAPIDeviceObject::destroy();
}
MVKSwapchain::~MVKSwapchain() {
if (_licenseWatermark) { _licenseWatermark->destroy(); }
[this->_layerObserver release];
}