diff --git a/Docs/MoltenVK_Runtime_UserGuide.md b/Docs/MoltenVK_Runtime_UserGuide.md index cba451eb5..92f3d0be2 100644 --- a/Docs/MoltenVK_Runtime_UserGuide.md +++ b/Docs/MoltenVK_Runtime_UserGuide.md @@ -352,17 +352,21 @@ There are three mechanisms for setting the values of the **MoltenVK** configurat - Application runtime environment variables. - Build settings at **MoltenVK** build time. -To change the **MoltenVK** configuration settings at runtime using a programmatic API, use the -`vkGetMoltenVKConfigurationMVK()` and `vkSetMoltenVKConfigurationMVK()` functions to retrieve, -modify, and set a copy of the `MVKConfiguration` structure. +To change some of the **MoltenVK** configuration settings at runtime using a programmatic API, +use the `vkGetMoltenVKConfigurationMVK()` and `vkSetMoltenVKConfigurationMVK()` functions to +retrieve, modify, and set a copy of the `MVKConfiguration` structure. -The initial value of each of the configuration settings can established at runtime +The initial value of each of the configuration settings can be established at runtime by a corresponding environment variable, or if the environment variable is not set, by a corresponding build setting at the time **MoltenVK** is compiled. The environment variable and build setting for each configuration parameter share the same name. -See the description of the `MVKConfiguration` structure parameters in the `vk_mvk_moltenvk.h` -file for more info about configuring and optimizing **MoltenVK** at build time or runtime. +There are also a number of additional runtime environment variables that are not included in the +`MVKConfiguration` structure, but that also control **MoltenVK** behaviour. + +See the description of the environment variables and the `MVKConfiguration` structure parameters +in the `vk_mvk_moltenvk.h` file for more info about configuring and optimizing **MoltenVK** +at runtime or build time. diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md index 0fc15819c..aa010018e 100644 --- a/Docs/Whats_New.md +++ b/Docs/Whats_New.md @@ -17,15 +17,19 @@ For best results, use a Markdown reader.* MoltenVK 1.0.40 --------------- -Released TBD +Released 2020/01/21 +- Refactor descriptor management to reduce memory footprint and fix caching leak. +- Add `MVK_CONFIG_PREALLOCATE_DESCRIPTORS` environment variable to support preallocated + descriptor pooling within a `VkDescriptorPool` via the `VkDescriptorPoolSize` values. - Fix crash when app does not use queue family zero. - Fix buffer offset in `vkCmdPushDescriptorSet()` for non-dedicated buffer memory. - Fix Metal validation error on push constant sizing differences between C and MSL structs. - Track performance of `CAMetalLayer nextDrawable` call. - Document recommendation to use 3 swapchain images, particularly with full-screen rendering. +- Update `MoltenVK_Runtime_UserGuide.md` to better explain runtime environment variables. - Update `VK_MVK_MOLTENVK_SPEC_VERSION` to `24`. -- Update copyright to 2020. +- Update copyright notices to year 2020. diff --git a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h index e203c4352..078c134a4 100644 --- a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h +++ b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h @@ -144,6 +144,15 @@ typedef unsigned long MTLLanguageVersion; * on native 1D textures, including not being renderable, clearable, or permitting mipmaps. * Using a Metal 2D texture allows Vulkan 1D textures to support this additional functionality. * This setting is enabled by default, and MoltenVK will use a Metal 2D texture for each Vulkan 1D image. + * + * 7. The MVK_CONFIG_PREALLOCATE_DESCRIPTORS runtime environment variable or MoltenVK compile-time + * build setting controls whether MoltenVK should preallocate memory in each VkDescriptorPool + * according to the values of the VkDescriptorPoolSize parameters. Doing so may improve + * descriptor set allocation performance at a cost of preallocated application memory. + * If this environment variable is disabled, the descriptors required for a descriptor set will + * be dynamically allocated in application memory when the descriptor set itself is allocated. + * This setting is disabled by default, and MoltenVK will dynamically allocate descriptors + * when the containing descriptor set is allocated. */ typedef struct { diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h index 212fc6377..51756a323 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h @@ -162,6 +162,7 @@ class MVKDescriptorTypePreallocation : public MVKBaseObject { VkResult allocateDescriptor(MVKDescriptor** pMVKDesc); bool findDescriptor(uint32_t endIndex, MVKDescriptor** pMVKDesc); void freeDescriptor(MVKDescriptor* mvkDesc); + void reset(); std::vector _descriptors; std::vector _availability; @@ -188,6 +189,7 @@ class MVKPreallocatedDescriptors : public MVKBaseObject { VkResult allocateDescriptor(VkDescriptorType descriptorType, MVKDescriptor** pMVKDesc); void freeDescriptor(MVKDescriptor* mvkDesc); + void reset(); MVKDescriptorTypePreallocation _uniformBufferDescriptors; MVKDescriptorTypePreallocation _storageBufferDescriptors; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm index cfecbfd45..8e220bbdd 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.mm @@ -354,6 +354,11 @@ static inline bool getMVKPreallocateDescriptors() { } } +template +void MVKDescriptorTypePreallocation::reset() { + _nextAvailableIndex = 0; +} + template MVKDescriptorTypePreallocation::MVKDescriptorTypePreallocation(const VkDescriptorPoolCreateInfo* pCreateInfo, VkDescriptorType descriptorType) { @@ -466,6 +471,21 @@ static inline bool getMVKPreallocateDescriptors() { } } +void MVKPreallocatedDescriptors::reset() { + _uniformBufferDescriptors.reset(); + _storageBufferDescriptors.reset(); + _uniformBufferDynamicDescriptors.reset(); + _storageBufferDynamicDescriptors.reset(); + _inlineUniformBlockDescriptors.reset(); + _sampledImageDescriptors.reset(); + _storageImageDescriptors.reset(); + _inputAttachmentDescriptors.reset(); + _samplerDescriptors.reset(); + _combinedImageSamplerDescriptors.reset(); + _uniformTexelBufferDescriptors.reset(); + _storageTexelBufferDescriptors.reset(); +} + MVKPreallocatedDescriptors::MVKPreallocatedDescriptors(const VkDescriptorPoolCreateInfo* pCreateInfo) : _uniformBufferDescriptors(pCreateInfo, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER), _storageBufferDescriptors(pCreateInfo, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER), @@ -521,6 +541,7 @@ static inline bool getMVKPreallocateDescriptors() { VkResult MVKDescriptorPool::reset(VkDescriptorPoolResetFlags flags) { for (auto& mvkDS : _allocatedSets) { freeDescriptorSet(mvkDS); } _allocatedSets.clear(); + if (_preallocatedDescriptors) { _preallocatedDescriptors->reset(); } return VK_SUCCESS; }