I am trying to run through the basic Vulkan triangle demo. I am getting stuck at vkGetDeviceQueue which segfaults for me. I have written the same tutorial to about the same point in C and I am not getting the segfault. I have enabled validation layers and they are not picking up anything.
Any suggestions?
module vulkan; import std.exception : enforce; import erupted; import bindbc.sdl : SDL_Window, SDL_Vulkan_GetInstanceExtensions, SDL_Vulkan_CreateSurface; import memory; import util: CStringList; version (validateVulkan) { string [] validationLayers = ["VK_LAYER_KHRONOS_validation"]; const(char)[] debugExtension = "VK_EXT_debug_utils"; } else { string [] validationLayers = []; } CStringList getInstanceExtensions (SDL_Window * window) { uint n; SDL_Vulkan_GetInstanceExtensions(window,&n,null); version (validateVulkan) { auto extensions = CStringList(n+1); SDL_Vulkan_GetInstanceExtensions(window,&n,extensions.ptr); extensions[n] = cast(const(char)*) debugExtension.ptr; } else { auto extensions = CStringList(n); SDL_Vulkan_GetInstanceExtensions(window,&n,extensions.ptr); } return extensions; } void createInstance (CStringList extensions) { auto vlayers = CStringList(validationLayers); VkApplicationInfo appInfo = { pApplicationName: "Vulkan Test", apiVersion: VK_MAKE_API_VERSION(0,1,3,0), }; VkInstanceCreateInfo createInfo = { pApplicationInfo: &appInfo, enabledLayerCount: cast(uint) vlayers.length, ppEnabledLayerNames: vlayers.ptr, enabledExtensionCount: cast(uint) extensions.length, ppEnabledExtensionNames: extensions.ptr, }; auto r = vkCreateInstance(&createInfo, null, &instance); enforce(r == VK_SUCCESS,"failed to create instance"); loadInstanceLevelFunctions(instance); } void getPhysicalDevices () { uint n; vkEnumeratePhysicalDevices(instance, &n, null); physicalDevices = allocator.makeArray!VkPhysicalDevice(n); vkEnumeratePhysicalDevices(instance,&n,physicalDevices.ptr); enforce(physicalDevices.length > 0,"no physical devices found"); } void pickPhysicalDevice () { if (physicalDevices.length == 1) { primaryPhysicalDevice = physicalDevices[0]; } else { ulong maxScore,index=-1; foreach(i,device; physicalDevices) { uint score = 0; VkPhysicalDeviceProperties properties; device.vkGetPhysicalDeviceProperties(&properties); VkPhysicalDeviceFeatures features; device.vkGetPhysicalDeviceFeatures(&features); switch(properties.deviceType) { case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: score = 1000; break; case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: score = 500; break; case VK_PHYSICAL_DEVICE_TYPE_CPU: score = 100; break; default: score = 0; } if (score > maxScore) { maxScore = score; index = i; } } primaryPhysicalDevice = physicalDevices[index]; } enforce(primaryPhysicalDevice,"failed to find acceptable physical device"); } int [2] findQueueFamilies (VkPhysicalDevice dev) { int [2] r = [-1,-1]; uint n; vkGetPhysicalDeviceQueueFamilyProperties(dev,&n,null); auto families = memory.allocator.makeArray!VkQueueFamilyProperties(n); vkGetPhysicalDeviceQueueFamilyProperties(dev,&n,families.ptr); foreach (i,family; families) { if (family.queueCount > 0 && family.queueFlags & VK_QUEUE_GRAPHICS_BIT) r[0] = cast(uint) i; VkBool32 presentSupport = false; vkGetPhysicalDeviceSurfaceSupportKHR(dev,cast(uint)i, surface, &presentSupport); if (family.queueCount > 0 && presentSupport) r[1] = cast(uint) i; } enforce (r[0] >= 0,"failed to find grahpics family"); enforce (r[1] >= 0,"failed to find present family"); return r; } void createLogicalDevice (int[2] q) { const(float[]) priority = [1.0f]; VkDeviceQueueCreateInfo queueCreateInfo = { sType: VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, queueFamilyIndex: cast(uint) q[0], queueCount: 1, pQueuePriorities: priority.ptr, }; VkPhysicalDeviceFeatures deviceFeatures; VkDeviceCreateInfo createInfo = { sType: VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, pQueueCreateInfos: &queueCreateInfo, queueCreateInfoCount: 1, pEnabledFeatures: &deviceFeatures, }; auto r = vkCreateDevice(primaryPhysicalDevice,&createInfo,null,&device); enforce(r == VK_SUCCESS,"failed to create logical device"); } void getGraphicsQueue (uint i) { vkGetDeviceQueue(device, 0, 0, &graphicsQueue); enforce(graphicsQueue,"failed to get graphics queue"); } void init (SDL_Window * window) { createInstance(getInstanceExtensions(window)); version(validateVulkan) setupDebugMessenger(); getPhysicalDevices(); pickPhysicalDevice(); SDL_Vulkan_CreateSurface(window,instance,&surface); enforce(surface,"failed to create surface"); auto indicies = findQueueFamilies(primaryPhysicalDevice); createLogicalDevice(indicies); getGraphicsQueue(cast(uint)indicies[0]); } void shutdown() { vkDestroySurfaceKHR(instance,surface,null); memory.allocator.dispose(physicalDevices); version(validateVulkan) destroyDebugUtilsMessengerEXT(instance, debugMessenger, null); vkDestroyInstance(instance,null); } VkDebugUtilsMessengerEXT debugMessenger; VkSurfaceKHR surface = VK_NULL_HANDLE; VkInstance instance = null; VkPhysicalDevice [] physicalDevices; VkPhysicalDevice primaryPhysicalDevice; VkDevice device; VkQueue graphicsQueue, presentQueue; // Debug functions extern (C) uint debugCallback ( VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, uint messageType, const(VkDebugUtilsMessengerCallbackDataEXT)* pCallbackData, void * pUserData) nothrow @nogc { import std.stdio; printf("message type: %i\n",messageType); printf("%s\n", pCallbackData.pMessage); return VK_FALSE; } VkResult createDebugUtilsMessengerEXT( VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pDebugMessenger) { auto func = cast(PFN_vkCreateDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT"); if (func != null) { return func(instance, pCreateInfo, pAllocator, pDebugMessenger); } else { return VK_ERROR_EXTENSION_NOT_PRESENT; } } void destroyDebugUtilsMessengerEXT( VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator) { auto func = cast(PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT"); if (func != null) { func(instance, debugMessenger, pAllocator); } } void setupDebugMessenger () { if (validationLayers.length == 0) return; VkDebugUtilsMessengerCreateInfoEXT createInfo = { sType: VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, messageSeverity: VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, messageType: VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, pfnUserCallback: &debugCallback, }; enforce( createDebugUtilsMessengerEXT(instance, &createInfo, null, &debugMessenger) == VK_SUCCESS,"failed to create debug messenger"); }