Создание экземпляра Vulkan завершается ошибкой с SDL2. Я не уверен, где я ошибаюсь

Я пытаюсь создать экземпляр и проверить, может ли код создать этот экземпляр.

Однако по какой-то причине код компилируется и не может создать экземпляр. Я не знаю, что я делаю неправильно. Все до создания экземпляра работает. но когда я пытаюсь проверить создание экземпляра, это не удается. Я использую SDL2 для создания окна.

Это мой файл cmakelist:

cmake_minimum_required(VERSION 3.16)
#COMPIER
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_C_COMPILER "gcc")
set(CMAKE_C_STANDARD 17)   
set(CMAKE_C_STANDARD_REQUIRED ON)

#FLAGS
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -ggdb3") 
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")

#PROJECT
project(Vulkan_test LANGUAGES C)
enable_language(C)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})

#Find packages installed in your system.
include(FindPkgConfig)
pkg_search_module(SDL2 REQUIRED sdl2)
pkg_search_module(Vulkan REQUIRED vulkan)

#Include global directories 
include_directories( 
    ${SDL2_INCLUDE_DIRS}
    ${Vulkan_INCLUDE_DIRS}
)
#Executable Specific
add_executable(VULKAN_TEST 
    ${CMAKE_CURRENT_SOURCE_DIR}/main.c
)

#Compile options
target_compile_options(VULKAN_TEST PUBLIC -O0 -ggdb3 -std=c2x -Wall -Wextra -Wmissing-prototypes -Wwrite-strings -Wpedantic)

#Libraries to link
target_link_libraries(
    VULKAN_TEST
    ${SDL2_LIBRARIES}
    ${Vulkan_LIBRARIES}
)

Это файл main.h, который у меня есть:

#pragma once
/*  Required Standard Headers  */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>

/* SDL2 */
#include <SDL2/SDL.h>
#include <SDL2/SDL_vulkan.h>

/* Vulkan */
#include <vulkan/vulkan.h>

#define rt_assert(expr, ...) ((void) sizeof ((expr) ? 1 : 0), __extension__ ({                                                     \
    if (!(expr)) {                                                                                                                 \
        fprintf(stderr,"At function [%s] in file [%s:%d], assert failed: [(%s)].\n", __func__, __FILE__, __LINE__, (#expr));       \
        __VA_ARGS__;                                                                                                               \
        exit(EXIT_FAILURE);                                                                                                        \
    }                                                                                                                              \
}))

typedef struct _App {
    SDL_Window *window;
    int window_height;
    int window_width;
    const char* window_name;
    SDL_Event sdl_event;
    bool quit;
    VkInstance inst;
    uint32_t sdlExtCount;
    const char** extNames;
} App;

/* Function Prototype */
void init_window(App *);
void init_vulkan(App *);
void main_loop(App *);
void cleanup(App *);


/* sub vulkan functions */
void init_vk_instance(App *);

Этот файл мой main.c

#include "main.h"

#define SDL_MAIN_HANDLED
#define App_init(X) App (X) = { \
    .window = NULL, .window_height = 600, .window_width = 800, \
    .window_name = "Vulkan Test", .quit = false, \
    .inst = VK_NULL_HANDLE \
}

VkApplicationInfo appInfo = {0};
VkInstanceCreateInfo instInfo = {0};

void init_vk_instance(App *App) {
    /* Vulkan VkApplicationInfo */
    appInfo.sType =  VK_STRUCTURE_TYPE_APPLICATION_INFO;
    appInfo.pApplicationName = App->window_name;
    appInfo.applicationVersion = VK_MAKE_API_VERSION(0, 1, 0, 0);
    appInfo.pEngineName = App->window_name;
    appInfo.engineVersion = VK_MAKE_API_VERSION(0, 1, 0, 0);
    /* This is version I have installed from my linux package manager */
    appInfo.apiVersion = VK_MAKE_API_VERSION(0,1,3,231); 
    appInfo.pNext = NULL;
    /* Vulkan Instance info - VkInstanceCreateInfo */
    instInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    instInfo.pApplicationInfo = &appInfo;
    instInfo.enabledLayerCount = 0;
    SDL_Vulkan_GetInstanceExtensions(App->window,&App->sdlExtCount,NULL);
    App->extNames = malloc(App->sdlExtCount * sizeof(const char*));
    SDL_Vulkan_GetInstanceExtensions(App->window,&App->sdlExtCount,App->extNames);
    instInfo.enabledExtensionCount = App->sdlExtCount;
    instInfo.ppEnabledExtensionNames = App->extNames;
    for(uint32_t i = 0; i < App->sdlExtCount; i++) {
        printf("%u : %s\n",i,App->extNames[i]);
    }
    rt_assert( (vkCreateInstance(&instInfo, NULL, &App->inst) == VK_SUCCESS), printf("Instance creation failed\n"), cleanup(App));
}

