Answer
In Vulkan 1.3 an imported external OS allocation still creates a VkDeviceMemory object via vkAllocateMemory. The driver therefore treats each import as a distinct VkDeviceMemory and it counts toward VkPhysicalDeviceLimits::maxMemoryAllocationCount. Import does not bypass the allocation limit or replace vkAllocateMemory.
Confirmed facts
VkDeviceMemory objects are created only by vkAllocateMemory. There is no API to bind a raw OS pointer directly to Vulkan.
- OS allocator interoperability is via
VK_KHR_external_memory and platform extensions such as VK_KHR_external_memory_fd on Linux or VK_KHR_external_memory_win32 on Windows. Vulkan 1.1 core includes VK_KHR_external_memory.
- Import requires device support, a matching
VkExternalMemoryHandleTypeFlagBits, and a memory type that advertises external support in VkPhysicalDeviceExternalMemoryProperties. Export uses VkExportMemoryAllocateInfo in the VkMemoryAllocateInfo::pNext chain.
maxMemoryAllocationCount limits the number of live VkDeviceMemory handles. Pooling libraries like VMA exist to stay under this limit.
Likely explanation for the uncertainty
The confusion comes from the fact that the backing storage is provided by an external OS allocator. The backing is external, but the Vulkan object model is not. The driver still allocates a VkDeviceMemory handle, tracks it, and enforces the allocation count. Reusing the same external handle across multiple VkDeviceMemory objects is not allowed; each vkAllocateMemory with an import creates a new handle that counts.
Steps needed for this case
- Enable
VK_KHR_external_memory and the platform extension at device creation. Verify support with vkEnumerateDeviceExtensionProperties and VkPhysicalDeviceExternalMemoryFeatures via vkGetPhysicalDeviceFeatures2.
- Query external memory support per memory type with
vkGetPhysicalDeviceMemoryProperties and VkPhysicalDeviceExternalMemoryProperties. Confirm the desired VkExternalMemoryHandleTypeFlagBits is supported for buffers or images.
- Allocate OS memory with size and alignment matching
VkMemoryRequirements from vkGetBufferMemoryRequirements or vkGetImageMemoryRequirements2. Lifetime must exceed Vulkan usage.
- Create the import structure, e.g.
VkImportMemoryFdInfoKHR on Linux or VkImportMemoryWin32HandleInfoKHR on Windows, and chain it into VkMemoryAllocateInfo::pNext. Call vkAllocateMemory. This returns a VkDeviceMemory that counts toward the limit.
- Bind the memory to the resource with
vkBindBufferMemory or vkBindImageMemory. Validate with validation layers.
Assumption: Linux file descriptor import. On Windows the handle type and import struct differ. Version sensitive behavior applies to driver support for external memory for images vs buffers.
One missing diagnostic detail that changes the recommendation: which platform and external handle type you intend to import. The exact import struct, required extensions, and property queries differ between fd and Win32 handles.
Verification
- Confirm extensions and features are enabled before allocating.
- Use
vkGetMemoryFdPropertiesKHR or equivalent to confirm imported memory properties match the OS allocation.
- Enable validation layers; they report external memory mismatches and handle type errors.
Cautions: not all memory types support external memory; alignment from memory requirements must be honored by the OS allocator; freeing the OS allocation early causes use-after-free.