vkCreateSwapchainKHR() Segmentation fault (core dumped)

Alright, hi all! So the past few days I've been trying to solve this Vulkan issue with ceating a SwapchainKHR from Swift. I have posted an issue on the Vulkan Forums with no luck yet so I figured I would bring this issue over here just to see if I can get some help. So basically, the error is caused on line 417 in the Sources/NYON/main.swift file from the vkCreateSwapchainKHR() C Function. It is throwing a Segmentation fault (core dumped) error. You can find the current github project with the bug HERE. Super sorry to post this I know it is out of the interest of many but this happens to be the issues I run into LOL. It could possibly be an issue with the &swapchain or the &swapchainInfo but I have tried so many different variations of the info with no luck. If anyone has an idea of what is going on or what I did wrong here, or maybe know more about Vulkan please let me know what you think is going on. Thank you so much for the help you all as always!!!! For the record I am using Swift 5.1.1 on Ubuntu 19.10 with nvidia-driver-435. My graphics card is the GTX 1050 Ti 4gb.
Here's the lump of code:
(the line causing the error is commented // CAUSING ERROR)

import CVulkan
import CGLFW

guard glfwInit() == GLFW_TRUE else {

    fatalError("Failed to init GLFW")

}

guard glfwVulkanSupported() == GLFW_TRUE else {

    fatalError("Vulkan not supported")

}

glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API)

var width = 800

var height = 600

guard let window = glfwCreateWindow(Int32(width), Int32(height), "NYON", nil, nil) else {

    fatalError("Failed to create window")

}

var inst: VkInstance?

var appInfo = VkApplicationInfo(
    sType: VK_STRUCTURE_TYPE_APPLICATION_INFO,
    pNext: nil,
    pApplicationName: "NYON",
    applicationVersion: 1,
    pEngineName: "FREY",
    engineVersion: 1,
    apiVersion: 0)

var extensionCount: UInt32 = 0

var extensions = glfwGetRequiredInstanceExtensions(&extensionCount)

var instInfo = VkInstanceCreateInfo(
    sType: VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
    pNext: nil,
    flags: 0,
    pApplicationInfo: &appInfo,
    enabledLayerCount: 0,
    ppEnabledLayerNames: nil,
    enabledExtensionCount: extensionCount,
    ppEnabledExtensionNames: extensions)

guard vkCreateInstance(&instInfo, nil, &inst) == VK_SUCCESS else {

    fatalError("Failed to create instance")

}

var deviceCount: UInt32 = 0

guard vkEnumeratePhysicalDevices(inst, &deviceCount, nil) == VK_SUCCESS else {

    fatalError("Failed to get device count")

}

var devices = UnsafeMutablePointer<VkPhysicalDevice?>.allocate(capacity:Int(deviceCount))

guard vkEnumeratePhysicalDevices(inst, &deviceCount, devices) == VK_SUCCESS else {

    fatalError("Failed to get devices")

}

guard deviceCount != 0 else {

    fatalError("No devices")

}

var queueFamilyCount: UInt32 = 0

vkGetPhysicalDeviceQueueFamilyProperties(devices.pointee, &queueFamilyCount, nil)

var queueProps = UnsafeMutablePointer<VkQueueFamilyProperties>.allocate(capacity:Int(queueFamilyCount))

vkGetPhysicalDeviceQueueFamilyProperties(devices.pointee, &queueFamilyCount, queueProps)

var deviceIndex = 0

for (index, queueFamily) in UnsafeBufferPointer(start: queueProps, count: Int(queueFamilyCount)).enumerated() {

    if type(of: queueFamily) == VkQueueFamilyProperties.self {

        if queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT.rawValue != 0 {

            deviceIndex = index

        }

    }

}

guard queueFamilyCount > 0 else {

    fatalError("No queue")

}

var queuePriority: Float = 1.0

var queueInfo = VkDeviceQueueCreateInfo(
    sType: VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
    pNext: nil,
    flags: 0,
    queueFamilyIndex: 0,
    queueCount: 1,
    pQueuePriorities: &queuePriority)

var deviceInfo = VkDeviceCreateInfo(
    sType: VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
    pNext: nil,
    flags: 0,
    queueCreateInfoCount: 1,
    pQueueCreateInfos: &queueInfo,
    enabledLayerCount: 0,
    ppEnabledLayerNames: nil,
    enabledExtensionCount: 0,
    ppEnabledExtensionNames: nil,
    pEnabledFeatures: nil)

var device: VkDevice?

