Hi,
I’m having trouble getting error information from Vulkan. As far as I understand I have enabled the validation layer VK_LAYER_KHRONOS
_validation and the extension VK_EXT_debug_report
. I’m using SDL2 to create a window and a VkSurfaceKHR
. All the SDL-calls succeed, but then when I call vkCreateDevice
I get a VkResult
of -7
, which is VK_ERROR_EXTENSION_NOT_PRESENT
. However, I don’t know how to find out what extension is in question. The validation layers don’t print anything. Here’s the relevant code:
#include "Rendering.h"
VKAPI_ATTR VkBool32 VKAPI_CALL _VK_debug_fn(
VkDebugReportFlagsEXT p_flags,
VkDebugReportObjectTypeEXT p_obj_type,
uint64 p_obj,
size_t p_location,
int32 p_code,
const char *p_layer_prefix,
const char *p_msg,
void *p_data
) {
print("VK VALIDATION: ");
println(p_msg);
return VK_FALSE;
}
InitTerm _Renderer_InitTerm(
[] () {
println("_Rendering_Init");
Memory_Global->Rendering_SDL_window = SDL_CreateWindow(Memory_Global->App_name, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1920, 1080, SDL_WINDOW_VULKAN|SDL_WINDOW_SHOWN);
if (!Memory_Global->Rendering_SDL_window) {
println(concat("SDL_CreateWindow error: ", SDL_GetError()));
abort();
}
uint32 ext_count;
if (!SDL_Vulkan_GetInstanceExtensions(Memory_Global->Rendering_SDL_window, &ext_count, 0)) {
println(concat("SDL_Vulkan_GetInstanceExtensions error: ", SDL_GetError()));
abort();
}
ListRef<const char*> exts(ext_count);
auto exts_data = get_data(exts);
exts_data[0] = VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
if (!SDL_Vulkan_GetInstanceExtensions(Memory_Global->Rendering_SDL_window, &ext_count, exts_data + 1)) {
println(concat("SDL_Vulkan_GetInstanceExtensions error: ", SDL_GetError()));
abort();
}
ext_count += 1;
const char *layers[] = {
"VK_LAYER_KHRONOS_validation",
//"VK_LAYER_LUNARG_api_dump",
};
uint32 layer_count = sizeof(layers)/sizeof(const char *);
println("Vulkan instance extensions (enabled):");
for (uint32 i = 0; i < ext_count; ++i) {
print(" ");
println(exts_data[i]);
}
println("Vulkan validation layers (enabled):");
for (uint32 i = 0; i < layer_count; ++i) {
print(" ");
println(layers[i]);
}
VkApplicationInfo app_info = {};
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
app_info.pApplicationName = Memory_Global->App_name;
app_info.applicationVersion = VK_MAKE_VERSION(
Memory_Global->App_version_major,
Memory_Global->App_version_minor,
Memory_Global->App_version_patch
);
app_info.pEngineName = "Unnamed engine";
app_info.engineVersion = VK_MAKE_VERSION(
Memory_Global->App_version_major,
Memory_Global->App_version_minor,
Memory_Global->App_version_patch
);
app_info.apiVersion = VK_API_VERSION_1_2;
VkInstanceCreateInfo inst_create_info = {};
inst_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
inst_create_info.pApplicationInfo = &app_info;
inst_create_info.enabledLayerCount = layer_count;
inst_create_info.ppEnabledLayerNames = layers;
inst_create_info.enabledExtensionCount = ext_count;
inst_create_info.ppEnabledExtensionNames = exts_data;
println(vkCreateInstance(&inst_create_info, 0, &Memory_Global->Rendering_VK_instance));
auto SDL2_vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)SDL_Vulkan_GetVkGetInstanceProcAddr();
VkDebugReportCallbackCreateInfoEXT debug_callback_create_info = {};
debug_callback_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
debug_callback_create_info.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT|VK_DEBUG_REPORT_WARNING_BIT_EXT|VK_DEBUG_REPORT_DEBUG_BIT_EXT;
debug_callback_create_info.pfnCallback = _VK_debug_fn;
SDL2_vkCreateDebugReportCallbackEXT(Memory_Global->Rendering_VK_instance, &debug_callback_create_info, 0, &Memory_Global->Rendering_VK_debug_callback);
if (!SDL_Vulkan_CreateSurface(Memory_Global->Rendering_SDL_window, Memory_Global->Rendering_VK_instance, &Memory_Global->Rendering_VK_surface)) {
println(concat("SDL_Vulkan_CreateSurface error: ", SDL_GetError()));
abort();
}
uint32 dev_count;
println(vkEnumeratePhysicalDevices(Memory_Global->Rendering_VK_instance, &dev_count, 0));
ListRef<VkPhysicalDevice> devs(dev_count);
auto devs_data = get_data(devs);
println(vkEnumeratePhysicalDevices(Memory_Global->Rendering_VK_instance, &dev_count, devs_data));
println("Physical devices:");
for (uint32 i = 0; i < dev_count; ++i) {
VkPhysicalDeviceProperties dev_props;
vkGetPhysicalDeviceProperties(devs_data[i], &dev_props);
print(" ");
println(dev_props.deviceName);
}
Memory_Global->Rendering_VK_physical_device = devs_data[0];
uint32 queue_family_count;
vkGetPhysicalDeviceQueueFamilyProperties(Memory_Global->Rendering_VK_physical_device, &queue_family_count, 0);
ListRef<VkQueueFamilyProperties> queue_families(queue_family_count);
auto queue_families_data = get_data(queue_families);
vkGetPhysicalDeviceQueueFamilyProperties(Memory_Global->Rendering_VK_physical_device, &queue_family_count, queue_families_data);
uint32 graphics_queue_index = 0xffffffff;
uint32 present_queue_index = 0xffffffff;
for (uint32 i = 0; i < queue_family_count; ++i) {
auto queue_family = queue_families_data + i;
if (queue_family->queueCount > 0 && queue_family->queueFlags & VK_QUEUE_GRAPHICS_BIT) {
graphics_queue_index = i;
}
VkBool32 present_support = VK_FALSE;
println(vkGetPhysicalDeviceSurfaceSupportKHR(
Memory_Global->Rendering_VK_physical_device,
i,
Memory_Global->Rendering_VK_surface,
&present_support
));
if (queue_family->queueCount > 0 && present_support) {
present_queue_index = i;
}
if (graphics_queue_index != 0xffffffff && present_queue_index != 0xffffffff) {
break;
}
}
const char *dev_exts[] = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME
};
float32 queue_prio = 1.0f;
VkDeviceQueueCreateInfo device_queue_create_infos[2] = {};
device_queue_create_infos[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
device_queue_create_infos[0].queueFamilyIndex = graphics_queue_index;
device_queue_create_infos[0].queueCount = 1;
device_queue_create_infos[0].pQueuePriorities = &queue_prio;
device_queue_create_infos[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
device_queue_create_infos[1].queueFamilyIndex = present_queue_index;
device_queue_create_infos[1].queueCount = 1;
device_queue_create_infos[1].pQueuePriorities = &queue_prio;
uint32 device_queue_create_infos_count = sizeof(device_queue_create_infos)/sizeof(VkDeviceQueueCreateInfo);
VkPhysicalDeviceFeatures physical_device_features = {};
VkDeviceCreateInfo device_create_info = {};
device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
device_create_info.queueCreateInfoCount = device_queue_create_infos_count;
device_create_info.pQueueCreateInfos = device_queue_create_infos;
device_create_info.pEnabledFeatures = &physical_device_features;
device_create_info.enabledExtensionCount = ext_count;
device_create_info.ppEnabledExtensionNames = exts_data;
device_create_info.enabledLayerCount = layer_count;
device_create_info.ppEnabledLayerNames = layers;
print("About to create device: ");
println(vkCreateDevice(Memory_Global->Rendering_VK_physical_device, &device_create_info, 0, &Memory_Global->Rendering_VK_device));
vkGetDeviceQueue(Memory_Global->Rendering_VK_device, graphics_queue_index, 0, &Memory_Global->Rendering_VK_graphics_queue);
vkGetDeviceQueue(Memory_Global->Rendering_VK_device, present_queue_index, 0, &Memory_Global->Rendering_VK_present_queue);
VkSurfaceCapabilitiesKHR capabilities;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(Memory_Global->Rendering_VK_physical_device, Memory_Global->Rendering_VK_surface, &capabilities);
},
[] () {
println("_Rendering_Term");
vkDestroyDevice(Memory_Global->Rendering_VK_device, 0);
vkDestroySurfaceKHR(Memory_Global->Rendering_VK_instance, Memory_Global->Rendering_VK_surface, 0);
vkDestroyInstance(Memory_Global->Rendering_VK_instance, 0);
SDL_DestroyWindow(Memory_Global->Rendering_SDL_window);
return 0;
}
);
Memory_Global
points to a struct that contains variables for storing the window, surface, device etc.
The output from my prints reads as follows:
_Rendering_Init
Vulkan instance extensions (enabled):
VK_EXT_debug_report
VK_KHR_surface
VK_KHR_win32_surface
Vulkan validation layers (enabled):
VK_LAYER_KHRONOS_validation
0
0
0
Physical devices:
NVIDIA GeForce GTX 1060 6GB
0
About to create device: -7
And that’s when the program crashes, when a call to vkGetDeviceQueue
gets made. Any help with this would be greatly appreciated. Let me know if you need the output from VK_LAYER_LUNARG_api
_dump.
Cheers,
EngineArtist