Tibe Cornelis
Tibe Cornelis

Reputation: 21

Vulkan Swapchain Creation Segmentation Fault on macOS (M3 MacBook Pro)

I'm following the Vulkan tutorial - "Drawing a Triangle" but I'm encountering an issue when creating a swapchain. The function vkCreateSwapchainKHR() throws an error, resulting in a segmentation fault:

./PhysicsEngine -r
zsh: segmentation fault  ./PhysicsEngine -r

Error Details


Additional Information


Relevant Code Snippets

Swapchain Creation Function

void App::CreateSwapchain()
{
    SwapchainSupportDetails mySwapchainSupportDetails = QuerySwapChainSupport(P_GPU);
    
    VkSurfaceFormatKHR mySurfaceFormat = ChooseSwapchainSurfaceFormat(mySwapchainSupportDetails.surfaceFormats);
    VkPresentModeKHR myPresentMode = ChooseSwapchainPresentMode(mySwapchainSupportDetails.presentModes);
    VkExtent2D myExtent = ChooseSwapchainExtent(mySwapchainSupportDetails.surfaceCapabilities);
    
    uint32_t MinimumImageCount = mySwapchainSupportDetails.surfaceCapabilities.minImageCount + 1;
    if (mySwapchainSupportDetails.surfaceCapabilities.maxImageCount > 0 &&
        MinimumImageCount > mySwapchainSupportDetails.surfaceCapabilities.maxImageCount)
    {
        MinimumImageCount = mySwapchainSupportDetails.surfaceCapabilities.maxImageCount;
    }
    
    VkSwapchainCreateInfoKHR CreateInfo{};
    CreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
    CreateInfo.surface = P_Surface;
    CreateInfo.minImageCount = MinimumImageCount;
    CreateInfo.imageFormat = mySurfaceFormat.format;
    CreateInfo.imageColorSpace = mySurfaceFormat.colorSpace;
    CreateInfo.imageExtent = myExtent;
    CreateInfo.imageArrayLayers = 1;
    CreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;

    QueueFamilyIndices myFamilyIndices = FindQueueFamilies(P_GPU);
    uint32_t QueueFamilyIndices[] = {myFamilyIndices.graphicsFamily.value(), myFamilyIndices.presentFamily.value()};
    if (myFamilyIndices.graphicsFamily != myFamilyIndices.presentFamily)
    {
        CreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
        CreateInfo.queueFamilyIndexCount = 2;
        CreateInfo.pQueueFamilyIndices = QueueFamilyIndices;
    }
    else
    {
        CreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
    }

    CreateInfo.preTransform = mySwapchainSupportDetails.surfaceCapabilities.currentTransform;
    CreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
    CreateInfo.presentMode = myPresentMode;
    CreateInfo.clipped = VK_TRUE;
    CreateInfo.oldSwapchain = VK_NULL_HANDLE;

    if (vkCreateSwapchainKHR(P_LogicalDevice, &CreateInfo, nullptr, &P_Swapchain) != VK_SUCCESS)
    {
        throw std::runtime_error("Error : Failed to create swapchain");
    }
}

Troubleshooting Steps Taken

  1. Verified Vulkan Installation: Checked Vulkan SDK installation and glfw Vulkan support

  2. Checked Swapchain Support: Used QuerySwapChainSupport() to confirm my GPU supports the required swapchain properties.

  3. Ensured Valid Logical Device: vkCreateDevice() does not return an error, and P_LogicalDevice is valid before calling vkCreateSwapchainKHR().

  4. Verified Surface Creation: glfwCreateWindowSurface() succeeds without errors.


Upvotes: 1

Views: 47

Answers (1)

Tibe Cornelis
Tibe Cornelis

Reputation: 21

Vulkan: Resolved Issue by Calling gladLoadVulkanUserPtr After Selecting GPU.

void App::PickPhysicalDevice()
{
    uint32_t DeviceCount = 0;
    vkEnumeratePhysicalDevices( P_VulkanInstance, &DeviceCount, nullptr );

    if( DeviceCount == 0 )
    {
        throw std::runtime_error("Error : failed to find gpu with vulkan support!");
    }

    std::vector<VkPhysicalDevice> GpuList( DeviceCount );
    VkPhysicalDevice SelectedGpu = VK_NULL_HANDLE;

    vkEnumeratePhysicalDevices( P_VulkanInstance, &DeviceCount, GpuList.data() );

    for( const auto& Gpu : GpuList )
    {
        if( IsGPUSuitable( Gpu ) )
        {
            SelectedGpu = Gpu;
            break;
        }
    }

    if( SelectedGpu == VK_NULL_HANDLE )
    {
        throw std::runtime_error("Error : failed to find suitable gpu");
    }

    P_GPU = SelectedGpu;

    gladLoadVulkanUserPtr( P_GPU, (GLADuserptrloadfunc)glfwGetInstanceProcAddress, P_VulkanInstance );

}

It seems function pointers weren’t properly loaded before selecting the GPU. Moving gladLoadVulkanUserPtr after assigning P_GPU fixed the problem.

Upvotes: 1

Related Questions