/* 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.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
 * Author: Tobin Ehlis <tobin@lunarg.com>
 * Author: Mark Young <marky@lunarg.com>
 *
 */

#ifndef LAYER_LOGGING_H
#define LAYER_LOGGING_H

#include "vk_loader_layer.h"
#include "vk_layer_config.h"
#include "vk_layer_data.h"
#include "vk_loader_platform.h"
#include "vulkan/vk_layer.h"
#include "vk_object_types.h"
#include "vk_validation_error_messages.h"
#include "vk_layer_dispatch_table.h"
#include <signal.h>
#include <cinttypes>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <unordered_map>
#include <vector>
#include <sstream>
#include <string>

// Suppress unused warning on Linux
#if defined(__GNUC__)
#define DECORATE_UNUSED __attribute__((unused))
#else
#define DECORATE_UNUSED
#endif

static const char DECORATE_UNUSED *kVUIDUndefined = "VUID_Undefined";

#undef DECORATE_UNUSED

// 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;
    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) {
    *da_severity = 0;
    *da_type = 0;
    // If it's explicitly listed as a performance warning, treat it as a performance message.
    // Otherwise, treat it as a validation issue.
    if ((dr_flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) != 0) {
        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
        *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
    }
    if ((dr_flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) != 0) {
        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
        *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
    }
    if ((dr_flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) != 0) {
        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
        *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
    }
    if ((dr_flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) != 0) {
        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
        *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
    }
    if ((dr_flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) != 0) {
        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
        *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
    }
}

// Forward Declarations
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, const char *layer_prefix, const char *message,
                                 const char *text_vuid);

// Add a debug message callback node structure to the specified callback linked list
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 = nullptr;
    bool matched = false;
    VkFlags local_severities = 0;
    VkFlags local_types = 0;

    while (cur_callback) {
        if (cur_callback->is_messenger) {
            // If it's actually a messenger, then set it up for deletion.
            if (cur_callback->messenger.messenger == messenger) {
                matched = true;
                if (*list_head == cur_callback) {
                    *list_head = cur_callback->pNext;
                } else {
                    assert(nullptr != prev_callback);
                    prev_callback->pNext = 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, "DebugUtilsMessenger",
                              "Destroyed messenger\n", kVUIDUndefined);
            } else {
                // If it's not the one we're looking for, just keep the types/severities
                local_severities |= cur_callback->messenger.messageSeverity;
                local_types |= cur_callback->messenger.messageType;
            }
        } else {
            // If it's not a messenger, just keep the types/severities
            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;
        }
        if (matched) {
            free(cur_callback);
            matched = false;
            // Intentionally keep the last prev_callback, but select the proper cur_callback
            if (nullptr != prev_callback) {
                cur_callback = prev_callback->pNext;
            } else {
                cur_callback = *list_head;
            }
        } else {
            prev_callback = cur_callback;
            cur_callback = cur_callback->pNext;
        }
    }
    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 RemoveDebugUtilsMessageCallback(debug_report_data *debug_data, VkLayerDbgFunctionNode **list_head,
                                                   VkDebugReportCallbackEXT callback) {
    VkLayerDbgFunctionNode *cur_callback = *list_head;
    VkLayerDbgFunctionNode *prev_callback = nullptr;
    bool matched = false;
    VkFlags local_severities = 0;
    VkFlags local_types = 0;

    while (cur_callback) {
        if (!cur_callback->is_messenger) {
            // If it's actually a callback, then set it up for deletion.
            if (cur_callback->report.msgCallback == callback) {
                matched = true;
                if (*list_head == cur_callback) {
                    *list_head = cur_callback->pNext;
                } else {
                    assert(nullptr != prev_callback);
                    prev_callback->pNext = 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->report.msgCallback), 0, "DebugReport",
                              "Destroyed callback\n", kVUIDUndefined);
            } else {
                // If it's not the one we're looking for, just keep the types/severities
                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;
            }
        } else {
            // If it's not a callback, just keep the types/severities
            local_severities |= cur_callback->messenger.messageSeverity;
            local_types |= cur_callback->messenger.messageType;
        }
        if (matched) {
            free(cur_callback);
            matched = false;
            // Intentionally keep the last prev_callback, but select the proper cur_callback
            if (nullptr != prev_callback) {
                cur_callback = prev_callback->pNext;
            } else {
                cur_callback = *list_head;
            }
        } else {
            prev_callback = cur_callback;
            cur_callback = cur_callback->pNext;
        }
    }
    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
