aboutsummaryrefslogtreecommitdiff
path: root/layers
diff options
context:
space:
mode:
authorMark Young <marky@lunarg.com>2017-11-09 10:37:04 -0700
committerMike Schuchardt <mikes@lunarg.com>2018-03-09 13:54:31 -0700
commit4df1d6e03c91637d89d70339674deaece0d7641e (patch)
tree274058c2d30cad6b10da6fe6e994da3f22521750 /layers
parent9a6be7a671252c15a6b632568cc3f05631f8ef6f (diff)
downloadusermoji-4df1d6e03c91637d89d70339674deaece0d7641e.tar.xz
Implement initial VK_EXT_debug_utils changes
This affects the loader, scripts, and layers and introduces the changes to support the VK_EXT_debug_utils extension. Change-Id: Ia5336f63e85b00f1e59416c06aacd4ae331fd692
Diffstat (limited to 'layers')
-rw-r--r--layers/core_validation.cpp138
-rw-r--r--layers/object_tracker.h20
-rw-r--r--layers/object_tracker_utils.cpp210
-rw-r--r--layers/parameter_validation.h11
-rw-r--r--layers/parameter_validation_utils.cpp137
-rw-r--r--layers/threading.cpp126
-rw-r--r--layers/threading.h27
-rw-r--r--layers/unique_objects.cpp89
-rw-r--r--layers/unique_objects.h13
-rw-r--r--layers/vk_layer_config.cpp55
-rw-r--r--layers/vk_layer_config.h4
-rw-r--r--layers/vk_layer_logging.h845
-rw-r--r--layers/vk_layer_utils.cpp72
-rw-r--r--layers/vk_layer_utils.h13
14 files changed, 1507 insertions, 253 deletions
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 1f1ec3b5..51223dca 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -144,7 +144,8 @@ static const VkDeviceMemory MEMORY_UNBOUND = VkDeviceMemory(~((uint64_t)(0)) - 1
struct instance_layer_data {
VkInstance instance = VK_NULL_HANDLE;
debug_report_data *report_data = nullptr;
- std::vector<VkDebugReportCallbackEXT> logging_callback;
+ vector<VkDebugReportCallbackEXT> logging_callback;
+ vector<VkDebugUtilsMessengerEXT> logging_messenger;
VkLayerInstanceDispatchTable dispatch_table;
CALL_STATE vkEnumeratePhysicalDevicesState = UNCALLED;
@@ -2032,7 +2033,9 @@ bool outsideRenderPass(const layer_data *dev_data, GLOBAL_CB_NODE *pCB, const ch
}
static void init_core_validation(instance_layer_data *instance_data, const VkAllocationCallbacks *pAllocator) {
- layer_debug_actions(instance_data->report_data, instance_data->logging_callback, pAllocator, "lunarg_core_validation");
+ layer_debug_report_actions(instance_data->report_data, instance_data->logging_callback, pAllocator, "lunarg_core_validation");
+ layer_debug_messenger_actions(instance_data->report_data, instance_data->logging_messenger, pAllocator,
+ "lunarg_core_validation");
}
// For the given ValidationCheck enum, set all relevant instance disabled flags to true
@@ -2070,7 +2073,7 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreat
instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(*pInstance), instance_layer_data_map);
instance_data->instance = *pInstance;
layer_init_instance_dispatch_table(*pInstance, &instance_data->dispatch_table, fpGetInstanceProcAddr);
- instance_data->report_data = debug_report_create_instance(
+ instance_data->report_data = debug_utils_create_instance(
&instance_data->dispatch_table, *pInstance, pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames);
instance_data->api_version = instance_data->extensions.InitFromInstanceCreateInfo(
@@ -2098,13 +2101,18 @@ VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocati
lock_guard_t lock(global_lock);
// Clean up logging callback, if any
+ while (instance_data->logging_messenger.size() > 0) {
+ VkDebugUtilsMessengerEXT messenger = instance_data->logging_messenger.back();
+ layer_destroy_messenger_callback(instance_data->report_data, messenger, pAllocator);
+ instance_data->logging_messenger.pop_back();
+ }
while (instance_data->logging_callback.size() > 0) {
VkDebugReportCallbackEXT callback = instance_data->logging_callback.back();
- layer_destroy_msg_callback(instance_data->report_data, callback, pAllocator);
+ layer_destroy_report_callback(instance_data->report_data, callback, pAllocator);
instance_data->logging_callback.pop_back();
}
- layer_debug_report_destroy_instance(instance_data->report_data);
+ layer_debug_utils_destroy_instance(instance_data->report_data);
FreeLayerDataPtr(key, instance_layer_data_map);
}
@@ -2277,7 +2285,7 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu, const VkDevice
// Save PhysicalDevice handle
device_data->physical_device = gpu;
- device_data->report_data = layer_debug_report_create_device(instance_data->report_data, *pDevice);
+ device_data->report_data = layer_debug_utils_create_device(instance_data->report_data, *pDevice);
// Get physical device limits for this device
instance_data->dispatch_table.GetPhysicalDeviceProperties(gpu, &(device_data->phys_dev_properties.properties));
@@ -2342,7 +2350,7 @@ VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCall
// Queues persist until device is destroyed
dev_data->queueMap.clear();
// Report any memory leaks
- layer_debug_report_destroy_device(device);
+ layer_debug_utils_destroy_device(device);
lock.unlock();
#if DISPATCH_MAP_DEBUG
@@ -11713,6 +11721,107 @@ VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDev
return result;
}
+// VK_EXT_debug_utils commands
+VKAPI_ATTR VkResult VKAPI_CALL SetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsObjectNameInfoEXT *pNameInfo) {
+ layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+ VkResult result = VK_SUCCESS;
+ if (pNameInfo->pObjectName) {
+ dev_data->report_data->debugUtilsObjectNameMap->insert(
+ std::make_pair<uint64_t, std::string>((uint64_t &&) pNameInfo->objectHandle, pNameInfo->pObjectName));
+ } else {
+ dev_data->report_data->debugUtilsObjectNameMap->erase(pNameInfo->objectHandle);
+ }
+ if (nullptr != dev_data->dispatch_table.SetDebugUtilsObjectNameEXT) {
+ result = dev_data->dispatch_table.SetDebugUtilsObjectNameEXT(device, pNameInfo);
+ }
+ return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL SetDebugUtilsObjectTagEXT(VkDevice device, const VkDebugUtilsObjectTagInfoEXT *pTagInfo) {
+ layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+ VkResult result = VK_SUCCESS;
+ if (nullptr != dev_data->dispatch_table.SetDebugUtilsObjectTagEXT) {
+ result = dev_data->dispatch_table.SetDebugUtilsObjectTagEXT(device, pTagInfo);
+ }
+ return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL QueueBeginDebugUtilsLabelEXT(VkQueue queue, const VkDebugUtilsLabelEXT *pLabelInfo) {
+ layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map);
+ BeginQueueDebugUtilsLabel(dev_data->report_data, queue, pLabelInfo);
+ if (nullptr != dev_data->dispatch_table.QueueBeginDebugUtilsLabelEXT) {
+ dev_data->dispatch_table.QueueBeginDebugUtilsLabelEXT(queue, pLabelInfo);
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL QueueEndDebugUtilsLabelEXT(VkQueue queue) {
+ layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map);
+ if (nullptr != dev_data->dispatch_table.QueueEndDebugUtilsLabelEXT) {
+ dev_data->dispatch_table.QueueEndDebugUtilsLabelEXT(queue);
+ }
+ EndQueueDebugUtilsLabel(dev_data->report_data, queue);
+}
+
+VKAPI_ATTR void VKAPI_CALL QueueInsertDebugUtilsLabelEXT(VkQueue queue, const VkDebugUtilsLabelEXT *pLabelInfo) {
+ layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map);
+ InsertQueueDebugUtilsLabel(dev_data->report_data, queue, pLabelInfo);
+ if (nullptr != dev_data->dispatch_table.QueueInsertDebugUtilsLabelEXT) {
+ dev_data->dispatch_table.QueueInsertDebugUtilsLabelEXT(queue, pLabelInfo);
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBeginDebugUtilsLabelEXT(VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT *pLabelInfo) {
+ layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map);
+ BeginCmdDebugUtilsLabel(dev_data->report_data, commandBuffer, pLabelInfo);
+ if (nullptr != dev_data->dispatch_table.CmdBeginDebugUtilsLabelEXT) {
+ dev_data->dispatch_table.CmdBeginDebugUtilsLabelEXT(commandBuffer, pLabelInfo);
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdEndDebugUtilsLabelEXT(VkCommandBuffer commandBuffer) {
+ layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map);
+ if (nullptr != dev_data->dispatch_table.CmdEndDebugUtilsLabelEXT) {
+ dev_data->dispatch_table.CmdEndDebugUtilsLabelEXT(commandBuffer);
+ }
+ EndCmdDebugUtilsLabel(dev_data->report_data, commandBuffer);
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdInsertDebugUtilsLabelEXT(VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT *pLabelInfo) {
+ layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map);
+ InsertCmdDebugUtilsLabel(dev_data->report_data, commandBuffer, pLabelInfo);
+ if (nullptr != dev_data->dispatch_table.CmdInsertDebugUtilsLabelEXT) {
+ dev_data->dispatch_table.CmdInsertDebugUtilsLabelEXT(commandBuffer, pLabelInfo);
+ }
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateDebugUtilsMessengerEXT(VkInstance instance,
+ const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkDebugUtilsMessengerEXT *pMessenger) {
+ instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map);
+ VkResult result = instance_data->dispatch_table.CreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger);
+
+ if (VK_SUCCESS == result) {
+ result = layer_create_messenger_callback(instance_data->report_data, false, pCreateInfo, pAllocator, pMessenger);
+ }
+ return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
+ const VkAllocationCallbacks *pAllocator) {
+ instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map);
+ instance_data->dispatch_table.DestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator);
+ layer_destroy_messenger_callback(instance_data->report_data, messenger, pAllocator);
+}
+
+VKAPI_ATTR void VKAPI_CALL SubmitDebugUtilsMessageEXT(VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
+ VkDebugUtilsMessageTypeFlagsEXT messageTypes,
+ const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) {
+ instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map);
+ instance_data->dispatch_table.SubmitDebugUtilsMessageEXT(instance, messageSeverity, messageTypes, pCallbackData);
+}
+
+// VK_EXT_debug_report commands
VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance,
const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
@@ -11721,7 +11830,7 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance,
VkResult res = instance_data->dispatch_table.CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
if (VK_SUCCESS == res) {
lock_guard_t lock(global_lock);
- res = layer_create_msg_callback(instance_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback);
+ res = layer_create_report_callback(instance_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback);
}
return res;
}
@@ -11731,7 +11840,7 @@ VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance, Vk
instance_layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map);
instance_data->dispatch_table.DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
lock_guard_t lock(global_lock);
- layer_destroy_msg_callback(instance_data->report_data, msgCallback, pAllocator);
+ layer_destroy_report_callback(instance_data->report_data, msgCallback, pAllocator);
}
VKAPI_ATTR void VKAPI_CALL DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
@@ -12388,6 +12497,17 @@ static const std::unordered_map<std::string, void *> name_to_funcptr_map = {
{"vkMergeValidationCachesEXT", (void *)MergeValidationCachesEXT},
{"vkCmdSetDiscardRectangleEXT", (void *)CmdSetDiscardRectangleEXT},
{"vkCmdSetSampleLocationsEXT", (void *)CmdSetSampleLocationsEXT},
+ {"vkSetDebugUtilsObjectNameEXT", (void *)SetDebugUtilsObjectNameEXT},
+ {"vkSetDebugUtilsObjectTagEXT", (void *)SetDebugUtilsObjectTagEXT},
+ {"vkQueueBeginDebugUtilsLabelEXT", (void *)QueueBeginDebugUtilsLabelEXT},
+ {"vkQueueEndDebugUtilsLabelEXT", (void *)QueueEndDebugUtilsLabelEXT},
+ {"vkQueueInsertDebugUtilsLabelEXT", (void *)QueueInsertDebugUtilsLabelEXT},
+ {"vkCmdBeginDebugUtilsLabelEXT", (void *)CmdBeginDebugUtilsLabelEXT},
+ {"vkCmdEndDebugUtilsLabelEXT", (void *)CmdEndDebugUtilsLabelEXT},
+ {"vkCmdInsertDebugUtilsLabelEXT", (void *)CmdInsertDebugUtilsLabelEXT},
+ {"vkCreateDebugUtilsMessengerEXT", (void *)CreateDebugUtilsMessengerEXT},
+ {"vkDestroyDebugUtilsMessengerEXT", (void *)DestroyDebugUtilsMessengerEXT},
+ {"vkSubmitDebugUtilsMessageEXT", (void *)SubmitDebugUtilsMessageEXT},
};
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName) {
diff --git a/layers/object_tracker.h b/layers/object_tracker.h
index d9fdf8b4..5a6f545d 100644
--- a/layers/object_tracker.h
+++ b/layers/object_tracker.h
@@ -35,7 +35,6 @@
#include "vk_layer_table.h"
#include "vk_object_types.h"
#include "vulkan/vk_layer.h"
-#include "vk_object_types.h"
#include "vk_enum_string_helper.h"
#include "vk_layer_extension_utils.h"
#include "vk_layer_table.h"
@@ -96,11 +95,15 @@ struct layer_data {
debug_report_data *report_data;
std::vector<VkDebugReportCallbackEXT> logging_callback;
+ std::vector<VkDebugUtilsMessengerEXT> logging_messenger;
// The following are for keeping track of the temporary callbacks that can
// be used in vkCreateInstance and vkDestroyInstance:
- uint32_t num_tmp_callbacks;
- VkDebugReportCallbackCreateInfoEXT *tmp_dbg_create_infos;
- VkDebugReportCallbackEXT *tmp_callbacks;
+ uint32_t num_tmp_report_callbacks;
+ VkDebugReportCallbackCreateInfoEXT *tmp_report_create_infos;
+ VkDebugReportCallbackEXT *tmp_report_callbacks;
+ uint32_t num_tmp_debug_messengers;
+ VkDebugUtilsMessengerCreateInfoEXT *tmp_messenger_create_infos;
+ VkDebugUtilsMessengerEXT *tmp_debug_messengers;
std::vector<VkQueueFamilyProperties> queue_family_properties;
@@ -119,9 +122,12 @@ struct layer_data {
num_objects{},
num_total_objects(0),
report_data(nullptr),
- num_tmp_callbacks(0),
- tmp_dbg_create_infos(nullptr),
- tmp_callbacks(nullptr),
+ num_tmp_report_callbacks(0),
+ tmp_report_create_infos(nullptr),
+ tmp_report_callbacks(nullptr),
+ num_tmp_debug_messengers(0),
+ tmp_messenger_create_infos(nullptr),
+ tmp_debug_messengers(nullptr),
object_map{},
dispatch_table{} {
object_map.resize(kVulkanObjectTypeMax + 1);
diff --git a/layers/object_tracker_utils.cpp b/layers/object_tracker_utils.cpp
index c9573dd3..177c1455 100644
--- a/layers/object_tracker_utils.cpp
+++ b/layers/object_tracker_utils.cpp
@@ -32,7 +32,8 @@ uint64_t object_track_index = 0;
uint32_t loader_layer_if_version = CURRENT_LOADER_LAYER_INTERFACE_VERSION;
void InitObjectTracker(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
- layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_object_tracker");
+ layer_debug_report_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_object_tracker");
+ layer_debug_messenger_actions(my_data->report_data, my_data->logging_messenger, pAllocator, "lunarg_object_tracker");
}
// Add new queue to head of global queue list
@@ -328,12 +329,13 @@ VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocati
layer_data *instance_data = GetLayerDataPtr(key, layer_data_map);
// Enable the temporary callback(s) here to catch cleanup issues:
- bool callback_setup = false;
- if (instance_data->num_tmp_callbacks > 0) {
- if (!layer_enable_tmp_callbacks(instance_data->report_data, instance_data->num_tmp_callbacks,
- instance_data->tmp_dbg_create_infos, instance_data->tmp_callbacks)) {
- callback_setup = true;
- }
+ if (instance_data->num_tmp_debug_messengers > 0) {
+ layer_enable_tmp_debug_messengers(instance_data->report_data, instance_data->num_tmp_debug_messengers,
+ instance_data->tmp_messenger_create_infos, instance_data->tmp_debug_messengers);
+ }
+ if (instance_data->num_tmp_report_callbacks > 0) {
+ layer_enable_tmp_report_callbacks(instance_data->report_data, instance_data->num_tmp_report_callbacks,
+ instance_data->tmp_report_create_infos, instance_data->tmp_report_callbacks);
}
// TODO: The instance handle can not be validated here. The loader will likely have to validate it.
@@ -375,22 +377,32 @@ VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocati
pInstanceTable->DestroyInstance(instance, pAllocator);
// Disable and cleanup the temporary callback(s):
- if (callback_setup) {
- layer_disable_tmp_callbacks(instance_data->report_data, instance_data->num_tmp_callbacks, instance_data->tmp_callbacks);
+ layer_disable_tmp_debug_messengers(instance_data->report_data, instance_data->num_tmp_debug_messengers,
+ instance_data->tmp_debug_messengers);
+ layer_disable_tmp_report_callbacks(instance_data->report_data, instance_data->num_tmp_report_callbacks,
+ instance_data->tmp_report_callbacks);
+ if (instance_data->num_tmp_debug_messengers > 0) {
+ layer_free_tmp_debug_messengers(instance_data->tmp_messenger_create_infos, instance_data->tmp_debug_messengers);
+ instance_data->num_tmp_debug_messengers = 0;
}
- if (instance_data->num_tmp_callbacks > 0) {
- layer_free_tmp_callbacks(instance_data->tmp_dbg_create_infos, instance_data->tmp_callbacks);
- instance_data->num_tmp_callbacks = 0;
+ if (instance_data->num_tmp_report_callbacks > 0) {
+ layer_free_tmp_report_callbacks(instance_data->tmp_report_create_infos, instance_data->tmp_report_callbacks);
+ instance_data->num_tmp_report_callbacks = 0;
}
// Clean up logging callback, if any
+ while (instance_data->logging_messenger.size() > 0) {
+ VkDebugUtilsMessengerEXT messenger = instance_data->logging_messenger.back();
+ layer_destroy_messenger_callback(instance_data->report_data, messenger, pAllocator);
+ instance_data->logging_messenger.pop_back();
+ }
while (instance_data->logging_callback.size() > 0) {
VkDebugReportCallbackEXT callback = instance_data->logging_callback.back();
- layer_destroy_msg_callback(instance_data->report_data, callback, pAllocator);
+ layer_destroy_report_callback(instance_data->report_data, callback, pAllocator);
instance_data->logging_callback.pop_back();
}
- layer_debug_report_destroy_instance(instance_data->report_data);
+ layer_debug_utils_destroy_instance(instance_data->report_data);
FreeLayerDataPtr(key, layer_data_map);
lock.unlock();
@@ -572,7 +584,7 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance,
VkResult result = pInstanceTable->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);
if (VK_SUCCESS == result) {
layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
- result = layer_create_msg_callback(instance_data->report_data, false, pCreateInfo, pAllocator, pCallback);
+ result = layer_create_report_callback(instance_data->report_data, false, pCreateInfo, pAllocator, pCallback);
CreateObject(instance, *pCallback, kVulkanObjectTypeDebugReportCallbackEXT, pAllocator);
}
return result;
@@ -583,7 +595,7 @@ VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance, Vk
VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ot_instance_table_map, instance);
pInstanceTable->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
- layer_destroy_msg_callback(instance_data->report_data, msgCallback, pAllocator);
+ layer_destroy_report_callback(instance_data->report_data, msgCallback, pAllocator);
DestroyObject(instance, msgCallback, kVulkanObjectTypeDebugReportCallbackEXT, pAllocator, VALIDATION_ERROR_242009b4,
VALIDATION_ERROR_242009b6);
}
@@ -595,7 +607,159 @@ VKAPI_ATTR void VKAPI_CALL DebugReportMessageEXT(VkInstance instance, VkDebugRep
pInstanceTable->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
}
-static const VkExtensionProperties instance_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}};
+// VK_EXT_debug_utils commands
+VKAPI_ATTR VkResult VKAPI_CALL SetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsObjectNameInfoEXT *pNameInfo) {
+ bool skip = VK_FALSE;
+ std::unique_lock<std::mutex> lock(global_lock);
+ skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
+ lock.unlock();
+ if (skip) {
+ return VK_ERROR_VALIDATION_FAILED_EXT;
+ }
+ layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+ if (pNameInfo->pObjectName) {
+ dev_data->report_data->debugUtilsObjectNameMap->insert(
+ std::make_pair<uint64_t, std::string>((uint64_t &&) pNameInfo->objectHandle, pNameInfo->pObjectName));
+ } else {
+ dev_data->report_data->debugUtilsObjectNameMap->erase(pNameInfo->objectHandle);
+ }
+ VkResult result = dev_data->dispatch_table.SetDebugUtilsObjectNameEXT(device, pNameInfo);
+ return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL SetDebugUtilsObjectTagEXT(VkDevice device, const VkDebugUtilsObjectTagInfoEXT *pTagInfo) {
+ bool skip = VK_FALSE;
+ std::unique_lock<std::mutex> lock(global_lock);
+ skip |= ValidateObject(device, device, kVulkanObjectTypeDevice, false, VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
+ lock.unlock();
+ if (skip) {
+ return VK_ERROR_VALIDATION_FAILED_EXT;
+ }
+ layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+ VkResult result = dev_data->dispatch_table.SetDebugUtilsObjectTagEXT(device, pTagInfo);
+ return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL QueueBeginDebugUtilsLabelEXT(VkQueue queue, const VkDebugUtilsLabelEXT *pLabelInfo) {
+ bool skip = VK_FALSE;
+ std::unique_lock<std::mutex> lock(global_lock);
+ skip |= ValidateObject(queue, queue, kVulkanObjectTypeQueue, false, VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
+ lock.unlock();
+ layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map);
+ if (!skip) {
+ BeginQueueDebugUtilsLabel(dev_data->report_data, queue, pLabelInfo);
+ if (dev_data->dispatch_table.QueueBeginDebugUtilsLabelEXT) {
+ dev_data->dispatch_table.QueueBeginDebugUtilsLabelEXT(queue, pLabelInfo);
+ }
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL QueueEndDebugUtilsLabelEXT(VkQueue queue) {
+ bool skip = VK_FALSE;
+ std::unique_lock<std::mutex> lock(global_lock);
+ skip |= ValidateObject(queue, queue, kVulkanObjectTypeQueue, false, VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
+ lock.unlock();
+ layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map);
+ if (!skip) {
+ if (dev_data->dispatch_table.QueueEndDebugUtilsLabelEXT) {
+ dev_data->dispatch_table.QueueEndDebugUtilsLabelEXT(queue);
+ }
+ EndQueueDebugUtilsLabel(dev_data->report_data, queue);
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL QueueInsertDebugUtilsLabelEXT(VkQueue queue, const VkDebugUtilsLabelEXT *pLabelInfo) {
+ bool skip = VK_FALSE;
+ std::unique_lock<std::mutex> lock(global_lock);
+ skip |= ValidateObject(queue, queue, kVulkanObjectTypeQueue, false, VALIDATION_ERROR_UNDEFINED, VALIDATION_ERROR_UNDEFINED);
+ lock.unlock();
+ layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(queue), layer_data_map);
+ if (!skip) {
+ InsertQueueDebugUtilsLabel(dev_data->report_data, queue, pLabelInfo);
+ if (dev_data->dispatch_table.QueueInsertDebugUtilsLabelEXT) {
+ dev_data->dispatch_table.QueueInsertDebugUtilsLabelEXT(queue, pLabelInfo);
+ }
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdBeginDebugUtilsLabelEXT(VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT *pLabelInfo) {
+ bool skip = VK_FALSE;
+ std::unique_lock<std::mutex> lock(global_lock);
+ skip |= ValidateObject(commandBuffer, commandBuffer, kVulkanObjectTypeCommandBuffer, false, VALIDATION_ERROR_UNDEFINED,
+ VALIDATION_ERROR_UNDEFINED);
+ lock.unlock();
+ layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map);
+ if (!skip) {
+ BeginCmdDebugUtilsLabel(dev_data->report_data, commandBuffer, pLabelInfo);
+ if (dev_data->dispatch_table.CmdBeginDebugUtilsLabelEXT) {
+ dev_data->dispatch_table.CmdBeginDebugUtilsLabelEXT(commandBuffer, pLabelInfo);
+ }
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdEndDebugUtilsLabelEXT(VkCommandBuffer commandBuffer) {
+ bool skip = VK_FALSE;
+ std::unique_lock<std::mutex> lock(global_lock);
+ skip |= ValidateObject(commandBuffer, commandBuffer, kVulkanObjectTypeCommandBuffer, false, VALIDATION_ERROR_UNDEFINED,
+ VALIDATION_ERROR_UNDEFINED);
+ lock.unlock();
+ layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map);
+ if (!skip) {
+ if (dev_data->dispatch_table.CmdEndDebugUtilsLabelEXT) {
+ dev_data->dispatch_table.CmdEndDebugUtilsLabelEXT(commandBuffer);
+ }
+ EndCmdDebugUtilsLabel(dev_data->report_data, commandBuffer);
+ }
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdInsertDebugUtilsLabelEXT(VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT *pLabelInfo) {
+ bool skip = VK_FALSE;
+ std::unique_lock<std::mutex> lock(global_lock);
+ skip |= ValidateObject(commandBuffer, commandBuffer, kVulkanObjectTypeCommandBuffer, false, VALIDATION_ERROR_UNDEFINED,
+ VALIDATION_ERROR_UNDEFINED);
+ lock.unlock();
+ layer_data *dev_data = GetLayerDataPtr(get_dispatch_key(commandBuffer), layer_data_map);
+ if (!skip) {
+ InsertCmdDebugUtilsLabel(dev_data->report_data, commandBuffer, pLabelInfo);
+ if (dev_data->dispatch_table.CmdInsertDebugUtilsLabelEXT) {
+ dev_data->dispatch_table.CmdInsertDebugUtilsLabelEXT(commandBuffer, pLabelInfo);
+ }
+ }
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateDebugUtilsMessengerEXT(VkInstance instance,
+ const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkDebugUtilsMessengerEXT *pMessenger) {
+ VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ot_instance_table_map, instance);
+ VkResult result = pInstanceTable->CreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger);
+ if (VK_SUCCESS == result) {
+ layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
+ result = layer_create_messenger_callback(instance_data->report_data, false, pCreateInfo, pAllocator, pMessenger);
+ CreateObject(instance, *pMessenger, kVulkanObjectTypeDebugUtilsMessengerEXT, pAllocator);
+ }
+ return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
+ const VkAllocationCallbacks *pAllocator) {
+ VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ot_instance_table_map, instance);
+ pInstanceTable->DestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator);
+ layer_data *instance_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
+ layer_destroy_messenger_callback(instance_data->report_data, messenger, pAllocator);
+ DestroyObject(instance, messenger, kVulkanObjectTypeDebugUtilsMessengerEXT, pAllocator, VALIDATION_ERROR_UNDEFINED,
+ VALIDATION_ERROR_UNDEFINED);
+}
+
+VKAPI_ATTR void VKAPI_CALL SubmitDebugUtilsMessageEXT(VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
+ VkDebugUtilsMessageTypeFlagsEXT messageTypes,
+ const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) {
+ VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(ot_instance_table_map, instance);
+ pInstanceTable->SubmitDebugUtilsMessageEXT(instance, messageSeverity, messageTypes, pCallbackData);
+}
+
+static const VkExtensionProperties instance_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION},
+ {VK_EXT_DEBUG_UTILS_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_SPEC_VERSION}};
static const VkLayerProperties globalLayerProps = {"VK_LAYER_LUNARG_object_tracker",
VK_LAYER_API_VERSION, // specVersion
@@ -656,7 +820,7 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice physicalDevice, con
}
layer_data *device_data = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
- device_data->report_data = layer_debug_report_create_device(phy_dev_data->report_data, *pDevice);
+ device_data->report_data = layer_debug_utils_create_device(phy_dev_data->report_data, *pDevice);
layer_init_device_dispatch_table(*pDevice, &device_data->dispatch_table, fpGetDeviceProcAddr);
// Add link back to physDev
@@ -779,11 +943,13 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreat
// Look for one or more debug report create info structures, and copy the
// callback(s) for each one found (for use by vkDestroyInstance)
- layer_copy_tmp_callbacks(pCreateInfo->pNext, &instance_data->num_tmp_callbacks, &instance_data->tmp_dbg_create_infos,
- &instance_data->tmp_callbacks);
+ layer_copy_tmp_debug_messengers(pCreateInfo->pNext, &instance_data->num_tmp_debug_messengers,
+ &instance_data->tmp_messenger_create_infos, &instance_data->tmp_debug_messengers);
+ layer_copy_tmp_report_callbacks(pCreateInfo->pNext, &instance_data->num_tmp_report_callbacks,
+ &instance_data->tmp_report_create_infos, &instance_data->tmp_report_callbacks);
- instance_data->report_data = debug_report_create_instance(pInstanceTable, *pInstance, pCreateInfo->enabledExtensionCount,
- pCreateInfo->ppEnabledExtensionNames);
+ instance_data->report_data = debug_utils_create_instance(pInstanceTable, *pInstance, pCreateInfo->enabledExtensionCount,
+ pCreateInfo->ppEnabledExtensionNames);
InitObjectTracker(instance_data, pAllocator);
diff --git a/layers/parameter_validation.h b/layers/parameter_validation.h
index 49ff279a..d03152c1 100644
--- a/layers/parameter_validation.h
+++ b/layers/parameter_validation.h
@@ -61,12 +61,17 @@ struct instance_layer_data {
debug_report_data *report_data = nullptr;
std::vector<VkDebugReportCallbackEXT> logging_callback;
+ std::vector<VkDebugUtilsMessengerEXT> logging_messenger;
// The following are for keeping track of the temporary callbacks that can
// be used in vkCreateInstance and vkDestroyInstance:
- uint32_t num_tmp_callbacks = 0;
- VkDebugReportCallbackCreateInfoEXT *tmp_dbg_create_infos = nullptr;
- VkDebugReportCallbackEXT *tmp_callbacks = nullptr;
+ uint32_t num_tmp_report_callbacks = 0;
+ VkDebugReportCallbackCreateInfoEXT *tmp_report_create_infos = nullptr;
+ VkDebugReportCallbackEXT *tmp_report_callbacks = nullptr;
+ uint32_t num_tmp_debug_messengers = 0;
+ VkDebugUtilsMessengerCreateInfoEXT *tmp_messenger_create_infos = nullptr;
+ VkDebugUtilsMessengerEXT *tmp_debug_messengers = nullptr;
+
InstanceExtensions extensions = {};
VkLayerInstanceDispatchTable dispatch_table = {};
uint32_t api_version;
diff --git a/layers/parameter_validation_utils.cpp b/layers/parameter_validation_utils.cpp
index b818159c..3dfd27ce 100644
--- a/layers/parameter_validation_utils.cpp
+++ b/layers/parameter_validation_utils.cpp
@@ -79,6 +79,12 @@ extern bool parameter_validation_vkCreateDebugReportCallbackEXT(VkInstance insta
VkDebugReportCallbackEXT *pMsgCallback);
extern bool parameter_validation_vkDestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback,
const VkAllocationCallbacks *pAllocator);
+extern bool parameter_validation_vkCreateDebugUtilsMessengerEXT(VkInstance instance,
+ const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkDebugUtilsMessengerEXT *pMessenger);
+extern bool parameter_validation_vkDestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
+ const VkAllocationCallbacks *pAllocator);
extern bool parameter_validation_vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool);
extern bool parameter_validation_vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
@@ -96,10 +102,14 @@ std::unordered_map<void *, instance_layer_data *> instance_layer_data_map;
void InitializeManualParameterValidationFunctionPointers(void);
static void init_parameter_validation(instance_layer_data *instance_data, const VkAllocationCallbacks *pAllocator) {
- layer_debug_actions(instance_data->report_data, instance_data->logging_callback, pAllocator, "lunarg_parameter_validation");
+ layer_debug_report_actions(instance_data->report_data, instance_data->logging_callback, pAllocator,
+ "lunarg_parameter_validation");
+ layer_debug_messenger_actions(instance_data->report_data, instance_data->logging_messenger, pAllocator,
+ "lunarg_parameter_validation");
}
-static const VkExtensionProperties instance_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}};
+static const VkExtensionProperties instance_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION},
+ {VK_EXT_DEBUG_UTILS_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_SPEC_VERSION}};
static const VkLayerProperties global_layer = {
"VK_LAYER_LUNARG_parameter_validation",
@@ -216,21 +226,39 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo *pCre
layer_init_instance_dispatch_table(*pInstance, &my_instance_data->dispatch_table, fpGetInstanceProcAddr);
my_instance_data->instance = *pInstance;
my_instance_data->report_data =
- debug_report_create_instance(&my_instance_data->dispatch_table, *pInstance, pCreateInfo->enabledExtensionCount,
- pCreateInfo->ppEnabledExtensionNames);
+ debug_utils_create_instance(&my_instance_data->dispatch_table, *pInstance, pCreateInfo->enabledExtensionCount,
+ pCreateInfo->ppEnabledExtensionNames);
// Look for one or more debug report create info structures
// and setup a callback(s) for each one found.
- if (!layer_copy_tmp_callbacks(pCreateInfo->pNext, &my_instance_data->num_tmp_callbacks,
- &my_instance_data->tmp_dbg_create_infos, &my_instance_data->tmp_callbacks)) {
- if (my_instance_data->num_tmp_callbacks > 0) {
+ if (!layer_copy_tmp_debug_messengers(pCreateInfo->pNext, &my_instance_data->num_tmp_debug_messengers,
+ &my_instance_data->tmp_messenger_create_infos,
+ &my_instance_data->tmp_debug_messengers)) {
+ if (my_instance_data->num_tmp_debug_messengers > 0) {
+ // Setup the temporary callback(s) here to catch early issues:
+ if (layer_enable_tmp_debug_messengers(my_instance_data->report_data, my_instance_data->num_tmp_debug_messengers,
+ my_instance_data->tmp_messenger_create_infos,
+ my_instance_data->tmp_debug_messengers)) {
+ // Failure of setting up one or more of the callback.
+ // Therefore, clean up and don't use those callbacks:
+ layer_free_tmp_debug_messengers(my_instance_data->tmp_messenger_create_infos,
+ my_instance_data->tmp_debug_messengers);
+ my_instance_data->num_tmp_debug_messengers = 0;
+ }
+ }
+ }
+ if (!layer_copy_tmp_report_callbacks(pCreateInfo->pNext, &my_instance_data->num_tmp_report_callbacks,
+ &my_instance_data->tmp_report_create_infos, &my_instance_data->tmp_report_callbacks)) {
+ if (my_instance_data->num_tmp_report_callbacks > 0) {
// Setup the temporary callback(s) here to catch early issues:
- if (layer_enable_tmp_callbacks(my_instance_data->report_data, my_instance_data->num_tmp_callbacks,
- my_instance_data->tmp_dbg_create_infos, my_instance_data->tmp_callbacks)) {
+ if (layer_enable_tmp_report_callbacks(my_instance_data->report_data, my_instance_data->num_tmp_report_callbacks,
+ my_instance_data->tmp_report_create_infos,
+ my_instance_data->tmp_report_callbacks)) {
// Failure of setting up one or more of the callback.
// Therefore, clean up and don't use those callbacks:
- layer_free_tmp_callbacks(my_instance_data->tmp_dbg_create_infos, my_instance_data->tmp_callbacks);
- my_instance_data->num_tmp_callbacks = 0;
+ layer_free_tmp_report_callbacks(my_instance_data->tmp_report_create_infos,
+ my_instance_data->tmp_report_callbacks);
+ my_instance_data->num_tmp_report_callbacks = 0;
}
}
}
@@ -269,9 +297,13 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo *pCre
}
// Disable the tmp callbacks:
- if (my_instance_data->num_tmp_callbacks > 0) {
- layer_disable_tmp_callbacks(my_instance_data->report_data, my_instance_data->num_tmp_callbacks,
- my_instance_data->tmp_callbacks);
+ if (my_instance_data->num_tmp_debug_messengers > 0) {
+ layer_disable_tmp_debug_messengers(my_instance_data->report_data, my_instance_data->num_tmp_debug_messengers,
+ my_instance_data->tmp_debug_messengers);
+ }
+ if (my_instance_data->num_tmp_report_callbacks > 0) {
+ layer_disable_tmp_report_callbacks(my_instance_data->report_data, my_instance_data->num_tmp_report_callbacks,
+ my_instance_data->tmp_report_callbacks);
}
}
@@ -286,9 +318,15 @@ VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAlloca
// Enable the temporary callback(s) here to catch vkDestroyInstance issues:
bool callback_setup = false;
- if (instance_data->num_tmp_callbacks > 0) {
- if (!layer_enable_tmp_callbacks(instance_data->report_data, instance_data->num_tmp_callbacks,
- instance_data->tmp_dbg_create_infos, instance_data->tmp_callbacks)) {
+ if (instance_data->num_tmp_debug_messengers > 0) {
+ if (!layer_enable_tmp_debug_messengers(instance_data->report_data, instance_data->num_tmp_debug_messengers,
+ instance_data->tmp_messenger_create_infos, instance_data->tmp_debug_messengers)) {
+ callback_setup = true;
+ }
+ }
+ if (instance_data->num_tmp_report_callbacks > 0) {
+ if (!layer_enable_tmp_report_callbacks(instance_data->report_data, instance_data->num_tmp_report_callbacks,
+ instance_data->tmp_report_create_infos, instance_data->tmp_report_callbacks)) {
callback_setup = true;
}
}
@@ -297,24 +335,36 @@ VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAlloca
// Disable and cleanup the temporary callback(s):
if (callback_setup) {
- layer_disable_tmp_callbacks(instance_data->report_data, instance_data->num_tmp_callbacks, instance_data->tmp_callbacks);
+ layer_disable_tmp_debug_messengers(instance_data->report_data, instance_data->num_tmp_debug_messengers,
+ instance_data->tmp_debug_messengers);
+ layer_disable_tmp_report_callbacks(instance_data->report_data, instance_data->num_tmp_report_callbacks,
+ instance_data->tmp_report_callbacks);
}
- if (instance_data->num_tmp_callbacks > 0) {
- layer_free_tmp_callbacks(instance_data->tmp_dbg_create_infos, instance_data->tmp_callbacks);
- instance_data->num_tmp_callbacks = 0;
+ if (instance_data->num_tmp_debug_messengers > 0) {
+ layer_free_tmp_debug_messengers(instance_data->tmp_messenger_create_infos, instance_data->tmp_debug_messengers);
+ instance_data->num_tmp_debug_messengers = 0;
+ }
+ if (instance_data->num_tmp_report_callbacks > 0) {
+ layer_free_tmp_report_callbacks(instance_data->tmp_report_create_infos, instance_data->tmp_report_callbacks);
+ instance_data->num_tmp_report_callbacks = 0;
}
if (!skip) {
instance_data->dispatch_table.DestroyInstance(instance, pAllocator);
// Clean up logging callback, if any
+ while (instance_data->logging_messenger.size() > 0) {
+ VkDebugUtilsMessengerEXT messenger = instance_data->logging_messenger.back();
+ layer_destroy_messenger_callback(instance_data->report_data, messenger, pAllocator);
+ instance_data->logging_messenger.pop_back();
+ }
while (instance_data->logging_callback.size() > 0) {
VkDebugReportCallbackEXT callback = instance_data->logging_callback.back();
- layer_destroy_msg_callback(instance_data->report_data, callback, pAllocator);
+ layer_destroy_report_callback(instance_data->report_data, callback, pAllocator);
instance_data->logging_callback.pop_back();
}
- layer_debug_report_destroy_instance(instance_data->report_data);
+ layer_debug_utils_destroy_instance(instance_data->report_data);
}
FreeLayerDataPtr(key, instance_layer_data_map);
@@ -330,7 +380,11 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(VkInstance instanc
auto instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map);
VkResult result = instance_data->dispatch_table.CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
if (result == VK_SUCCESS) {
- result = layer_create_msg_callback(instance_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback);
+ result = layer_create_report_callback(instance_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback);
+ // If something happened during this call, clean up the message callback that was created earlier in the lower levels
+ if (VK_SUCCESS != result) {
+ instance_data->dispatch_table.DestroyDebugReportCallbackEXT(instance, *pMsgCallback, pAllocator);
+ }
}
return result;
}
@@ -341,7 +395,36 @@ VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance,
if (!skip) {
auto instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map);
instance_data->dispatch_table.DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
- layer_destroy_msg_callback(instance_data->report_data, msgCallback, pAllocator);
+ layer_destroy_report_callback(instance_data->report_data, msgCallback, pAllocator);
+ }
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugUtilsMessengerEXT(VkInstance instance,
+ const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkDebugUtilsMessengerEXT *pMessenger) {
+ bool skip = parameter_validation_vkCreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger);
+ if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;
+
+ auto instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map);
+ VkResult result = instance_data->dispatch_table.CreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger);
+ if (VK_SUCCESS == result) {
+ result = layer_create_messenger_callback(instance_data->report_data, false, pCreateInfo, pAllocator, pMessenger);
+ // If something happened during this call, clean up the message callback that was created earlier in the lower levels
+ if (VK_SUCCESS != result) {
+ instance_data->dispatch_table.DestroyDebugUtilsMessengerEXT(instance, *pMessenger, pAllocator);
+ }
+ }
+ return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
+ const VkAllocationCallbacks *pAllocator) {
+ bool skip = parameter_validation_vkDestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator);
+ if (!skip) {
+ auto instance_data = GetLayerDataPtr(get_dispatch_key(instance), instance_layer_data_map);
+ instance_data->dispatch_table.DestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator);
+ layer_destroy_messenger_callback(instance_data->report_data, messenger, pAllocator);
}
}
@@ -472,7 +555,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, c
layer_data *my_device_data = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
assert(my_device_data != nullptr);
- my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
+ my_device_data->report_data = layer_debug_utils_create_device(my_instance_data->report_data, *pDevice);
layer_init_device_dispatch_table(*pDevice, &my_device_data->dispatch_table, fpGetDeviceProcAddr);
// Query and save physical device limits for this device
@@ -533,7 +616,7 @@ VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCa
}
if (!skip) {
- layer_debug_report_destroy_device(device);
+ layer_debug_utils_destroy_device(device);
device_data->dispatch_table.DestroyDevice(device, pAllocator);
}
FreeLayerDataPtr(key, layer_data_map);
diff --git a/layers/threading.cpp b/layers/threading.cpp
index d27d75f3..ce5f8e3e 100644
--- a/layers/threading.cpp
+++ b/layers/threading.cpp
@@ -42,7 +42,8 @@ namespace threading {
static uint32_t loader_layer_if_version = CURRENT_LOADER_LAYER_INTERFACE_VERSION;
static void initThreading(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
- layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "google_threading");
+ layer_debug_report_actions(my_data->report_data, my_data->logging_callback, pAllocator, "google_threading");
+ layer_debug_messenger_actions(my_data->report_data, my_data->logging_messenger, pAllocator, "google_threading");
}
VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
@@ -67,14 +68,16 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreat
my_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
layer_init_instance_dispatch_table(*pInstance, my_data->instance_dispatch_table, fpGetInstanceProcAddr);
- my_data->report_data = debug_report_create_instance(my_data->instance_dispatch_table, *pInstance,
- pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames);
+ my_data->report_data = debug_utils_create_instance(my_data->instance_dispatch_table, *pInstance,
+ pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames);
initThreading(my_data, pAllocator);
// Look for one or more debug report create info structures, and copy the
// callback(s) for each one found (for use by vkDestroyInstance)
- layer_copy_tmp_callbacks(pCreateInfo->pNext, &my_data->num_tmp_callbacks, &my_data->tmp_dbg_create_infos,
- &my_data->tmp_callbacks);
+ layer_copy_tmp_debug_messengers(pCreateInfo->pNext, &my_data->num_tmp_debug_messengers, &my_data->tmp_messenger_create_infos,
+ &my_data->tmp_debug_messengers);
+ layer_copy_tmp_report_callbacks(pCreateInfo->pNext, &my_data->num_tmp_report_callbacks, &my_data->tmp_report_create_infos,
+ &my_data->tmp_report_callbacks);
return result;
}
@@ -85,9 +88,15 @@ VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocati
// Enable the temporary callback(s) here to catch cleanup issues:
bool callback_setup = false;
- if (my_data->num_tmp_callbacks > 0) {
- if (!layer_enable_tmp_callbacks(my_data->report_data, my_data->num_tmp_callbacks, my_data->tmp_dbg_create_infos,
- my_data->tmp_callbacks)) {
+ if (my_data->num_tmp_debug_messengers > 0) {
+ if (!layer_enable_tmp_debug_messengers(my_data->report_data, my_data->num_tmp_debug_messengers,
+ my_data->tmp_messenger_create_infos, my_data->tmp_debug_messengers)) {
+ callback_setup = true;
+ }
+ }
+ if (my_data->num_tmp_report_callbacks > 0) {
+ if (!layer_enable_tmp_report_callbacks(my_data->report_data, my_data->num_tmp_report_callbacks,
+ my_data->tmp_report_create_infos, my_data->tmp_report_callbacks)) {
callback_setup = true;
}
}
@@ -105,21 +114,31 @@ VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocati
// Disable and cleanup the temporary callback(s):
if (callback_setup) {
- layer_disable_tmp_callbacks(my_data->report_data, my_data->num_tmp_callbacks, my_data->tmp_callbacks);
+ layer_disable_tmp_debug_messengers(my_data->report_data, my_data->num_tmp_debug_messengers, my_data->tmp_debug_messengers);
+ layer_disable_tmp_report_callbacks(my_data->report_data, my_data->num_tmp_report_callbacks, my_data->tmp_report_callbacks);
}
- if (my_data->num_tmp_callbacks > 0) {
- layer_free_tmp_callbacks(my_data->tmp_dbg_create_infos, my_data->tmp_callbacks);
- my_data->num_tmp_callbacks = 0;
+ if (my_data->num_tmp_debug_messengers > 0) {
+ layer_free_tmp_debug_messengers(my_data->tmp_messenger_create_infos, my_data->tmp_debug_messengers);
+ my_data->num_tmp_debug_messengers = 0;
+ }
+ if (my_data->num_tmp_report_callbacks > 0) {
+ layer_free_tmp_report_callbacks(my_data->tmp_report_create_infos, my_data->tmp_report_callbacks);
+ my_data->num_tmp_report_callbacks = 0;
}
- // Clean up logging callback, if any
+ // Clean up logging callbacks, if any
+ while (my_data->logging_messenger.size() > 0) {
+ VkDebugUtilsMessengerEXT messenger = my_data->logging_messenger.back();
+ layer_destroy_messenger_callback(my_data->report_data, messenger, pAllocator);
+ my_data->logging_messenger.pop_back();
+ }
while (my_data->logging_callback.size() > 0) {
VkDebugReportCallbackEXT callback = my_data->logging_callback.back();
- layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);
+ layer_destroy_report_callback(my_data->report_data, callback, pAllocator);
my_data->logging_callback.pop_back();
}
- layer_debug_report_destroy_instance(my_data->report_data);
+ layer_debug_utils_destroy_instance(my_data->report_data);
delete my_data->instance_dispatch_table;
FreeLayerDataPtr(key, layer_data_map);
}
@@ -151,7 +170,7 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu, const VkDevice
my_device_data->device_dispatch_table = new VkLayerDispatchTable;
layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
- my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
+ my_device_data->report_data = layer_debug_utils_create_device(my_instance_data->report_data, *pDevice);
return result;
}
@@ -194,8 +213,8 @@ VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainImagesKHR(VkDevice device, VkSwapchai
return result;
}
-static const VkExtensionProperties threading_extensions[] = {
- {VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}};
+static const VkExtensionProperties threading_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION},
+ {VK_EXT_DEBUG_UTILS_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_SPEC_VERSION}};
static const VkLayerProperties layerProps = {
"VK_LAYER_GOOGLE_threading",
@@ -272,6 +291,52 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance in
return pTable->GetPhysicalDeviceProcAddr(instance, funcName);
}
+// VK_EXT_debug_utils commands
+VKAPI_ATTR VkResult VKAPI_CALL CreateDebugUtilsMessengerEXT(VkInstance instance,
+ const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkDebugUtilsMessengerEXT *pMessenger) {
+ layer_data *my_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
+ bool threadChecks = startMultiThread();
+ if (threadChecks) {
+ startReadObject(my_data, instance);
+ }
+ VkResult result = my_data->instance_dispatch_table->CreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger);
+
+ if (VK_SUCCESS == result) {
+ result = layer_create_messenger_callback(my_data->report_data, false, pCreateInfo, pAllocator, pMessenger);
+ // If something happened during this call, clean up the message callback that was created earlier in the lower levels
+ if (VK_SUCCESS != result) {
+ my_data->instance_dispatch_table->DestroyDebugUtilsMessengerEXT(instance, *pMessenger, pAllocator);
+ }
+ }
+ if (threadChecks) {
+ finishReadObject(my_data, instance);
+ } else {
+ finishMultiThread();
+ }
+ return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
+ const VkAllocationCallbacks *pAllocator) {
+ layer_data *my_data = GetLayerDataPtr(get_dispatch_key(instance), layer_data_map);
+ bool threadChecks = startMultiThread();
+ if (threadChecks) {
+ startReadObject(my_data, instance);
+ startWriteObject(my_data, messenger);
+ }
+ my_data->instance_dispatch_table->DestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator);
+ layer_destroy_messenger_callback(my_data->report_data, messenger, pAllocator);
+ if (threadChecks) {
+ finishReadObject(my_data, instance);
+ finishWriteObject(my_data, messenger);
+ } else {
+ finishMultiThread();
+ }
+}
+
+// VK_EXT_debug_report commands
VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance,
const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
@@ -284,7 +349,11 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance,
VkResult result =
my_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
if (VK_SUCCESS == result) {
- result = layer_create_msg_callback(my_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback);
+ result = layer_create_report_callback(my_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback);
+ // If something happened during this call, clean up the message callback that was created earlier in the lower levels
+ if (VK_SUCCESS != result) {
+ my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, *pMsgCallback, pAllocator);
+ }
}
if (threadChecks) {
finishReadObject(my_data, instance);
@@ -303,7 +372,7 @@ VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance, Vk
startWriteObject(my_data, callback);
}
my_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, callback, pAllocator);
- layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);
+ layer_destroy_report_callback(my_data->report_data, callback, pAllocator);
if (threadChecks) {
finishReadObject(my_data, instance);
finishWriteObject(my_data, callback);
@@ -400,6 +469,23 @@ VKAPI_ATTR void VKAPI_CALL FreeCommandBuffers(VkDevice device, VkCommandPool com
} // namespace threading
// vk_layer_logging.h expects these to be defined
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugUtilsMessengerEXT(VkInstance instance,
+ const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkDebugUtilsMessengerEXT *pMessenger) {
+ return threading::CreateDebugUtilsMessengerEXT(instance, pCreateInfo, pAllocator, pMessenger);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
+ const VkAllocationCallbacks *pAllocator) {
+ threading::DestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkSubmitDebugUtilsMessageEXT(VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
+ VkDebugUtilsMessageTypeFlagsEXT messageTypes,
+ const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) {
+ threading::SubmitDebugUtilsMessageEXT(instance, messageSeverity, messageTypes, pCallbackData);
+}
VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(VkInstance instance,
const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
diff --git a/layers/threading.h b/layers/threading.h
index e2301d00..70814a53 100644
--- a/layers/threading.h
+++ b/layers/threading.h
@@ -228,13 +228,19 @@ struct layer_data {
debug_report_data *report_data;
std::vector<VkDebugReportCallbackEXT> logging_callback;
+ std::vector<VkDebugUtilsMessengerEXT> logging_messenger;
VkLayerDispatchTable *device_dispatch_table;
VkLayerInstanceDispatchTable *instance_dispatch_table;
+
// The following are for keeping track of the temporary callbacks that can
// be used in vkCreateInstance and vkDestroyInstance:
- uint32_t num_tmp_callbacks;
- VkDebugReportCallbackCreateInfoEXT *tmp_dbg_create_infos;
- VkDebugReportCallbackEXT *tmp_callbacks;
+ uint32_t num_tmp_report_callbacks;
+ VkDebugReportCallbackCreateInfoEXT *tmp_report_create_infos;
+ VkDebugReportCallbackEXT *tmp_report_callbacks;
+ uint32_t num_tmp_debug_messengers;
+ VkDebugUtilsMessengerCreateInfoEXT *tmp_messenger_create_infos;
+ VkDebugUtilsMessengerEXT *tmp_debug_messengers;
+
counter<VkCommandBuffer> c_VkCommandBuffer;
counter<VkDevice> c_VkDevice;
counter<VkInstance> c_VkInstance;
@@ -270,15 +276,19 @@ struct layer_data {
counter<VkDescriptorUpdateTemplateKHR> c_VkDescriptorUpdateTemplateKHR;
counter<VkValidationCacheEXT> c_VkValidationCacheEXT;
counter<VkSamplerYcbcrConversionKHR> c_VkSamplerYcbcrConversionKHR;
+ counter<VkDebugUtilsMessengerEXT> c_VkDebugUtilsMessengerEXT;
#else // DISTINCT_NONDISPATCHABLE_HANDLES
counter<uint64_t> c_uint64_t;
#endif // DISTINCT_NONDISPATCHABLE_HANDLES
layer_data()
: report_data(nullptr),
- num_tmp_callbacks(0),
- tmp_dbg_create_infos(nullptr),
- tmp_callbacks(nullptr),
+ num_tmp_report_callbacks(0),
+ tmp_report_create_infos(nullptr),
+ tmp_report_callbacks(nullptr),
+ num_tmp_debug_messengers(0),
+ tmp_messenger_create_infos(nullptr),
+ tmp_debug_messengers(nullptr),
c_VkCommandBuffer("VkCommandBuffer", VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT),
c_VkDevice("VkDevice", VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT),
c_VkInstance("VkInstance", VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT),
@@ -314,7 +324,9 @@ struct layer_data {
c_VkSwapchainKHR("VkSwapchainKHR", VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT),
c_VkDescriptorUpdateTemplateKHR("VkDescriptorUpdateTemplateKHR",
VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT),
- c_VkSamplerYcbcrConversionKHR("VkSamplerYcbcrConversionKHR", VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT)
+ c_VkSamplerYcbcrConversionKHR("VkSamplerYcbcrConversionKHR",
+ VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT),
+ c_VkDebugUtilsMessengerEXT("VkDebugUtilsMessengerEXT", VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT)
#else // DISTINCT_NONDISPATCHABLE_HANDLES
c_uint64_t("NON_DISPATCHABLE_HANDLE", VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT)
#endif // DISTINCT_NONDISPATCHABLE_HANDLES
@@ -365,6 +377,7 @@ WRAPPER(VkSwapchainKHR)
WRAPPER(VkDescriptorUpdateTemplateKHR)
WRAPPER(VkValidationCacheEXT)
WRAPPER(VkSamplerYcbcrConversionKHR)
+WRAPPER(VkDebugUtilsMessengerEXT)
#else // DISTINCT_NONDISPATCHABLE_HANDLES
WRAPPER(uint64_t)
#endif // DISTINCT_NONDISPATCHABLE_HANDLES
diff --git a/layers/unique_objects.cpp b/layers/unique_objects.cpp
index 37003700..702f07b1 100644
--- a/layers/unique_objects.cpp
+++ b/layers/unique_objects.cpp
@@ -59,7 +59,9 @@ namespace unique_objects {
static uint32_t loader_layer_if_version = CURRENT_LOADER_LAYER_INTERFACE_VERSION;
static void initUniqueObjects(instance_layer_data *instance_data, const VkAllocationCallbacks *pAllocator) {
- layer_debug_actions(instance_data->report_data, instance_data->logging_callback, pAllocator, "google_unique_objects");
+ layer_debug_report_actions(instance_data->report_data, instance_data->logging_callback, pAllocator, "google_unique_objects");
+ layer_debug_messenger_actions(instance_data->report_data, instance_data->logging_messenger, pAllocator,
+ "google_unique_objects");
}
// Check enabled instance extensions against supported instance extension whitelist
@@ -118,17 +120,27 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreat
layer_init_instance_dispatch_table(*pInstance, &instance_data->dispatch_table, fpGetInstanceProcAddr);
instance_data->instance = *pInstance;
- instance_data->report_data = debug_report_create_instance(
+ instance_data->report_data = debug_utils_create_instance(
&instance_data->dispatch_table, *pInstance, pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames);
// Set up temporary debug callbacks to output messages at CreateInstance-time
- if (!layer_copy_tmp_callbacks(pCreateInfo->pNext, &instance_data->num_tmp_callbacks, &instance_data->tmp_dbg_create_infos,
- &instance_data->tmp_callbacks)) {
- if (instance_data->num_tmp_callbacks > 0) {
- if (layer_enable_tmp_callbacks(instance_data->report_data, instance_data->num_tmp_callbacks,
- instance_data->tmp_dbg_create_infos, instance_data->tmp_callbacks)) {
- layer_free_tmp_callbacks(instance_data->tmp_dbg_create_infos, instance_data->tmp_callbacks);
- instance_data->num_tmp_callbacks = 0;
+ if (!layer_copy_tmp_debug_messengers(pCreateInfo->pNext, &instance_data->num_tmp_debug_messengers,
+ &instance_data->tmp_messenger_create_infos, &instance_data->tmp_debug_messengers)) {
+ if (instance_data->num_tmp_debug_messengers > 0) {
+ if (layer_enable_tmp_debug_messengers(instance_data->report_data, instance_data->num_tmp_debug_messengers,
+ instance_data->tmp_messenger_create_infos, instance_data->tmp_debug_messengers)) {
+ layer_free_tmp_debug_messengers(instance_data->tmp_messenger_create_infos, instance_data->tmp_debug_messengers);
+ instance_data->num_tmp_debug_messengers = 0;
+ }
+ }
+ }
+ if (!layer_copy_tmp_report_callbacks(pCreateInfo->pNext, &instance_data->num_tmp_report_callbacks,
+ &instance_data->tmp_report_create_infos, &instance_data->tmp_report_callbacks)) {
+ if (instance_data->num_tmp_report_callbacks > 0) {
+ if (layer_enable_tmp_report_callbacks(instance_data->report_data, instance_data->num_tmp_report_callbacks,
+ instance_data->tmp_report_create_infos, instance_data->tmp_report_callbacks)) {
+ layer_free_tmp_report_callbacks(instance_data->tmp_report_create_infos, instance_data->tmp_report_callbacks);
+ instance_data->num_tmp_report_callbacks = 0;
}
}
}
@@ -137,10 +149,17 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreat
InstanceExtensionWhitelist(pCreateInfo, *pInstance);
// Disable and free tmp callbacks, no longer necessary
- if (instance_data->num_tmp_callbacks > 0) {
- layer_disable_tmp_callbacks(instance_data->report_data, instance_data->num_tmp_callbacks, instance_data->tmp_callbacks);
- layer_free_tmp_callbacks(instance_data->tmp_dbg_create_infos, instance_data->tmp_callbacks);
- instance_data->num_tmp_callbacks = 0;
+ if (instance_data->num_tmp_debug_messengers > 0) {
+ layer_disable_tmp_debug_messengers(instance_data->report_data, instance_data->num_tmp_debug_messengers,
+ instance_data->tmp_debug_messengers);
+ layer_free_tmp_debug_messengers(instance_data->tmp_messenger_create_infos, instance_data->tmp_debug_messengers);
+ instance_data->num_tmp_debug_messengers = 0;
+ }
+ if (instance_data->num_tmp_report_callbacks > 0) {
+ layer_disable_tmp_report_callbacks(instance_data->report_data, instance_data->num_tmp_report_callbacks,
+ instance_data->tmp_report_callbacks);
+ layer_free_tmp_report_callbacks(instance_data->tmp_report_create_infos, instance_data->tmp_report_callbacks);
+ instance_data->num_tmp_report_callbacks = 0;
}
return result;
@@ -153,13 +172,18 @@ VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocati
disp_table->DestroyInstance(instance, pAllocator);
// Clean up logging callback, if any
+ while (instance_data->logging_messenger.size() > 0) {
+ VkDebugUtilsMessengerEXT messenger = instance_data->logging_messenger.back();
+ layer_destroy_messenger_callback(instance_data->report_data, messenger, pAllocator);
+ instance_data->logging_messenger.pop_back();
+ }
while (instance_data->logging_callback.size() > 0) {
VkDebugReportCallbackEXT callback = instance_data->logging_callback.back();
- layer_destroy_msg_callback(instance_data->report_data, callback, pAllocator);
+ layer_destroy_report_callback(instance_data->report_data, callback, pAllocator);
instance_data->logging_callback.pop_back();
}
- layer_debug_report_destroy_instance(instance_data->report_data);
+ layer_debug_utils_destroy_instance(instance_data->report_data);
FreeLayerDataPtr(key, instance_layer_data_map);
}
@@ -185,7 +209,7 @@ VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu, const VkDevice
}
layer_data *my_device_data = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
- my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
+ my_device_data->report_data = layer_debug_utils_create_device(my_instance_data->report_data, *pDevice);
// Setup layer's device dispatch table
layer_init_device_dispatch_table(*pDevice, &my_device_data->dispatch_table, fpGetDeviceProcAddr);
@@ -202,7 +226,7 @@ VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCall
dispatch_key key = get_dispatch_key(device);
layer_data *dev_data = GetLayerDataPtr(key, layer_data_map);
- layer_debug_report_destroy_device(device);
+ layer_debug_utils_destroy_device(device);
dev_data->dispatch_table.DestroyDevice(device, pAllocator);
FreeLayerDataPtr(key, layer_data_map);
@@ -877,6 +901,37 @@ VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectNameEXT(VkDevice device, cons
return result;
}
+// VK_EXT_debug_utils
+VKAPI_ATTR VkResult VKAPI_CALL SetDebugUtilsObjectTagEXT(VkDevice device, const VkDebugUtilsObjectTagInfoEXT *pTagInfo) {
+ layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+ auto local_tag_info = new safe_VkDebugUtilsObjectTagInfoEXT(pTagInfo);
+ {
+ std::lock_guard<std::mutex> lock(global_lock);
+ auto it = device_data->unique_id_mapping.find(reinterpret_cast<uint64_t &>(local_tag_info->objectHandle));
+ if (it != device_data->unique_id_mapping.end()) {
+ local_tag_info->objectHandle = it->second;
+ }
+ }
+ VkResult result = device_data->dispatch_table.SetDebugUtilsObjectTagEXT(
+ device, reinterpret_cast<const VkDebugUtilsObjectTagInfoEXT *>(local_tag_info));
+ return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL SetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsObjectNameInfoEXT *pNameInfo) {
+ layer_data *device_data = GetLayerDataPtr(get_dispatch_key(device), layer_data_map);
+ auto local_name_info = new safe_VkDebugUtilsObjectNameInfoEXT(pNameInfo);
+ {
+ std::lock_guard<std::mutex> lock(global_lock);
+ auto it = device_data->unique_id_mapping.find(reinterpret_cast<uint64_t &>(local_name_info->objectHandle));
+ if (it != device_data->unique_id_mapping.end()) {
+ local_name_info->objectHandle = it->second;
+ }
+ }
+ VkResult result = device_data->dispatch_table.SetDebugUtilsObjectNameEXT(
+ device, reinterpret_cast<const VkDebugUtilsObjectNameInfoEXT *>(local_name_info));
+ return result;
+}
+
} // namespace unique_objects
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,
diff --git a/layers/unique_objects.h b/layers/unique_objects.h
index 3dd3a797..0a03234c 100644
--- a/layers/unique_objects.h
+++ b/layers/unique_objects.h
@@ -50,12 +50,17 @@ struct instance_layer_data {
debug_report_data *report_data;
std::vector<VkDebugReportCallbackEXT> logging_callback;
+ std::vector<VkDebugUtilsMessengerEXT> logging_messenger;
VkLayerInstanceDispatchTable dispatch_table = {};
- // The following are for keeping track of the temporary callbacks that can be used in vkCreateInstance and vkDestroyInstance:
- uint32_t num_tmp_callbacks;
- VkDebugReportCallbackCreateInfoEXT *tmp_dbg_create_infos;
- VkDebugReportCallbackEXT *tmp_callbacks;
+ // The following are for keeping track of the temporary callbacks that can
+ // be used in vkCreateInstance and vkDestroyInstance:
+ uint32_t num_tmp_report_callbacks;
+ VkDebugReportCallbackCreateInfoEXT *tmp_report_create_infos;
+ VkDebugReportCallbackEXT *tmp_report_callbacks;
+ uint32_t num_tmp_debug_messengers;
+ VkDebugUtilsMessengerCreateInfoEXT *tmp_messenger_create_infos;
+ VkDebugUtilsMessengerEXT *tmp_debug_messengers;
};
struct layer_data {
diff --git a/layers/vk_layer_config.cpp b/layers/vk_layer_config.cpp
index b1b09d4c..51f42780 100644
--- a/layers/vk_layer_config.cpp
+++ b/layers/vk_layer_config.cpp
@@ -248,31 +248,74 @@ void ConfigFile::parseFile(const char *filename) {
}
}
-VK_LAYER_EXPORT void print_msg_flags(VkFlags msgFlags, char *msg_flags) {
+VK_LAYER_EXPORT void PrintMessageFlags(VkFlags vk_flags, char *msg_flags) {
bool separator = false;
msg_flags[0] = 0;
- if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
+ if (vk_flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
strcat(msg_flags, "DEBUG");
separator = true;
}
- if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
+ if (vk_flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
if (separator) strcat(msg_flags, ",");
strcat(msg_flags, "INFO");
separator = true;
}
- if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
+ if (vk_flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
if (separator) strcat(msg_flags, ",");
strcat(msg_flags, "WARN");
separator = true;
}
- if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
+ if (vk_flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
if (separator) strcat(msg_flags, ",");
strcat(msg_flags, "PERF");
separator = true;
}
- if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
+ if (vk_flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
if (separator) strcat(msg_flags, ",");
strcat(msg_flags, "ERROR");
}
}
+
+VK_LAYER_EXPORT void PrintMessageSeverity(VkFlags vk_flags, char *msg_flags) {
+ bool separator = false;
+
+ msg_flags[0] = 0;
+ if (vk_flags & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) {
+ strcat(msg_flags, "VERBOSE");
+ separator = true;
+ }
+ if (vk_flags & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) {
+ if (separator) strcat(msg_flags, ",");
+ strcat(msg_flags, "INFO");
+ separator = true;
+ }
+ if (vk_flags & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
+ if (separator) strcat(msg_flags, ",");
+ strcat(msg_flags, "WARN");
+ separator = true;
+ }
+ if (vk_flags & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
+ if (separator) strcat(msg_flags, ",");
+ strcat(msg_flags, "ERROR");
+ }
+}
+
+VK_LAYER_EXPORT void PrintMessageType(VkFlags vk_flags, char *msg_flags) {
+ bool separator = false;
+
+ msg_flags[0] = 0;
+ if (vk_flags & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT) {
+ strcat(msg_flags, "GEN");
+ separator = true;
+ }
+ if (vk_flags & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT) {
+ strcat(msg_flags, "SPEC");
+ separator = true;
+ }
+ if (vk_flags & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) {
+ if (separator) strcat(msg_flags, ",");
+ strcat(msg_flags, "PERF");
+ separator = true;
+ }
+}
diff --git a/layers/vk_layer_config.h b/layers/vk_layer_config.h
index b12ba50d..e0b9d326 100644
--- a/layers/vk_layer_config.h
+++ b/layers/vk_layer_config.h
@@ -63,7 +63,9 @@ VK_LAYER_EXPORT VkFlags GetLayerOptionFlags(std::string _option, std::unordered_
uint32_t option_default);
VK_LAYER_EXPORT void setLayerOption(const char *_option, const char *_val);
-VK_LAYER_EXPORT void print_msg_flags(VkFlags msgFlags, char *msg_flags);
+VK_LAYER_EXPORT void PrintMessageFlags(VkFlags vk_flags, char *msg_flags);
+VK_LAYER_EXPORT void PrintMessageSeverity(VkFlags vk_flags, char *msg_flags);
+VK_LAYER_EXPORT void PrintMessageType(VkFlags vk_flags, char *msg_flags);
#ifdef __cplusplus
}
diff --git a/layers/vk_layer_logging.h b/layers/vk_layer_logging.h
index 559b5a45..61e109af 100644
--- a/layers/vk_layer_logging.h
+++ b/layers/vk_layer_logging.h
@@ -1,6 +1,6 @@
-/* Copyright (c) 2015-2016 The Khronos Group Inc.
- * Copyright (c) 2015-2016 Valve Corporation
- * Copyright (c) 2015-2016 LunarG, Inc.
+/* Copyright (c) 2015-2017 The Khronos Group Inc.
+ * Copyright (c) 2015-2017 Valve Corporation
+ * Copyright (c) 2015-2017 LunarG, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
*
* Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
* Author: Tobin Ehlis <tobin@lunarg.com>
+ * Author: Mark Young <marky@lunarg.com>
*
*/
@@ -28,6 +29,7 @@
#include "vk_layer_table.h"
#include "vk_loader_platform.h"
#include "vulkan/vk_layer.h"
+#include "vk_object_types.h"
#include <signal.h>
#include <cinttypes>
#include <stdarg.h>
@@ -35,51 +37,140 @@
#include <stdio.h>
#include <unordered_map>
#include <vector>
+#include <sstream>
+#include <string>
+
+// TODO: Could be autogenerated for the specific handles for extra type safety...
+template <typename HANDLE_T>
+static inline uint64_t HandleToUint64(HANDLE_T *h) {
+ return reinterpret_cast<uint64_t>(h);
+}
+
+static inline uint64_t HandleToUint64(uint64_t h) { return h; }
+
+// Data we store per label for logging
+typedef struct _LoggingLabelData {
+ std::string name;
+ float color[4];
+} LoggingLabelData;
typedef struct _debug_report_data {
VkLayerDbgFunctionNode *debug_callback_list;
VkLayerDbgFunctionNode *default_debug_callback_list;
- VkFlags active_flags;
+ VkDebugUtilsMessageSeverityFlagsEXT active_severities;
+ VkDebugUtilsMessageTypeFlagsEXT active_types;
bool g_DEBUG_REPORT;
+ bool g_DEBUG_UTILS;
std::unordered_map<uint64_t, std::string> *debugObjectNameMap;
+ std::unordered_map<uint64_t, std::string> *debugUtilsObjectNameMap;
+ std::unordered_map<VkQueue, std::vector<LoggingLabelData>> *debugUtilsQueueLabels;
+ bool queueLabelHasInsert;
+ std::unordered_map<VkCommandBuffer, std::vector<LoggingLabelData>> *debugUtilsCmdBufLabels;
+ bool cmdBufLabelHasInsert;
} debug_report_data;
template debug_report_data *GetLayerDataPtr<debug_report_data>(void *data_key,
std::unordered_map<void *, debug_report_data *> &data_map);
+static inline void DebugReportFlagsToAnnotFlags(VkDebugReportFlagsEXT dr_flags, bool default_flag_is_spec,
+ VkDebugUtilsMessageSeverityFlagsEXT *da_severity,
+ VkDebugUtilsMessageTypeFlagsEXT *da_type) {
+ // All layer warnings are spec warnings currently. At least as far as anything not specifically
+ // called out. In the future, we'll label things using the new split severity and type values.
+ *da_type = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
+ *da_severity = 0;
+ if ((dr_flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) != 0) {
+ *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
+ *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
+ }
+ if ((dr_flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) != 0) {
+ *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
+ *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
+ }
+ if ((dr_flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) != 0) {
+ *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
+ *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
+ }
+ if ((dr_flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) != 0) {
+ *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
+ }
+ if ((dr_flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) != 0) {
+ *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
+ }
+}
+
// Forward Declarations
-static inline bool debug_report_log_msg(const debug_report_data *debug_data, VkFlags msgFlags,
- VkDebugReportObjectTypeEXT objectType, uint64_t srcObject, size_t location, int32_t msgCode,
- const char *pLayerPrefix, const char *pMsg);
+static inline bool debug_log_msg(const debug_report_data *debug_data, VkFlags msg_flags, VkDebugReportObjectTypeEXT object_type,
+ uint64_t src_object, size_t location, int32_t msg_code, const char *layer_prefix,
+ const char *message);
// Add a debug message callback node structure to the specified callback linked list
-static inline void AddDebugMessageCallback(debug_report_data *debug_data, VkLayerDbgFunctionNode **list_head,
- VkLayerDbgFunctionNode *new_node) {
+static inline void AddDebugCallbackNode(debug_report_data *debug_data, VkLayerDbgFunctionNode **list_head,
+ VkLayerDbgFunctionNode *new_node) {
new_node->pNext = *list_head;
*list_head = new_node;
}
+// Remove specified debug messenger node structure from the specified linked list
+static inline void RemoveDebugUtilsMessenger(debug_report_data *debug_data, VkLayerDbgFunctionNode **list_head,
+ VkDebugUtilsMessengerEXT messenger) {
+ VkLayerDbgFunctionNode *cur_callback = *list_head;
+ VkLayerDbgFunctionNode *prev_callback = cur_callback;
+ bool matched = false;
+ VkFlags local_severities = 0;
+ VkFlags local_types = 0;
+
+ while (cur_callback) {
+ if (cur_callback->is_messenger && cur_callback->messenger.messenger == messenger) {
+ matched = true;
+ prev_callback->pNext = cur_callback->pNext;
+ if (*list_head == cur_callback) {
+ *list_head = cur_callback->pNext;
+ }
+ debug_log_msg(debug_data, VK_DEBUG_REPORT_DEBUG_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT,
+ reinterpret_cast<uint64_t &>(cur_callback->messenger.messenger), 0, 0, "DebugUtilsMessenger",
+ "Destroyed messenger\n");
+ } else {
+ matched = false;
+ local_severities |= cur_callback->messenger.messageSeverity;
+ local_types |= cur_callback->messenger.messageType;
+ }
+ prev_callback = cur_callback;
+ cur_callback = cur_callback->pNext;
+ if (matched) {
+ free(prev_callback);
+ }
+ }
+ debug_data->active_severities = local_severities;
+ debug_data->active_types = local_types;
+}
+
// Remove specified debug message callback node structure from the specified callback linked list
-static inline void RemoveDebugMessageCallback(debug_report_data *debug_data, VkLayerDbgFunctionNode **list_head,
- VkDebugReportCallbackEXT callback) {
+static inline void RemoveDebugUtilsMessageCallback(debug_report_data *debug_data, VkLayerDbgFunctionNode **list_head,
+ VkDebugReportCallbackEXT callback) {
VkLayerDbgFunctionNode *cur_callback = *list_head;
VkLayerDbgFunctionNode *prev_callback = cur_callback;
bool matched = false;
- VkFlags local_flags = 0;
+ VkFlags local_severities = 0;
+ VkFlags local_types = 0;
while (cur_callback) {
- if (cur_callback->msgCallback == callback) {
+ if (!cur_callback->is_messenger && cur_callback->report.msgCallback == callback) {
matched = true;
prev_callback->pNext = cur_callback->pNext;
if (*list_head == cur_callback) {
*list_head = cur_callback->pNext;
}
- debug_report_log_msg(debug_data, VK_DEBUG_REPORT_DEBUG_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT,
- reinterpret_cast<uint64_t &>(cur_callback->msgCallback), 0, 0, "DebugReport",
- "Destroyed callback\n");
+ debug_log_msg(debug_data, VK_DEBUG_REPORT_DEBUG_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT,
+ reinterpret_cast<uint64_t &>(cur_callback->report.msgCallback), 0, 0, "DebugReport",
+ "Destroyed callback\n");
} else {
matched = false;
- local_flags |= cur_callback->msgFlags;
+ VkFlags this_severities = 0;
+ VkFlags this_types = 0;
+ DebugReportFlagsToAnnotFlags(cur_callback->report.msgFlags, true, &this_severities, &this_types);
+ local_severities |= this_severities;
+ local_types |= this_types;
}
prev_callback = cur_callback;
cur_callback = cur_callback->pNext;
@@ -87,7 +178,8 @@ static inline void RemoveDebugMessageCallback(debug_report_data *debug_data, VkL
free(prev_callback);
}
}
- debug_data->active_flags = local_flags;
+ debug_data->active_severities = local_severities;
+ debug_data->active_types = local_types;
}
// Removes all debug callback function nodes from the specified callback linked lists and frees their resources
@@ -97,9 +189,15 @@ static inline void RemoveAllMessageCallbacks(debug_report_data *debug_data, VkLa
while (current_callback) {
prev_callback = current_callback->pNext;
- debug_report_log_msg(debug_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT,
- (uint64_t)current_callback->msgCallback, 0, 0, "DebugReport",
- "Debug Report callbacks not removed before DestroyInstance");
+ if (!current_callback->is_messenger) {
+ debug_log_msg(debug_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT,
+ (uint64_t)current_callback->report.msgCallback, 0, 0, "DebugReport",
+ "Debug Report callbacks not removed before DestroyInstance");
+ } else {
+ debug_log_msg(debug_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT,
+ (uint64_t)current_callback->messenger.messenger, 0, 0, "Messenger",
+ "Debug messengers not removed before DestroyInstance");
+ }
free(current_callback);
current_callback = prev_callback;
}
@@ -107,46 +205,222 @@ static inline void RemoveAllMessageCallbacks(debug_report_data *debug_data, VkLa
}
// Utility function to handle reporting
-static inline bool debug_report_log_msg(const debug_report_data *debug_data, VkFlags msgFlags,
- VkDebugReportObjectTypeEXT objectType, uint64_t srcObject, size_t location, int32_t msgCode,
- const char *pLayerPrefix, const char *pMsg) {
+static inline bool debug_log_msg(const debug_report_data *debug_data, VkFlags msg_flags, VkDebugReportObjectTypeEXT object_type,
+ uint64_t src_object, size_t location, int32_t msg_code, const char *layer_prefix,
+ const char *message) {
bool bail = false;
- VkLayerDbgFunctionNode *pTrav = NULL;
+ VkLayerDbgFunctionNode *layer_dbg_node = NULL;
if (debug_data->debug_callback_list != NULL) {
- pTrav = debug_data->debug_callback_list;
+ layer_dbg_node = debug_data->debug_callback_list;
} else {
- pTrav = debug_data->default_debug_callback_list;
+ layer_dbg_node = debug_data->default_debug_callback_list;
}
- while (pTrav) {
- if (pTrav->msgFlags & msgFlags) {
- auto it = debug_data->debugObjectNameMap->find(srcObject);
+ VkDebugUtilsMessageSeverityFlagsEXT severity;
+ VkDebugUtilsMessageTypeFlagsEXT types;
+ VkDebugUtilsMessengerCallbackDataEXT callback_data;
+ VkDebugUtilsObjectNameInfoEXT object_name_info;
+
+ // Convert the info to the VK_EXT_debug_utils form in case we need it.
+ DebugReportFlagsToAnnotFlags(msg_flags, true, &severity, &types);
+ object_name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
+ object_name_info.pNext = NULL;
+ object_name_info.objectType = convertDebugReportObjectToCoreObject(object_type);
+ object_name_info.objectHandle = (uint64_t)(uintptr_t)src_object;
+ object_name_info.pObjectName = NULL;
+
+ callback_data.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT;
+ callback_data.pNext = NULL;
+ callback_data.flags = 0;
+ callback_data.pMessageIdName = layer_prefix;
+ callback_data.messageIdNumber = msg_code;
+ callback_data.pMessage = message;
+ callback_data.queueLabelCount = 0;
+ callback_data.pQueueLabels = NULL;
+ callback_data.cmdBufLabelCount = 0;
+ callback_data.pCmdBufLabels = NULL;
+ callback_data.objectCount = 1;
+ callback_data.pObjects = &object_name_info;
+
+ VkDebugUtilsLabelEXT *queue_labels = nullptr;
+ VkDebugUtilsLabelEXT *cmd_buf_labels = nullptr;
+ std::string new_debug_report_message = "";
+ std::ostringstream oss;
+ oss << "Object: 0x" << std::hex << src_object;
+
+ if (0 != src_object) {
+ // If this is a queue, add any queue labels to the callback data.
+ if (VK_OBJECT_TYPE_QUEUE == object_name_info.objectType) {
+ auto label_iter = debug_data->debugUtilsQueueLabels->find(reinterpret_cast<VkQueue>(src_object));
+ if (label_iter != debug_data->debugUtilsQueueLabels->end()) {
+ queue_labels = new VkDebugUtilsLabelEXT[label_iter->second.size()];
+ if (nullptr != queue_labels) {
+ // Record the labels, but record them in reverse order since we want the
+ // most recent at the top.
+ uint32_t label_size = static_cast<uint32_t>(label_iter->second.size());
+ uint32_t last_index = label_size - 1;
+ for (uint32_t label = 0; label < label_size; ++label) {
+ queue_labels[last_index - label].sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
+ queue_labels[last_index - label].pNext = nullptr;
+ queue_labels[last_index - label].pLabelName = label_iter->second[label].name.c_str();
+ queue_labels[last_index - label].color[0] = label_iter->second[label].color[0];
+ queue_labels[last_index - label].color[1] = label_iter->second[label].color[1];
+ queue_labels[last_index - label].color[2] = label_iter->second[label].color[2];
+ queue_labels[last_index - label].color[3] = label_iter->second[label].color[3];
+ }
+ callback_data.queueLabelCount = label_size;
+ callback_data.pQueueLabels = queue_labels;
+ }
+ }
+ // If this is a command buffer, add any command buffer labels to the callback data.
+ } else if (VK_OBJECT_TYPE_COMMAND_BUFFER == object_name_info.objectType) {
+ auto label_iter = debug_data->debugUtilsCmdBufLabels->find(reinterpret_cast<VkCommandBuffer>(src_object));
+ if (label_iter != debug_data->debugUtilsCmdBufLabels->end()) {
+ cmd_buf_labels = new VkDebugUtilsLabelEXT[label_iter->second.size()];
+ if (nullptr != cmd_buf_labels) {
+ // Record the labels, but record them in reverse order since we want the
+ // most recent at the top.
+ uint32_t label_size = static_cast<uint32_t>(label_iter->second.size());
+ uint32_t last_index = label_size - 1;
+ for (uint32_t label = 0; label < label_size; ++label) {
+ cmd_buf_labels[last_index - label].sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
+ cmd_buf_labels[last_index - label].pNext = nullptr;
+ cmd_buf_labels[last_index - label].pLabelName = label_iter->second[label].name.c_str();
+ cmd_buf_labels[last_index - label].color[0] = label_iter->second[label].color[0];
+ cmd_buf_labels[last_index - label].color[1] = label_iter->second[label].color[1];
+ cmd_buf_labels[last_index - label].color[2] = label_iter->second[label].color[2];
+ cmd_buf_labels[last_index - label].color[3] = label_iter->second[label].color[3];
+ }
+ callback_data.cmdBufLabelCount = label_size;
+ callback_data.pCmdBufLabels = cmd_buf_labels;
+ }
+ }
+ }
+ // Look for any debug utils or marker names to use for this object
+ callback_data.pObjects[0].pObjectName = NULL;
+ auto utils_name_iter = debug_data->debugUtilsObjectNameMap->find(src_object);
+ if (utils_name_iter != debug_data->debugUtilsObjectNameMap->end()) {
+ callback_data.pObjects[0].pObjectName = utils_name_iter->second.c_str();
+ } else {
+ auto marker_name_iter = debug_data->debugObjectNameMap->find(src_object);
+ if (marker_name_iter != debug_data->debugObjectNameMap->end()) {
+ callback_data.pObjects[0].pObjectName = marker_name_iter->second.c_str();
+ }
+ }
+ if (NULL != callback_data.pObjects[0].pObjectName) {
+ oss << " (Name = " << callback_data.pObjects[0].pObjectName << ")";
+ }
+ }
+ new_debug_report_message += oss.str();
+ new_debug_report_message += " | ";
+ new_debug_report_message += message;
+
+ while (layer_dbg_node) {
+ if (!layer_dbg_node->is_messenger && (layer_dbg_node->report.msgFlags & msg_flags) &&
+ layer_dbg_node->report.pfnMsgCallback(msg_flags, object_type, src_object, location, msg_code, layer_prefix,
+ new_debug_report_message.c_str(), layer_dbg_node->pUserData)) {
+ bail = true;
+ } else if (layer_dbg_node->is_messenger && (layer_dbg_node->messenger.messageSeverity & severity) &&
+ (layer_dbg_node->messenger.messageType & types) &&
+ layer_dbg_node->messenger.pfnUserCallback(static_cast<VkDebugUtilsMessageSeverityFlagBitsEXT>(severity), types,
+ &callback_data, layer_dbg_node->pUserData)) {
+ bail = true;
+ }
+ layer_dbg_node = layer_dbg_node->pNext;
+ }
+
+ if (nullptr != queue_labels) {
+ delete[] queue_labels;
+ }
+ if (nullptr != cmd_buf_labels) {
+ delete[] cmd_buf_labels;
+ }
+
+ return bail;
+}
+
+static inline void DebugAnnotFlagsToReportFlags(VkDebugUtilsMessageSeverityFlagBitsEXT da_severity,
+ VkDebugUtilsMessageTypeFlagsEXT da_type, VkDebugReportFlagsEXT *dr_flags) {
+ *dr_flags = 0;
+
+ if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) != 0) {
+ *dr_flags |= VK_DEBUG_REPORT_ERROR_BIT_EXT;
+ } else if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) != 0) {
+ if ((da_type & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) != 0) {
+ *dr_flags |= VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
+ } else {
+ *dr_flags |= VK_DEBUG_REPORT_WARNING_BIT_EXT;
+ }
+ } else if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) != 0) {
+ *dr_flags |= VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
+ } else if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) != 0) {
+ *dr_flags |= VK_DEBUG_REPORT_DEBUG_BIT_EXT;
+ }
+}
+
+static inline bool debug_messenger_log_msg(const debug_report_data *debug_data,
+ VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
+ VkDebugUtilsMessageTypeFlagsEXT message_type,
+ VkDebugUtilsMessengerCallbackDataEXT *callback_data) {
+ bool bail = false;
+ VkLayerDbgFunctionNode *layer_dbg_node = NULL;
+
+ if (debug_data->debug_callback_list != NULL) {
+ layer_dbg_node = debug_data->debug_callback_list;
+ } else {
+ layer_dbg_node = debug_data->default_debug_callback_list;
+ }
+
+ VkDebugReportFlagsEXT object_flags = 0;
+
+ DebugAnnotFlagsToReportFlags(message_severity, message_type, &object_flags);
+
+ while (layer_dbg_node) {
+ if (layer_dbg_node->is_messenger && (layer_dbg_node->messenger.messageSeverity & message_severity) &&
+ (layer_dbg_node->messenger.messageType & message_type)) {
+ // Loop through each object and give it the proper name if it was set.
+ for (uint32_t obj = 0; obj < callback_data->objectCount; obj++) {
+ auto it = debug_data->debugUtilsObjectNameMap->find(callback_data->pObjects[obj].objectHandle);
+ if (it == debug_data->debugUtilsObjectNameMap->end()) {
+ continue;
+ }
+ callback_data->pObjects[obj].pObjectName = it->second.c_str();
+ }
+ if (layer_dbg_node->messenger.pfnUserCallback(message_severity, message_type, callback_data,
+ layer_dbg_node->pUserData)) {
+ bail = true;
+ }
+ } else if (!layer_dbg_node->is_messenger && layer_dbg_node->report.msgFlags & object_flags) {
+ auto it = debug_data->debugObjectNameMap->find(callback_data->pObjects[0].objectHandle);
+ VkDebugReportObjectTypeEXT object_type = get_debug_report_enum[callback_data->pObjects[0].objectType];
if (it == debug_data->debugObjectNameMap->end()) {
- if (pTrav->pfnMsgCallback(msgFlags, objectType, srcObject, location, msgCode, pLayerPrefix, pMsg,
- pTrav->pUserData)) {
+ if (layer_dbg_node->report.pfnMsgCallback(object_flags, object_type, callback_data->pObjects[0].objectHandle, 0,
+ callback_data->messageIdNumber, callback_data->pMessageIdName,
+ callback_data->pMessage, layer_dbg_node->pUserData)) {
bail = true;
}
} else {
std::string newMsg = "SrcObject name = ";
newMsg.append(it->second.c_str());
newMsg.append(" ");
- newMsg.append(pMsg);
- if (pTrav->pfnMsgCallback(msgFlags, objectType, srcObject, location, msgCode, pLayerPrefix, newMsg.c_str(),
- pTrav->pUserData)) {
+ newMsg.append(callback_data->pMessage);
+ if (layer_dbg_node->report.pfnMsgCallback(object_flags, object_type, callback_data->pObjects[0].objectHandle, 0,
+ callback_data->messageIdNumber, callback_data->pMessageIdName,
+ newMsg.c_str(), layer_dbg_node->pUserData)) {
bail = true;
}
}
}
- pTrav = pTrav->pNext;
+ layer_dbg_node = layer_dbg_node->pNext;
}
return bail;
}
-static inline debug_report_data *debug_report_create_instance(
+static inline debug_report_data *debug_utils_create_instance(
VkLayerInstanceDispatchTable *table, VkInstance inst, uint32_t extension_count,
- const char *const *ppEnabledExtensions) // layer or extension name to be enabled
+ const char *const *enabled_extensions) // layer or extension name to be enabled
{
debug_report_data *debug_data = (debug_report_data *)malloc(sizeof(debug_report_data));
if (!debug_data) return NULL;
@@ -154,78 +428,162 @@ static inline debug_report_data *debug_report_create_instance(
memset(debug_data, 0, sizeof(debug_report_data));
for (uint32_t i = 0; i < extension_count; i++) {
// TODO: Check other property fields
- if (strcmp(ppEnabledExtensions[i], VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) {
+ if (strcmp(enabled_extensions[i], VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) {
debug_data->g_DEBUG_REPORT = true;
+ } else if (strcmp(enabled_extensions[i], VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0) {
+ debug_data->g_DEBUG_UTILS = true;
}
}
debug_data->debugObjectNameMap = new std::unordered_map<uint64_t, std::string>;
+ debug_data->debugUtilsObjectNameMap = new std::unordered_map<uint64_t, std::string>;
+ debug_data->debugUtilsQueueLabels = new std::unordered_map<VkQueue, std::vector<LoggingLabelData>>;
+ debug_data->debugUtilsCmdBufLabels = new std::unordered_map<VkCommandBuffer, std::vector<LoggingLabelData>>;
+ debug_data->queueLabelHasInsert = false;
+ debug_data->cmdBufLabelHasInsert = false;
return debug_data;
}
-static inline void layer_debug_report_destroy_instance(debug_report_data *debug_data) {
+static inline void layer_debug_utils_destroy_instance(debug_report_data *debug_data) {
if (debug_data) {
RemoveAllMessageCallbacks(debug_data, &debug_data->default_debug_callback_list);
RemoveAllMessageCallbacks(debug_data, &debug_data->debug_callback_list);
delete debug_data->debugObjectNameMap;
+ delete debug_data->debugUtilsObjectNameMap;
+ delete debug_data->debugUtilsQueueLabels;
+ delete debug_data->debugUtilsCmdBufLabels;
free(debug_data);
}
}
-static inline debug_report_data *layer_debug_report_create_device(debug_report_data *instance_debug_data, VkDevice device) {
+static inline debug_report_data *layer_debug_utils_create_device(debug_report_data *instance_debug_data, VkDevice device) {
// DEBUG_REPORT shares data between Instance and Device,
// so just return instance's data pointer
return instance_debug_data;
}
-static inline void layer_debug_report_destroy_device(VkDevice device) {
+static inline void layer_debug_utils_destroy_device(VkDevice device) {
// Nothing to do since we're using instance data record
}
-static inline void layer_destroy_msg_callback(debug_report_data *debug_data, VkDebugReportCallbackEXT callback,
- const VkAllocationCallbacks *pAllocator) {
- RemoveDebugMessageCallback(debug_data, &debug_data->debug_callback_list, callback);
- RemoveDebugMessageCallback(debug_data, &debug_data->default_debug_callback_list, callback);
+static inline void layer_destroy_messenger_callback(debug_report_data *debug_data, VkDebugUtilsMessengerEXT messenger,
+ const VkAllocationCallbacks *allocator) {
+ RemoveDebugUtilsMessenger(debug_data, &debug_data->debug_callback_list, messenger);
+ RemoveDebugUtilsMessenger(debug_data, &debug_data->default_debug_callback_list, messenger);
}
-static inline VkResult layer_create_msg_callback(debug_report_data *debug_data, bool default_callback,
- const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
- const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback) {
+static inline VkResult layer_create_messenger_callback(debug_report_data *debug_data, bool default_callback,
+ const VkDebugUtilsMessengerCreateInfoEXT *create_info,
+ const VkAllocationCallbacks *allocator,
+ VkDebugUtilsMessengerEXT *messenger) {
VkLayerDbgFunctionNode *pNewDbgFuncNode = (VkLayerDbgFunctionNode *)malloc(sizeof(VkLayerDbgFunctionNode));
if (!pNewDbgFuncNode) return VK_ERROR_OUT_OF_HOST_MEMORY;
+ memset(pNewDbgFuncNode, 0, sizeof(VkLayerDbgFunctionNode));
+ pNewDbgFuncNode->is_messenger = true;
// Handle of 0 is logging_callback so use allocated Node address as unique handle
- if (!(*pCallback)) *pCallback = (VkDebugReportCallbackEXT)pNewDbgFuncNode;
- pNewDbgFuncNode->msgCallback = *pCallback;
- pNewDbgFuncNode->pfnMsgCallback = pCreateInfo->pfnCallback;
- pNewDbgFuncNode->msgFlags = pCreateInfo->flags;
- pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
+ if (!(*messenger)) *messenger = (VkDebugUtilsMessengerEXT)pNewDbgFuncNode;
+ pNewDbgFuncNode->messenger.messenger = *messenger;
+ pNewDbgFuncNode->messenger.pfnUserCallback = create_info->pfnUserCallback;
+ pNewDbgFuncNode->messenger.messageSeverity = create_info->messageSeverity;
+ pNewDbgFuncNode->messenger.messageType = create_info->messageType;
+ pNewDbgFuncNode->pUserData = create_info->pUserData;
+ debug_data->active_severities |= create_info->messageSeverity;
+ debug_data->active_types |= create_info->messageType;
if (default_callback) {
- AddDebugMessageCallback(debug_data, &debug_data->default_debug_callback_list, pNewDbgFuncNode);
- debug_data->active_flags |= pCreateInfo->flags;
+ AddDebugCallbackNode(debug_data, &debug_data->default_debug_callback_list, pNewDbgFuncNode);
} else {
- AddDebugMessageCallback(debug_data, &debug_data->debug_callback_list, pNewDbgFuncNode);
- debug_data->active_flags = pCreateInfo->flags;
+ AddDebugCallbackNode(debug_data, &debug_data->debug_callback_list, pNewDbgFuncNode);
}
- debug_report_log_msg(debug_data, VK_DEBUG_REPORT_DEBUG_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT,
- (uint64_t)*pCallback, 0, 0, "DebugReport", "Added callback");
+ VkDebugUtilsMessengerCallbackDataEXT callback_data = {};
+ VkDebugUtilsObjectNameInfoEXT blank_object = {};
+ callback_data.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT;
+ callback_data.pNext = NULL;
+ callback_data.flags = 0;
+ callback_data.pMessageIdName = "Layer Internal Message";
+ callback_data.messageIdNumber = 0;
+ callback_data.pMessage = "Added messenger";
+ callback_data.queueLabelCount = 0;
+ callback_data.pQueueLabels = NULL;
+ callback_data.cmdBufLabelCount = 0;
+ callback_data.pCmdBufLabels = NULL;
+ callback_data.objectCount = 1;
+ callback_data.pObjects = &blank_object;
+ blank_object.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
+ blank_object.pNext = NULL;
+ blank_object.objectType = VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT;
+ blank_object.objectHandle = HandleToUint64(*messenger);
+ blank_object.pObjectName = NULL;
+ debug_messenger_log_msg(debug_data, VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT,
+ VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data);
return VK_SUCCESS;
}
-static inline PFN_vkVoidFunction debug_report_get_instance_proc_addr(debug_report_data *debug_data, const char *funcName) {
- if (!debug_data || !debug_data->g_DEBUG_REPORT) {
- return NULL;
+static inline void layer_destroy_report_callback(debug_report_data *debug_data, VkDebugReportCallbackEXT callback,
+ const VkAllocationCallbacks *allocator) {
+ RemoveDebugUtilsMessageCallback(debug_data, &debug_data->debug_callback_list, callback);
+ RemoveDebugUtilsMessageCallback(debug_data, &debug_data->default_debug_callback_list, callback);
+}
+
+static inline VkResult layer_create_report_callback(debug_report_data *debug_data, bool default_callback,
+ const VkDebugReportCallbackCreateInfoEXT *create_info,
+ const VkAllocationCallbacks *allocator, VkDebugReportCallbackEXT *callback) {
+ VkLayerDbgFunctionNode *pNewDbgFuncNode = (VkLayerDbgFunctionNode *)malloc(sizeof(VkLayerDbgFunctionNode));
+ if (!pNewDbgFuncNode) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ memset(pNewDbgFuncNode, 0, sizeof(VkLayerDbgFunctionNode));
+ pNewDbgFuncNode->is_messenger = false;
+
+ // Handle of 0 is logging_callback so use allocated Node address as unique handle
+ if (!(*callback)) *callback = (VkDebugReportCallbackEXT)pNewDbgFuncNode;
+ pNewDbgFuncNode->report.msgCallback = *callback;
+ pNewDbgFuncNode->report.pfnMsgCallback = create_info->pfnCallback;
+ pNewDbgFuncNode->report.msgFlags = create_info->flags;
+ pNewDbgFuncNode->pUserData = create_info->pUserData;
+
+ VkFlags local_severity = 0;
+ VkFlags local_type = 0;
+ DebugReportFlagsToAnnotFlags(create_info->flags, true, &local_severity, &local_type);
+ debug_data->active_severities |= local_severity;
+ debug_data->active_types |= local_type;
+ if (default_callback) {
+ AddDebugCallbackNode(debug_data, &debug_data->default_debug_callback_list, pNewDbgFuncNode);
+ } else {
+ AddDebugCallbackNode(debug_data, &debug_data->debug_callback_list, pNewDbgFuncNode);
}
- if (!strcmp(funcName, "vkCreateDebugReportCallbackEXT")) {
- return (PFN_vkVoidFunction)vkCreateDebugReportCallbackEXT;
+ debug_log_msg(debug_data, VK_DEBUG_REPORT_DEBUG_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT, (uint64_t)*callback, 0,
+ 0, "DebugReport", "Added callback");
+ return VK_SUCCESS;
+}
+
+static inline PFN_vkVoidFunction debug_utils_get_instance_proc_addr(debug_report_data *debug_data, const char *func_name) {
+ if (!debug_data) {
+ return NULL;
}
- if (!strcmp(funcName, "vkDestroyDebugReportCallbackEXT")) {
- return (PFN_vkVoidFunction)vkDestroyDebugReportCallbackEXT;
+ if (debug_data->g_DEBUG_REPORT) {
+ if (!strcmp(func_name, "vkCreateDebugReportCallbackEXT")) {
+ return (PFN_vkVoidFunction)vkCreateDebugReportCallbackEXT;
+ }
+ if (!strcmp(func_name, "vkDestroyDebugReportCallbackEXT")) {
+ return (PFN_vkVoidFunction)vkDestroyDebugReportCallbackEXT;
+ }
+ if (!strcmp(func_name, "vkDebugReportMessageEXT")) {
+ return (PFN_vkVoidFunction)vkDebugReportMessageEXT;
+ }
}
- if (!strcmp(funcName, "vkDebugReportMessageEXT")) {
- return (PFN_vkVoidFunction)vkDebugReportMessageEXT;
+ if (debug_data->g_DEBUG_UTILS) {
+ if (!strcmp(func_name, "vkCreateDebugUtilsMessengerEXT")) {
+ return (PFN_vkVoidFunction)vkCreateDebugUtilsMessengerEXT;
+ }
+ if (!strcmp(func_name, "vkDestroyDebugUtilsMessengerEXT")) {
+ return (PFN_vkVoidFunction)vkDestroyDebugUtilsMessengerEXT;
+ }
+ if (!strcmp(func_name, "vkSubmitDebugUtilsMessageEXT")) {
+ return (PFN_vkVoidFunction)vkSubmitDebugUtilsMessageEXT;
+ }
}
return NULL;
}
@@ -235,8 +593,9 @@ static inline PFN_vkVoidFunction debug_report_get_instance_proc_addr(debug_repor
// then allocates an array that can hold that many structs, as well as that
// many VkDebugReportCallbackEXT handles. It then copies each
// VkDebugReportCallbackCreateInfoEXT, and initializes each handle.
-static inline VkResult layer_copy_tmp_callbacks(const void *pChain, uint32_t *num_callbacks,
- VkDebugReportCallbackCreateInfoEXT **infos, VkDebugReportCallbackEXT **callbacks) {
+static inline VkResult layer_copy_tmp_report_callbacks(const void *pChain, uint32_t *num_callbacks,
+ VkDebugReportCallbackCreateInfoEXT **infos,
+ VkDebugReportCallbackEXT **callbacks) {
uint32_t n = *num_callbacks = 0;
const void *pNext = pChain;
@@ -279,22 +638,23 @@ static inline VkResult layer_copy_tmp_callbacks(const void *pChain, uint32_t *nu
return VK_SUCCESS;
}
-// This utility frees the arrays allocated by layer_copy_tmp_callbacks()
-static inline void layer_free_tmp_callbacks(VkDebugReportCallbackCreateInfoEXT *infos, VkDebugReportCallbackEXT *callbacks) {
+// This utility frees the arrays allocated by layer_copy_tmp_report_callbacks()
+static inline void layer_free_tmp_report_callbacks(VkDebugReportCallbackCreateInfoEXT *infos, VkDebugReportCallbackEXT *callbacks) {
free(infos);
free(callbacks);
}
// This utility enables all of the VkDebugReportCallbackCreateInfoEXT structs
-// that were copied by layer_copy_tmp_callbacks()
-static inline VkResult layer_enable_tmp_callbacks(debug_report_data *debug_data, uint32_t num_callbacks,
- VkDebugReportCallbackCreateInfoEXT *infos, VkDebugReportCallbackEXT *callbacks) {
+// that were copied by layer_copy_tmp_report_callbacks()
+static inline VkResult layer_enable_tmp_report_callbacks(debug_report_data *debug_data, uint32_t num_callbacks,
+ VkDebugReportCallbackCreateInfoEXT *infos,
+ VkDebugReportCallbackEXT *callbacks) {
VkResult rtn = VK_SUCCESS;
for (uint32_t i = 0; i < num_callbacks; i++) {
- rtn = layer_create_msg_callback(debug_data, false, &infos[i], NULL, &callbacks[i]);
+ rtn = layer_create_report_callback(debug_data, false, &infos[i], NULL, &callbacks[i]);
if (rtn != VK_SUCCESS) {
for (uint32_t j = 0; j < i; j++) {
- layer_destroy_msg_callback(debug_data, callbacks[j], NULL);
+ layer_destroy_report_callback(debug_data, callbacks[j], NULL);
}
return rtn;
}
@@ -303,19 +663,104 @@ static inline VkResult layer_enable_tmp_callbacks(debug_report_data *debug_data,
}
// This utility disables all of the VkDebugReportCallbackCreateInfoEXT structs
-// that were copied by layer_copy_tmp_callbacks()
-static inline void layer_disable_tmp_callbacks(debug_report_data *debug_data, uint32_t num_callbacks,
- VkDebugReportCallbackEXT *callbacks) {
+// that were copied by layer_copy_tmp_report_callbacks()
+static inline void layer_disable_tmp_report_callbacks(debug_report_data *debug_data, uint32_t num_callbacks,
+ VkDebugReportCallbackEXT *callbacks) {
for (uint32_t i = 0; i < num_callbacks; i++) {
- layer_destroy_msg_callback(debug_data, callbacks[i], NULL);
+ layer_destroy_report_callback(debug_data, callbacks[i], NULL);
+ }
+}
+
+// This utility (called at vkCreateInstance() time), looks at a pNext chain.
+// It counts any VkDebugUtilsMessengerCreateInfoEXT structs that it finds. It
+// then allocates an array that can hold that many structs, as well as that
+// many VkDebugUtilsMessengerEXT handles. It then copies each
+// VkDebugUtilsMessengerCreateInfoEXT, and initializes each handle.
+static VkResult layer_copy_tmp_debug_messengers(const void *pChain, uint32_t *num_messengers,
+ VkDebugUtilsMessengerCreateInfoEXT **infos, VkDebugUtilsMessengerEXT **messengers) {
+ uint32_t n = *num_messengers = 0;
+
+ const void *pNext = pChain;
+ while (pNext) {
+ // 1st, count the number VkDebugUtilsMessengerCreateInfoEXT:
+ if (((VkDebugUtilsMessengerCreateInfoEXT *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) {
+ n++;
+ }
+ pNext = (void *)((VkDebugUtilsMessengerCreateInfoEXT *)pNext)->pNext;
+ }
+ if (n == 0) {
+ return VK_SUCCESS;
+ }
+
+ // 2nd, allocate memory for each VkDebugUtilsMessengerCreateInfoEXT:
+ VkDebugUtilsMessengerCreateInfoEXT *pInfos = *infos =
+ ((VkDebugUtilsMessengerCreateInfoEXT *)malloc(n * sizeof(VkDebugUtilsMessengerCreateInfoEXT)));
+ if (!pInfos) {
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ // 3rd, allocate memory for a unique handle for each messenger:
+ VkDebugUtilsMessengerEXT *pMessengers = *messengers =
+ ((VkDebugUtilsMessengerEXT *)malloc(n * sizeof(VkDebugUtilsMessengerEXT)));
+ if (!pMessengers) {
+ free(pInfos);
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ // 4th, copy each VkDebugUtilsMessengerCreateInfoEXT for use by
+ // vkDestroyInstance, and assign a unique handle to each callback (just
+ // use the address of the copied VkDebugUtilsMessengerCreateInfoEXT):
+ pNext = pChain;
+ while (pNext) {
+ if (((VkInstanceCreateInfo *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) {
+ memcpy(pInfos, pNext, sizeof(VkDebugUtilsMessengerCreateInfoEXT));
+ *pMessengers++ = (VkDebugUtilsMessengerEXT)pInfos++;
+ }
+ pNext = (void *)((VkInstanceCreateInfo *)pNext)->pNext;
+ }
+
+ *num_messengers = n;
+ return VK_SUCCESS;
+}
+
+// This utility frees the arrays allocated by layer_copy_tmp_debug_messengers()
+static void layer_free_tmp_debug_messengers(VkDebugUtilsMessengerCreateInfoEXT *infos, VkDebugUtilsMessengerEXT *messengers) {
+ free(infos);
+ free(messengers);
+}
+
+// This utility enables all of the VkDebugUtilsMessengerCreateInfoEXT structs
+// that were copied by layer_copy_tmp_debug_messengers()
+static VkResult layer_enable_tmp_debug_messengers(debug_report_data *debug_data, uint32_t num_messengers,
+ VkDebugUtilsMessengerCreateInfoEXT *infos, VkDebugUtilsMessengerEXT *messengers) {
+ VkResult rtn = VK_SUCCESS;
+ for (uint32_t i = 0; i < num_messengers; i++) {
+ rtn = layer_create_messenger_callback(debug_data, false, &infos[i], NULL, &messengers[i]);
+ if (rtn != VK_SUCCESS) {
+ for (uint32_t j = 0; j < i; j++) {
+ layer_destroy_messenger_callback(debug_data, messengers[j], NULL);
+ }
+ return rtn;
+ }
+ }
+ return rtn;
+}
+
+// This utility disables all of the VkDebugUtilsMessengerCreateInfoEXT structs
+// that were copied by layer_copy_tmp_debug_messengers()
+static void layer_disable_tmp_debug_messengers(debug_report_data *debug_data, uint32_t num_messengers,
+ VkDebugUtilsMessengerEXT *messengers) {
+ for (uint32_t i = 0; i < num_messengers; i++) {
+ layer_destroy_messenger_callback(debug_data, messengers[i], NULL);
}
}
// Checks if the message will get logged.
// Allows layer to defer collecting & formating data if the
// message will be discarded.
-static inline bool will_log_msg(debug_report_data *debug_data, VkFlags msgFlags) {
- if (!debug_data || !(debug_data->active_flags & msgFlags)) {
+static inline bool will_log_msg(debug_report_data *debug_data, VkFlags msg_flags) {
+ VkFlags local_severity = 0;
+ VkFlags local_type = 0;
+ DebugReportFlagsToAnnotFlags(msg_flags, true, &local_severity, &local_type);
+ if (!debug_data || !(debug_data->active_severities & local_severity) || !(debug_data->active_types & local_type)) {
// Message is not wanted
return false;
}
@@ -358,14 +803,17 @@ static inline int vasprintf(char **strp, char const *fmt, va_list ap) {
// Takes format and variable arg list so that output string
// is only computed if a message needs to be logged
#ifndef WIN32
-static inline bool log_msg(const debug_report_data *debug_data, VkFlags msgFlags, VkDebugReportObjectTypeEXT objectType,
- uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *format, ...)
- __attribute__((format(printf, 8, 9)));
+static inline bool log_msg(const debug_report_data *debug_data, VkFlags msg_flags, VkDebugReportObjectTypeEXT object_type,
+ uint64_t src_object, size_t location, int32_t msg_code, const char *layer_prefix, const char *format,
+ ...) __attribute__((format(printf, 8, 9)));
#endif
-static inline bool log_msg(const debug_report_data *debug_data, VkFlags msgFlags, VkDebugReportObjectTypeEXT objectType,
- uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *format,
+static inline bool log_msg(const debug_report_data *debug_data, VkFlags msg_flags, VkDebugReportObjectTypeEXT object_type,
+ uint64_t src_object, size_t location, int32_t msg_code, const char *layer_prefix, const char *format,
...) {
- if (!debug_data || !(debug_data->active_flags & msgFlags)) {
+ VkFlags local_severity = 0;
+ VkFlags local_type = 0;
+ DebugReportFlagsToAnnotFlags(msg_flags, true, &local_severity, &local_type);
+ if (!debug_data || !(debug_data->active_severities & local_severity) || !(debug_data->active_types & local_type)) {
// Message is not wanted
return false;
}
@@ -378,37 +826,38 @@ static inline bool log_msg(const debug_report_data *debug_data, VkFlags msgFlags
str = nullptr;
}
va_end(argptr);
- bool result = debug_report_log_msg(debug_data, msgFlags, objectType, srcObject, location, msgCode, pLayerPrefix,
- str ? str : "Allocation failure");
+ bool result = debug_log_msg(debug_data, msg_flags, object_type, src_object, location, msg_code, layer_prefix,
+ str ? str : "Allocation failure");
free(str);
return result;
}
-static inline VKAPI_ATTR VkBool32 VKAPI_CALL log_callback(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject,
- size_t location, int32_t msgCode, const char *pLayerPrefix,
- const char *pMsg, void *pUserData) {
- char msg_flags[30];
+static inline VKAPI_ATTR VkBool32 VKAPI_CALL report_log_callback(VkFlags msg_flags, VkDebugReportObjectTypeEXT obj_type,
+ uint64_t src_object, size_t location, int32_t msg_code,
+ const char *layer_prefix, const char *message, void *user_data) {
+ char msg_flag_string[30];
- print_msg_flags(msgFlags, msg_flags);
+ PrintMessageFlags(msg_flags, msg_flag_string);
- fprintf((FILE *)pUserData, "%s(%s): object: 0x%" PRIx64 " type: %d location: %lu msgCode: %d: %s\n", pLayerPrefix, msg_flags,
- srcObject, objType, (unsigned long)location, msgCode, pMsg);
- fflush((FILE *)pUserData);
+ fprintf((FILE *)user_data, "%s(%s): object: 0x%" PRIx64 " type: %d location: %lu msg_code: %d: %s\n", layer_prefix,
+ msg_flag_string, src_object, obj_type, (unsigned long)location, msg_code, message);
+ fflush((FILE *)user_data);
return false;
}
-static inline VKAPI_ATTR VkBool32 VKAPI_CALL win32_debug_output_msg(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType,
- uint64_t srcObject, size_t location, int32_t msgCode,
- const char *pLayerPrefix, const char *pMsg, void *pUserData) {
+static inline VKAPI_ATTR VkBool32 VKAPI_CALL report_win32_debug_output_msg(VkFlags msg_flags, VkDebugReportObjectTypeEXT obj_type,
+ uint64_t src_object, size_t location, int32_t msg_code,
+ const char *layer_prefix, const char *message,
+ void *user_data) {
#ifdef WIN32
- char msg_flags[30];
+ char msg_flag_string[30];
char buf[2048];
- print_msg_flags(msgFlags, msg_flags);
+ PrintMessageFlags(msg_flags, msg_flag_string);
_snprintf(buf, sizeof(buf) - 1,
- "%s (%s): object: 0x%" PRIxPTR " type: %d location: " PRINTF_SIZE_T_SPECIFIER " msgCode: %d: %s\n", pLayerPrefix,
- msg_flags, (size_t)srcObject, objType, location, msgCode, pMsg);
+ "%s (%s): object: 0x%" PRIxPTR " type: %d location: " PRINTF_SIZE_T_SPECIFIER " msg_code: %d: %s\n", layer_prefix,
+ msg_flag_string, (size_t)src_object, obj_type, location, msg_code, message);
OutputDebugString(buf);
#endif
@@ -416,9 +865,9 @@ static inline VKAPI_ATTR VkBool32 VKAPI_CALL win32_debug_output_msg(VkFlags msgF
return false;
}
-static inline VKAPI_ATTR VkBool32 VKAPI_CALL DebugBreakCallback(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType,
- uint64_t srcObject, size_t location, int32_t msgCode,
- const char *pLayerPrefix, const char *pMsg, void *pUserData) {
+static inline VKAPI_ATTR VkBool32 VKAPI_CALL DebugBreakCallback(VkFlags msgFlags, VkDebugReportObjectTypeEXT obj_type,
+ uint64_t src_object, size_t location, int32_t msg_code,
+ const char *layer_prefix, const char *message, void *user_data) {
#ifdef WIN32
DebugBreak();
#else
@@ -428,15 +877,177 @@ static inline VKAPI_ATTR VkBool32 VKAPI_CALL DebugBreakCallback(VkFlags msgFlags
return false;
}
-// TODO: Could be autogenerated for the specific handles for extra type safety...
-template <typename HANDLE_T>
-static inline uint64_t HandleToUint64(HANDLE_T *h) {
- return reinterpret_cast<uint64_t>(h);
+static inline VKAPI_ATTR VkBool32 VKAPI_CALL messenger_log_callback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
+ VkDebugUtilsMessageTypeFlagsEXT message_type,
+ const VkDebugUtilsMessengerCallbackDataEXT *callback_data,
+ void *user_data) {
+ char msg_severity[30];
+ char msg_type[30];
+
+ PrintMessageSeverity(message_severity, msg_severity);
+ PrintMessageType(message_type, msg_type);
+
+ fprintf((FILE *)user_data, "%s(%s / %s): object: 0x%" PRIx64 " type: %d msgNum: %d - %s\n", callback_data->pMessageIdName,
+ msg_severity, msg_type, callback_data->pObjects[0].objectHandle, callback_data->pObjects[0].objectType,
+ callback_data->messageIdNumber, callback_data->pMessage);
+ fflush((FILE *)user_data);
+
+ return false;
}
-template <typename HANDLE_T>
-uint64_t HandleToUint64(HANDLE_T h);
+static inline VKAPI_ATTR VkBool32 VKAPI_CALL messenger_win32_debug_output_msg(
+ VkDebugUtilsMessageSeverityFlagBitsEXT message_severity, VkDebugUtilsMessageTypeFlagsEXT message_type,
+ const VkDebugUtilsMessengerCallbackDataEXT *callback_data, void *user_data) {
+#ifdef WIN32
+ char buf[2048];
+ char msg_severity[30];
+ char msg_type[30];
-static inline uint64_t HandleToUint64(uint64_t h) { return h; }
+ PrintMessageSeverity(message_severity, msg_severity);
+ PrintMessageType(message_type, msg_type);
+
+ _snprintf(buf, sizeof(buf) - 1, "%s (%s / %s): object: 0x%" PRIxPTR " type: %d msgNum: %d - %s\n",
+ callback_data->pMessageIdName, msg_severity, msg_type, callback_data->pObjects[0].objectHandle,
+ callback_data->pObjects[0].objectType, callback_data->messageIdNumber, callback_data->pMessage);
+
+ OutputDebugString(buf);
+#endif
+
+ return false;
+}
+
+// This utility converts from the VkDebugUtilsLabelEXT structure into the logging version of the structure.
+// In the logging version, we only record what we absolutely need to convey back to the callbacks.
+static inline void InsertLabelIntoLog(const VkDebugUtilsLabelEXT *utils_label, std::vector<LoggingLabelData> &log_vector) {
+ LoggingLabelData log_label_data = {};
+ log_label_data.name = utils_label->pLabelName;
+ log_label_data.color[0] = utils_label->color[0];
+ log_label_data.color[1] = utils_label->color[1];
+ log_label_data.color[2] = utils_label->color[2];
+ log_label_data.color[3] = utils_label->color[3];
+ log_vector.push_back(log_label_data);
+}
+
+static void BeginQueueDebugUtilsLabel(debug_report_data *report_data, VkQueue queue, const VkDebugUtilsLabelEXT *label_info) {
+ if (nullptr != label_info && nullptr != label_info->pLabelName) {
+ auto label_iter = report_data->debugUtilsQueueLabels->find(queue);
+ if (label_iter == report_data->debugUtilsQueueLabels->end()) {
+ std::vector<LoggingLabelData> new_queue_labels;
+ InsertLabelIntoLog(label_info, new_queue_labels);
+ report_data->debugUtilsQueueLabels->insert({queue, new_queue_labels});
+ } else {
+ // If the last thing was a label insert, we need to pop it off of the label vector before any
+ // changes. This is because a label added with "vkQueueInsertDebugUtilsLabelEXT" is only a
+ // temporary location that exists until the next operation occurs. In this case, a new
+ // "vkQueueBeginDebugUtilsLabelEXT" has occurred erasing the previous inserted label.
+ if (report_data->queueLabelHasInsert) {
+ report_data->queueLabelHasInsert = false;
+ label_iter->second.pop_back();
+ }
+ InsertLabelIntoLog(label_info, label_iter->second);
+ }
+ }
+}
+
+static void EndQueueDebugUtilsLabel(debug_report_data *report_data, VkQueue queue) {
+ auto label_iter = report_data->debugUtilsQueueLabels->find(queue);
+ if (label_iter != report_data->debugUtilsQueueLabels->end()) {
+ // If the last thing was a label insert, we need to pop it off of the label vector before any
+ // changes. This is because a label added with "vkQueueInsertDebugUtilsLabelEXT" is only a
+ // temporary location that exists until the next operation occurs. In this case, a
+ // "vkQueueEndDebugUtilsLabelEXT" has occurred erasing the inserted label.
+ if (report_data->queueLabelHasInsert) {
+ report_data->queueLabelHasInsert = false;
+ label_iter->second.pop_back();
+ }
+ // Now pop the normal item
+ label_iter->second.pop_back();
+ }
+}
+
+static void InsertQueueDebugUtilsLabel(debug_report_data *report_data, VkQueue queue, const VkDebugUtilsLabelEXT *label_info) {
+ if (nullptr != label_info && nullptr != label_info->pLabelName) {
+ auto label_iter = report_data->debugUtilsQueueLabels->find(queue);
+ if (label_iter == report_data->debugUtilsQueueLabels->end()) {
+ std::vector<LoggingLabelData> new_queue_labels;
+ InsertLabelIntoLog(label_info, new_queue_labels);
+ report_data->debugUtilsQueueLabels->insert({queue, new_queue_labels});
+ } else {
+ // If the last thing was a label insert, we need to pop it off of the label vector before any
+ // changes. This is because a label added with "vkQueueInsertDebugUtilsLabelEXT" is only a
+ // temporary location that exists until the next operation occurs. In this case, a new
+ // "vkQueueInsertDebugUtilsLabelEXT" has occurred erasing the previous inserted label.
+ if (report_data->queueLabelHasInsert) {
+ label_iter->second.pop_back();
+ }
+ // Insert this new label and mark it as one that has been "inserted" so we can remove it on
+ // the next queue label operation.
+ InsertLabelIntoLog(label_info, label_iter->second);
+ report_data->queueLabelHasInsert = true;
+ }
+ }
+}
+
+static void BeginCmdDebugUtilsLabel(debug_report_data *report_data, VkCommandBuffer command_buffer,
+ const VkDebugUtilsLabelEXT *label_info) {
+ if (nullptr != label_info && nullptr != label_info->pLabelName) {
+ auto label_iter = report_data->debugUtilsCmdBufLabels->find(command_buffer);
+ if (label_iter == report_data->debugUtilsCmdBufLabels->end()) {
+ std::vector<LoggingLabelData> new_cmdbuf_labels;
+ InsertLabelIntoLog(label_info, new_cmdbuf_labels);
+ report_data->debugUtilsCmdBufLabels->insert({command_buffer, new_cmdbuf_labels});
+ } else {
+ // If the last thing was a label insert, we need to pop it off of the label vector before any
+ // changes. This is because a label added with "vkCmdInsertDebugUtilsLabelEXT" is only a
+ // temporary location that exists until the next operation occurs. In this case, a
+ // "vkCmdBeginDebugUtilsLabelEXT" has occurred erasing the inserted label.
+ if (report_data->cmdBufLabelHasInsert) {
+ report_data->cmdBufLabelHasInsert = false;
+ label_iter->second.pop_back();
+ }
+ InsertLabelIntoLog(label_info, label_iter->second);
+ }
+ }
+}
+
+static void EndCmdDebugUtilsLabel(debug_report_data *report_data, VkCommandBuffer command_buffer) {
+ auto label_iter = report_data->debugUtilsCmdBufLabels->find(command_buffer);
+ if (label_iter != report_data->debugUtilsCmdBufLabels->end()) {
+ // If the last thing was a label insert, we need to pop it off of the label vector before any
+ // changes. This is because a label added with "vkCmdInsertDebugUtilsLabelEXT" is only a
+ // temporary location that exists until the next operation occurs. In this case, a
+ // "vkCmdEndDebugUtilsLabelEXT" has occurred erasing the inserted label.
+ if (report_data->cmdBufLabelHasInsert) {
+ report_data->cmdBufLabelHasInsert = false;
+ label_iter->second.pop_back();
+ }
+ // Now pop the normal item
+ label_iter->second.pop_back();
+ }
+}
+
+static void InsertCmdDebugUtilsLabel(debug_report_data *report_data, VkCommandBuffer command_buffer,
+ const VkDebugUtilsLabelEXT *label_info) {
+ if (nullptr != label_info && nullptr != label_info->pLabelName) {
+ auto label_iter = report_data->debugUtilsCmdBufLabels->find(command_buffer);
+ if (label_iter == report_data->debugUtilsCmdBufLabels->end()) {
+ std::vector<LoggingLabelData> new_cmdbuf_labels;
+ InsertLabelIntoLog(label_info, new_cmdbuf_labels);
+ report_data->debugUtilsCmdBufLabels->insert({command_buffer, new_cmdbuf_labels});
+ } else {
+ // If the last thing was a label insert, we need to pop it off of the label vector before any
+ // changes. This is because a label added with "vkCmdInsertDebugUtilsLabelEXT" is only a
+ // temporary location that exists until the next operation occurs. In this case, a new
+ // "vkCmdInsertDebugUtilsLabelEXT" has occurred erasing the previous inserted label.
+ if (report_data->cmdBufLabelHasInsert) {
+ label_iter->second.pop_back();
+ }
+ // Insert this new label and mark it as one that has been "inserted" so we can remove it on
+ // the next command buffer label operation.
+ InsertLabelIntoLog(label_info, label_iter->second);
+ report_data->cmdBufLabelHasInsert = true;
+ }
+ }
+}
#endif // LAYER_LOGGING_H
diff --git a/layers/vk_layer_utils.cpp b/layers/vk_layer_utils.cpp
index d788daf7..629b19f4 100644
--- a/layers/vk_layer_utils.cpp
+++ b/layers/vk_layer_utils.cpp
@@ -91,8 +91,9 @@ VK_LAYER_EXPORT bool white_list(const char *item, const char *list) {
// If a vk_layer_settings.txt file is present and an application defines a debug callback, both callbacks
// will be active. If no vk_layer_settings.txt file is present, creating an application-defined debug
// callback will cause the default callbacks to be unregisterd and removed.
-VK_LAYER_EXPORT void layer_debug_actions(debug_report_data *report_data, std::vector<VkDebugReportCallbackEXT> &logging_callback,
- const VkAllocationCallbacks *pAllocator, const char *layer_identifier) {
+VK_LAYER_EXPORT void layer_debug_report_actions(debug_report_data *report_data,
+ std::vector<VkDebugReportCallbackEXT> &logging_callback,
+ const VkAllocationCallbacks *pAllocator, const char *layer_identifier) {
VkDebugReportCallbackEXT callback = VK_NULL_HANDLE;
std::string report_flags_key = layer_identifier;
@@ -115,9 +116,9 @@ VK_LAYER_EXPORT void layer_debug_actions(debug_report_data *report_data, std::ve
memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));
dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
dbgCreateInfo.flags = report_flags;
- dbgCreateInfo.pfnCallback = log_callback;
+ dbgCreateInfo.pfnCallback = report_log_callback;
dbgCreateInfo.pUserData = (void *)log_output;
- layer_create_msg_callback(report_data, default_layer_callback, &dbgCreateInfo, pAllocator, &callback);
+ layer_create_report_callback(report_data, default_layer_callback, &dbgCreateInfo, pAllocator, &callback);
logging_callback.push_back(callback);
}
@@ -128,9 +129,9 @@ VK_LAYER_EXPORT void layer_debug_actions(debug_report_data *report_data, std::ve
memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));
dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
dbgCreateInfo.flags = report_flags;
- dbgCreateInfo.pfnCallback = win32_debug_output_msg;
+ dbgCreateInfo.pfnCallback = report_win32_debug_output_msg;
dbgCreateInfo.pUserData = NULL;
- layer_create_msg_callback(report_data, default_layer_callback, &dbgCreateInfo, pAllocator, &callback);
+ layer_create_report_callback(report_data, default_layer_callback, &dbgCreateInfo, pAllocator, &callback);
logging_callback.push_back(callback);
}
@@ -143,7 +144,64 @@ VK_LAYER_EXPORT void layer_debug_actions(debug_report_data *report_data, std::ve
dbgCreateInfo.flags = report_flags;
dbgCreateInfo.pfnCallback = DebugBreakCallback;
dbgCreateInfo.pUserData = NULL;
- layer_create_msg_callback(report_data, default_layer_callback, &dbgCreateInfo, pAllocator, &callback);
+ layer_create_report_callback(report_data, default_layer_callback, &dbgCreateInfo, pAllocator, &callback);
logging_callback.push_back(callback);
}
}
+
+VK_LAYER_EXPORT void layer_debug_messenger_actions(debug_report_data *report_data,
+ std::vector<VkDebugUtilsMessengerEXT> &logging_messenger,
+ const VkAllocationCallbacks *pAllocator, const char *layer_identifier) {
+ VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE;
+
+ std::string report_flags_key = layer_identifier;
+ std::string debug_action_key = layer_identifier;
+ std::string log_filename_key = layer_identifier;
+ report_flags_key.append(".report_flags");
+ debug_action_key.append(".debug_action");
+ log_filename_key.append(".log_filename");
+
+ // Initialize layer options
+ VkDebugReportFlagsEXT report_flags = GetLayerOptionFlags(report_flags_key, report_flags_option_definitions, 0);
+ VkLayerDbgActionFlags debug_action = GetLayerOptionFlags(debug_action_key, debug_actions_option_definitions, 0);
+ // Flag as default if these settings are not from a vk_layer_settings.txt file
+ bool default_layer_callback = (debug_action & VK_DBG_LAYER_ACTION_DEFAULT) ? true : false;
+ VkDebugUtilsMessengerCreateInfoEXT dbgCreateInfo;
+ memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));
+ dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
+ dbgCreateInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
+ if (report_flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
+ dbgCreateInfo.messageSeverity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
+ }
+ if (report_flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
+ dbgCreateInfo.messageSeverity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
+ }
+ if (report_flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
+ dbgCreateInfo.messageSeverity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
+ dbgCreateInfo.messageType |= VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
+ }
+ if (report_flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
+ dbgCreateInfo.messageSeverity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
+ }
+ if (report_flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
+ dbgCreateInfo.messageSeverity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
+ }
+
+ if (debug_action & VK_DBG_LAYER_ACTION_LOG_MSG) {
+ const char *log_filename = getLayerOption(log_filename_key.c_str());
+ FILE *log_output = getLayerLogOutput(log_filename, layer_identifier);
+ dbgCreateInfo.pfnUserCallback = messenger_log_callback;
+ dbgCreateInfo.pUserData = (void *)log_output;
+ layer_create_messenger_callback(report_data, default_layer_callback, &dbgCreateInfo, pAllocator, &messenger);
+ logging_messenger.push_back(messenger);
+ }
+
+ messenger = VK_NULL_HANDLE;
+
+ if (debug_action & VK_DBG_LAYER_ACTION_DEBUG_OUTPUT) {
+ dbgCreateInfo.pfnUserCallback = messenger_win32_debug_output_msg;
+ dbgCreateInfo.pUserData = NULL;
+ layer_create_messenger_callback(report_data, default_layer_callback, &dbgCreateInfo, pAllocator, &messenger);
+ logging_messenger.push_back(messenger);
+ }
+}
diff --git a/layers/vk_layer_utils.h b/layers/vk_layer_utils.h
index d1969c84..08574a5e 100644
--- a/layers/vk_layer_utils.h
+++ b/layers/vk_layer_utils.h
@@ -37,10 +37,6 @@ extern "C" {
#define VK_LAYER_API_VERSION VK_MAKE_VERSION(1, 0, VK_HEADER_VERSION)
-
-
-
-
typedef enum VkStringErrorFlagBits {
VK_STRING_ERROR_NONE = 0x00000000,
VK_STRING_ERROR_LENGTH = 0x00000001,
@@ -48,8 +44,13 @@ typedef enum VkStringErrorFlagBits {
} VkStringErrorFlagBits;
typedef VkFlags VkStringErrorFlags;
-VK_LAYER_EXPORT void layer_debug_actions(debug_report_data *report_data, std::vector<VkDebugReportCallbackEXT> &logging_callback,
- const VkAllocationCallbacks *pAllocator, const char *layer_identifier);
+VK_LAYER_EXPORT void layer_debug_report_actions(debug_report_data *report_data,
+ std::vector<VkDebugReportCallbackEXT> &logging_callback,
+ const VkAllocationCallbacks *pAllocator, const char *layer_identifier);
+
+VK_LAYER_EXPORT void layer_debug_messenger_actions(debug_report_data *report_data,
+ std::vector<VkDebugUtilsMessengerEXT> &logging_messenger,
+ const VkAllocationCallbacks *pAllocator, const char *layer_identifier);
VK_LAYER_EXPORT VkStringErrorFlags vk_string_validate(const int max_length, const char *char_array);
VK_LAYER_EXPORT bool white_list(const char *item, const char *whitelist);