Home > front end >  Vulkan instance creation crashes on C
Vulkan instance creation crashes on C

Time:12-07

I've tried to run instance creation and validation layer tutorial of official vulkan tutorial in the code below, but it crashes on code vkCreateInstance after that debugger goes to the blank tab called vulkan-1!vkResetFences() at 0x7ffe44ad3810 and in none-debugging, app is forcibly closing fast.

I'm using MSYS2 mingw64 on Windows 10 64bit. Also I've available extensions and required extension for glfw was there. Note i didn't download vulkan sdk, I've just downloaded packages from MSYS2, header, loader and validation layer. Included libraries -l: vulkan-1 and glfw.

#define GLFW_INCLUDE_VULKAN
#define  VK_LAYER_KHRONOS_validation
#include <GLFW/glfw3.h>

//#include <vulkan/vk_layer.h>
#include <stdio.h>
#include <string.h>
//#include <error.h>
#include <stdlib.h>
#include <stdbool.h>

#define  WIDTH 800
#define  HEIGHT 600

const char* validationLayers = {
    "VK_LAYER_KHRONOS_validation"
};

#ifdef NDEBUG
const bool enableValidationLayers = false;
#else
const bool enableValidationLayers = true;
#endif

VkResult CreateDebugUtilsMessengerEXT(VkInstance instance,
        const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
        const VkAllocationCallbacks* pAllocator,
        VkDebugUtilsMessengerEXT* pDebugMessenger)
{
    PFN_vkCreateDebugUtilsMessengerEXT func = (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) {
    PFN_vkDestroyDebugUtilsMessengerEXT func = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
    if (func != NULL) {
        func(instance, debugMessenger, pAllocator);
    }
}


static GLFWwindow* window;
static VkInstance instance;
static VkDebugUtilsMessengerEXT debugMessenger;



void HelloTriangle_initWindow() {
        glfwInit();

        glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
        glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);

        window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", NULL, NULL);
    }
bool HelloTriangle_checkValidationLayerSupport()
{
    uint32_t layerCount;
    vkEnumerateInstanceLayerProperties(&layerCount, NULL);

    VkLayerProperties availableLayers[layerCount];
    vkEnumerateInstanceLayerProperties(&layerCount, availableLayers);


    bool layerFound = false;

    for (unsigned short i=0;i<layerCount;i  )
    {
        if (strcmp(validationLayers, availableLayers[i].layerName) == 0)
        {
            layerFound = true;
            break;
        }
    }

    if (!layerFound)
    {
        return false;
    }

    return true;
}
void HelloTriangle_setupDebugMessenger() {
        if (!enableValidationLayers) return;

        VkDebugUtilsMessengerCreateInfoEXT createInfo;
        HelloTriangle_populateDebugMessengerCreateInfo(&createInfo);

        if (CreateDebugUtilsMessengerEXT(instance, &createInfo, NULL, &debugMessenger) != VK_SUCCESS) {
            printf("failed to set up debug messenger!");
        }
    }
static char** getRequiredExtensions(uint32_t* pExtensionsCount)
{
    uint32_t glfwExtensionCount = 0;

     const char** glfwExtensions;
    glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);


    if (enableValidationLayers)
    {
        *pExtensionsCount=glfwExtensionCount 1;
    }
    char* * extensions;//needs instance
    extensions=(char* *)malloc(*pExtensionsCount*sizeof(char*));

    for(uint8_t i=0;i<(*pExtensionsCount);i  )
    {
        extensions[i]=(char*)malloc(10*sizeof(char));
        memset(extensions[i],0,10*sizeof(char));
    }

    for(uint8_t i=0;i<glfwExtensionCount;i  )
    {
        strcpy(&extensions[i][0],&glfwExtensions[i][0]);
    }
    char debugextension[]=VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
    if (enableValidationLayers)
    {
        strcpy(&extensions[(*pExtensionsCount)-1][0],debugextension);
    }
    return extensions;

}



void HelloTriangle_createInstance()
{
        if (enableValidationLayers && !HelloTriangle_checkValidationLayerSupport()) {
            printf("validation layers requested, but not available!");
        }

        VkApplicationInfo appInfo;
        appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
        appInfo.pApplicationName = "Hello Triangle";
        appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
        appInfo.pEngineName = "No Engine";
        appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
        appInfo.apiVersion = VK_API_VERSION_1_0;

        VkInstanceCreateInfo createInfo;
        createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
        createInfo.pApplicationInfo = &appInfo;

        uint32_t ExtensionsCount=0;
        char** extensions;
        extensions = getRequiredExtensions(&ExtensionsCount);
        createInfo.enabledExtensionCount = ExtensionsCount;
        createInfo.ppEnabledExtensionNames = extensions;

        VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo;
        if (enableValidationLayers)
        {
            createInfo.enabledLayerCount = 1;
            createInfo.ppEnabledLayerNames = validationLayers;

            HelloTriangle_populateDebugMessengerCreateInfo(&debugCreateInfo);
            createInfo.pNext = (VkDebugUtilsMessengerCreateInfoEXT*) &debugCreateInfo;
        }
        else
        {
            createInfo.enabledLayerCount = 0;

            createInfo.pNext = NULL;
        }

        if (vkCreateInstance(&createInfo, NULL, &instance) != VK_SUCCESS) {
            printf("failed to create instance!");
        }
}
void HelloTriangle_initVulkan()
{
    HelloTriangle_createInstance();
    HelloTriangle_setupDebugMessenger();
}
void HelloTriangle_mainLoop()
{
   while (!glfwWindowShouldClose(window))
   {
       glfwPollEvents();
   }
}
void HelloTriangle_cleanup() {
        if (enableValidationLayers) {
            DestroyDebugUtilsMessengerEXT(instance, debugMessenger, NULL);
        }

        vkDestroyInstance(instance, NULL);

        glfwDestroyWindow(window);

        glfwTerminate();
    }

void HelloTriangle_run() {
    HelloTriangle_initWindow();
    HelloTriangle_initVulkan();
    HelloTriangle_mainLoop();
    HelloTriangle_cleanup();
}



static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData) {
        printf("validation layer: %s",pCallbackData->pMessage);

        return VK_FALSE;
    }

void HelloTriangle_populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT* createInfo)
{
    createInfo->sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
    createInfo->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;
    createInfo->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 | VK_DEBUG_UTILS_MESSAGE_TYPE_DEVICE_ADDRESS_BINDING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_FLAG_BITS_MAX_ENUM_EXT;
    createInfo->pfnUserCallback = debugCallback;
}


int main()
{


    HelloTriangle_run();


    return EXIT_SUCCESS;
}

It tries to activate these:

Extension: VK_KHR_surface Extension: VK_KHR_win32_surface Extension: VK_EXT_debug_utils

CodePudding user response:

You code have various rookie errors:

  • uninitialized variable appInfo.pNext
  • uninitialized variable createInfo.flags
  • you don't check whether mallocs succeed in getRequiredExtensions
  • your malloc limits size of extension name to 10 chars incl. null, but e.g. VK_KHR_surface is 15.
  • createInfo.ppEnabledLayerNames = validationLayers; assigns char* to char**
  • debugCreateInfo.pNext is unitialized
  • debugCreateInfo.flags is unitialized

Personal advice is to steer clear of Vulkan for now. If you do not know how to program properly yet, then Vulkan will teach you exactly the wrong thing about programming. And vice versa, good programing practices applicable to 99 % of cases may teach you the wrong thing about Vulkan.

  • Related