guard vkCreateDevice(devices[deviceIndex], &deviceInfo, nil, &device) == VK_SUCCESS else {

    fatalError("Failed to create device")

}

var cmdPoolInfo = VkCommandPoolCreateInfo(
    sType: VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
    pNext: nil,
    flags: 0,
    queueFamilyIndex: UInt32(deviceIndex))

var cmdPool: VkCommandPool?

guard vkCreateCommandPool(device, &cmdPoolInfo, nil, &cmdPool) == VK_SUCCESS else {

    fatalError("Failed to create command pool")

}

var cmdInfo = VkCommandBufferAllocateInfo(
    sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
    pNext: nil,
    commandPool: cmdPool,
    level: VK_COMMAND_BUFFER_LEVEL_PRIMARY,
    commandBufferCount: 1)

var cmd: VkCommandBuffer?

guard vkAllocateCommandBuffers(device, &cmdInfo, &cmd) == VK_SUCCESS else {

    fatalError("Failed to allocate command buffers")

}

guard glfwGetPhysicalDevicePresentationSupport(inst, devices[deviceIndex], queueFamilyCount) == GLFW_NO_ERROR else {

    fatalError("Failed device presentation support")

}

var surface: VkSurfaceKHR?

guard glfwCreateWindowSurface(inst, window, nil, &surface) == VK_SUCCESS else {

    fatalError("Failed to create window surface")

}

var pSupportsPresent = UnsafeMutablePointer<VkBool32>.allocate(capacity:Int(queueFamilyCount * UInt32(MemoryLayout.size(ofValue: VkBool32.self))))

for index in 0...queueFamilyCount {

    vkGetPhysicalDeviceSurfaceSupportKHR(devices[deviceIndex], index, surface, &pSupportsPresent[Int(index)])

}

var graphicsQueueFamilyIndex = UInt32.max

var presentQueueFamilyIndex = UInt32.max

for index in 0...queueFamilyCount {

    if queueProps[Int(index)].queueFlags & UInt32(VK_QUEUE_GRAPHICS_BIT.rawValue) != 0 {

        if graphicsQueueFamilyIndex == UInt32.max {

            graphicsQueueFamilyIndex = index

        }

        if pSupportsPresent[Int(index)] == VK_TRUE {

            graphicsQueueFamilyIndex = index

            presentQueueFamilyIndex = index

            break

        }

    }

}

if presentQueueFamilyIndex == UInt32.max {

    for index in 0...queueFamilyCount {

        if pSupportsPresent[Int(index)] == VK_TRUE {

            presentQueueFamilyIndex = index

            break

        }

    }

}

free(pSupportsPresent)

guard graphicsQueueFamilyIndex != UInt32.max else {

    fatalError("Failed to find graphics index")

}

guard presentQueueFamilyIndex != UInt32.max else {

    fatalError("Failed to find family index")

}

var formatCount: UInt32 = 0

guard vkGetPhysicalDeviceSurfaceFormatsKHR(devices[deviceIndex], surface, &formatCount, nil) == VK_SUCCESS else {

    fatalError("Failed device format count")

}

var surfFormats = UnsafeMutablePointer<VkSurfaceFormatKHR>.allocate(capacity:Int(formatCount * UInt32(MemoryLayout.size(ofValue: VkSurfaceFormatKHR.self))))

guard vkGetPhysicalDeviceSurfaceFormatsKHR(devices[deviceIndex], surface, &formatCount, surfFormats) == VK_SUCCESS else {

    fatalError("Failed device surface format")

}

var format: VkFormat

if formatCount == 1 && surfFormats[0].format == VK_FORMAT_UNDEFINED {

    format = VK_FORMAT_B8G8R8A8_UNORM

} else {

    guard formatCount > 0 else {

        fatalError("Failed format check")

    }

    format = surfFormats[0].format

}

free(surfFormats)

var surfCapabilities = VkSurfaceCapabilitiesKHR()

guard vkGetPhysicalDeviceSurfaceCapabilitiesKHR(devices[deviceIndex], surface, &surfCapabilities) == VK_SUCCESS else {

    fatalError("Failed device surface capabilities")

}

var presentModeCount: UInt32 = 0

guard vkGetPhysicalDeviceSurfacePresentModesKHR(devices[deviceIndex], surface, &presentModeCount, nil) == VK_SUCCESS else {

    fatalError("Failed device surface count")

}

var presentModes = UnsafeMutablePointer<VkPresentModeKHR>.allocate(capacity:Int(presentModeCount * UInt32(MemoryLayout.size(ofValue: VkPresentModeKHR.self))))