void init_vulkan(App *App) {
    init_vk_instance(App);
}

void init_window(App *App) {
    App->window =  SDL_CreateWindow( App->window_name,
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 
        App->window_width, App->window_height, SDL_WINDOW_SHOWN | SDL_WINDOW_VULKAN |
        SDL_WINDOW_RESIZABLE);
}
void cleanup(App *App) {
    free(App->extNames);
    SDL_DestroyWindow(App->window);
    SDL_Quit();
}
void main_loop(App *App) {
    while(!App->quit) {
        while (SDL_PollEvent(&App->sdl_event)) {
            if ( App->sdl_event.type == SDL_QUIT ) App->quit = true;
        }
    }
}
int main ( void ) {
    printf("Vulkan-Engine\n");
    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
    App_init(test);
    init_window(&test);
    init_vulkan(&test);
    main_loop(&test);
    vkDestroyInstance(test.inst, NULL);
    cleanup(&test);
    return EXIT_SUCCESS;
}

Это вывод, который я получаю после запуска моей программы:

Vulkan-Engine
0 : VK_KHR_surface
1 : VK_KHR_xlib_surface
At function [init_vk_instance] in file [/home/Codes/C/Vulkan/main.c:35], assert failed: [((vkCreateInstance(&instInfo, NULL, &App->inst) == VK_SUCCESS))].
Instance creation failed

Вывод CMake во время компиляции:

-- The C compiler identification is GNU 12.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/gcc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.2") 
-- Checking for one of the modules 'sdl2'
-- Checking for one of the modules 'vulkan'
-- Configuring done
-- Generating done
-- Build files have been written to: /home/Codes/C/Vulkan/build
[ 50%] Building C object CMakeFiles/VULKAN_TEST.dir/main.c.o
[100%] Linking C executable /home/Codes/C/Vulkan/VULKAN_TEST
[100%] Built target VULKAN_TEST

Это пакет, связанный с vulkan, который я установил в своей системе через менеджер пакетов:

Как видно из изображения, версия vulkan api — 1.3.231.1_1. Правильно ли я использую VK_MAKE_API_VERSION(0,1,3,231)?

Какое значение результата возвращается вызовом vkCreateInstance?

ComicSansMS 08.01.2023 07:42

пожалуйста, используйте github.com/acdemiralp/vulkan_sdl, вам нужно создать поверхность для конкретной платформы

Dickens A S 08.01.2023 08:35

@DickensAS SDL теперь изначально обеспечивает идентичную поддержку Vulkan, поэтому мне не нужно использовать этот репозиторий github.

Pragmatic 08.01.2023 08:56

@ComicSansMS Проблема в том, что vkCreateInstance возвращает VK_FAILURE не успех. Я думаю, что экземпляр должен быть создан первым, прежде чем я попытаюсь создать поверхность.

Pragmatic 08.01.2023 08:58

@Pragmatic ниже я дал код, оттуда вы можете что-то сделать со своей стороны

Dickens A S 08.01.2023 09:01

@DickensAS Ваш код очень похож на мой. Попробую найти этот макрос. Если это не проблема, я думаю, что проблема в cmake. Спасибо.

Pragmatic 08.01.2023 09:03

проблема была с моими переменными среды, а не с кодом. спасибо за помощь

Pragmatic 11.01.2023 10:17

В таких случаях лучше всего запустить vulkaninfo в терминале и посмотреть, нет ли проблем с vulkan.

Pragmatic 11.01.2023 10:23
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
86
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю вам не хватает KHR макроса
Например, я использую windows 10 и MSYS2 Это то, что я сделал

#define VK_USE_PLATFORM_WIN32_KHR
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define SDL_MAIN_HANDLED
#include <SDL2/SDL.h>
#include <SDL2/SDL_vulkan.h>
#include <vulkan/vulkan.h>
#include <vulkan/vulkan_core.h>


