Merge pull request #11219 from K0bin/android-vk-alidation

VideoBackends:Vulkan: Migrate to VK_EXT_debug_utils
This commit is contained in:
JMC47 2022-12-28 14:16:51 -05:00 committed by GitHub
commit 82e5f438f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 153 additions and 75 deletions

View File

@ -84,13 +84,13 @@ static bool IsHostGPULoggingEnabled()
Common::Log::LogLevel::LERROR); Common::Log::LogLevel::LERROR);
} }
// Helper method to determine whether to enable the debug report extension. // Helper method to determine whether to enable the debug utils extension.
static bool ShouldEnableDebugReports(bool enable_validation_layers) static bool ShouldEnableDebugUtils(bool enable_validation_layers)
{ {
// Enable debug reports if the Host GPU log option is checked, or validation layers are enabled. // Enable debug utils if the Host GPU log option is checked, or validation layers are enabled.
// The only issue here is that if Host GPU is not checked when the instance is created, the debug // The only issue here is that if Host GPU is not checked when the instance is created, the debug
// report extension will not be enabled, requiring the game to be restarted before any reports // report extension will not be enabled, requiring the game to be restarted before any reports
// will be logged. Otherwise, we'd have to enable debug reports on every instance, when most // will be logged. Otherwise, we'd have to enable debug utils on every instance, when most
// users will never check the Host GPU logging category. // users will never check the Host GPU logging category.
return enable_validation_layers || IsHostGPULoggingEnabled(); return enable_validation_layers || IsHostGPULoggingEnabled();
} }
@ -114,10 +114,10 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
// Create Vulkan instance, needed before we can create a surface, or enumerate devices. // Create Vulkan instance, needed before we can create a surface, or enumerate devices.
// We use this instance to fill in backend info, then re-use it for the actual device. // We use this instance to fill in backend info, then re-use it for the actual device.
bool enable_surface = wsi.type != WindowSystemType::Headless; bool enable_surface = wsi.type != WindowSystemType::Headless;
bool enable_debug_reports = ShouldEnableDebugReports(enable_validation_layer); bool enable_debug_utils = ShouldEnableDebugUtils(enable_validation_layer);
u32 vk_api_version = 0; u32 vk_api_version = 0;
VkInstance instance = VulkanContext::CreateVulkanInstance( VkInstance instance = VulkanContext::CreateVulkanInstance(
wsi.type, enable_debug_reports, enable_validation_layer, &vk_api_version); wsi.type, enable_debug_utils, enable_validation_layer, &vk_api_version);
if (instance == VK_NULL_HANDLE) if (instance == VK_NULL_HANDLE)
{ {
PanicAlertFmt("Failed to create Vulkan instance."); PanicAlertFmt("Failed to create Vulkan instance.");
@ -174,8 +174,8 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
// Now we can create the Vulkan device. VulkanContext takes ownership of the instance and surface. // Now we can create the Vulkan device. VulkanContext takes ownership of the instance and surface.
g_vulkan_context = g_vulkan_context =
VulkanContext::Create(instance, gpu_list[selected_adapter_index], surface, VulkanContext::Create(instance, gpu_list[selected_adapter_index], surface, enable_debug_utils,
enable_debug_reports, enable_validation_layer, vk_api_version); enable_validation_layer, vk_api_version);
if (!g_vulkan_context) if (!g_vulkan_context)
{ {
PanicAlertFmt("Failed to create Vulkan device"); PanicAlertFmt("Failed to create Vulkan device");

View File

@ -18,6 +18,8 @@
namespace Vulkan namespace Vulkan
{ {
static constexpr const char* VALIDATION_LAYER_NAME = "VK_LAYER_KHRONOS_validation";
std::unique_ptr<VulkanContext> g_vulkan_context; std::unique_ptr<VulkanContext> g_vulkan_context;
VulkanContext::VulkanContext(VkInstance instance, VkPhysicalDevice physical_device) VulkanContext::VulkanContext(VkInstance instance, VkPhysicalDevice physical_device)
@ -45,8 +47,8 @@ VulkanContext::~VulkanContext()
if (m_device != VK_NULL_HANDLE) if (m_device != VK_NULL_HANDLE)
vkDestroyDevice(m_device, nullptr); vkDestroyDevice(m_device, nullptr);
if (m_debug_report_callback != VK_NULL_HANDLE) if (m_debug_utils_messenger != VK_NULL_HANDLE)
DisableDebugReports(); DisableDebugUtils();
vkDestroyInstance(m_instance, nullptr); vkDestroyInstance(m_instance, nullptr);
} }
@ -77,22 +79,49 @@ bool VulkanContext::CheckValidationLayerAvailablility()
res = vkEnumerateInstanceLayerProperties(&layer_count, layer_list.data()); res = vkEnumerateInstanceLayerProperties(&layer_count, layer_list.data());
ASSERT(res == VK_SUCCESS); ASSERT(res == VK_SUCCESS);
// Check for both VK_EXT_debug_report and VK_LAYER_LUNARG_standard_validation bool supports_validation_layers =
return (std::find_if(extension_list.begin(), extension_list.end(),
[](const auto& it) {
return strcmp(it.extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0;
}) != extension_list.end() &&
std::find_if(layer_list.begin(), layer_list.end(), [](const auto& it) { std::find_if(layer_list.begin(), layer_list.end(), [](const auto& it) {
return strcmp(it.layerName, "VK_LAYER_KHRONOS_validation") == 0; return strcmp(it.layerName, VALIDATION_LAYER_NAME) == 0;
}) != layer_list.end()); }) != layer_list.end();
bool supports_debug_utils =
std::find_if(extension_list.begin(), extension_list.end(), [](const auto& it) {
return strcmp(it.extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0;
}) != extension_list.end();
if (!supports_debug_utils && supports_validation_layers)
{
// If the instance doesn't support debug utils but we're using validation layers,
// try to use the implementation of the extension provided by the validation layers.
extension_count = 0;
res = vkEnumerateInstanceExtensionProperties(VALIDATION_LAYER_NAME, &extension_count, nullptr);
if (res != VK_SUCCESS)
{
LOG_VULKAN_ERROR(res, "vkEnumerateInstanceExtensionProperties failed: ");
return false;
} }
VkInstance VulkanContext::CreateVulkanInstance(WindowSystemType wstype, bool enable_debug_report, extension_list.resize(extension_count);
res = vkEnumerateInstanceExtensionProperties(VALIDATION_LAYER_NAME, &extension_count,
extension_list.data());
ASSERT(res == VK_SUCCESS);
supports_debug_utils =
std::find_if(extension_list.begin(), extension_list.end(), [](const auto& it) {
return strcmp(it.extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0;
}) != extension_list.end();
}
// Check for both VK_EXT_debug_utils and VK_LAYER_KHRONOS_validation
return supports_debug_utils && supports_validation_layers;
}
VkInstance VulkanContext::CreateVulkanInstance(WindowSystemType wstype, bool enable_debug_utils,
bool enable_validation_layer, bool enable_validation_layer,
u32* out_vk_api_version) u32* out_vk_api_version)
{ {
std::vector<const char*> enabled_extensions; std::vector<const char*> enabled_extensions;
if (!SelectInstanceExtensions(&enabled_extensions, wstype, enable_debug_report)) if (!SelectInstanceExtensions(&enabled_extensions, wstype, enable_debug_utils,
enable_validation_layer))
return VK_NULL_HANDLE; return VK_NULL_HANDLE;
VkApplicationInfo app_info = {}; VkApplicationInfo app_info = {};
@ -129,12 +158,11 @@ VkInstance VulkanContext::CreateVulkanInstance(WindowSystemType wstype, bool ena
instance_create_info.enabledLayerCount = 0; instance_create_info.enabledLayerCount = 0;
instance_create_info.ppEnabledLayerNames = nullptr; instance_create_info.ppEnabledLayerNames = nullptr;
// Enable debug layer on debug builds // Enable validation layer if the user enabled them in the settings
if (enable_validation_layer) if (enable_validation_layer)
{ {
static const char* layer_names[] = {"VK_LAYER_KHRONOS_validation"};
instance_create_info.enabledLayerCount = 1; instance_create_info.enabledLayerCount = 1;
instance_create_info.ppEnabledLayerNames = layer_names; instance_create_info.ppEnabledLayerNames = &VALIDATION_LAYER_NAME;
} }
VkInstance instance; VkInstance instance;
@ -149,7 +177,8 @@ VkInstance VulkanContext::CreateVulkanInstance(WindowSystemType wstype, bool ena
} }
bool VulkanContext::SelectInstanceExtensions(std::vector<const char*>* extension_list, bool VulkanContext::SelectInstanceExtensions(std::vector<const char*>* extension_list,
WindowSystemType wstype, bool enable_debug_report) WindowSystemType wstype, bool enable_debug_utils,
bool validation_layer_enabled)
{ {
u32 extension_count = 0; u32 extension_count = 0;
VkResult res = vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr); VkResult res = vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr);
@ -170,14 +199,50 @@ bool VulkanContext::SelectInstanceExtensions(std::vector<const char*>* extension
available_extension_list.data()); available_extension_list.data());
ASSERT(res == VK_SUCCESS); ASSERT(res == VK_SUCCESS);
u32 validation_layer_extension_count = 0;
std::vector<VkExtensionProperties> validation_layer_extension_list;
if (validation_layer_enabled)
{
res = vkEnumerateInstanceExtensionProperties(VALIDATION_LAYER_NAME,
&validation_layer_extension_count, nullptr);
if (res != VK_SUCCESS)
{
LOG_VULKAN_ERROR(res,
"vkEnumerateInstanceExtensionProperties failed for validation layers: ");
}
else
{
validation_layer_extension_list.resize(validation_layer_extension_count);
res = vkEnumerateInstanceExtensionProperties(VALIDATION_LAYER_NAME,
&validation_layer_extension_count,
validation_layer_extension_list.data());
ASSERT(res == VK_SUCCESS);
}
}
for (const auto& extension_properties : available_extension_list) for (const auto& extension_properties : available_extension_list)
INFO_LOG_FMT(VIDEO, "Available extension: {}", extension_properties.extensionName); INFO_LOG_FMT(VIDEO, "Available extension: {}", extension_properties.extensionName);
for (const auto& extension_properties : validation_layer_extension_list)
{
INFO_LOG_FMT(VIDEO, "Available extension in validation layer: {}",
extension_properties.extensionName);
}
auto AddExtension = [&](const char* name, bool required) { auto AddExtension = [&](const char* name, bool required) {
if (std::find_if(available_extension_list.begin(), available_extension_list.end(), bool extension_supported =
std::find_if(available_extension_list.begin(), available_extension_list.end(),
[&](const VkExtensionProperties& properties) { [&](const VkExtensionProperties& properties) {
return !strcmp(name, properties.extensionName); return !strcmp(name, properties.extensionName);
}) != available_extension_list.end()) }) != available_extension_list.end();
extension_supported =
extension_supported ||
std::find_if(validation_layer_extension_list.begin(), validation_layer_extension_list.end(),
[&](const VkExtensionProperties& properties) {
return !strcmp(name, properties.extensionName);
}) != validation_layer_extension_list.end();
if (extension_supported)
{ {
INFO_LOG_FMT(VIDEO, "Enabling extension: {}", name); INFO_LOG_FMT(VIDEO, "Enabling extension: {}", name);
extension_list->push_back(name); extension_list->push_back(name);
@ -223,20 +288,21 @@ bool VulkanContext::SelectInstanceExtensions(std::vector<const char*>* extension
} }
#endif #endif
// VK_EXT_debug_report
if (enable_debug_report && !AddExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME, false))
WARN_LOG_FMT(VIDEO, "Vulkan: Debug report requested, but extension is not available.");
AddExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, false); AddExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, false);
if (wstype != WindowSystemType::Headless) if (wstype != WindowSystemType::Headless)
{ {
AddExtension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, false); AddExtension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, false);
} }
// VK_EXT_debug_utils
if (AddExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, false)) if (AddExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, false))
{ {
g_Config.backend_info.bSupportsSettingObjectNames = true; g_Config.backend_info.bSupportsSettingObjectNames = true;
} }
else if (enable_debug_utils)
{
WARN_LOG_FMT(VIDEO, "Vulkan: Debug utils requested, but extension is not available.");
}
return true; return true;
} }
@ -435,9 +501,10 @@ void VulkanContext::PopulateBackendInfoMultisampleModes(
config->backend_info.AAModes.emplace_back(64); config->backend_info.AAModes.emplace_back(64);
} }
std::unique_ptr<VulkanContext> std::unique_ptr<VulkanContext> VulkanContext::Create(VkInstance instance, VkPhysicalDevice gpu,
VulkanContext::Create(VkInstance instance, VkPhysicalDevice gpu, VkSurfaceKHR surface, VkSurfaceKHR surface, bool enable_debug_utils,
bool enable_debug_reports, bool enable_validation_layer, u32 vk_api_version) bool enable_validation_layer,
u32 vk_api_version)
{ {
std::unique_ptr<VulkanContext> context = std::make_unique<VulkanContext>(instance, gpu); std::unique_ptr<VulkanContext> context = std::make_unique<VulkanContext>(instance, gpu);
@ -445,9 +512,9 @@ VulkanContext::Create(VkInstance instance, VkPhysicalDevice gpu, VkSurfaceKHR su
context->InitDriverDetails(); context->InitDriverDetails();
context->PopulateShaderSubgroupSupport(); context->PopulateShaderSubgroupSupport();
// Enable debug reports if the "Host GPU" log category is enabled. // Enable debug messages if the "Host GPU" log category is enabled.
if (enable_debug_reports) if (enable_debug_utils)
context->EnableDebugReports(); context->EnableDebugUtils();
// Attempt to create the device. // Attempt to create the device.
if (!context->CreateDevice(surface, enable_validation_layer) || if (!context->CreateDevice(surface, enable_validation_layer) ||
@ -679,9 +746,8 @@ bool VulkanContext::CreateDevice(VkSurfaceKHR surface, bool enable_validation_la
// Enable debug layer on debug builds // Enable debug layer on debug builds
if (enable_validation_layer) if (enable_validation_layer)
{ {
static const char* layer_names[] = {"VK_LAYER_LUNARG_standard_validation"};
device_info.enabledLayerCount = 1; device_info.enabledLayerCount = 1;
device_info.ppEnabledLayerNames = layer_names; device_info.ppEnabledLayerNames = &VALIDATION_LAYER_NAME;
} }
VkResult res = vkCreateDevice(m_physical_device, &device_info, nullptr, &m_device); VkResult res = vkCreateDevice(m_physical_device, &device_info, nullptr, &m_device);
@ -732,20 +798,17 @@ bool VulkanContext::CreateAllocator(u32 vk_api_version)
return true; return true;
} }
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(VkDebugReportFlagsEXT flags, static VKAPI_ATTR VkBool32 VKAPI_CALL
VkDebugReportObjectTypeEXT objectType, DebugUtilsCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
uint64_t object, size_t location, VkDebugUtilsMessageTypeFlagsEXT messageTypes,
int32_t messageCode, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData)
const char* pLayerPrefix,
const char* pMessage, void* pUserData)
{ {
const std::string log_message = const std::string log_message = fmt::format("Vulkan debug message: {}", pCallbackData->pMessage);
fmt::format("Vulkan debug report: ({}) {}", pLayerPrefix ? pLayerPrefix : "", pMessage); if (messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT)
ERROR_LOG_FMT(HOST_GPU, "{}", log_message); ERROR_LOG_FMT(HOST_GPU, "{}", log_message);
else if (flags & (VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)) else if (messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
WARN_LOG_FMT(HOST_GPU, "{}", log_message); WARN_LOG_FMT(HOST_GPU, "{}", log_message);
else if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) else if (messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT)
INFO_LOG_FMT(HOST_GPU, "{}", log_message); INFO_LOG_FMT(HOST_GPU, "{}", log_message);
else else
DEBUG_LOG_FMT(HOST_GPU, "{}", log_message); DEBUG_LOG_FMT(HOST_GPU, "{}", log_message);
@ -753,43 +816,50 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(VkDebugReportFlagsEXT
return VK_FALSE; return VK_FALSE;
} }
bool VulkanContext::EnableDebugReports() bool VulkanContext::EnableDebugUtils()
{ {
// Already enabled? // Already enabled?
if (m_debug_report_callback != VK_NULL_HANDLE) if (m_debug_utils_messenger != VK_NULL_HANDLE)
return true; return true;
// Check for presence of the functions before calling // Check for presence of the functions before calling
if (!vkCreateDebugReportCallbackEXT || !vkDestroyDebugReportCallbackEXT || if (!vkCreateDebugUtilsMessengerEXT || !vkDestroyDebugUtilsMessengerEXT ||
!vkDebugReportMessageEXT) !vkSubmitDebugUtilsMessageEXT)
{ {
return false; return false;
} }
VkDebugReportCallbackCreateInfoEXT callback_info = { VkDebugUtilsMessengerCreateInfoEXT messenger_info = {
VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, nullptr, VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | nullptr,
VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT | VK_DEBUG_REPORT_INFORMATION_BIT_EXT | 0,
VK_DEBUG_REPORT_DEBUG_BIT_EXT, VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT |
DebugReportCallback, nullptr}; VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT,
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
DebugUtilsCallback,
nullptr};
VkResult res = VkResult res = vkCreateDebugUtilsMessengerEXT(m_instance, &messenger_info, nullptr,
vkCreateDebugReportCallbackEXT(m_instance, &callback_info, nullptr, &m_debug_report_callback); &m_debug_utils_messenger);
if (res != VK_SUCCESS) if (res != VK_SUCCESS)
{ {
LOG_VULKAN_ERROR(res, "vkCreateDebugReportCallbackEXT failed: "); LOG_VULKAN_ERROR(res, "vkCreateDebugUtilsMessengerEXT failed: ");
return false; return false;
} }
return true; return true;
} }
void VulkanContext::DisableDebugReports() void VulkanContext::DisableDebugUtils()
{ {
if (m_debug_report_callback != VK_NULL_HANDLE) if (m_debug_utils_messenger != VK_NULL_HANDLE)
{ {
vkDestroyDebugReportCallbackEXT(m_instance, m_debug_report_callback, nullptr); vkDestroyDebugUtilsMessengerEXT(m_instance, m_debug_utils_messenger, nullptr);
m_debug_report_callback = VK_NULL_HANDLE; m_debug_utils_messenger = VK_NULL_HANDLE;
} }
} }

View File

@ -25,7 +25,7 @@ public:
static bool CheckValidationLayerAvailablility(); static bool CheckValidationLayerAvailablility();
// Helper method to create a Vulkan instance. // Helper method to create a Vulkan instance.
static VkInstance CreateVulkanInstance(WindowSystemType wstype, bool enable_debug_report, static VkInstance CreateVulkanInstance(WindowSystemType wstype, bool enable_debug_utils,
bool enable_validation_layer, u32* out_vk_api_version); bool enable_validation_layer, u32* out_vk_api_version);
// Returns a list of Vulkan-compatible GPUs. // Returns a list of Vulkan-compatible GPUs.
@ -46,12 +46,12 @@ public:
// This assumes that PopulateBackendInfo and PopulateBackendInfoAdapters has already // This assumes that PopulateBackendInfo and PopulateBackendInfoAdapters has already
// been called for the specified VideoConfig. // been called for the specified VideoConfig.
static std::unique_ptr<VulkanContext> Create(VkInstance instance, VkPhysicalDevice gpu, static std::unique_ptr<VulkanContext> Create(VkInstance instance, VkPhysicalDevice gpu,
VkSurfaceKHR surface, bool enable_debug_reports, VkSurfaceKHR surface, bool enable_debug_utils,
bool enable_validation_layer, u32 api_version); bool enable_validation_layer, u32 api_version);
// Enable/disable debug message runtime. // Enable/disable debug message runtime.
bool EnableDebugReports(); bool EnableDebugUtils();
void DisableDebugReports(); void DisableDebugUtils();
// Global state accessors // Global state accessors
VkInstance GetVulkanInstance() const { return m_instance; } VkInstance GetVulkanInstance() const { return m_instance; }
@ -115,7 +115,8 @@ public:
private: private:
static bool SelectInstanceExtensions(std::vector<const char*>* extension_list, static bool SelectInstanceExtensions(std::vector<const char*>* extension_list,
WindowSystemType wstype, bool enable_debug_report); WindowSystemType wstype, bool enable_debug_utils,
bool validation_layer_enabled);
bool SelectDeviceExtensions(bool enable_surface); bool SelectDeviceExtensions(bool enable_surface);
bool SelectDeviceFeatures(); bool SelectDeviceFeatures();
bool CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer); bool CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer);
@ -134,7 +135,7 @@ private:
u32 m_present_queue_family_index = 0; u32 m_present_queue_family_index = 0;
VkQueueFamilyProperties m_graphics_queue_properties = {}; VkQueueFamilyProperties m_graphics_queue_properties = {};
VkDebugReportCallbackEXT m_debug_report_callback = VK_NULL_HANDLE; VkDebugUtilsMessengerEXT m_debug_utils_messenger = VK_NULL_HANDLE;
VkPhysicalDeviceFeatures m_device_features = {}; VkPhysicalDeviceFeatures m_device_features = {};
VkPhysicalDeviceProperties m_device_properties = {}; VkPhysicalDeviceProperties m_device_properties = {};

View File

@ -57,9 +57,16 @@ VULKAN_INSTANCE_ENTRY_POINT(vkCreateAndroidSurfaceKHR, false)
VULKAN_INSTANCE_ENTRY_POINT(vkCreateMetalSurfaceEXT, false) VULKAN_INSTANCE_ENTRY_POINT(vkCreateMetalSurfaceEXT, false)
#endif #endif
VULKAN_INSTANCE_ENTRY_POINT(vkCreateDebugReportCallbackEXT, false) VULKAN_INSTANCE_ENTRY_POINT(vkCmdBeginDebugUtilsLabelEXT, false)
VULKAN_INSTANCE_ENTRY_POINT(vkDestroyDebugReportCallbackEXT, false) VULKAN_INSTANCE_ENTRY_POINT(vkCmdEndDebugUtilsLabelEXT, false)
VULKAN_INSTANCE_ENTRY_POINT(vkDebugReportMessageEXT, false) VULKAN_INSTANCE_ENTRY_POINT(vkCmdInsertDebugUtilsLabelEXT, false)
VULKAN_INSTANCE_ENTRY_POINT(vkDestroyDebugUtilsMessengerEXT, false)
VULKAN_INSTANCE_ENTRY_POINT(vkCreateDebugUtilsMessengerEXT, false)
VULKAN_INSTANCE_ENTRY_POINT(vkQueueBeginDebugUtilsLabelEXT, false)
VULKAN_INSTANCE_ENTRY_POINT(vkQueueEndDebugUtilsLabelEXT, false)
VULKAN_INSTANCE_ENTRY_POINT(vkQueueInsertDebugUtilsLabelEXT, false)
VULKAN_INSTANCE_ENTRY_POINT(vkSetDebugUtilsObjectTagEXT, false)
VULKAN_INSTANCE_ENTRY_POINT(vkSubmitDebugUtilsMessageEXT, false)
VULKAN_INSTANCE_ENTRY_POINT(vkGetPhysicalDeviceProperties2, false) VULKAN_INSTANCE_ENTRY_POINT(vkGetPhysicalDeviceProperties2, false)
VULKAN_INSTANCE_ENTRY_POINT(vkGetPhysicalDeviceSurfaceCapabilities2KHR, false) VULKAN_INSTANCE_ENTRY_POINT(vkGetPhysicalDeviceSurfaceCapabilities2KHR, false)
VULKAN_INSTANCE_ENTRY_POINT(vkSetDebugUtilsObjectNameEXT, false) VULKAN_INSTANCE_ENTRY_POINT(vkSetDebugUtilsObjectNameEXT, false)