static inline void RemoveAllMessageCallbacks(debug_report_data *debug_data, VkLayerDbgFunctionNode **list_head) {
    VkLayerDbgFunctionNode *current_callback = *list_head;
    VkLayerDbgFunctionNode *prev_callback = current_callback;

    while (current_callback) {
        prev_callback = current_callback->pNext;
        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, "DebugReport",
                          "Debug Report callbacks not removed before DestroyInstance", kVUIDUndefined);
        } 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, "Messenger",
                          "Debug messengers not removed before DestroyInstance", kVUIDUndefined);
        }
        free(current_callback);
        current_callback = prev_callback;
    }
    *list_head = NULL;
}

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, const char *layer_prefix, const char *message,
                                 const char *text_vuid) {
    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;
    }

    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 = text_vuid;
    callback_data.messageIdNumber = 0;  // deprecated, validation layers use only the pMessageIdName
    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;

    if (0 != src_object) {
        oss << "Object: 0x" << std::hex << 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 << " : Type = ";
        } else {
            oss << " (Type = ";
        }
        oss << std::to_string(object_type) << ")";
    } else {
        oss << "Object: VK_NULL_HANDLE (Type = " << std::to_string(object_type) << ")";
    }
    new_debug_report_message += oss.str();
    new_debug_report_message += " | ";
    new_debug_report_message += message;

    while (layer_dbg_node) {
        // If the app uses the VK_EXT_debug_report extension, call all of those registered callbacks.
        if (!layer_dbg_node->is_messenger && (layer_dbg_node->report.msgFlags & msg_flags)) {
            if (text_vuid != nullptr) {
                // If a text vuid is supplied for the old debug report extension, prepend it to the message string
                new_debug_report_message.insert(0, " ] ");
                new_debug_report_message.insert(0, text_vuid);
                new_debug_report_message.insert(0, " [ ");
            }

            if (layer_dbg_node->report.pfnMsgCallback(msg_flags, object_type, src_object, location, 0, layer_prefix,
                                                      new_debug_report_message.c_str(), layer_dbg_node->pUserData)) {
                bail = true;
            }
            // If the app uses the VK_EXT_debug_utils extension, call all of those registered callbacks.
        } else if (layer_dbg_node->is_messenger && (layer_dbg_node->messenger.messageSeverity & severity) &&
                   (layer_dbg_node->messenger.messageType & types)) {
            if (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 = convertCoreObjectToDebugReportObject(callback_data->pObjects[0].objectType);
            if (it == debug_data->debugObjectNameMap->end()) {
                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(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;
                }
            }
        }
        layer_dbg_node = layer_dbg_node->pNext;
    }

    return bail;
}

