@@ -58,6 +58,43 @@ class VulkanContext {
5858 error = halide_error_code_device_interface_no_device;
5959 halide_error_no_device_interface (user_context);
6060 }
61+ // If user overrode halide_vulkan_acquire_context and returned nullptr for allocator,
62+ // create Halide's allocator for the provided device. User must override `halide_vulkan_export_memory_allocator`
63+ // and make sure to propagate it back at the next call of `halide_vulkan_acquire_context` as he overrides it.
64+ if (allocator == nullptr &&
65+ instance != VK_NULL_HANDLE &&
66+ device != VK_NULL_HANDLE &&
67+ physical_device != VK_NULL_HANDLE) {
68+ #ifdef DEBUG_RUNTIME
69+ // Initialize clock for debug timing - normally done in halide_vulkan_acquire_context
70+ halide_start_clock (user_context);
71+ #endif
72+ // make sure halide vulkan is loaded BEFORE creating allocator
73+ debug (user_context) << " VulkanContext: Loading Vulkan function pointers for context override...\n " ;
74+
75+ vk_load_vulkan_loader_functions (user_context);
76+ if (vkGetInstanceProcAddr == nullptr ) {
77+ debug (user_context) << " VulkanContext: Failed to load vkGetInstanceProcAddr from loader!\n " ;
78+ } else {
79+ debug (user_context) << " VulkanContext: vkGetInstanceProcAddr loaded successfully: " << (void *)vkGetInstanceProcAddr << " \n " ;
80+ vk_load_vulkan_instance_functions (user_context, instance);
81+ vk_load_vulkan_device_functions (user_context, device);
82+ }
83+
84+ allocator = vk_create_memory_allocator (user_context, device, physical_device,
85+ halide_vulkan_get_allocation_callbacks (user_context));
86+ if (allocator == nullptr ) {
87+ error = halide_error_code_out_of_memory;
88+ debug (user_context) << " Vulkan: Failed to create memory allocator for device!\n " ;
89+ return ;
90+ }
91+ int result = halide_vulkan_export_memory_allocator (user_context, reinterpret_cast <halide_vulkan_memory_allocator *>(allocator));
92+ if (result != halide_error_code_success) {
93+ error = static_cast <halide_error_code_t >(result);
94+ debug (user_context) << " Vulkan: Failed to export memory allocator for device!\n " ;
95+ return ;
96+ }
97+ }
6198 halide_debug_assert (user_context, allocator != nullptr );
6299 halide_debug_assert (user_context, instance != VK_NULL_HANDLE);
63100 halide_debug_assert (user_context, device != VK_NULL_HANDLE);
@@ -546,8 +583,8 @@ int vk_destroy_context(void *user_context, VulkanMemoryAllocator *allocator,
546583
547584 if (allocator != nullptr ) {
548585 vk_destroy_shader_modules (user_context, allocator);
549- vk_destroy_memory_allocator (user_context, allocator);
550586 vk_destroy_debug_utils_messenger (user_context, instance, allocator, messenger);
587+ vk_destroy_memory_allocator (user_context, allocator);
551588 }
552589
553590 const VkAllocationCallbacks *alloc_callbacks = halide_vulkan_get_allocation_callbacks (user_context);
@@ -560,6 +597,20 @@ int vk_destroy_context(void *user_context, VulkanMemoryAllocator *allocator,
560597 return halide_error_code_success;
561598}
562599
600+ // Clean up only Halide's internal resources for external context (leaves device/instance alone)
601+ int vk_release_memory_allocator (void *user_context, VulkanMemoryAllocator *allocator,
602+ VkInstance instance, VkDebugUtilsMessengerEXT messenger) {
603+ debug (user_context) << " vk_release_memory_allocator (user_context: " << user_context << " )\n " ;
604+ // Clean up only Halide's internal resources, not the device/instance we don't own
605+ if (allocator != nullptr ) {
606+ vk_destroy_shader_modules (user_context, allocator);
607+ vk_destroy_debug_utils_messenger (user_context, instance, allocator, messenger);
608+ vk_destroy_memory_allocator (user_context, allocator);
609+ }
610+
611+ return halide_error_code_success;
612+ }
613+
563614// --------------------------------------------------------------------------
564615
565616VKAPI_ATTR VkBool32 VKAPI_CALL vk_debug_utils_messenger_callback (
0 commit comments