VkResult util_CreateDebugUtilsMessenger(struct loader_instance *inst, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT messenger) {
- VkLayerDbgFunctionNode *pNewDbgFuncNode = NULL;
+ VkLayerDbgFunctionNode *new_dbg_function_node = NULL;
- pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
+ new_dbg_function_node = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
pAllocator, inst, sizeof(VkLayerDbgFunctionNode), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
- if (!pNewDbgFuncNode) {
+ if (!new_dbg_function_node) {
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
- pNewDbgFuncNode->is_messenger = true;
- pNewDbgFuncNode->messenger.messenger = messenger;
- pNewDbgFuncNode->messenger.pfnUserCallback = pCreateInfo->pfnUserCallback;
- pNewDbgFuncNode->messenger.messageSeverity = pCreateInfo->messageSeverity;
- pNewDbgFuncNode->messenger.messageType = pCreateInfo->messageType;
- pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
- pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
- inst->DbgFunctionHead = pNewDbgFuncNode;
+ new_dbg_function_node->is_messenger = true;
+ new_dbg_function_node->messenger.messenger = messenger;
+ new_dbg_function_node->messenger.pfnUserCallback = pCreateInfo->pfnUserCallback;
+ new_dbg_function_node->messenger.messageSeverity = pCreateInfo->messageSeverity;
+ new_dbg_function_node->messenger.messageType = pCreateInfo->messageType;
+ new_dbg_function_node->pUserData = pCreateInfo->pUserData;
+ new_dbg_function_node->pNext = inst->instance_only_dbg_function_head;
+ inst->instance_only_dbg_function_head = new_dbg_function_node;
+ inst->current_dbg_function_head = inst->instance_only_dbg_function_head;
return VK_SUCCESS;
}
VkBool32 bail = false;
if (NULL != pCallbackData) {
- VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
+ VkLayerDbgFunctionNode *pTrav = inst->current_dbg_function_head;
VkDebugReportObjectTypeEXT object_type = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;
VkDebugReportFlagsEXT object_flags = 0;
uint64_t object_handle = 0;
void util_DestroyDebugUtilsMessenger(struct loader_instance *inst, VkDebugUtilsMessengerEXT messenger,
const VkAllocationCallbacks *pAllocator) {
- VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
+ VkLayerDbgFunctionNode *pTrav = inst->current_dbg_function_head;
VkLayerDbgFunctionNode *pPrev = pTrav;
while (pTrav) {
if (pTrav->is_messenger && pTrav->messenger.messenger == messenger) {
pPrev->pNext = pTrav->pNext;
- if (inst->DbgFunctionHead == pTrav) inst->DbgFunctionHead = pTrav->pNext;
+ if (inst->current_dbg_function_head == pTrav) inst->current_dbg_function_head = pTrav->pNext;
+ if (inst->instance_only_dbg_function_head == pTrav) inst->instance_only_dbg_function_head = pTrav->pNext;
+ if (inst->standard_dbg_function_head == pTrav) inst->standard_dbg_function_head = pTrav->pNext;
loader_free_with_instance_fallback(pAllocator, inst, pTrav);
break;
}
struct loader_instance *inst = (struct loader_instance *)instance;
VkResult res = VK_SUCCESS;
uint32_t storage_idx;
- VkLayerDbgFunctionNode *pNewDbgFuncNode = NULL;
+ VkLayerDbgFunctionNode *new_dbg_func_node = NULL;
icd_info = (VkDebugUtilsMessengerEXT *)loader_calloc_with_instance_fallback(
pAllocator, inst, inst->total_icd_count * sizeof(VkDebugUtilsMessengerEXT), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
// Setup the debug report callback in the terminator since a layer may want
// to grab the information itself (RenderDoc) and then return back to the
// user callback a sub-set of the messages.
- pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
+ new_dbg_func_node = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
pAllocator, inst, sizeof(VkLayerDbgFunctionNode), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
- if (!pNewDbgFuncNode) {
+ if (!new_dbg_func_node) {
res = VK_ERROR_OUT_OF_HOST_MEMORY;
goto out;
}
- pNewDbgFuncNode->is_messenger = true;
- pNewDbgFuncNode->messenger.pfnUserCallback = pCreateInfo->pfnUserCallback;
- pNewDbgFuncNode->messenger.messageSeverity = pCreateInfo->messageSeverity;
- pNewDbgFuncNode->messenger.messageType = pCreateInfo->messageType;
- pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
- pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
- inst->DbgFunctionHead = pNewDbgFuncNode;
+ new_dbg_func_node->is_messenger = true;
+ new_dbg_func_node->messenger.pfnUserCallback = pCreateInfo->pfnUserCallback;
+ new_dbg_func_node->messenger.messageSeverity = pCreateInfo->messageSeverity;
+ new_dbg_func_node->messenger.messageType = pCreateInfo->messageType;
+ new_dbg_func_node->pUserData = pCreateInfo->pUserData;
+ new_dbg_func_node->pNext = inst->standard_dbg_function_head;
+ inst->standard_dbg_function_head = new_dbg_func_node;
+ inst->current_dbg_function_head = inst->standard_dbg_function_head;
*(VkDebugUtilsMessengerEXT **)pMessenger = icd_info;
- pNewDbgFuncNode->messenger.messenger = *pMessenger;
+ new_dbg_func_node->messenger.messenger = *pMessenger;
out:
}
storage_idx++;
}
- loader_free_with_instance_fallback(pAllocator, inst, pNewDbgFuncNode);
+ loader_free_with_instance_fallback(pAllocator, inst, new_dbg_func_node);
loader_free_with_instance_fallback(pAllocator, inst, icd_info);
}
VkResult util_CreateDebugReportCallback(struct loader_instance *inst, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT callback) {
- VkLayerDbgFunctionNode *pNewDbgFuncNode = NULL;
+ VkLayerDbgFunctionNode *new_dbg_func_node = NULL;
- pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
+ new_dbg_func_node = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
pAllocator, inst, sizeof(VkLayerDbgFunctionNode), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
- if (!pNewDbgFuncNode) {
+ if (!new_dbg_func_node) {
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
- pNewDbgFuncNode->is_messenger = false;
- pNewDbgFuncNode->report.msgCallback = callback;
- pNewDbgFuncNode->report.pfnMsgCallback = pCreateInfo->pfnCallback;
- pNewDbgFuncNode->report.msgFlags = pCreateInfo->flags;
- pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
- pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
- inst->DbgFunctionHead = pNewDbgFuncNode;
+ new_dbg_func_node->is_messenger = false;
+ new_dbg_func_node->report.msgCallback = callback;
+ new_dbg_func_node->report.pfnMsgCallback = pCreateInfo->pfnCallback;
+ new_dbg_func_node->report.msgFlags = pCreateInfo->flags;
+ new_dbg_func_node->pUserData = pCreateInfo->pUserData;
+ new_dbg_func_node->pNext = inst->instance_only_dbg_function_head;
+ inst->instance_only_dbg_function_head = new_dbg_func_node;
+ inst->current_dbg_function_head = inst->instance_only_dbg_function_head;
return VK_SUCCESS;
}
VkBool32 util_DebugReportMessage(const struct loader_instance *inst, VkFlags msgFlags, VkDebugReportObjectTypeEXT objectType,
uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
VkBool32 bail = false;
- VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
+ VkLayerDbgFunctionNode *pTrav = inst->current_dbg_function_head;
VkDebugUtilsMessageSeverityFlagBitsEXT severity;
VkDebugUtilsMessageTypeFlagsEXT types;
VkDebugUtilsMessengerCallbackDataEXT callback_data;
void util_DestroyDebugReportCallback(struct loader_instance *inst, VkDebugReportCallbackEXT callback,
const VkAllocationCallbacks *pAllocator) {
- VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
+ VkLayerDbgFunctionNode *pTrav = inst->current_dbg_function_head;
VkLayerDbgFunctionNode *pPrev = pTrav;
while (pTrav) {
if (!pTrav->is_messenger && pTrav->report.msgCallback == callback) {
pPrev->pNext = pTrav->pNext;
- if (inst->DbgFunctionHead == pTrav) inst->DbgFunctionHead = pTrav->pNext;
+ if (inst->current_dbg_function_head == pTrav) inst->current_dbg_function_head = pTrav->pNext;
+ if (inst->instance_only_dbg_function_head == pTrav) inst->instance_only_dbg_function_head = pTrav->pNext;
+ if (inst->standard_dbg_function_head == pTrav) inst->standard_dbg_function_head = pTrav->pNext;
loader_free_with_instance_fallback(pAllocator, inst, pTrav);
break;
}
struct loader_instance *inst = (struct loader_instance *)instance;
VkResult res = VK_SUCCESS;
uint32_t storage_idx;
- VkLayerDbgFunctionNode *pNewDbgFuncNode = NULL;
+ VkLayerDbgFunctionNode *new_dbg_func_node = NULL;
icd_info = ((VkDebugReportCallbackEXT *)loader_calloc_with_instance_fallback(
pAllocator, inst, inst->total_icd_count * sizeof(VkDebugReportCallbackEXT), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
// Setup the debug report callback in the terminator since a layer may want
// to grab the information itself (RenderDoc) and then return back to the
// user callback a sub-set of the messages.
- pNewDbgFuncNode = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
+ new_dbg_func_node = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
pAllocator, inst, sizeof(VkLayerDbgFunctionNode), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
- if (!pNewDbgFuncNode) {
+ if (!new_dbg_func_node) {
res = VK_ERROR_OUT_OF_HOST_MEMORY;
goto out;
}
- pNewDbgFuncNode->is_messenger = false;
- pNewDbgFuncNode->report.pfnMsgCallback = pCreateInfo->pfnCallback;
- pNewDbgFuncNode->report.msgFlags = pCreateInfo->flags;
- pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
- pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
- inst->DbgFunctionHead = pNewDbgFuncNode;
+ new_dbg_func_node->is_messenger = false;
+ new_dbg_func_node->report.pfnMsgCallback = pCreateInfo->pfnCallback;
+ new_dbg_func_node->report.msgFlags = pCreateInfo->flags;
+ new_dbg_func_node->pUserData = pCreateInfo->pUserData;
+ new_dbg_func_node->pNext = inst->current_dbg_function_head;
+ inst->current_dbg_function_head = new_dbg_func_node;
+ inst->standard_dbg_function_head = inst->current_dbg_function_head;
*(VkDebugReportCallbackEXT **)pCallback = icd_info;
- pNewDbgFuncNode->report.msgCallback = *pCallback;
+ new_dbg_func_node->report.msgCallback = *pCallback;
out:
}
storage_idx++;
}
- loader_free_with_instance_fallback(pAllocator, inst, pNewDbgFuncNode);
+ loader_free_with_instance_fallback(pAllocator, inst, new_dbg_func_node);
loader_free_with_instance_fallback(pAllocator, inst, icd_info);
}
};
void destroy_debug_callbacks_chain(struct loader_instance *inst, const VkAllocationCallbacks *pAllocator) {
- VkLayerDbgFunctionNode *pTrav = inst->DbgFunctionHead;
+ VkLayerDbgFunctionNode *pTrav = inst->current_dbg_function_head;
VkLayerDbgFunctionNode *pNext = NULL;
while (pTrav) {
pNext = pTrav->pNext;
loader_free_with_instance_fallback(pAllocator, inst, pTrav);
pTrav = pNext;
}
- inst->DbgFunctionHead = NULL;
+ inst->current_dbg_function_head = NULL;
}
VkResult add_debug_extensions_to_ext_list(const struct loader_instance *inst, struct loader_extension_list *ext_list) {
return loader_add_to_ext_list(inst, ext_list, sizeof(debug_utils_extension_info) / sizeof(VkExtensionProperties),
- debug_utils_extension_info);
+ debug_utils_extension_info);
}
void check_for_enabled_debug_extensions(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo) {
return res;
}
+// Add the "instance-only" debug functions to the list of active debug functions
+// at the very end. This way it doesn't get replaced by any new messengers
+static void AddInstanceOnlyDebugFunctions(struct loader_instance *ptr_instance) {
+ VkLayerDbgFunctionNode *cur_node = ptr_instance->current_dbg_function_head;
+ if (cur_node == NULL) {
+ ptr_instance->current_dbg_function_head = ptr_instance->instance_only_dbg_function_head;
+ } else {
+ while (cur_node != NULL) {
+ if (cur_node == ptr_instance->instance_only_dbg_function_head) {
+ // Already added
+ break;
+ }
+ // Last item
+ else if (cur_node->pNext == NULL) {
+ cur_node->pNext = ptr_instance->instance_only_dbg_function_head;
+ }
+ cur_node = cur_node->pNext;
+ }
+ }
+}
+
+// Remove the "instance-only" debug functions from the list of active debug functions.
+// It should be added after the last actual debug utils/debug report function.
+static void RemoveInstanceOnlyDebugFunctions(struct loader_instance *ptr_instance) {
+ VkLayerDbgFunctionNode *cur_node = ptr_instance->current_dbg_function_head;
+
+ // Only thing in list is the instance only head
+ if (cur_node == ptr_instance->instance_only_dbg_function_head) {
+ ptr_instance->current_dbg_function_head = NULL;
+ }
+ while (cur_node != NULL) {
+ if (cur_node->pNext == ptr_instance->instance_only_dbg_function_head) {
+ cur_node->pNext = NULL;
+ break;
+ }
+ cur_node = cur_node->pNext;
+ }
+}
+
LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) {
struct loader_instance *ptr_instance = NULL;
loader_instance_heap_free(ptr_instance, ptr_instance);
} else {
// success path, swap out created debug callbacks out so they aren't used until instance destruction
- ptr_instance->InstanceCreationDeletionDebugFunctionHead = ptr_instance->DbgFunctionHead;
- ptr_instance->DbgFunctionHead = NULL;
+ RemoveInstanceOnlyDebugFunctions(ptr_instance);
}
// Only unlock when ptr_instance isn't NULL, as if it is, the above code didn't make it to when loader_lock was locked.
loader_platform_thread_unlock_mutex(&loader_lock);
destroy_debug_callbacks_chain(ptr_instance, pAllocator);
// Swap in the debug callbacks created during instance creation
- ptr_instance->DbgFunctionHead = ptr_instance->InstanceCreationDeletionDebugFunctionHead;
- ptr_instance->InstanceCreationDeletionDebugFunctionHead = NULL;
+ AddInstanceOnlyDebugFunctions(ptr_instance);
disp = loader_get_instance_layer_dispatch(instance);
disp->DestroyInstance(ptr_instance->instance, pAllocator);