static inline debug_report_data *debug_utils_create_instance(
    VkLayerInstanceDispatchTable *table, VkInstance inst, uint32_t extension_count,
    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;

    memset(debug_data, 0, sizeof(debug_report_data));
    for (uint32_t i = 0; i < extension_count; i++) {
        // TODO: Check other property fields
        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_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_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_utils_destroy_device(VkDevice device) {
    // Nothing to do since we're using instance data record
}

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_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 (!(*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) {
        AddDebugCallbackNode(debug_data, &debug_data->default_debug_callback_list, pNewDbgFuncNode);
    } else {
        AddDebugCallbackNode(debug_data, &debug_data->debug_callback_list, pNewDbgFuncNode);
    }

    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 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);
    }

    debug_log_msg(debug_data, VK_DEBUG_REPORT_DEBUG_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT, (uint64_t)*callback, 0,
                  "DebugReport", "Added callback", kVUIDUndefined);
    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 (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 (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;
}

// This utility (called at vkCreateInstance() time), looks at a pNext chain.
// It counts any VkDebugReportCallbackCreateInfoEXT structs that it finds.  It
// 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_report_callbacks(const void *pChain, uint32_t *num_callbacks,
                                                       VkDebugReportCallbackCreateInfoEXT **infos,
                                                       VkDebugReportCallbackEXT **callbacks) {
    uint32_t n = *num_callbacks = 0;

    const void *pNext = pChain;
    while (pNext) {
        // 1st, count the number VkDebugReportCallbackCreateInfoEXT:
        if (((VkDebugReportCallbackCreateInfoEXT *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
            n++;
        }
        pNext = (void *)((VkDebugReportCallbackCreateInfoEXT *)pNext)->pNext;
    }
    if (n == 0) {
        return VK_SUCCESS;
    }

    // 2nd, allocate memory for each VkDebugReportCallbackCreateInfoEXT:
    VkDebugReportCallbackCreateInfoEXT *pInfos = *infos =
        ((VkDebugReportCallbackCreateInfoEXT *)malloc(n * sizeof(VkDebugReportCallbackCreateInfoEXT)));
    if (!pInfos) {
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }
    // 3rd, allocate memory for a unique handle for each callback:
    VkDebugReportCallbackEXT *pCallbacks = *callbacks = ((VkDebugReportCallbackEXT *)malloc(n * sizeof(VkDebugReportCallbackEXT)));
    if (!pCallbacks) {
        free(pInfos);
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }
    // 4th, copy each VkDebugReportCallbackCreateInfoEXT for use by
    // vkDestroyInstance, and assign a unique handle to each callback (just
    // use the address of the copied VkDebugReportCallbackCreateInfoEXT):
    pNext = pChain;
    while (pNext) {
        if (((VkInstanceCreateInfo *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
            memcpy(pInfos, pNext, sizeof(VkDebugReportCallbackCreateInfoEXT));
            *pCallbacks++ = (VkDebugReportCallbackEXT)pInfos++;
        }
        pNext = (void *)((VkInstanceCreateInfo *)pNext)->pNext;
    }

    *num_callbacks = n;
    return VK_SUCCESS;
}

// 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_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_report_callback(debug_data, false, &infos[i], NULL, &callbacks[i]);
        if (rtn != VK_SUCCESS) {
            for (uint32_t j = 0; j < i; j++) {
                layer_destroy_report_callback(debug_data, callbacks[j], NULL);
            }
            return rtn;
        }
    }
    return rtn;
}

// This utility disables all of the VkDebugReportCallbackCreateInfoEXT structs
// 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_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 inline 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 inline 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 inline 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 inline 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 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;
    }

    return true;
}
#ifndef WIN32
static inline int string_sprintf(std::string *output, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
#endif
static inline int string_sprintf(std::string *output, const char *fmt, ...) {
    std::string &formatted = *output;
    va_list argptr;
    va_start(argptr, fmt);
    int reserve = vsnprintf(nullptr, 0, fmt, argptr);
    va_end(argptr);
    formatted.reserve(reserve + 1);
    va_start(argptr, fmt);
    int result = vsnprintf((char *)formatted.data(), formatted.capacity(), fmt, argptr);
    va_end(argptr);
    assert(result == reserve);
    return result;
}

#ifdef WIN32
static inline int vasprintf(char **strp, char const *fmt, va_list ap) {
    *strp = nullptr;
    int size = _vscprintf(fmt, ap);
    if (size >= 0) {
        *strp = (char *)malloc(size + 1);
        if (!*strp) {
            return -1;
        }
        _vsnprintf(*strp, size + 1, fmt, ap);
    }
    return size;
}
#endif

// Output log message via DEBUG_REPORT. 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 msg_flags, VkDebugReportObjectTypeEXT object_type,
                           uint64_t src_object, std::string vuid_text, const char *format, ...)
    __attribute__((format(printf, 6, 7)));
#endif
static inline bool log_msg(const debug_report_data *debug_data, VkFlags msg_flags, VkDebugReportObjectTypeEXT object_type,
                           uint64_t src_object, std::string vuid_text, const char *format, ...) {
    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;
    }

    va_list argptr;
    va_start(argptr, format);
    char *str;
    if (-1 == vasprintf(&str, format, argptr)) {
        // On failure, glibc vasprintf leaves str undefined
        str = nullptr;
    }
    va_end(argptr);

    std::string str_plus_spec_text(str ? str : "Allocation failure");

    // Append the spec error text to the error message, unless it's an UNASSIGNED or UNDEFINED vuid
    if ((vuid_text.find("UNASSIGNED-") == std::string::npos) && (vuid_text.find(kVUIDUndefined) == std::string::npos)) {
        if (vuid_to_error_text_map.find(vuid_text) == vuid_to_error_text_map.end()) {
            // If this happens, you've hit a VUID string that isn't defined in the spec's json file
            // Try running 'vk_validation_stats -c' to look for invalid VUID strings in the repo code
            assert(0);
        } else {
            str_plus_spec_text += " The Vulkan spec states: ";
            str_plus_spec_text += vuid_to_error_text_map[vuid_text];
        }
    }

    // Append layer prefix with VUID string, pass in recovered legacy numerical VUID
    bool result = debug_log_msg(debug_data, msg_flags, object_type, src_object, 0, "Validation", str_plus_spec_text.c_str(),
                                vuid_text.c_str());

    free(str);
    return result;
}

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];

    PrintMessageFlags(msg_flags, msg_flag_string);

    fprintf((FILE *)user_data, "%s(%s): msg_code: %d: %s\n", layer_prefix, msg_flag_string, msg_code, message);
    fflush((FILE *)user_data);

    return false;
}

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_flag_string[30];
    char buf[2048];

    PrintMessageFlags(msg_flags, msg_flag_string);
    _snprintf(buf, sizeof(buf) - 1, "%s (%s): msg_code: %d: %s\n", layer_prefix, msg_flag_string, msg_code, message);

    OutputDebugString(buf);