int main(int argc, char** argv)
{
    if (0 != SDL_Init(SDL_INIT_EVERYTHING))
    {
        printf("failed to initialize SDL2 with everything\n");
    }

    SDL_Window* window = SDL_CreateWindow("test", 10, 10, 640, 480, SDL_WINDOW_SHOWN | SDL_WINDOW_VULKAN);
    if (NULL == window)
    {
        printf("failed to create window\n");
    }

    VkApplicationInfo app_info = { 0 };
    app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    app_info.apiVersion = VK_API_VERSION_1_3;
    app_info.pApplicationName = "test-app";
    app_info.applicationVersion = VK_MAKE_API_VERSION(1, 0, 0, 0);
    app_info.pEngineName = "test-engine";
    app_info.engineVersion = VK_MAKE_API_VERSION(1, 0, 0, 0);

    VkInstanceCreateInfo instance_info = { 0 };
    instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    instance_info.pApplicationInfo = &app_info;
    instance_info.enabledLayerCount = 0;
    instance_info.ppEnabledLayerNames = NULL;

    unsigned int count = 0;
    SDL_Vulkan_GetInstanceExtensions(window, &count, NULL);
    const char** extensions = malloc(sizeof(char*) * count);
    SDL_Vulkan_GetInstanceExtensions(window, &count, extensions);

    for (unsigned int i = 0; i < count; i ++)
    {
        printf("%u: %s\n", i, extensions[i]);
    }

    instance_info.enabledExtensionCount = count;
    instance_info.ppEnabledExtensionNames = extensions;

    VkInstance instance = VK_NULL_HANDLE;
    if (0 > vkCreateInstance(&instance_info, NULL, &instance))
    {
        printf("failed to create instance\n");
    }

    VkSurfaceKHR surface = VK_NULL_HANDLE;
    if (SDL_FALSE == SDL_Vulkan_CreateSurface(window, instance, &surface))
    {
        printf("failed to create surface, SDL Error: %s", SDL_GetError());
    }

    return 0;
}

Для меня это работает нормально, поэтому, по моим наблюдениям, вам нужно найти способ определить подобный макрос, например #define VK_USE_PLATFORM_WIN32_KHR

Ниже приведены расширения списка, предполагаемые в vulkan.h.

VK_USE_PLATFORM_ANDROID_KHR
VK_USE_PLATFORM_FUCHSIA
VK_USE_PLATFORM_IOS_MVK
VK_USE_PLATFORM_MACOS_MVK
VK_USE_PLATFORM_METAL_EXT
VK_USE_PLATFORM_VI_NN
VK_USE_PLATFORM_WAYLAND_KHR
VK_USE_PLATFORM_WIN32_KHR
VK_USE_PLATFORM_XCB_KHR
VK_USE_PLATFORM_XLIB_KHR
VK_USE_PLATFORM_DIRECTFB_EXT
VK_USE_PLATFORM_XLIB_XRANDR_EXT
VK_USE_PLATFORM_GGP
VK_USE_PLATFORM_SCREEN_QNX
VK_ENABLE_BETA_EXTENSIONS

Вот как я компилирую MSYS2

gcc -O0 -g3 -Wall -c -fmessage-length=0 -o "src\\ansi-c.o" "..\\src\\ansi-c.c" 
gcc -o ansi-c.exe "src\\ansi-c.o" -lmingw32 -lSDL2main -lSDL2 -lvulkan-1.dll 

Я попробовал то, что вы сказали. Я не знаю, компьютер это или ОС, но вулкан просто не работает. У меня nvidia1050ti и запущенный линукс. Я также установил все зависимости. По какой-то причине vulkan просто не может создать экземпляр. Я попробовал макрос и потратил еще 3 часа, но vkCreateInstance никогда не возвращает успех. Спасибо за вашу помощь.

Pragmatic 08.01.2023 11:57

В какой-то момент я подумал, что, возможно, проблема с компоновкой, но если бы была проблема с компоновкой, она должна была показать ошибку во время компиляции.

Pragmatic 08.01.2023 11:59

в моем коде у меня есть два вызова SDL_Vulkan_GetInstanceExtensions вы можете попробовать это, или вы можете попробовать мой код напрямую

Dickens A S 08.01.2023 12:11

также попробуйте VK_API_VERSION_1_3 и VK_MAKE_API_VERSION(1, 0, 0, 0); для переменной instance_info

Dickens A S 08.01.2023 12:14

Я попробовал ваш код напрямую 0: VK_KHR_surface 1: VK_KHR_xlib_surface failed to create instance failed to create surface, SDL Error: Parameter 'instance' is invalid Вот что я получаю. Есть некоторая проблема с экземпляром в моей настройке. это не тот код, который я попробовал макрос VK_USE_PLATFORM_XLIB_KHR, а затем переключился на wayland и попробовал VK_USE_PLATFORM_WAYLAND_KHR кажется, ничего не решает проблему сбоя создания экземпляра

Pragmatic 08.01.2023 12:16

прочитайте подробности X11 здесь для void linux -- docs.voidlinux-ppc.org/configuration/graphics.html

Dickens A S 08.01.2023 12:17

Давайте продолжим обсуждение в чате.

Dickens A S 08.01.2023 12:19

Другие вопросы по теме