/* 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_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>
#include <stdbool.h>
#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;
    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_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 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 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_severities = 0;
    VkFlags local_types = 0;

    while (cur_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_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;
            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;
        if (matched) {
            free(prev_callback);
        }
    }
    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, 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;
    }
    *list_head = NULL;
}

// Utility function to handle reporting
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 *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 = 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 (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,
                  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 (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 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 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, 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 msg_flags, VkDebugReportObjectTypeEXT object_type,
                           uint64_t src_object, size_t location, int32_t msg_code, const char *layer_prefix, 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);
    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 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): 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 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): 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

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

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

    _snprintf(buf, sizeof(buf) - 1, "%s (%s / %s): object: 0x%" PRIx64 " type: %d  msgNum: %d - %s\n",
              callback_data->pMessageIdName, msg_severity, msg_type, HandleToUint64(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
