15db71995Sopenharmony_ci/*
25db71995Sopenharmony_ci * Copyright (c) 2015-2021 The Khronos Group Inc.
35db71995Sopenharmony_ci * Copyright (c) 2015-2021 Valve Corporation
45db71995Sopenharmony_ci * Copyright (c) 2015-2021 LunarG, Inc.
55db71995Sopenharmony_ci * Copyright (C) 2015-2016 Google Inc.
65db71995Sopenharmony_ci *
75db71995Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
85db71995Sopenharmony_ci * you may not use this file except in compliance with the License.
95db71995Sopenharmony_ci * You may obtain a copy of the License at
105db71995Sopenharmony_ci *
115db71995Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
125db71995Sopenharmony_ci *
135db71995Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
145db71995Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
155db71995Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
165db71995Sopenharmony_ci * See the License for the specific language governing permissions and
175db71995Sopenharmony_ci * limitations under the License.
185db71995Sopenharmony_ci *
195db71995Sopenharmony_ci * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
205db71995Sopenharmony_ci * Author: Jon Ashburn <jon@LunarG.com>
215db71995Sopenharmony_ci * Author: Mark Young <marky@lunarg.com>
225db71995Sopenharmony_ci * Author: Charles Giessen <charles@lunarg.com>
235db71995Sopenharmony_ci *
245db71995Sopenharmony_ci */
255db71995Sopenharmony_ci
265db71995Sopenharmony_ci#include <inttypes.h>
275db71995Sopenharmony_ci#include <stdio.h>
285db71995Sopenharmony_ci#include <stdlib.h>
295db71995Sopenharmony_ci#include <string.h>
305db71995Sopenharmony_ci#if !defined(WIN32)
315db71995Sopenharmony_ci#include <signal.h>
325db71995Sopenharmony_ci#endif
335db71995Sopenharmony_ci
345db71995Sopenharmony_ci#include "vulkan/vk_layer.h"
355db71995Sopenharmony_ci#include "vk_object_types.h"
365db71995Sopenharmony_ci
375db71995Sopenharmony_ci#include "allocation.h"
385db71995Sopenharmony_ci#include "debug_utils.h"
395db71995Sopenharmony_ci#include "log.h"
405db71995Sopenharmony_ci#include "loader.h"
415db71995Sopenharmony_ci#include "vk_loader_platform.h"
425db71995Sopenharmony_ci
435db71995Sopenharmony_ci// VK_EXT_debug_report related items
445db71995Sopenharmony_ci
455db71995Sopenharmony_ciVkResult util_CreateDebugUtilsMessenger(struct loader_instance *inst, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
465db71995Sopenharmony_ci                                        const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT messenger) {
475db71995Sopenharmony_ci    VkLayerDbgFunctionNode *new_dbg_function_node = NULL;
485db71995Sopenharmony_ci
495db71995Sopenharmony_ci    new_dbg_function_node = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
505db71995Sopenharmony_ci        pAllocator, inst, sizeof(VkLayerDbgFunctionNode), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
515db71995Sopenharmony_ci
525db71995Sopenharmony_ci    if (!new_dbg_function_node) {
535db71995Sopenharmony_ci        return VK_ERROR_OUT_OF_HOST_MEMORY;
545db71995Sopenharmony_ci    }
555db71995Sopenharmony_ci
565db71995Sopenharmony_ci    new_dbg_function_node->is_messenger = true;
575db71995Sopenharmony_ci    new_dbg_function_node->messenger.messenger = messenger;
585db71995Sopenharmony_ci    new_dbg_function_node->messenger.pfnUserCallback = pCreateInfo->pfnUserCallback;
595db71995Sopenharmony_ci    new_dbg_function_node->messenger.messageSeverity = pCreateInfo->messageSeverity;
605db71995Sopenharmony_ci    new_dbg_function_node->messenger.messageType = pCreateInfo->messageType;
615db71995Sopenharmony_ci    new_dbg_function_node->pUserData = pCreateInfo->pUserData;
625db71995Sopenharmony_ci    new_dbg_function_node->pNext = inst->instance_only_dbg_function_head;
635db71995Sopenharmony_ci    inst->instance_only_dbg_function_head = new_dbg_function_node;
645db71995Sopenharmony_ci    inst->current_dbg_function_head = inst->instance_only_dbg_function_head;
655db71995Sopenharmony_ci
665db71995Sopenharmony_ci    return VK_SUCCESS;
675db71995Sopenharmony_ci}
685db71995Sopenharmony_ci
695db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL debug_utils_CreateDebugUtilsMessengerEXT(VkInstance instance,
705db71995Sopenharmony_ci                                                                        const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
715db71995Sopenharmony_ci                                                                        const VkAllocationCallbacks *pAllocator,
725db71995Sopenharmony_ci                                                                        VkDebugUtilsMessengerEXT *pMessenger) {
735db71995Sopenharmony_ci    struct loader_instance *inst = loader_get_instance(instance);
745db71995Sopenharmony_ci    loader_platform_thread_lock_mutex(&loader_lock);
755db71995Sopenharmony_ci    VkResult result = inst->disp->layer_inst_disp.CreateDebugUtilsMessengerEXT(inst->instance, pCreateInfo, pAllocator, pMessenger);
765db71995Sopenharmony_ci    loader_platform_thread_unlock_mutex(&loader_lock);
775db71995Sopenharmony_ci    return result;
785db71995Sopenharmony_ci}
795db71995Sopenharmony_ci
805db71995Sopenharmony_ciVkBool32 util_SubmitDebugUtilsMessageEXT(const struct loader_instance *inst, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
815db71995Sopenharmony_ci                                         VkDebugUtilsMessageTypeFlagsEXT messageTypes,
825db71995Sopenharmony_ci                                         const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) {
835db71995Sopenharmony_ci    VkBool32 bail = false;
845db71995Sopenharmony_ci
855db71995Sopenharmony_ci    if (NULL != pCallbackData) {
865db71995Sopenharmony_ci        VkLayerDbgFunctionNode *pTrav = inst->current_dbg_function_head;
875db71995Sopenharmony_ci        VkDebugReportObjectTypeEXT object_type = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;
885db71995Sopenharmony_ci        VkDebugReportFlagsEXT object_flags = 0;
895db71995Sopenharmony_ci        uint64_t object_handle = 0;
905db71995Sopenharmony_ci
915db71995Sopenharmony_ci        debug_utils_AnnotFlagsToReportFlags(messageSeverity, messageTypes, &object_flags);
925db71995Sopenharmony_ci        if (0 < pCallbackData->objectCount) {
935db71995Sopenharmony_ci            debug_utils_AnnotObjectToDebugReportObject(pCallbackData->pObjects, &object_type, &object_handle);
945db71995Sopenharmony_ci        }
955db71995Sopenharmony_ci
965db71995Sopenharmony_ci        while (pTrav) {
975db71995Sopenharmony_ci            if (pTrav->is_messenger && (pTrav->messenger.messageSeverity & messageSeverity) &&
985db71995Sopenharmony_ci                (pTrav->messenger.messageType & messageTypes)) {
995db71995Sopenharmony_ci                if (pTrav->messenger.pfnUserCallback(messageSeverity, messageTypes, pCallbackData, pTrav->pUserData)) {
1005db71995Sopenharmony_ci                    bail = true;
1015db71995Sopenharmony_ci                }
1025db71995Sopenharmony_ci            }
1035db71995Sopenharmony_ci            if (!pTrav->is_messenger && pTrav->report.msgFlags & object_flags) {
1045db71995Sopenharmony_ci                if (pTrav->report.pfnMsgCallback(object_flags, object_type, object_handle, 0, pCallbackData->messageIdNumber,
1055db71995Sopenharmony_ci                                                 pCallbackData->pMessageIdName, pCallbackData->pMessage, pTrav->pUserData)) {
1065db71995Sopenharmony_ci                    bail = true;
1075db71995Sopenharmony_ci                }
1085db71995Sopenharmony_ci            }
1095db71995Sopenharmony_ci
1105db71995Sopenharmony_ci            pTrav = pTrav->pNext;
1115db71995Sopenharmony_ci        }
1125db71995Sopenharmony_ci    }
1135db71995Sopenharmony_ci
1145db71995Sopenharmony_ci    return bail;
1155db71995Sopenharmony_ci}
1165db71995Sopenharmony_ci
1175db71995Sopenharmony_civoid util_DestroyDebugUtilsMessenger(struct loader_instance *inst, VkDebugUtilsMessengerEXT messenger,
1185db71995Sopenharmony_ci                                     const VkAllocationCallbacks *pAllocator) {
1195db71995Sopenharmony_ci    VkLayerDbgFunctionNode *pTrav = inst->current_dbg_function_head;
1205db71995Sopenharmony_ci    VkLayerDbgFunctionNode *pPrev = pTrav;
1215db71995Sopenharmony_ci
1225db71995Sopenharmony_ci    while (pTrav) {
1235db71995Sopenharmony_ci        if (pTrav->is_messenger && pTrav->messenger.messenger == messenger) {
1245db71995Sopenharmony_ci            pPrev->pNext = pTrav->pNext;
1255db71995Sopenharmony_ci            if (inst->current_dbg_function_head == pTrav) inst->current_dbg_function_head = pTrav->pNext;
1265db71995Sopenharmony_ci            if (inst->instance_only_dbg_function_head == pTrav) inst->instance_only_dbg_function_head = pTrav->pNext;
1275db71995Sopenharmony_ci            loader_free_with_instance_fallback(pAllocator, inst, pTrav);
1285db71995Sopenharmony_ci            break;
1295db71995Sopenharmony_ci        }
1305db71995Sopenharmony_ci        pPrev = pTrav;
1315db71995Sopenharmony_ci        pTrav = pTrav->pNext;
1325db71995Sopenharmony_ci    }
1335db71995Sopenharmony_ci}
1345db71995Sopenharmony_ci
1355db71995Sopenharmony_ciVkResult util_CreateDebugUtilsMessengers(struct loader_instance *inst, const void *pChain,
1365db71995Sopenharmony_ci                                         const VkAllocationCallbacks *pAllocator) {
1375db71995Sopenharmony_ci    const void *pNext = pChain;
1385db71995Sopenharmony_ci    while (pNext) {
1395db71995Sopenharmony_ci        if (((const VkBaseInStructure *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) {
1405db71995Sopenharmony_ci            // Assign a unique handle to each messenger (just use the address of the VkDebugUtilsMessengerCreateInfoEXT)
1415db71995Sopenharmony_ci            // This is only being used this way due to it being for an 'anonymous' callback during instance creation
1425db71995Sopenharmony_ci            VkDebugUtilsMessengerEXT messenger_handle = (VkDebugUtilsMessengerEXT)(uintptr_t)pNext;
1435db71995Sopenharmony_ci            VkResult ret = util_CreateDebugUtilsMessenger(inst, (const VkDebugUtilsMessengerCreateInfoEXT *)pNext, pAllocator,
1445db71995Sopenharmony_ci                                                          messenger_handle);
1455db71995Sopenharmony_ci            if (ret != VK_SUCCESS) {
1465db71995Sopenharmony_ci                return ret;
1475db71995Sopenharmony_ci            }
1485db71995Sopenharmony_ci        }
1495db71995Sopenharmony_ci        pNext = (void *)((VkBaseInStructure *)pNext)->pNext;
1505db71995Sopenharmony_ci    }
1515db71995Sopenharmony_ci    return VK_SUCCESS;
1525db71995Sopenharmony_ci}
1535db71995Sopenharmony_ci
1545db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL debug_utils_SubmitDebugUtilsMessageEXT(VkInstance instance,
1555db71995Sopenharmony_ci                                                                  VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
1565db71995Sopenharmony_ci                                                                  VkDebugUtilsMessageTypeFlagsEXT messageTypes,
1575db71995Sopenharmony_ci                                                                  const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) {
1585db71995Sopenharmony_ci    struct loader_instance *inst = loader_get_instance(instance);
1595db71995Sopenharmony_ci
1605db71995Sopenharmony_ci    inst->disp->layer_inst_disp.SubmitDebugUtilsMessageEXT(inst->instance, messageSeverity, messageTypes, pCallbackData);
1615db71995Sopenharmony_ci}
1625db71995Sopenharmony_ci
1635db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL debug_utils_DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
1645db71995Sopenharmony_ci                                                                     const VkAllocationCallbacks *pAllocator) {
1655db71995Sopenharmony_ci    struct loader_instance *inst = loader_get_instance(instance);
1665db71995Sopenharmony_ci    loader_platform_thread_lock_mutex(&loader_lock);
1675db71995Sopenharmony_ci
1685db71995Sopenharmony_ci    inst->disp->layer_inst_disp.DestroyDebugUtilsMessengerEXT(inst->instance, messenger, pAllocator);
1695db71995Sopenharmony_ci
1705db71995Sopenharmony_ci    loader_platform_thread_unlock_mutex(&loader_lock);
1715db71995Sopenharmony_ci}
1725db71995Sopenharmony_ci
1735db71995Sopenharmony_ci// This is the instance chain terminator function for CreateDebugUtilsMessenger
1745db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugUtilsMessengerEXT(VkInstance instance,
1755db71995Sopenharmony_ci                                                                       const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo,
1765db71995Sopenharmony_ci                                                                       const VkAllocationCallbacks *pAllocator,
1775db71995Sopenharmony_ci                                                                       VkDebugUtilsMessengerEXT *pMessenger) {
1785db71995Sopenharmony_ci    VkDebugUtilsMessengerEXT *icd_info = NULL;
1795db71995Sopenharmony_ci    const struct loader_icd_term *icd_term;
1805db71995Sopenharmony_ci    struct loader_instance *inst = (struct loader_instance *)instance;
1815db71995Sopenharmony_ci    VkResult res = VK_SUCCESS;
1825db71995Sopenharmony_ci    uint32_t storage_idx;
1835db71995Sopenharmony_ci    VkLayerDbgFunctionNode *new_dbg_func_node = NULL;
1845db71995Sopenharmony_ci
1855db71995Sopenharmony_ci    icd_info = (VkDebugUtilsMessengerEXT *)loader_calloc_with_instance_fallback(
1865db71995Sopenharmony_ci        pAllocator, inst, inst->total_icd_count * sizeof(VkDebugUtilsMessengerEXT), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1875db71995Sopenharmony_ci
1885db71995Sopenharmony_ci    if (!icd_info) {
1895db71995Sopenharmony_ci        res = VK_ERROR_OUT_OF_HOST_MEMORY;
1905db71995Sopenharmony_ci        goto out;
1915db71995Sopenharmony_ci    }
1925db71995Sopenharmony_ci
1935db71995Sopenharmony_ci    storage_idx = 0;
1945db71995Sopenharmony_ci    for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
1955db71995Sopenharmony_ci        if (!icd_term->dispatch.CreateDebugUtilsMessengerEXT) {
1965db71995Sopenharmony_ci            continue;
1975db71995Sopenharmony_ci        }
1985db71995Sopenharmony_ci
1995db71995Sopenharmony_ci        res = icd_term->dispatch.CreateDebugUtilsMessengerEXT(icd_term->instance, pCreateInfo, pAllocator, &icd_info[storage_idx]);
2005db71995Sopenharmony_ci
2015db71995Sopenharmony_ci        if (res != VK_SUCCESS) {
2025db71995Sopenharmony_ci            goto out;
2035db71995Sopenharmony_ci        }
2045db71995Sopenharmony_ci        storage_idx++;
2055db71995Sopenharmony_ci    }
2065db71995Sopenharmony_ci
2075db71995Sopenharmony_ci    // Setup the debug report callback in the terminator since a layer may want
2085db71995Sopenharmony_ci    // to grab the information itself (RenderDoc) and then return back to the
2095db71995Sopenharmony_ci    // user callback a sub-set of the messages.
2105db71995Sopenharmony_ci    new_dbg_func_node = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
2115db71995Sopenharmony_ci        pAllocator, inst, sizeof(VkLayerDbgFunctionNode), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2125db71995Sopenharmony_ci    if (!new_dbg_func_node) {
2135db71995Sopenharmony_ci        res = VK_ERROR_OUT_OF_HOST_MEMORY;
2145db71995Sopenharmony_ci        goto out;
2155db71995Sopenharmony_ci    }
2165db71995Sopenharmony_ci
2175db71995Sopenharmony_ci    new_dbg_func_node->is_messenger = true;
2185db71995Sopenharmony_ci    new_dbg_func_node->messenger.pfnUserCallback = pCreateInfo->pfnUserCallback;
2195db71995Sopenharmony_ci    new_dbg_func_node->messenger.messageSeverity = pCreateInfo->messageSeverity;
2205db71995Sopenharmony_ci    new_dbg_func_node->messenger.messageType = pCreateInfo->messageType;
2215db71995Sopenharmony_ci    new_dbg_func_node->pUserData = pCreateInfo->pUserData;
2225db71995Sopenharmony_ci    new_dbg_func_node->pNext = inst->current_dbg_function_head;
2235db71995Sopenharmony_ci    inst->current_dbg_function_head = new_dbg_func_node;
2245db71995Sopenharmony_ci
2255db71995Sopenharmony_ci    *pMessenger = (VkDebugUtilsMessengerEXT)(uintptr_t)icd_info;
2265db71995Sopenharmony_ci    new_dbg_func_node->messenger.messenger = *pMessenger;
2275db71995Sopenharmony_ci
2285db71995Sopenharmony_ciout:
2295db71995Sopenharmony_ci
2305db71995Sopenharmony_ci    // Roll back on errors
2315db71995Sopenharmony_ci    if (VK_SUCCESS != res) {
2325db71995Sopenharmony_ci        storage_idx = 0;
2335db71995Sopenharmony_ci        for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
2345db71995Sopenharmony_ci            if (NULL == icd_term->dispatch.DestroyDebugUtilsMessengerEXT) {
2355db71995Sopenharmony_ci                continue;
2365db71995Sopenharmony_ci            }
2375db71995Sopenharmony_ci
2385db71995Sopenharmony_ci            if (icd_info && icd_info[storage_idx]) {
2395db71995Sopenharmony_ci                icd_term->dispatch.DestroyDebugUtilsMessengerEXT(icd_term->instance, icd_info[storage_idx], pAllocator);
2405db71995Sopenharmony_ci            }
2415db71995Sopenharmony_ci            storage_idx++;
2425db71995Sopenharmony_ci        }
2435db71995Sopenharmony_ci        loader_free_with_instance_fallback(pAllocator, inst, new_dbg_func_node);
2445db71995Sopenharmony_ci        loader_free_with_instance_fallback(pAllocator, inst, icd_info);
2455db71995Sopenharmony_ci    }
2465db71995Sopenharmony_ci
2475db71995Sopenharmony_ci    return res;
2485db71995Sopenharmony_ci}
2495db71995Sopenharmony_ci
2505db71995Sopenharmony_ci// This is the instance chain terminator function for DestroyDebugUtilsMessenger
2515db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger,
2525db71995Sopenharmony_ci                                                                    const VkAllocationCallbacks *pAllocator) {
2535db71995Sopenharmony_ci    uint32_t storage_idx;
2545db71995Sopenharmony_ci    VkDebugUtilsMessengerEXT *icd_info;
2555db71995Sopenharmony_ci    const struct loader_icd_term *icd_term;
2565db71995Sopenharmony_ci
2575db71995Sopenharmony_ci    struct loader_instance *inst = (struct loader_instance *)instance;
2585db71995Sopenharmony_ci    icd_info = (VkDebugUtilsMessengerEXT *)(uintptr_t)messenger;
2595db71995Sopenharmony_ci    storage_idx = 0;
2605db71995Sopenharmony_ci    for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
2615db71995Sopenharmony_ci        if (NULL == icd_term->dispatch.DestroyDebugUtilsMessengerEXT) {
2625db71995Sopenharmony_ci            continue;
2635db71995Sopenharmony_ci        }
2645db71995Sopenharmony_ci
2655db71995Sopenharmony_ci        if (icd_info && icd_info[storage_idx]) {
2665db71995Sopenharmony_ci            icd_term->dispatch.DestroyDebugUtilsMessengerEXT(icd_term->instance, icd_info[storage_idx], pAllocator);
2675db71995Sopenharmony_ci        }
2685db71995Sopenharmony_ci        storage_idx++;
2695db71995Sopenharmony_ci    }
2705db71995Sopenharmony_ci
2715db71995Sopenharmony_ci    util_DestroyDebugUtilsMessenger(inst, messenger, pAllocator);
2725db71995Sopenharmony_ci
2735db71995Sopenharmony_ci    loader_free_with_instance_fallback(pAllocator, inst, icd_info);
2745db71995Sopenharmony_ci}
2755db71995Sopenharmony_ci
2765db71995Sopenharmony_ci// This is the instance chain terminator function for SubmitDebugUtilsMessageEXT
2775db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL terminator_SubmitDebugUtilsMessageEXT(VkInstance instance,
2785db71995Sopenharmony_ci                                                                 VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
2795db71995Sopenharmony_ci                                                                 VkDebugUtilsMessageTypeFlagsEXT messageTypes,
2805db71995Sopenharmony_ci                                                                 const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData) {
2815db71995Sopenharmony_ci    loader_platform_thread_lock_mutex(&loader_lock);
2825db71995Sopenharmony_ci    // NOTE: Just make the callback ourselves because there could be one or more ICDs that support this extension
2835db71995Sopenharmony_ci    //       and each one will trigger the callback to the user.  This would result in multiple callback triggers
2845db71995Sopenharmony_ci    //       per message.  Instead, if we get a messaged up to here, then just trigger the message ourselves and
2855db71995Sopenharmony_ci    //       return.  This would still allow the ICDs to trigger their own messages, but won't get any external ones.
2865db71995Sopenharmony_ci    struct loader_instance *inst = (struct loader_instance *)instance;
2875db71995Sopenharmony_ci    util_SubmitDebugUtilsMessageEXT(inst, messageSeverity, messageTypes, pCallbackData);
2885db71995Sopenharmony_ci    loader_platform_thread_unlock_mutex(&loader_lock);
2895db71995Sopenharmony_ci}
2905db71995Sopenharmony_ci
2915db71995Sopenharmony_ci// VK_EXT_debug_report related items
2925db71995Sopenharmony_ci
2935db71995Sopenharmony_ciVkResult util_CreateDebugReportCallback(struct loader_instance *inst, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
2945db71995Sopenharmony_ci                                        const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT callback) {
2955db71995Sopenharmony_ci    VkLayerDbgFunctionNode *new_dbg_func_node = NULL;
2965db71995Sopenharmony_ci
2975db71995Sopenharmony_ci    new_dbg_func_node = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
2985db71995Sopenharmony_ci        pAllocator, inst, sizeof(VkLayerDbgFunctionNode), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2995db71995Sopenharmony_ci    if (!new_dbg_func_node) {
3005db71995Sopenharmony_ci        return VK_ERROR_OUT_OF_HOST_MEMORY;
3015db71995Sopenharmony_ci    }
3025db71995Sopenharmony_ci
3035db71995Sopenharmony_ci    new_dbg_func_node->is_messenger = false;
3045db71995Sopenharmony_ci    new_dbg_func_node->report.msgCallback = callback;
3055db71995Sopenharmony_ci    new_dbg_func_node->report.pfnMsgCallback = pCreateInfo->pfnCallback;
3065db71995Sopenharmony_ci    new_dbg_func_node->report.msgFlags = pCreateInfo->flags;
3075db71995Sopenharmony_ci    new_dbg_func_node->pUserData = pCreateInfo->pUserData;
3085db71995Sopenharmony_ci    new_dbg_func_node->pNext = inst->instance_only_dbg_function_head;
3095db71995Sopenharmony_ci    inst->instance_only_dbg_function_head = new_dbg_func_node;
3105db71995Sopenharmony_ci    inst->current_dbg_function_head = inst->instance_only_dbg_function_head;
3115db71995Sopenharmony_ci
3125db71995Sopenharmony_ci    return VK_SUCCESS;
3135db71995Sopenharmony_ci}
3145db71995Sopenharmony_ci
3155db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL debug_utils_CreateDebugReportCallbackEXT(VkInstance instance,
3165db71995Sopenharmony_ci                                                                        const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
3175db71995Sopenharmony_ci                                                                        const VkAllocationCallbacks *pAllocator,
3185db71995Sopenharmony_ci                                                                        VkDebugReportCallbackEXT *pCallback) {
3195db71995Sopenharmony_ci    struct loader_instance *inst = loader_get_instance(instance);
3205db71995Sopenharmony_ci    loader_platform_thread_lock_mutex(&loader_lock);
3215db71995Sopenharmony_ci    VkResult result = inst->disp->layer_inst_disp.CreateDebugReportCallbackEXT(inst->instance, pCreateInfo, pAllocator, pCallback);
3225db71995Sopenharmony_ci    loader_platform_thread_unlock_mutex(&loader_lock);
3235db71995Sopenharmony_ci    return result;
3245db71995Sopenharmony_ci}
3255db71995Sopenharmony_ci
3265db71995Sopenharmony_ci// Utility function to handle reporting
3275db71995Sopenharmony_ciVkBool32 util_DebugReportMessage(const struct loader_instance *inst, VkFlags msgFlags, VkDebugReportObjectTypeEXT objectType,
3285db71995Sopenharmony_ci                                 uint64_t srcObject, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
3295db71995Sopenharmony_ci    VkBool32 bail = false;
3305db71995Sopenharmony_ci    VkLayerDbgFunctionNode *pTrav = inst->current_dbg_function_head;
3315db71995Sopenharmony_ci    VkDebugUtilsMessageSeverityFlagBitsEXT severity;
3325db71995Sopenharmony_ci    VkDebugUtilsMessageTypeFlagsEXT types;
3335db71995Sopenharmony_ci    VkDebugUtilsMessengerCallbackDataEXT callback_data;
3345db71995Sopenharmony_ci    VkDebugUtilsObjectNameInfoEXT object_name;
3355db71995Sopenharmony_ci
3365db71995Sopenharmony_ci    debug_utils_ReportFlagsToAnnotFlags(msgFlags, false, &severity, &types);
3375db71995Sopenharmony_ci    debug_utils_ReportObjectToAnnotObject(objectType, srcObject, &object_name);
3385db71995Sopenharmony_ci
3395db71995Sopenharmony_ci    callback_data.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT;
3405db71995Sopenharmony_ci    callback_data.pNext = NULL;
3415db71995Sopenharmony_ci    callback_data.flags = 0;
3425db71995Sopenharmony_ci    callback_data.pMessageIdName = pLayerPrefix;
3435db71995Sopenharmony_ci    callback_data.messageIdNumber = msgCode;
3445db71995Sopenharmony_ci    callback_data.pMessage = pMsg;
3455db71995Sopenharmony_ci    callback_data.cmdBufLabelCount = 0;
3465db71995Sopenharmony_ci    callback_data.pCmdBufLabels = NULL;
3475db71995Sopenharmony_ci    callback_data.queueLabelCount = 0;
3485db71995Sopenharmony_ci    callback_data.pQueueLabels = NULL;
3495db71995Sopenharmony_ci    callback_data.objectCount = 1;
3505db71995Sopenharmony_ci    callback_data.pObjects = &object_name;
3515db71995Sopenharmony_ci
3525db71995Sopenharmony_ci    while (pTrav) {
3535db71995Sopenharmony_ci        if (!pTrav->is_messenger && pTrav->report.msgFlags & msgFlags) {
3545db71995Sopenharmony_ci            if (pTrav->report.pfnMsgCallback(msgFlags, objectType, srcObject, location, msgCode, pLayerPrefix, pMsg,
3555db71995Sopenharmony_ci                                             pTrav->pUserData)) {
3565db71995Sopenharmony_ci                bail = true;
3575db71995Sopenharmony_ci            }
3585db71995Sopenharmony_ci        }
3595db71995Sopenharmony_ci        if (pTrav->is_messenger && (pTrav->messenger.messageSeverity & severity) && (pTrav->messenger.messageType & types)) {
3605db71995Sopenharmony_ci            if (pTrav->messenger.pfnUserCallback(severity, types, &callback_data, pTrav->pUserData)) {
3615db71995Sopenharmony_ci                bail = true;
3625db71995Sopenharmony_ci            }
3635db71995Sopenharmony_ci        }
3645db71995Sopenharmony_ci
3655db71995Sopenharmony_ci        pTrav = pTrav->pNext;
3665db71995Sopenharmony_ci    }
3675db71995Sopenharmony_ci
3685db71995Sopenharmony_ci    return bail;
3695db71995Sopenharmony_ci}
3705db71995Sopenharmony_ci
3715db71995Sopenharmony_civoid util_DestroyDebugReportCallback(struct loader_instance *inst, VkDebugReportCallbackEXT callback,
3725db71995Sopenharmony_ci                                     const VkAllocationCallbacks *pAllocator) {
3735db71995Sopenharmony_ci    VkLayerDbgFunctionNode *pTrav = inst->current_dbg_function_head;
3745db71995Sopenharmony_ci    VkLayerDbgFunctionNode *pPrev = pTrav;
3755db71995Sopenharmony_ci
3765db71995Sopenharmony_ci    while (pTrav) {
3775db71995Sopenharmony_ci        if (!pTrav->is_messenger && pTrav->report.msgCallback == callback) {
3785db71995Sopenharmony_ci            pPrev->pNext = pTrav->pNext;
3795db71995Sopenharmony_ci            if (inst->current_dbg_function_head == pTrav) inst->current_dbg_function_head = pTrav->pNext;
3805db71995Sopenharmony_ci            if (inst->instance_only_dbg_function_head == pTrav) inst->instance_only_dbg_function_head = pTrav->pNext;
3815db71995Sopenharmony_ci            if (inst->current_dbg_function_head == pTrav) inst->current_dbg_function_head = pTrav->pNext;
3825db71995Sopenharmony_ci            loader_free_with_instance_fallback(pAllocator, inst, pTrav);
3835db71995Sopenharmony_ci            break;
3845db71995Sopenharmony_ci        }
3855db71995Sopenharmony_ci        pPrev = pTrav;
3865db71995Sopenharmony_ci        pTrav = pTrav->pNext;
3875db71995Sopenharmony_ci    }
3885db71995Sopenharmony_ci}
3895db71995Sopenharmony_ci
3905db71995Sopenharmony_ciVkResult util_CreateDebugReportCallbacks(struct loader_instance *inst, const void *pChain,
3915db71995Sopenharmony_ci                                         const VkAllocationCallbacks *pAllocator) {
3925db71995Sopenharmony_ci    const void *pNext = pChain;
3935db71995Sopenharmony_ci    while (pNext) {
3945db71995Sopenharmony_ci        if (((VkBaseInStructure *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
3955db71995Sopenharmony_ci            // Assign a unique handle to each callback (just use the address of the VkDebugReportCallbackCreateInfoEXT):
3965db71995Sopenharmony_ci            // This is only being used this way due to it being for an 'anonymous' callback during instance creation
3975db71995Sopenharmony_ci            VkDebugReportCallbackEXT report_handle = (VkDebugReportCallbackEXT)(uintptr_t)pNext;
3985db71995Sopenharmony_ci            VkResult ret =
3995db71995Sopenharmony_ci                util_CreateDebugReportCallback(inst, (const VkDebugReportCallbackCreateInfoEXT *)pNext, pAllocator, report_handle);
4005db71995Sopenharmony_ci            if (ret != VK_SUCCESS) {
4015db71995Sopenharmony_ci                return ret;
4025db71995Sopenharmony_ci            }
4035db71995Sopenharmony_ci        }
4045db71995Sopenharmony_ci        pNext = (void *)((VkBaseInStructure *)pNext)->pNext;
4055db71995Sopenharmony_ci    }
4065db71995Sopenharmony_ci    return VK_SUCCESS;
4075db71995Sopenharmony_ci}
4085db71995Sopenharmony_ci
4095db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL debug_utils_DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback,
4105db71995Sopenharmony_ci                                                                     const VkAllocationCallbacks *pAllocator) {
4115db71995Sopenharmony_ci    struct loader_instance *inst = loader_get_instance(instance);
4125db71995Sopenharmony_ci    loader_platform_thread_lock_mutex(&loader_lock);
4135db71995Sopenharmony_ci
4145db71995Sopenharmony_ci    inst->disp->layer_inst_disp.DestroyDebugReportCallbackEXT(inst->instance, callback, pAllocator);
4155db71995Sopenharmony_ci
4165db71995Sopenharmony_ci    loader_platform_thread_unlock_mutex(&loader_lock);
4175db71995Sopenharmony_ci}
4185db71995Sopenharmony_ci
4195db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL debug_utils_DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
4205db71995Sopenharmony_ci                                                             VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
4215db71995Sopenharmony_ci                                                             int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
4225db71995Sopenharmony_ci    struct loader_instance *inst = loader_get_instance(instance);
4235db71995Sopenharmony_ci
4245db71995Sopenharmony_ci    inst->disp->layer_inst_disp.DebugReportMessageEXT(inst->instance, flags, objType, object, location, msgCode, pLayerPrefix,
4255db71995Sopenharmony_ci                                                      pMsg);
4265db71995Sopenharmony_ci}
4275db71995Sopenharmony_ci
4285db71995Sopenharmony_ci// This is the instance chain terminator function
4295db71995Sopenharmony_ci// for CreateDebugReportCallback
4305db71995Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDebugReportCallbackEXT(VkInstance instance,
4315db71995Sopenharmony_ci                                                                       const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
4325db71995Sopenharmony_ci                                                                       const VkAllocationCallbacks *pAllocator,
4335db71995Sopenharmony_ci                                                                       VkDebugReportCallbackEXT *pCallback) {
4345db71995Sopenharmony_ci    VkDebugReportCallbackEXT *icd_info = NULL;
4355db71995Sopenharmony_ci    const struct loader_icd_term *icd_term;
4365db71995Sopenharmony_ci    struct loader_instance *inst = (struct loader_instance *)instance;
4375db71995Sopenharmony_ci    VkResult res = VK_SUCCESS;
4385db71995Sopenharmony_ci    uint32_t storage_idx;
4395db71995Sopenharmony_ci    VkLayerDbgFunctionNode *new_dbg_func_node = NULL;
4405db71995Sopenharmony_ci
4415db71995Sopenharmony_ci    icd_info = ((VkDebugReportCallbackEXT *)loader_calloc_with_instance_fallback(
4425db71995Sopenharmony_ci        pAllocator, inst, inst->total_icd_count * sizeof(VkDebugReportCallbackEXT), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT));
4435db71995Sopenharmony_ci    if (!icd_info) {
4445db71995Sopenharmony_ci        res = VK_ERROR_OUT_OF_HOST_MEMORY;
4455db71995Sopenharmony_ci        goto out;
4465db71995Sopenharmony_ci    }
4475db71995Sopenharmony_ci
4485db71995Sopenharmony_ci    storage_idx = 0;
4495db71995Sopenharmony_ci    for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
4505db71995Sopenharmony_ci        if (!icd_term->dispatch.CreateDebugReportCallbackEXT) {
4515db71995Sopenharmony_ci            continue;
4525db71995Sopenharmony_ci        }
4535db71995Sopenharmony_ci
4545db71995Sopenharmony_ci        res = icd_term->dispatch.CreateDebugReportCallbackEXT(icd_term->instance, pCreateInfo, pAllocator, &icd_info[storage_idx]);
4555db71995Sopenharmony_ci
4565db71995Sopenharmony_ci        if (res != VK_SUCCESS) {
4575db71995Sopenharmony_ci            goto out;
4585db71995Sopenharmony_ci        }
4595db71995Sopenharmony_ci        storage_idx++;
4605db71995Sopenharmony_ci    }
4615db71995Sopenharmony_ci
4625db71995Sopenharmony_ci    // Setup the debug report callback in the terminator since a layer may want
4635db71995Sopenharmony_ci    // to grab the information itself (RenderDoc) and then return back to the
4645db71995Sopenharmony_ci    // user callback a sub-set of the messages.
4655db71995Sopenharmony_ci    new_dbg_func_node = (VkLayerDbgFunctionNode *)loader_calloc_with_instance_fallback(
4665db71995Sopenharmony_ci        pAllocator, inst, sizeof(VkLayerDbgFunctionNode), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
4675db71995Sopenharmony_ci
4685db71995Sopenharmony_ci    if (!new_dbg_func_node) {
4695db71995Sopenharmony_ci        res = VK_ERROR_OUT_OF_HOST_MEMORY;
4705db71995Sopenharmony_ci        goto out;
4715db71995Sopenharmony_ci    }
4725db71995Sopenharmony_ci
4735db71995Sopenharmony_ci    new_dbg_func_node->is_messenger = false;
4745db71995Sopenharmony_ci    new_dbg_func_node->report.pfnMsgCallback = pCreateInfo->pfnCallback;
4755db71995Sopenharmony_ci    new_dbg_func_node->report.msgFlags = pCreateInfo->flags;
4765db71995Sopenharmony_ci    new_dbg_func_node->pUserData = pCreateInfo->pUserData;
4775db71995Sopenharmony_ci    new_dbg_func_node->pNext = inst->current_dbg_function_head;
4785db71995Sopenharmony_ci    inst->current_dbg_function_head = new_dbg_func_node;
4795db71995Sopenharmony_ci
4805db71995Sopenharmony_ci    *pCallback = (VkDebugReportCallbackEXT)(uintptr_t)icd_info;
4815db71995Sopenharmony_ci    new_dbg_func_node->report.msgCallback = *pCallback;
4825db71995Sopenharmony_ci
4835db71995Sopenharmony_ciout:
4845db71995Sopenharmony_ci
4855db71995Sopenharmony_ci    // Roll back on errors
4865db71995Sopenharmony_ci    if (VK_SUCCESS != res) {
4875db71995Sopenharmony_ci        storage_idx = 0;
4885db71995Sopenharmony_ci        for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
4895db71995Sopenharmony_ci            if (NULL == icd_term->dispatch.DestroyDebugReportCallbackEXT) {
4905db71995Sopenharmony_ci                continue;
4915db71995Sopenharmony_ci            }
4925db71995Sopenharmony_ci
4935db71995Sopenharmony_ci            if (icd_info && icd_info[storage_idx]) {
4945db71995Sopenharmony_ci                icd_term->dispatch.DestroyDebugReportCallbackEXT(icd_term->instance, icd_info[storage_idx], pAllocator);
4955db71995Sopenharmony_ci            }
4965db71995Sopenharmony_ci            storage_idx++;
4975db71995Sopenharmony_ci        }
4985db71995Sopenharmony_ci        loader_free_with_instance_fallback(pAllocator, inst, new_dbg_func_node);
4995db71995Sopenharmony_ci        loader_free_with_instance_fallback(pAllocator, inst, icd_info);
5005db71995Sopenharmony_ci    }
5015db71995Sopenharmony_ci
5025db71995Sopenharmony_ci    return res;
5035db71995Sopenharmony_ci}
5045db71995Sopenharmony_ci
5055db71995Sopenharmony_ci// This is the instance chain terminator function for DestroyDebugReportCallback
5065db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL terminator_DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback,
5075db71995Sopenharmony_ci                                                                    const VkAllocationCallbacks *pAllocator) {
5085db71995Sopenharmony_ci    uint32_t storage_idx;
5095db71995Sopenharmony_ci    VkDebugReportCallbackEXT *icd_info;
5105db71995Sopenharmony_ci    const struct loader_icd_term *icd_term;
5115db71995Sopenharmony_ci
5125db71995Sopenharmony_ci    struct loader_instance *inst = (struct loader_instance *)instance;
5135db71995Sopenharmony_ci    icd_info = (VkDebugReportCallbackEXT *)(uintptr_t)callback;
5145db71995Sopenharmony_ci    storage_idx = 0;
5155db71995Sopenharmony_ci    for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
5165db71995Sopenharmony_ci        if (NULL == icd_term->dispatch.DestroyDebugReportCallbackEXT) {
5175db71995Sopenharmony_ci            continue;
5185db71995Sopenharmony_ci        }
5195db71995Sopenharmony_ci
5205db71995Sopenharmony_ci        if (icd_info[storage_idx]) {
5215db71995Sopenharmony_ci            icd_term->dispatch.DestroyDebugReportCallbackEXT(icd_term->instance, icd_info[storage_idx], pAllocator);
5225db71995Sopenharmony_ci        }
5235db71995Sopenharmony_ci        storage_idx++;
5245db71995Sopenharmony_ci    }
5255db71995Sopenharmony_ci
5265db71995Sopenharmony_ci    util_DestroyDebugReportCallback(inst, callback, pAllocator);
5275db71995Sopenharmony_ci
5285db71995Sopenharmony_ci    loader_free_with_instance_fallback(pAllocator, inst, icd_info);
5295db71995Sopenharmony_ci}
5305db71995Sopenharmony_ci
5315db71995Sopenharmony_ci// This is the instance chain terminator function for DebugReportMessage
5325db71995Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL terminator_DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
5335db71995Sopenharmony_ci                                                            VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
5345db71995Sopenharmony_ci                                                            int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
5355db71995Sopenharmony_ci    const struct loader_icd_term *icd_term;
5365db71995Sopenharmony_ci
5375db71995Sopenharmony_ci    struct loader_instance *inst = (struct loader_instance *)instance;
5385db71995Sopenharmony_ci
5395db71995Sopenharmony_ci    loader_platform_thread_lock_mutex(&loader_lock);
5405db71995Sopenharmony_ci    for (icd_term = inst->icd_terms; icd_term; icd_term = icd_term->next) {
5415db71995Sopenharmony_ci        if (icd_term->dispatch.DebugReportMessageEXT != NULL) {
5425db71995Sopenharmony_ci            icd_term->dispatch.DebugReportMessageEXT(icd_term->instance, flags, objType, object, location, msgCode, pLayerPrefix,
5435db71995Sopenharmony_ci                                                     pMsg);
5445db71995Sopenharmony_ci        }
5455db71995Sopenharmony_ci    }
5465db71995Sopenharmony_ci
5475db71995Sopenharmony_ci    // Now that all ICDs have seen the message, call the necessary callbacks.  Ignoring "bail" return value
5485db71995Sopenharmony_ci    // as there is nothing to bail from at this point.
5495db71995Sopenharmony_ci
5505db71995Sopenharmony_ci    util_DebugReportMessage(inst, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
5515db71995Sopenharmony_ci
5525db71995Sopenharmony_ci    loader_platform_thread_unlock_mutex(&loader_lock);
5535db71995Sopenharmony_ci}
5545db71995Sopenharmony_ci
5555db71995Sopenharmony_ci// General utilities
5565db71995Sopenharmony_ci
5575db71995Sopenharmony_ciconst VkExtensionProperties debug_utils_extension_info[] = {
5585db71995Sopenharmony_ci    {VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION},
5595db71995Sopenharmony_ci    {VK_EXT_DEBUG_UTILS_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_SPEC_VERSION},
5605db71995Sopenharmony_ci};
5615db71995Sopenharmony_ci
5625db71995Sopenharmony_civoid destroy_debug_callbacks_chain(struct loader_instance *inst, const VkAllocationCallbacks *pAllocator) {
5635db71995Sopenharmony_ci    VkLayerDbgFunctionNode *pTrav = inst->current_dbg_function_head;
5645db71995Sopenharmony_ci    VkLayerDbgFunctionNode *pNext = NULL;
5655db71995Sopenharmony_ci    while (pTrav) {
5665db71995Sopenharmony_ci        pNext = pTrav->pNext;
5675db71995Sopenharmony_ci        loader_free_with_instance_fallback(pAllocator, inst, pTrav);
5685db71995Sopenharmony_ci        pTrav = pNext;
5695db71995Sopenharmony_ci    }
5705db71995Sopenharmony_ci    inst->current_dbg_function_head = NULL;
5715db71995Sopenharmony_ci}
5725db71995Sopenharmony_ci
5735db71995Sopenharmony_ciVkResult add_debug_extensions_to_ext_list(const struct loader_instance *inst, struct loader_extension_list *ext_list) {
5745db71995Sopenharmony_ci    return loader_add_to_ext_list(inst, ext_list, sizeof(debug_utils_extension_info) / sizeof(VkExtensionProperties),
5755db71995Sopenharmony_ci                                  debug_utils_extension_info);
5765db71995Sopenharmony_ci}
5775db71995Sopenharmony_ci
5785db71995Sopenharmony_civoid check_for_enabled_debug_extensions(struct loader_instance *ptr_instance, const VkInstanceCreateInfo *pCreateInfo) {
5795db71995Sopenharmony_ci    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
5805db71995Sopenharmony_ci        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) {
5815db71995Sopenharmony_ci            ptr_instance->enabled_known_extensions.ext_debug_report = 1;
5825db71995Sopenharmony_ci        } else if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0) {
5835db71995Sopenharmony_ci            ptr_instance->enabled_known_extensions.ext_debug_utils = 1;
5845db71995Sopenharmony_ci        }
5855db71995Sopenharmony_ci    }
5865db71995Sopenharmony_ci}
5875db71995Sopenharmony_ci
5885db71995Sopenharmony_cibool debug_extensions_InstanceGpa(struct loader_instance *ptr_instance, const char *name, void **addr) {
5895db71995Sopenharmony_ci    bool ret_type = false;
5905db71995Sopenharmony_ci
5915db71995Sopenharmony_ci    *addr = NULL;
5925db71995Sopenharmony_ci
5935db71995Sopenharmony_ci    if (!strcmp("vkCreateDebugReportCallbackEXT", name)) {
5945db71995Sopenharmony_ci        *addr =
5955db71995Sopenharmony_ci            ptr_instance->enabled_known_extensions.ext_debug_report == 1 ? (void *)debug_utils_CreateDebugReportCallbackEXT : NULL;
5965db71995Sopenharmony_ci        ret_type = true;
5975db71995Sopenharmony_ci    } else if (!strcmp("vkDestroyDebugReportCallbackEXT", name)) {
5985db71995Sopenharmony_ci        *addr =
5995db71995Sopenharmony_ci            ptr_instance->enabled_known_extensions.ext_debug_report == 1 ? (void *)debug_utils_DestroyDebugReportCallbackEXT : NULL;
6005db71995Sopenharmony_ci        ret_type = true;
6015db71995Sopenharmony_ci    } else if (!strcmp("vkDebugReportMessageEXT", name)) {
6025db71995Sopenharmony_ci        *addr = ptr_instance->enabled_known_extensions.ext_debug_report == 1 ? (void *)debug_utils_DebugReportMessageEXT : NULL;
6035db71995Sopenharmony_ci        return true;
6045db71995Sopenharmony_ci    }
6055db71995Sopenharmony_ci    if (!strcmp("vkCreateDebugUtilsMessengerEXT", name)) {
6065db71995Sopenharmony_ci        *addr =
6075db71995Sopenharmony_ci            ptr_instance->enabled_known_extensions.ext_debug_utils == 1 ? (void *)debug_utils_CreateDebugUtilsMessengerEXT : NULL;
6085db71995Sopenharmony_ci        ret_type = true;
6095db71995Sopenharmony_ci    } else if (!strcmp("vkDestroyDebugUtilsMessengerEXT", name)) {
6105db71995Sopenharmony_ci        *addr =
6115db71995Sopenharmony_ci            ptr_instance->enabled_known_extensions.ext_debug_utils == 1 ? (void *)debug_utils_DestroyDebugUtilsMessengerEXT : NULL;
6125db71995Sopenharmony_ci        ret_type = true;
6135db71995Sopenharmony_ci    } else if (!strcmp("vkSubmitDebugUtilsMessageEXT", name)) {
6145db71995Sopenharmony_ci        *addr = ptr_instance->enabled_known_extensions.ext_debug_utils == 1 ? (void *)debug_utils_SubmitDebugUtilsMessageEXT : NULL;
6155db71995Sopenharmony_ci        ret_type = true;
6165db71995Sopenharmony_ci    }
6175db71995Sopenharmony_ci
6185db71995Sopenharmony_ci    return ret_type;
6195db71995Sopenharmony_ci}
6205db71995Sopenharmony_ci
6215db71995Sopenharmony_cibool debug_utils_ReportFlagsToAnnotFlags(VkDebugReportFlagsEXT dr_flags, bool default_flag_is_spec,
6225db71995Sopenharmony_ci                                         VkDebugUtilsMessageSeverityFlagBitsEXT *da_severity,
6235db71995Sopenharmony_ci                                         VkDebugUtilsMessageTypeFlagsEXT *da_type) {
6245db71995Sopenharmony_ci    bool type_set = false;
6255db71995Sopenharmony_ci    if (NULL == da_severity || NULL == da_type) {
6265db71995Sopenharmony_ci        return false;
6275db71995Sopenharmony_ci    }
6285db71995Sopenharmony_ci    *da_type = 0;
6295db71995Sopenharmony_ci    *da_severity = 0;
6305db71995Sopenharmony_ci
6315db71995Sopenharmony_ci    if ((dr_flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) != 0) {
6325db71995Sopenharmony_ci        *da_severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
6335db71995Sopenharmony_ci        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
6345db71995Sopenharmony_ci        type_set = true;
6355db71995Sopenharmony_ci    } else if ((dr_flags & (VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)) != 0) {
6365db71995Sopenharmony_ci        *da_severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
6375db71995Sopenharmony_ci    } else if ((dr_flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) != 0) {
6385db71995Sopenharmony_ci        *da_severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
6395db71995Sopenharmony_ci    } else if ((dr_flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) != 0) {
6405db71995Sopenharmony_ci        *da_severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
6415db71995Sopenharmony_ci        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
6425db71995Sopenharmony_ci        type_set = true;
6435db71995Sopenharmony_ci    }
6445db71995Sopenharmony_ci
6455db71995Sopenharmony_ci    if ((dr_flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) != 0) {
6465db71995Sopenharmony_ci        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
6475db71995Sopenharmony_ci    } else if (!type_set) {
6485db71995Sopenharmony_ci        if (default_flag_is_spec) {
6495db71995Sopenharmony_ci            *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
6505db71995Sopenharmony_ci        } else {
6515db71995Sopenharmony_ci            *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
6525db71995Sopenharmony_ci        }
6535db71995Sopenharmony_ci    }
6545db71995Sopenharmony_ci
6555db71995Sopenharmony_ci    return true;
6565db71995Sopenharmony_ci}
6575db71995Sopenharmony_ci
6585db71995Sopenharmony_cibool debug_utils_AnnotFlagsToReportFlags(VkDebugUtilsMessageSeverityFlagBitsEXT da_severity,
6595db71995Sopenharmony_ci                                         VkDebugUtilsMessageTypeFlagsEXT da_type, VkDebugReportFlagsEXT *dr_flags) {
6605db71995Sopenharmony_ci    if (NULL == dr_flags) {
6615db71995Sopenharmony_ci        return false;
6625db71995Sopenharmony_ci    }
6635db71995Sopenharmony_ci
6645db71995Sopenharmony_ci    *dr_flags = 0;
6655db71995Sopenharmony_ci
6665db71995Sopenharmony_ci    if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) != 0) {
6675db71995Sopenharmony_ci        *dr_flags |= VK_DEBUG_REPORT_ERROR_BIT_EXT;
6685db71995Sopenharmony_ci    } else if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) != 0) {
6695db71995Sopenharmony_ci        if ((da_type & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) != 0) {
6705db71995Sopenharmony_ci            *dr_flags |= VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
6715db71995Sopenharmony_ci        } else {
6725db71995Sopenharmony_ci            *dr_flags |= VK_DEBUG_REPORT_WARNING_BIT_EXT;
6735db71995Sopenharmony_ci        }
6745db71995Sopenharmony_ci    } else if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) != 0) {
6755db71995Sopenharmony_ci        *dr_flags |= VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
6765db71995Sopenharmony_ci    } else if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) != 0) {
6775db71995Sopenharmony_ci        *dr_flags |= VK_DEBUG_REPORT_DEBUG_BIT_EXT;
6785db71995Sopenharmony_ci    }
6795db71995Sopenharmony_ci
6805db71995Sopenharmony_ci    return true;
6815db71995Sopenharmony_ci}
6825db71995Sopenharmony_ci
6835db71995Sopenharmony_cibool debug_utils_ReportObjectToAnnotObject(VkDebugReportObjectTypeEXT dr_object_type, uint64_t object_handle,
6845db71995Sopenharmony_ci                                           VkDebugUtilsObjectNameInfoEXT *da_object_name_info) {
6855db71995Sopenharmony_ci    if (NULL == da_object_name_info) {
6865db71995Sopenharmony_ci        return false;
6875db71995Sopenharmony_ci    }
6885db71995Sopenharmony_ci    da_object_name_info->sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
6895db71995Sopenharmony_ci    da_object_name_info->pNext = NULL;
6905db71995Sopenharmony_ci    da_object_name_info->objectHandle = (uint64_t)(uintptr_t)object_handle;
6915db71995Sopenharmony_ci    da_object_name_info->pObjectName = NULL;
6925db71995Sopenharmony_ci    da_object_name_info->objectType = convertDebugReportObjectToCoreObject(dr_object_type);
6935db71995Sopenharmony_ci    return true;
6945db71995Sopenharmony_ci}
6955db71995Sopenharmony_ci
6965db71995Sopenharmony_cibool debug_utils_AnnotObjectToDebugReportObject(const VkDebugUtilsObjectNameInfoEXT *da_object_name_info,
6975db71995Sopenharmony_ci                                                VkDebugReportObjectTypeEXT *dr_object_type, uint64_t *dr_object_handle) {
6985db71995Sopenharmony_ci    if (NULL == da_object_name_info || NULL == dr_object_type || NULL == dr_object_handle) {
6995db71995Sopenharmony_ci        return false;
7005db71995Sopenharmony_ci    }
7015db71995Sopenharmony_ci    *dr_object_type = convertCoreObjectToDebugReportObject(da_object_name_info->objectType);
7025db71995Sopenharmony_ci    *dr_object_handle = da_object_name_info->objectHandle;
7035db71995Sopenharmony_ci    return true;
7045db71995Sopenharmony_ci}
705