Vulkan: use VK_EXT_debug_report in debug configuration and break on warnings and errors.

This commit is contained in:
Artem Kharytoniuk 2017-12-30 22:16:17 +01:00
parent 8c60e190c5
commit c30a4b867f
2 changed files with 76 additions and 23 deletions

View File

@ -44,6 +44,8 @@ PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabili
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR; PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR; PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR; PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers; PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers;
PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets; PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets;
@ -441,40 +443,58 @@ static void ensure_staging_buffer_allocation(VkDeviceSize size) {
vk_world.staging_buffer_ptr = (byte*)data; vk_world.staging_buffer_ptr = (byte*)data;
} }
static VkBool32 debug_callback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT object_type, uint64_t object, size_t location,
int32_t message_code, const char* layer_prefix, const char* message, void* user_data) {
OutputDebugString(message);
OutputDebugString("\n");
DebugBreak();
return VK_FALSE;
}
static void create_instance() { static void create_instance() {
const char* instance_extensions[] = { const char* instance_extensions[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_EXTENSION_NAME,
VK_KHR_WIN32_SURFACE_EXTENSION_NAME VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
#ifndef NDEBUG
VK_EXT_DEBUG_REPORT_EXTENSION_NAME
#endif
}; };
uint32_t count = 0; // check extensions availability
VK_CHECK(vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr)); {
std::vector<VkExtensionProperties> extension_properties(count); uint32_t count = 0;
VK_CHECK(vkEnumerateInstanceExtensionProperties(nullptr, &count, extension_properties.data())); VK_CHECK(vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr));
std::vector<VkExtensionProperties> extension_properties(count);
VK_CHECK(vkEnumerateInstanceExtensionProperties(nullptr, &count, extension_properties.data()));
for (auto name : instance_extensions) { for (auto name : instance_extensions) {
bool supported = false; bool supported = false;
for (const auto& property : extension_properties) { for (const auto& property : extension_properties) {
if (!strcmp(property.extensionName, name)) { if (!strcmp(property.extensionName, name)) {
supported = true; supported = true;
break; break;
}
} }
if (!supported)
ri.Error(ERR_FATAL, "Vulkan: required instance extension is not available: %s", name);
} }
if (!supported)
ri.Error(ERR_FATAL, "Vulkan: required instance extension is not available: %s", name);
} }
VkInstanceCreateInfo desc; // create instance
desc.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; {
desc.pNext = nullptr; VkInstanceCreateInfo desc;
desc.flags = 0; desc.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
desc.pApplicationInfo = nullptr; desc.pNext = nullptr;
desc.enabledLayerCount = 0; desc.flags = 0;
desc.ppEnabledLayerNames = nullptr; desc.pApplicationInfo = nullptr;
desc.enabledExtensionCount = sizeof(instance_extensions)/sizeof(instance_extensions[0]); desc.enabledLayerCount = 0;
desc.ppEnabledExtensionNames = instance_extensions; desc.ppEnabledLayerNames = nullptr;
desc.enabledExtensionCount = sizeof(instance_extensions)/sizeof(instance_extensions[0]);
desc.ppEnabledExtensionNames = instance_extensions;
VK_CHECK(vkCreateInstance(&desc, nullptr, &vk.instance)); VK_CHECK(vkCreateInstance(&desc, nullptr, &vk.instance));
}
} }
static void create_device() { static void create_device() {
@ -616,6 +636,26 @@ static void init_vulkan_library() {
INIT_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR) INIT_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR)
INIT_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR) INIT_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR)
INIT_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR) INIT_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR)
INIT_INSTANCE_FUNCTION(vkCreateDebugReportCallbackEXT)
INIT_INSTANCE_FUNCTION(vkDestroyDebugReportCallbackEXT)
//
// Create debug callback.
//
#ifndef NDEBUG
{
VkDebugReportCallbackCreateInfoEXT desc;
desc.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
desc.pNext = nullptr;
desc.flags = VK_DEBUG_REPORT_WARNING_BIT_EXT |
VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT |
VK_DEBUG_REPORT_ERROR_BIT_EXT;
desc.pfnCallback = &debug_callback;
desc.pUserData = nullptr;
VK_CHECK(vkCreateDebugReportCallbackEXT(vk.instance, &desc, nullptr, &vk.debug_callback));
}
#endif
// //
// Get device level functions. // Get device level functions.
@ -719,6 +759,10 @@ static void deinit_vulkan_library() {
vkGetPhysicalDeviceSurfaceFormatsKHR = nullptr; vkGetPhysicalDeviceSurfaceFormatsKHR = nullptr;
vkGetPhysicalDeviceSurfacePresentModesKHR = nullptr; vkGetPhysicalDeviceSurfacePresentModesKHR = nullptr;
vkGetPhysicalDeviceSurfaceSupportKHR = nullptr; vkGetPhysicalDeviceSurfaceSupportKHR = nullptr;
#ifndef NDEBUG
vkCreateDebugReportCallbackEXT = nullptr;
vkDestroyDebugReportCallbackEXT = nullptr;
#endif
vkAllocateCommandBuffers = nullptr; vkAllocateCommandBuffers = nullptr;
vkAllocateDescriptorSets = nullptr; vkAllocateDescriptorSets = nullptr;
@ -1332,6 +1376,11 @@ void vk_shutdown() {
vkDestroySwapchainKHR(vk.device, vk.swapchain, nullptr); vkDestroySwapchainKHR(vk.device, vk.swapchain, nullptr);
vkDestroyDevice(vk.device, nullptr); vkDestroyDevice(vk.device, nullptr);
vkDestroySurfaceKHR(vk.instance, vk.surface, nullptr); vkDestroySurfaceKHR(vk.instance, vk.surface, nullptr);
#ifndef NDEBUG
vkDestroyDebugReportCallbackEXT(vk.instance, vk.debug_callback, nullptr);
#endif
vkDestroyInstance(vk.instance, nullptr); vkDestroyInstance(vk.instance, nullptr);
Com_Memset(&vk, 0, sizeof(vk)); Com_Memset(&vk, 0, sizeof(vk));

View File

@ -190,6 +190,10 @@ struct Vk_Instance {
VkPipeline surface_debug_pipeline_solid; VkPipeline surface_debug_pipeline_solid;
VkPipeline surface_debug_pipeline_outline; VkPipeline surface_debug_pipeline_outline;
VkPipeline images_debug_pipeline; VkPipeline images_debug_pipeline;
#ifndef NDEBUG
VkDebugReportCallbackEXT debug_callback;
#endif
}; };
// Vk_World contains vulkan resources/state requested by the game code. // Vk_World contains vulkan resources/state requested by the game code.