guard vkGetPhysicalDeviceSurfacePresentModesKHR(devices[deviceIndex], surface, &presentModeCount, presentModes) == VK_SUCCESS else {

    fatalError("Failed device surface mode")

}

var swapchainExtent: VkExtent2D

if surfCapabilities.currentExtent.width == 0xFFFFFFFF {

    swapchainExtent = VkExtent2D()

    swapchainExtent.width = UInt32(width)

    swapchainExtent.height = UInt32(height)

    if swapchainExtent.width < surfCapabilities.minImageExtent.width {

        swapchainExtent.width = surfCapabilities.minImageExtent.width

    } else if swapchainExtent.width > surfCapabilities.maxImageExtent.width {

        swapchainExtent.width = surfCapabilities.maxImageExtent.width

    }

    if swapchainExtent.height < surfCapabilities.minImageExtent.height {

        swapchainExtent.height = surfCapabilities.minImageExtent.height

    } else if swapchainExtent.height > surfCapabilities.maxImageExtent.height {

        swapchainExtent.height = surfCapabilities.maxImageExtent.height

    }

} else {

    swapchainExtent = surfCapabilities.currentExtent

}

var desiredNumberOfSwapChainImages = surfCapabilities.minImageCount

var preTransform: VkSurfaceTransformFlagBitsKHR

if surfCapabilities.supportedTransforms & UInt32(VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR.rawValue) != 0 {

    preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR

} else {

    preTransform = surfCapabilities.currentTransform

}

var compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR

var compositeAlphaFlags = [
    VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
    VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR,
    VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR,
    VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR
]

var iterateFlags = MemoryLayout.size(ofValue: compositeAlphaFlags) / MemoryLayout.size(ofValue: compositeAlphaFlags[0])

for index in 0...iterateFlags {

    if (surfCapabilities.supportedCompositeAlpha & UInt32(compositeAlphaFlags[index].rawValue)) != 0 {

        compositeAlpha = compositeAlphaFlags[index]

        break

    }

}

var swapchainInfo = VkSwapchainCreateInfoKHR(
    sType: VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
    pNext: nil,
    flags: 0,
    surface: surface,
    minImageCount: desiredNumberOfSwapChainImages,
    imageFormat: format,
    imageColorSpace: VK_COLORSPACE_SRGB_NONLINEAR_KHR,
    imageExtent: VkExtent2D(width: swapchainExtent.width, height: swapchainExtent.height),
    imageArrayLayers: 1,
    imageUsage: UInt32(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT.rawValue),
    imageSharingMode: VK_SHARING_MODE_EXCLUSIVE,
    queueFamilyIndexCount: 0,
    pQueueFamilyIndices: nil,
    preTransform: preTransform,
    compositeAlpha: compositeAlpha,
    presentMode: VK_PRESENT_MODE_FIFO_KHR,
    clipped: 1,
    oldSwapchain: nil)

var queueFamilyIndices = UnsafePointer([graphicsQueueFamilyIndex, presentQueueFamilyIndex])

if graphicsQueueFamilyIndex != presentQueueFamilyIndex {

    swapchainInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT

    swapchainInfo.queueFamilyIndexCount = 2

    swapchainInfo.pQueueFamilyIndices = queueFamilyIndices

}

var swapchain: VkSwapchainKHR?

guard vkCreateSwapchainKHR(device, &swapchainInfo, nil, &swapchain) == VK_SUCCESS else { // CAUSING ERROR

    fatalError("Failed create swapchain")
    
}

while 0 == glfwWindowShouldClose(window) {

    glfwPollEvents()

}

vkFreeCommandBuffers(device, cmdPool, 1, &cmd)

vkDestroyCommandPool(device, cmdPool, nil)

vkDestroyDevice(device, nil)

vkDestroyInstance(inst, nil)

glfwTerminate()

Are you getting anything back from validation layers?

1 Like

Sadly no, I tried setting up a few different versions of the layers through the vkCreateDevice() function but with no response. I may need to look into if the validation layers were actually working properly which is what I'll do now. TBH I may have not set up the validation layers in the correct way in the first place. Gonna try and figure that out now.

False alarm, anyone who wants to resolve the issue it may be that you forgot to add VK_KHR_swapchain to the device extensions at VkDeviceCreateInfo in vkCreateDevice(). Make sure you have that extension added!

1 Like

Thank you very much, my friend. This was immensely helpful!!