goto out;
}
- res = loader_get_next_available_entry(inst, &inst->debug_utils_messengers_list, &next_index);
+ res = loader_get_next_available_entry(inst, &inst->debug_utils_messengers_list, &next_index, pAllocator);
if (res != VK_SUCCESS) {
goto out;
}
}
}
if (inst->debug_utils_messengers_list.list &&
- inst->debug_utils_messengers_list.capacity > (*pNextIndex) * sizeof(VkBool32)) {
- inst->debug_utils_messengers_list.list[*pNextIndex] = VK_FALSE;
+ inst->debug_utils_messengers_list.capacity > (*pNextIndex) * sizeof(struct loader_used_object_status)) {
+ inst->debug_utils_messengers_list.list[*pNextIndex].status = VK_FALSE;
+ if (NULL != pAllocator) {
+ inst->debug_utils_messengers_list.list[*pNextIndex].allocation_callbacks = *pAllocator;
+ }
}
loader_free_with_instance_fallback(pAllocator, inst, new_dbg_func_node);
loader_free_with_instance_fallback(pAllocator, inst, pNextIndex);
util_DestroyDebugUtilsMessenger(inst, messenger, pAllocator);
if (inst->debug_utils_messengers_list.list &&
- inst->debug_utils_messengers_list.capacity > (*debug_messenger_index) * sizeof(VkBool32)) {
- inst->debug_utils_messengers_list.list[*debug_messenger_index] = VK_FALSE;
+ inst->debug_utils_messengers_list.capacity > (*debug_messenger_index) * sizeof(struct loader_used_object_status)) {
+ inst->debug_utils_messengers_list.list[*debug_messenger_index].status = VK_FALSE;
+ if (NULL != pAllocator) {
+ inst->debug_utils_messengers_list.list[*debug_messenger_index].allocation_callbacks = *pAllocator;
+ }
}
loader_free_with_instance_fallback(pAllocator, inst, debug_messenger_index);
goto out;
}
- res = loader_get_next_available_entry(inst, &inst->debug_report_callbacks_list, &next_index);
+ res = loader_get_next_available_entry(inst, &inst->debug_report_callbacks_list, &next_index, pAllocator);
if (res != VK_SUCCESS) {
goto out;
}
}
}
if (inst->debug_report_callbacks_list.list &&
- inst->debug_report_callbacks_list.capacity > (*pNextIndex) * sizeof(VkBool32)) {
- inst->debug_report_callbacks_list.list[*pNextIndex] = VK_FALSE;
+ inst->debug_report_callbacks_list.capacity > (*pNextIndex) * sizeof(struct loader_used_object_status)) {
+ inst->debug_report_callbacks_list.list[*pNextIndex].status = VK_FALSE;
+ if (NULL != pAllocator) {
+ inst->debug_report_callbacks_list.list[*pNextIndex].allocation_callbacks = *pAllocator;
+ }
}
loader_free_with_instance_fallback(pAllocator, inst, new_dbg_func_node);
loader_free_with_instance_fallback(pAllocator, inst, pNextIndex);
util_DestroyDebugReportCallback(inst, callback, pAllocator);
if (inst->debug_report_callbacks_list.list &&
- inst->debug_report_callbacks_list.capacity > (*debug_report_index) * sizeof(VkBool32)) {
- inst->debug_report_callbacks_list.list[*debug_report_index] = VK_FALSE;
+ inst->debug_report_callbacks_list.capacity > (*debug_report_index) * sizeof(struct loader_used_object_status)) {
+ inst->debug_report_callbacks_list.list[*debug_report_index].status = VK_FALSE;
+ if (NULL != pAllocator) {
+ inst->debug_report_callbacks_list.list[*debug_report_index].allocation_callbacks = *pAllocator;
+ }
}
loader_free_with_instance_fallback(pAllocator, inst, debug_report_index);
}
}
VkResult loader_get_next_available_entry(const struct loader_instance *inst, struct loader_used_object_list *list_info,
- uint32_t *free_index) {
+ uint32_t *free_index, const VkAllocationCallbacks *pAllocator) {
if (NULL == list_info->list) {
- VkResult res = loader_init_generic_list(inst, (struct loader_generic_list *)list_info, sizeof(VkBool32));
+ VkResult res =
+ loader_init_generic_list(inst, (struct loader_generic_list *)list_info, sizeof(struct loader_used_object_status));
if (VK_SUCCESS != res) {
return res;
}
}
- for (uint32_t i = 0; i < list_info->capacity / sizeof(VkBool32); i++) {
- if (list_info->list[i] == VK_FALSE) {
- list_info->list[i] = VK_TRUE;
+ for (uint32_t i = 0; i < list_info->capacity / sizeof(struct loader_used_object_status); i++) {
+ if (list_info->list[i].status == VK_FALSE) {
+ list_info->list[i].status = VK_TRUE;
+ if (pAllocator) {
+ list_info->list[i].allocation_callbacks = *pAllocator;
+ } else {
+ memset(&list_info->list[i].allocation_callbacks, 0, sizeof(VkAllocationCallbacks));
+ }
*free_index = i;
return VK_SUCCESS;
}
if (VK_SUCCESS != res) {
return res;
}
- uint32_t new_index = (uint32_t)(old_capacity / sizeof(VkBool32));
+ uint32_t new_index = (uint32_t)(old_capacity / sizeof(struct loader_used_object_status));
// Zero out the newly allocated back half of list.
memset(&list_info->list[new_index], 0, old_capacity);
- list_info->list[new_index] = VK_TRUE;
+ list_info->list[new_index].status = VK_TRUE;
+ if (pAllocator) {
+ list_info->list[new_index].allocation_callbacks = *pAllocator;
+ } else {
+ memset(&list_info->list[new_index].allocation_callbacks, 0, sizeof(VkAllocationCallbacks));
+ }
*free_index = new_index;
return VK_SUCCESS;
}
void loader_release_object_from_list(struct loader_used_object_list *list_info, uint32_t index_to_free) {
- if (list_info->list && list_info->capacity > index_to_free * sizeof(VkBool32)) {
- list_info->list[index_to_free] = VK_FALSE;
+ if (list_info->list && list_info->capacity > index_to_free * sizeof(struct loader_used_object_status)) {
+ list_info->list[index_to_free].status = VK_FALSE;
+ memset(&list_info->list[index_to_free].allocation_callbacks, 0, sizeof(VkAllocationCallbacks));
}
}
loader_destroy_logical_device(found_dev, pAllocator);
}
-void loader_icd_destroy(struct loader_instance *ptr_inst, struct loader_icd_term *icd_term,
- const VkAllocationCallbacks *pAllocator) {
- ptr_inst->icd_terms_count--;
- for (struct loader_device *dev = icd_term->logical_device_list; dev;) {
- struct loader_device *next_dev = dev->next;
- loader_destroy_logical_device(dev, pAllocator);
- dev = next_dev;
- }
+const VkAllocationCallbacks *ignore_null_callback(const VkAllocationCallbacks *callbacks) {
+ return NULL != callbacks->pfnAllocation && NULL != callbacks->pfnFree && NULL != callbacks->pfnReallocation &&
+ NULL != callbacks->pfnInternalAllocation && NULL != callbacks->pfnInternalFree
+ ? callbacks
+ : NULL;
+}
+// Try to close any open objects on the loader_icd_term - this must be done before destroying the instance
+void loader_icd_close_objects(struct loader_instance *ptr_inst, struct loader_icd_term *icd_term) {
for (uint32_t i = 0; i < icd_term->surface_list.capacity / sizeof(VkSurfaceKHR); i++) {
- if (ptr_inst->surfaces_list.capacity > i * sizeof(VkBool32) && ptr_inst->surfaces_list.list[i] == VK_TRUE &&
- NULL != icd_term->surface_list.list && icd_term->surface_list.list[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
- icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_term->surface_list.list[i], pAllocator);
+ if (ptr_inst->surfaces_list.capacity > i * sizeof(struct loader_used_object_status) &&
+ ptr_inst->surfaces_list.list[i].status == VK_TRUE && NULL != icd_term->surface_list.list &&
+ icd_term->surface_list.list[i] && NULL != icd_term->dispatch.DestroySurfaceKHR) {
+ icd_term->dispatch.DestroySurfaceKHR(icd_term->instance, icd_term->surface_list.list[i],
+ ignore_null_callback(&(ptr_inst->surfaces_list.list[i].allocation_callbacks)));
icd_term->surface_list.list[i] = (VkSurfaceKHR)(uintptr_t)NULL;
}
}
- loader_destroy_generic_list(ptr_inst, (struct loader_generic_list *)&icd_term->surface_list);
-
for (uint32_t i = 0; i < icd_term->debug_utils_messenger_list.capacity / sizeof(VkDebugUtilsMessengerEXT); i++) {
- if (ptr_inst->debug_utils_messengers_list.capacity > i * sizeof(VkBool32) &&
- ptr_inst->debug_utils_messengers_list.list[i] == VK_TRUE && NULL != icd_term->debug_utils_messenger_list.list &&
+ if (ptr_inst->debug_utils_messengers_list.capacity > i * sizeof(struct loader_used_object_status) &&
+ ptr_inst->debug_utils_messengers_list.list[i].status == VK_TRUE && NULL != icd_term->debug_utils_messenger_list.list &&
icd_term->debug_utils_messenger_list.list[i] && NULL != icd_term->dispatch.DestroyDebugUtilsMessengerEXT) {
- icd_term->dispatch.DestroyDebugUtilsMessengerEXT(icd_term->instance, icd_term->debug_utils_messenger_list.list[i],
- pAllocator);
+ icd_term->dispatch.DestroyDebugUtilsMessengerEXT(
+ icd_term->instance, icd_term->debug_utils_messenger_list.list[i],
+ ignore_null_callback(&(ptr_inst->debug_utils_messengers_list.list[i].allocation_callbacks)));
icd_term->debug_utils_messenger_list.list[i] = (VkDebugUtilsMessengerEXT)(uintptr_t)NULL;
}
}
- loader_destroy_generic_list(ptr_inst, (struct loader_generic_list *)&icd_term->debug_utils_messenger_list);
-
for (uint32_t i = 0; i < icd_term->debug_report_callback_list.capacity / sizeof(VkDebugReportCallbackEXT); i++) {
- if (ptr_inst->debug_report_callbacks_list.capacity > i * sizeof(VkBool32) &&
- ptr_inst->debug_report_callbacks_list.list[i] == VK_TRUE && NULL != icd_term->debug_report_callback_list.list &&
+ if (ptr_inst->debug_report_callbacks_list.capacity > i * sizeof(struct loader_used_object_status) &&
+ ptr_inst->debug_report_callbacks_list.list[i].status == VK_TRUE && NULL != icd_term->debug_report_callback_list.list &&
icd_term->debug_report_callback_list.list[i] && NULL != icd_term->dispatch.DestroyDebugReportCallbackEXT) {
- icd_term->dispatch.DestroyDebugReportCallbackEXT(icd_term->instance, icd_term->debug_report_callback_list.list[i],
- pAllocator);
+ icd_term->dispatch.DestroyDebugReportCallbackEXT(
+ icd_term->instance, icd_term->debug_report_callback_list.list[i],
+ ignore_null_callback(&(ptr_inst->debug_report_callbacks_list.list[i].allocation_callbacks)));
icd_term->debug_report_callback_list.list[i] = (VkDebugReportCallbackEXT)(uintptr_t)NULL;
}
}
+}
+// Free resources allocated inside the loader_icd_term
+void loader_icd_destroy(struct loader_instance *ptr_inst, struct loader_icd_term *icd_term,
+ const VkAllocationCallbacks *pAllocator) {
+ ptr_inst->icd_terms_count--;
+ for (struct loader_device *dev = icd_term->logical_device_list; dev;) {
+ struct loader_device *next_dev = dev->next;
+ loader_destroy_logical_device(dev, pAllocator);
+ dev = next_dev;
+ }
+
+ loader_destroy_generic_list(ptr_inst, (struct loader_generic_list *)&icd_term->surface_list);
+ loader_destroy_generic_list(ptr_inst, (struct loader_generic_list *)&icd_term->debug_utils_messenger_list);
loader_destroy_generic_list(ptr_inst, (struct loader_generic_list *)&icd_term->debug_report_callback_list);
loader_instance_heap_free(ptr_inst, icd_term);
icd_term = ptr_instance->icd_terms;
ptr_instance->icd_terms = icd_term->next;
if (NULL != icd_term->instance) {
+ loader_icd_close_objects(ptr_instance, icd_term);
icd_term->dispatch.DestroyInstance(icd_term->instance, pAllocator);
}
loader_icd_destroy(ptr_instance, icd_term, pAllocator);
struct loader_icd_term *icd_terms = ptr_instance->icd_terms;
while (NULL != icd_terms) {
if (icd_terms->instance) {
+ loader_icd_close_objects(ptr_instance, icd_terms);
icd_terms->dispatch.DestroyInstance(icd_terms->instance, pAllocator);
}
struct loader_icd_term *next_icd_term = icd_terms->next;
if (cur_scanned_icd_index != UINT32_MAX) {
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
"Removing driver %s due to not having any physical devices", cur_icd_term->scanned_icd->lib_name);
+
+ const VkAllocationCallbacks *allocation_callbacks = ignore_null_callback(&(inst->alloc_callbacks));
if (cur_icd_term->instance) {
- cur_icd_term->dispatch.DestroyInstance(cur_icd_term->instance, &(inst->alloc_callbacks));
+ loader_icd_close_objects(inst, cur_icd_term);
+ cur_icd_term->dispatch.DestroyInstance(cur_icd_term->instance, allocation_callbacks);
}
cur_icd_term->instance = VK_NULL_HANDLE;
- loader_icd_destroy(inst, cur_icd_term, &(inst->alloc_callbacks));
+ loader_icd_destroy(inst, cur_icd_term, allocation_callbacks);
cur_icd_term = NULL;
struct loader_scanned_icd *scanned_icd_to_remove = &inst->icd_tramp_list.scanned_list[cur_scanned_icd_index];
// Iterate through preloaded ICDs and remove the corresponding driver from that list
VkResult loader_init_generic_list(const struct loader_instance *inst, struct loader_generic_list *list_info, size_t element_size);
VkResult loader_resize_generic_list(const struct loader_instance *inst, struct loader_generic_list *list_info);
VkResult loader_get_next_available_entry(const struct loader_instance *inst, struct loader_used_object_list *list_info,
- uint32_t *free_index);
+ uint32_t *free_index, const VkAllocationCallbacks *pAllocator);
void loader_release_object_from_list(struct loader_used_object_list *list_info, uint32_t index_to_free);
bool has_vk_extension_property_array(const VkExtensionProperties *vk_ext_prop, const uint32_t count,
const VkExtensionProperties *ext_array);
void loader_clear_scanned_icd_list(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list);
VkResult loader_icd_scan(const struct loader_instance *inst, struct loader_icd_tramp_list *icd_tramp_list,
const VkInstanceCreateInfo *pCreateInfo, bool *skipped_portability_drivers);
+void loader_icd_close_objects(struct loader_instance *ptr_inst, struct loader_icd_term *icd_term);
void loader_icd_destroy(struct loader_instance *ptr_inst, struct loader_icd_term *icd_term,
const VkAllocationCallbacks *pAllocator);
VkResult loader_scan_for_layers(struct loader_instance *inst, struct loader_layer_list *instance_layers,
struct loader_dev_ext_props *list;
};
+struct loader_used_object_status {
+ VkBool32 status;
+ VkAllocationCallbacks allocation_callbacks;
+};
+
struct loader_used_object_list {
size_t capacity;
uint32_t padding; // count variable isn't used
- VkBool32 *list;
+ struct loader_used_object_status *list;
+};
+
+struct loader_surface_allocation {
+ VkSurfaceKHR surface;
+ VkAllocationCallbacks allocation_callbacks;
};
struct loader_surface_list {
// Call destroy Instance on each driver in case we successfully called down the chain but failed on
// our way back out of it.
if (icd_term->instance) {
+ loader_icd_close_objects(ptr_instance, icd_term);
icd_term->dispatch.DestroyInstance(icd_term->instance, pAllocator);
}
icd_term->instance = VK_NULL_HANDLE;
}
VkResult allocate_icd_surface_struct(struct loader_instance *instance, size_t base_size, size_t platform_size,
- VkIcdSurface **out_icd_surface) {
+ const VkAllocationCallbacks *pAllocator, VkIcdSurface **out_icd_surface) {
uint32_t next_index = 0;
VkIcdSurface *icd_surface = NULL;
- VkResult res = loader_get_next_available_entry(instance, &instance->surfaces_list, &next_index);
+ VkResult res = loader_get_next_available_entry(instance, &instance->surfaces_list, &next_index, pAllocator);
if (res != VK_SUCCESS) {
goto out;
}
}
}
if (loader_inst->surfaces_list.list &&
- loader_inst->surfaces_list.capacity > icd_surface->surface_index * sizeof(VkBool32)) {
- loader_inst->surfaces_list.list[icd_surface->surface_index] = VK_FALSE;
+ loader_inst->surfaces_list.capacity > icd_surface->surface_index * sizeof(struct loader_used_object_status)) {
+ loader_inst->surfaces_list.list[icd_surface->surface_index].status = VK_FALSE;
+ if (NULL != pAllocator) {
+ loader_inst->surfaces_list.list[icd_surface->surface_index].allocation_callbacks = *pAllocator;
+ }
}
loader_instance_heap_free(loader_inst, icd_surface);
}
}
// Next, if so, proceed with the implementation of this function:
- result =
- allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->win_surf.base), sizeof(icd_surface->win_surf), &icd_surface);
+ result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->win_surf.base), sizeof(icd_surface->win_surf), pAllocator,
+ &icd_surface);
if (VK_SUCCESS != result) {
goto out;
}
// Next, if so, proceed with the implementation of this function:
result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->wayland_surf.base), sizeof(icd_surface->wayland_surf),
- &icd_surface);
+ pAllocator, &icd_surface);
if (VK_SUCCESS != result) {
goto out;
}
}
// Next, if so, proceed with the implementation of this function:
- result =
- allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->xcb_surf.base), sizeof(icd_surface->xcb_surf), &icd_surface);
+ result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->xcb_surf.base), sizeof(icd_surface->xcb_surf), pAllocator,
+ &icd_surface);
if (VK_SUCCESS != result) {
goto out;
}
}
// Next, if so, proceed with the implementation of this function:
- result =
- allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->xlib_surf.base), sizeof(icd_surface->xlib_surf), &icd_surface);
+ result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->xlib_surf.base), sizeof(icd_surface->xlib_surf),
+ pAllocator, &icd_surface);
if (VK_SUCCESS != result) {
goto out;
}
// Next, if so, proceed with the implementation of this function:
result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->directfb_surf.base), sizeof(icd_surface->directfb_surf),
- &icd_surface);
+ pAllocator, &icd_surface);
if (VK_SUCCESS != result) {
goto out;
}
// Next, if so, proceed with the implementation of this function:
result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->headless_surf.base), sizeof(icd_surface->headless_surf),
- &icd_surface);
+ pAllocator, &icd_surface);
if (VK_SUCCESS != result) {
goto out;
}
// Next, if so, proceed with the implementation of this function:
result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->macos_surf.base), sizeof(icd_surface->macos_surf),
- &icd_surface);
+ pAllocator, &icd_surface);
if (VK_SUCCESS != result) {
goto out;
}
}
// Next, if so, proceed with the implementation of this function:
- result =
- allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->ggp_surf.base), sizeof(icd_surface->ggp_surf), &icd_surface);
+ result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->ggp_surf.base), sizeof(icd_surface->ggp_surf), pAllocator,
+ &icd_surface);
if (VK_SUCCESS != result) {
goto out;
}
// Next, if so, proceed with the implementation of this function:
result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->metal_surf.base), sizeof(icd_surface->metal_surf),
- &icd_surface);
+ pAllocator, &icd_surface);
if (VK_SUCCESS != result) {
goto out;
}
// Next, if so, proceed with the implementation of this function:
result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->screen_surf.base), sizeof(icd_surface->screen_surf),
- &icd_surface);
+ pAllocator, &icd_surface);
if (VK_SUCCESS != result) {
goto out;
}
}
// Next, if so, proceed with the implementation of this function:
- result =
- allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->vi_surf.base), sizeof(icd_surface->vi_surf), &icd_surface);
+ result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->vi_surf.base), sizeof(icd_surface->vi_surf), pAllocator,
+ &icd_surface);
if (VK_SUCCESS != result) {
goto out;
}
// Next, if so, proceed with the implementation of this function:
result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->display_surf.base), sizeof(icd_surface->display_surf),
- &icd_surface);
+ pAllocator, &icd_surface);
if (VK_SUCCESS != result) {
goto out;
}
// Next, if so, proceed with the implementation of this function:
result = allocate_icd_surface_struct(loader_inst, sizeof(icd_surface->imagepipe_surf.base), sizeof(icd_surface->imagepipe_surf),
- &icd_surface);
+ pAllocator, &icd_surface);
if (VK_SUCCESS != result) {
goto out;
}