I am trying to create an instance and validate that the code can create that instance.
However, For some reason code compiles and fails to create the instance. I do not know what I am doing wrong. Everything before creating instance works. but When I try to validate instance creation it fails. I am using SDL2 to create the window.
This is my cmakelist file:
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}
)
This is the is the main.h file that I have:
#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 *);
This file my 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;
}
This the output I get after running my program:
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 output during compilation:
-- 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
These are the vulkan related package I have installed on my system through package manager:
As you see from the image the vulkan api version is 1.3.231.1_1. Am I using the VK_MAKE_API_VERSION(0,1,3,231)
properly?
I think you are missing KHR
macro
For example I am using windows 10
and MSYS2
This is what I did
#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;
}
For me it is working fine, so my observation is you need to find a way for defining similar macro like #define VK_USE_PLATFORM_WIN32_KHR
Below are the list extensions assumed in 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
This is how I compile in 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