aboutsummaryrefslogtreecommitdiff
path: root/loader
diff options
context:
space:
mode:
Diffstat (limited to 'loader')
-rw-r--r--loader/debug_report.c108
-rw-r--r--loader/debug_report.h21
-rw-r--r--loader/loader.h4
-rw-r--r--loader/trampoline.c111
4 files changed, 208 insertions, 36 deletions
diff --git a/loader/debug_report.c b/loader/debug_report.c
index 7da370ce..3f49aa8c 100644
--- a/loader/debug_report.c
+++ b/loader/debug_report.c
@@ -156,6 +156,114 @@ void util_DestroyDebugReportCallback(struct loader_instance *inst,
}
}
+// This utility (used by vkInstanceCreateInfo(), looks at a pNext chain. It
+// counts any VkDebugReportCallbackCreateInfoEXT structs that it finds. It
+// then allocates array that can hold that many structs, as well as that many
+// VkDebugReportCallbackEXT handles. It then copies each
+// VkDebugReportCallbackCreateInfoEXT, and initializes each handle.
+VkResult
+util_CopyDebugReportCreateInfos(const void *pChain,
+ const VkAllocationCallbacks *pAllocator,
+ uint32_t *num_callbacks,
+ VkDebugReportCallbackCreateInfoEXT **infos,
+ VkDebugReportCallbackEXT **callbacks)
+{
+ uint32_t n = *num_callbacks = 0;
+
+ // NOTE: The loader is not using pAllocator, and so this function doesn't
+ // either.
+
+ const void *pNext = pChain;
+ while (pNext) {
+ // 1st, count the number VkDebugReportCallbackCreateInfoEXT:
+ if (((VkDebugReportCallbackCreateInfoEXT *)pNext)->sType ==
+ VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
+ n++;
+ }
+ pNext = (void *)((VkDebugReportCallbackCreateInfoEXT *)pNext)->pNext;
+ }
+ if (n == 0) {
+ return VK_SUCCESS;
+ }
+
+ // 2nd, allocate memory for each VkDebugReportCallbackCreateInfoEXT:
+ VkDebugReportCallbackCreateInfoEXT *pInfos =
+ *infos = ((VkDebugReportCallbackCreateInfoEXT *)
+ malloc(n * sizeof(VkDebugReportCallbackCreateInfoEXT)));
+ if (!pInfos) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ // 3rd, allocate memory for a unique handle for each callback:
+ VkDebugReportCallbackEXT *pCallbacks =
+ *callbacks = ((VkDebugReportCallbackEXT *)
+ malloc(n * sizeof(VkDebugReportCallbackEXT)));
+ if (!pCallbacks) {
+ free(pInfos);
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ // 4th, copy each VkDebugReportCallbackCreateInfoEXT for use by
+ // vkDestroyInstance, and assign a unique handle to each callback (just
+ // use the address of the copied VkDebugReportCallbackCreateInfoEXT):
+ pNext = pChain;
+ while (pNext) {
+ if (((VkInstanceCreateInfo *)pNext)->sType ==
+ VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
+ memcpy(pInfos, pNext,
+ sizeof(VkDebugReportCallbackCreateInfoEXT));
+ *pCallbacks++ = (VkDebugReportCallbackEXT)pInfos++;
+ }
+ pNext = (void *)((VkInstanceCreateInfo *)pNext)->pNext;
+ }
+
+ *num_callbacks = n;
+ return VK_SUCCESS;
+}
+
+void util_FreeDebugReportCreateInfos(const VkAllocationCallbacks *pAllocator,
+ VkDebugReportCallbackCreateInfoEXT *infos,
+ VkDebugReportCallbackEXT *callbacks)
+{
+ free(infos);
+ free(callbacks);
+}
+
+VkResult
+util_CreateDebugReportCallbacks(struct loader_instance *inst,
+ const VkAllocationCallbacks *pAllocator,
+ uint32_t num_callbacks,
+ VkDebugReportCallbackCreateInfoEXT *infos,
+ VkDebugReportCallbackEXT *callbacks)
+{
+ VkResult rtn;
+ for (uint32_t i = 0 ; i < num_callbacks ; i++) {
+ rtn = util_CreateDebugReportCallback(inst,
+ &infos[i],
+ pAllocator,
+ callbacks[i]);
+ if (rtn != VK_SUCCESS) {
+ for (uint32_t j = 0 ; j < i ; j++) {
+ util_DestroyDebugReportCallback(inst,
+ callbacks[j],
+ pAllocator);
+ }
+ return rtn;
+ }
+ }
+ return rtn;
+}
+
+void util_DestroyDebugReportCallbacks(struct loader_instance *inst,
+ const VkAllocationCallbacks *pAllocator,
+ uint32_t num_callbacks,
+ VkDebugReportCallbackEXT *callbacks)
+{
+ for (uint32_t i = 0 ; i < num_callbacks ; i++) {
+ util_DestroyDebugReportCallback(inst,
+ callbacks[i],
+ pAllocator);
+ }
+}
+
static VKAPI_ATTR void VKAPI_CALL
debug_report_DestroyDebugReportCallback(VkInstance instance,
VkDebugReportCallbackEXT callback,
diff --git a/loader/debug_report.h b/loader/debug_report.h
index baac021e..72a31e53 100644
--- a/loader/debug_report.h
+++ b/loader/debug_report.h
@@ -142,6 +142,27 @@ void util_DestroyDebugReportCallback(struct loader_instance *inst,
VkDebugReportCallbackEXT callback,
const VkAllocationCallbacks *pAllocator);
+VkResult
+util_CopyDebugReportCreateInfos(const void *pChain,
+ const VkAllocationCallbacks *pAllocator,
+ uint32_t *num_callbacks,
+ VkDebugReportCallbackCreateInfoEXT **infos,
+ VkDebugReportCallbackEXT **callbacks);
+void util_FreeDebugReportCreateInfos(const VkAllocationCallbacks *pAllocator,
+ VkDebugReportCallbackCreateInfoEXT *infos,
+ VkDebugReportCallbackEXT *callbacks);
+VkResult
+util_CreateDebugReportCallbacks(struct loader_instance *inst,
+ const VkAllocationCallbacks *pAllocator,
+ uint32_t num_callbacks,
+ VkDebugReportCallbackCreateInfoEXT *infos,
+ VkDebugReportCallbackEXT *callbacks);
+
+void util_DestroyDebugReportCallbacks(struct loader_instance *inst,
+ const VkAllocationCallbacks *pAllocator,
+ uint32_t num_callbacks,
+ VkDebugReportCallbackEXT *callbacks);
+
VkBool32 util_DebugReportMessage(const struct loader_instance *inst,
VkFlags msgFlags,
VkDebugReportObjectTypeEXT objectType,
diff --git a/loader/loader.h b/loader/loader.h
index 244066c0..8a0d4cc8 100644
--- a/loader/loader.h
+++ b/loader/loader.h
@@ -293,7 +293,9 @@ struct loader_instance {
bool debug_report_enabled;
VkLayerDbgFunctionNode *DbgFunctionHead;
- VkDebugReportCallbackCreateInfoEXT debugReportCreateInfo;
+ uint32_t num_tmp_callbacks;
+ VkDebugReportCallbackCreateInfoEXT *tmp_dbg_create_infos;
+ VkDebugReportCallbackEXT *tmp_callbacks;
VkAllocationCallbacks alloc_callbacks;
diff --git a/loader/trampoline.c b/loader/trampoline.c
index 9c9a879c..260fd340 100644
--- a/loader/trampoline.c
+++ b/loader/trampoline.c
@@ -242,8 +242,6 @@ vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
struct loader_instance *ptr_instance = NULL;
VkInstance created_instance = VK_NULL_HANDLE;
VkResult res = VK_ERROR_INITIALIZATION_FAILED;
- VkDebugReportCallbackEXT instance_callback = VK_NULL_HANDLE;
- void *pNext = (void *)pCreateInfo->pNext;
loader_platform_thread_once(&once_init, loader_initialize);
@@ -273,26 +271,38 @@ vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
#endif
/*
- * Look for a debug report create info structure
- * and setup a callback if found.
+ * Look for one or more debug report create info structures
+ * and setup a callback(s) for each one found.
*/
- while (pNext) {
- if (((VkInstanceCreateInfo *)pNext)->sType ==
- VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
- // Use this pNext so that vkCreateInstance has a callback that can
- // be used to log messages. Make a copy for use by
- // vkDestroyInstance as well.
- memcpy(&ptr_instance->debugReportCreateInfo, pNext,
- sizeof(VkDebugReportCallbackCreateInfoEXT));
- instance_callback = (VkDebugReportCallbackEXT)ptr_instance;
- if (util_CreateDebugReportCallback(ptr_instance, pNext, NULL,
- instance_callback)) {
- loader_heap_free(ptr_instance, ptr_instance);
- loader_platform_thread_unlock_mutex(&loader_lock);
- return VK_ERROR_OUT_OF_HOST_MEMORY;
- }
+ ptr_instance->num_tmp_callbacks = 0;
+ ptr_instance->tmp_dbg_create_infos = NULL;
+ ptr_instance->tmp_callbacks = NULL;
+ if (util_CopyDebugReportCreateInfos(pCreateInfo->pNext,
+ pAllocator,
+ &ptr_instance->num_tmp_callbacks,
+ &ptr_instance->tmp_dbg_create_infos,
+ &ptr_instance->tmp_callbacks)) {
+ // One or more were found, but allocation failed. Therefore, clean up
+ // and fail this function:
+ loader_heap_free(ptr_instance, ptr_instance);
+ loader_platform_thread_unlock_mutex(&loader_lock);
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ } else if (ptr_instance->num_tmp_callbacks > 0) {
+ // Setup the temporary callback(s) here to catch early issues:
+ if (util_CreateDebugReportCallbacks(ptr_instance,
+ pAllocator,
+ ptr_instance->num_tmp_callbacks,
+ ptr_instance->tmp_dbg_create_infos,
+ ptr_instance->tmp_callbacks)) {
+ // Failure of setting up one or more of the callback. Therefore,
+ // clean up and fail this function:
+ util_FreeDebugReportCreateInfos(pAllocator,
+ ptr_instance->tmp_dbg_create_infos,
+ ptr_instance->tmp_callbacks);
+ loader_heap_free(ptr_instance, ptr_instance);
+ loader_platform_thread_unlock_mutex(&loader_lock);
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
}
- pNext = (void *)((VkInstanceCreateInfo *)pNext)->pNext;
}
/* Due to implicit layers need to get layer list even if
@@ -312,8 +322,13 @@ vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
pCreateInfo->ppEnabledLayerNames,
&ptr_instance->instance_layer_list);
if (res != VK_SUCCESS) {
- util_DestroyDebugReportCallback(ptr_instance, instance_callback,
- NULL);
+ util_DestroyDebugReportCallbacks(ptr_instance,
+ pAllocator,
+ ptr_instance->num_tmp_callbacks,
+ ptr_instance->tmp_callbacks);
+ util_FreeDebugReportCreateInfos(pAllocator,
+ ptr_instance->tmp_dbg_create_infos,
+ ptr_instance->tmp_callbacks);
loader_heap_free(ptr_instance, ptr_instance);
loader_platform_thread_unlock_mutex(&loader_lock);
return res;
@@ -359,7 +374,13 @@ vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
loader_destroy_generic_list(
ptr_instance,
(struct loader_generic_list *)&ptr_instance->ext_list);
- util_DestroyDebugReportCallback(ptr_instance, instance_callback, NULL);
+ util_DestroyDebugReportCallbacks(ptr_instance,
+ pAllocator,
+ ptr_instance->num_tmp_callbacks,
+ ptr_instance->tmp_callbacks);
+ util_FreeDebugReportCreateInfos(pAllocator,
+ ptr_instance->tmp_dbg_create_infos,
+ ptr_instance->tmp_callbacks);
loader_platform_thread_unlock_mutex(&loader_lock);
loader_heap_free(ptr_instance, ptr_instance);
return res;
@@ -380,7 +401,13 @@ vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
loader_destroy_generic_list(
ptr_instance,
(struct loader_generic_list *)&ptr_instance->ext_list);
- util_DestroyDebugReportCallback(ptr_instance, instance_callback, NULL);
+ util_DestroyDebugReportCallbacks(ptr_instance,
+ pAllocator,
+ ptr_instance->num_tmp_callbacks,
+ ptr_instance->tmp_callbacks);
+ util_FreeDebugReportCreateInfos(pAllocator,
+ ptr_instance->tmp_dbg_create_infos,
+ ptr_instance->tmp_callbacks);
loader_platform_thread_unlock_mutex(&loader_lock);
loader_heap_free(ptr_instance, ptr_instance);
return VK_ERROR_OUT_OF_HOST_MEMORY;
@@ -405,7 +432,13 @@ vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
ptr_instance,
(struct loader_generic_list *)&ptr_instance->ext_list);
loader.instances = ptr_instance->next;
- util_DestroyDebugReportCallback(ptr_instance, instance_callback, NULL);
+ util_DestroyDebugReportCallbacks(ptr_instance,
+ pAllocator,
+ ptr_instance->num_tmp_callbacks,
+ ptr_instance->tmp_callbacks);
+ util_FreeDebugReportCreateInfos(pAllocator,
+ ptr_instance->tmp_dbg_create_infos,
+ ptr_instance->tmp_callbacks);
loader_platform_thread_unlock_mutex(&loader_lock);
loader_heap_free(ptr_instance, ptr_instance->disp);
loader_heap_free(ptr_instance, ptr_instance);
@@ -434,7 +467,10 @@ vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
}
/* Remove temporary debug_report callback */
- util_DestroyDebugReportCallback(ptr_instance, instance_callback, NULL);
+ util_DestroyDebugReportCallbacks(ptr_instance,
+ pAllocator,
+ ptr_instance->num_tmp_callbacks,
+ ptr_instance->tmp_callbacks);
loader_unexpand_inst_layer_names(ptr_instance, saved_layer_count,
saved_layer_names, saved_layer_ptr,
pCreateInfo);
@@ -447,7 +483,6 @@ vkDestroyInstance(VkInstance instance,
const VkAllocationCallbacks *pAllocator) {
const VkLayerInstanceDispatchTable *disp;
struct loader_instance *ptr_instance = NULL;
- VkDebugReportCallbackEXT instance_callback = VK_NULL_HANDLE;
bool callback_setup = false;
disp = loader_get_instance_dispatch(instance);
@@ -456,13 +491,13 @@ vkDestroyInstance(VkInstance instance,
ptr_instance = loader_get_instance(instance);
- if (ptr_instance->debugReportCreateInfo.sType ==
- VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
- // Setup a temporary callback here to catch cleanup issues:
- instance_callback = (VkDebugReportCallbackEXT)ptr_instance;
- if (!util_CreateDebugReportCallback(ptr_instance,
- &ptr_instance->debugReportCreateInfo,
- NULL, instance_callback)) {
+ if (ptr_instance->num_tmp_callbacks > 0) {
+ // Setup the temporary callback(s) here to catch cleanup issues:
+ if (!util_CreateDebugReportCallbacks(ptr_instance,
+ pAllocator,
+ ptr_instance->num_tmp_callbacks,
+ ptr_instance->tmp_dbg_create_infos,
+ ptr_instance->tmp_callbacks)) {
callback_setup = true;
}
}
@@ -473,7 +508,13 @@ vkDestroyInstance(VkInstance instance,
if (ptr_instance->phys_devs)
loader_heap_free(ptr_instance, ptr_instance->phys_devs);
if (callback_setup) {
- util_DestroyDebugReportCallback(ptr_instance, instance_callback, NULL);
+ util_DestroyDebugReportCallbacks(ptr_instance,
+ pAllocator,
+ ptr_instance->num_tmp_callbacks,
+ ptr_instance->tmp_callbacks);
+ util_FreeDebugReportCreateInfos(pAllocator,
+ ptr_instance->tmp_dbg_create_infos,
+ ptr_instance->tmp_callbacks);
}
loader_heap_free(ptr_instance, ptr_instance->disp);
loader_heap_free(ptr_instance, ptr_instance);