#endif

    return false;
}

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
    raise(SIGTRAP);
#endif

    return false;
}

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): msgNum: %d - %s\n", callback_data->pMessageIdName, msg_severity, msg_type,
            callback_data->messageIdNumber, callback_data->pMessage);
    fprintf((FILE *)user_data, "    Objects: %d\n", callback_data->objectCount);
    for (uint32_t obj = 0; obj < callback_data->objectCount; ++obj) {
        fprintf((FILE *)user_data, "       [%d] 0x%" PRIx64 ", type: %d, name: %s\n", obj,
                callback_data->pObjects[obj].objectHandle, callback_data->pObjects[obj].objectType,
                callback_data->pObjects[obj].pObjectName);
    }
    fflush((FILE *)user_data);

    return false;
}

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];

    PrintMessageSeverity(message_severity, msg_severity);
    PrintMessageType(message_type, msg_type);

    size_t buffer_space = sizeof(buf) - 1;
    size_t remaining_space = buffer_space;
    _snprintf(buf, sizeof(buf) - 1, "%s(%s / %s): msgNum: %d - %s\n", callback_data->pMessageIdName, msg_severity, msg_type,
              callback_data->messageIdNumber, callback_data->pMessage);
    remaining_space = buffer_space - strlen(buf);
    _snprintf(buf, remaining_space, "    Objects: %d\n", callback_data->objectCount);
    for (uint32_t obj = 0; obj < callback_data->objectCount; ++obj) {
        remaining_space = buffer_space - strlen(buf);
        if (remaining_space > 0) {
            _snprintf(buf, remaining_space, "       [%d] 0x%" PRIx64 ", type: %d, name: %s\n", obj,
                      callback_data->pObjects[obj].objectHandle, callback_data->pObjects[obj].objectType,
                      callback_data->pObjects[obj].pObjectName);
        }
    }
    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 inline 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 inline 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 inline 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 inline 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 inline 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 inline 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
