#ifndef _VKSETUP_H #define _VKSETUP_H /* Start header file */ /** vulkan setup and basic vector math Single header file with included implementation in the spirit of stb_* ASSUMPTIONS: ~~~~~~~~~~~~ - Using SDL2 for the window - Using cglm for maths - Using shaderc for compiling glsl - Using vulkan(!) USAGE: ~~~~~~ Do this: #define VKSETUP_IMPLEMENTATION before you include this file in *one* C or C++ file to create the implementation. // i.e. it should look like this: #include ... #include ... #include ... #define VKSETUP_IMPLEMENTATION #include "vksetup.h" */ #define SDL_MAIN_HANDLED #define VK_USE_PLATFORM_XCB_KHR #include #include #include #include #include "../lib/cglm/include/cglm/cglm.h" #ifdef __cplusplus extern "C" { #endif #ifndef VKSETUPDEF #ifdef VKSETUP_STATIC #define VKSETUPDEF static #else #define VKSETUPDEF extern #endif #endif // TODO Create structs for vulkan data typedef struct {void * a;} vksetup_vulkan; typedef struct {void * a;} vksetup_image; typedef struct {void * a;} vksetup_; // need abstraction with the /** Create a VkInstance */ VKSETUPDEF VkInstance vksetup_create_instance(bool validation_layers_toggle, const char * const validation_layers[], uint32_t validation_layer_count, SDL_Window *window); /* VKSETUPDEF void vulkan_create_surface(); */ /* VKSETUPDEF void vulkan_pick_physical_device(); */ /* VKSETUPDEF void vulkan_create_logical_device(); */ /* VKSETUPDEF void vulkan_create_swap_chain(); */ /* VKSETUPDEF void vulkan_create_image_views(); */ /* VKSETUPDEF void vulkan_create_descriptor_set_layout(); */ /* VKSETUPDEF void vulkan_create_graphics_pipeline(); */ /* VKSETUPDEF void vulkan_create_command_pool(); */ /* VKSETUPDEF void vulkan_create_depth_resources(); */ /* VKSETUPDEF void vulkan_create_texture_image(); */ /* VKSETUPDEF void vulkan_create_texture_image_view(); */ /* VKSETUPDEF void vulkan_create_texture_sampler(); */ /* VKSETUPDEF void vulkan_create_vertex_buffer(); */ /* VKSETUPDEF void vulkan_create_index_buffer(); */ /* VKSETUPDEF void vulkan_create_uniform_buffers(); */ /* VKSETUPDEF void vulkan_create_descriptor_pool(); */ /* VKSETUPDEF void vulkan_create_descriptor_sets(); */ /* VKSETUPDEF void vulkan_create_command_buffer(); */ /* VKSETUPDEF void vulkan_create_sync_objects(); */ #ifdef __cplusplus } #endif /* End header file */ #endif /* _VKSETUP_H */ #ifdef VKSETUP_IMPLEMENTATION #include #include #include #include "vkutil.h" bool _checkValidationLayerSupport(const char * const validation_layers[], uint32_t validation_layer_count) { uint32_t layerCount; vkEnumerateInstanceLayerProperties(&layerCount, NULL); VkLayerProperties availableLayers[layerCount]; vkEnumerateInstanceLayerProperties(&layerCount, availableLayers); for (uint32_t i = 0; i < validation_layer_count; i++) { bool layerFound = false; for (uint32_t j = 0; j < layerCount; j++) { if (strcmp(validation_layers[i], availableLayers[j].layerName) == 0) { layerFound = true; break; } } if (!layerFound) { return false; } } return true; } VKSETUPDEF VkInstance vksetup_create_instance(bool validation_layers_toggle, const char * const validation_layers[], uint32_t validation_layer_count, SDL_Window *window) { if (validation_layers_toggle && !_checkValidationLayerSupport(validation_layers, validation_layer_count)) { vk_log(VK_ERROR, "validation layers requested, but not available!\n"); } uint32_t instanceVersion; VkResult result = vkEnumerateInstanceVersion(&instanceVersion); if (result == VK_SUCCESS) { if (instanceVersion < VK_MAKE_API_VERSION(0, 1, 3, 0)) { vk_log(VK_ERROR, "Vulkan version 1.3 or greater required!\n"); exit(1); } vk_log(VK_INFO, "Vulkan version found (%d) %d.%d.%d\n", VK_API_VERSION_VARIANT(instanceVersion), VK_API_VERSION_MAJOR(instanceVersion), VK_API_VERSION_MINOR(instanceVersion), VK_API_VERSION_PATCH(instanceVersion)); } else { vk_log(VK_ERROR, "Failed to retrieve vulkan version, is vulkan supported in this system?\n"); exit(1); } // Load Vulkan and create instance VkApplicationInfo appInfo = { .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, .pApplicationName = "Vulkan Application", .applicationVersion = VK_MAKE_API_VERSION(0, 1, 3, 0), .pEngineName = NULL, .engineVersion = VK_MAKE_API_VERSION(0, 1, 3, 0), .apiVersion = VK_MAKE_API_VERSION(0, 1, 3, 0), }; uint32_t sdlExtensionCount = 0; if (SDL_Vulkan_GetInstanceExtensions(window, &sdlExtensionCount, NULL) == SDL_FALSE) { vk_log(VK_ERROR, "SDL_Vulkan_GetInstanceExtensions failed: %s\n", SDL_GetError()); } // make space for debug extenetion if (validation_layers_toggle) { sdlExtensionCount++; } const char* sdlExtensions[sdlExtensionCount]; if (SDL_Vulkan_GetInstanceExtensions(window, &sdlExtensionCount, sdlExtensions) == SDL_FALSE) { vk_log(VK_ERROR, "SDL_Vulkan_GetInstanceExtensions failed: %s\n", SDL_GetError()); } // add debug extenetion if (validation_layers_toggle) { sdlExtensions[sdlExtensionCount] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME; } vk_log(VK_INFO, "The sdl extensions:\n"); for (uint32_t i = 0; i < sdlExtensionCount; i++) { vk_log(VK_INFO, "\t%s\n", sdlExtensions[i]); } VkInstanceCreateInfo createInfo = { .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .pApplicationInfo = &appInfo, .enabledExtensionCount = sdlExtensionCount, .ppEnabledExtensionNames = sdlExtensions, .enabledLayerCount = 0, }; if (validation_layers_toggle) { createInfo.enabledLayerCount = validation_layer_count; createInfo.ppEnabledLayerNames = validation_layers; } VkInstance instance; if (vkCreateInstance(&createInfo, NULL, &instance) != VK_SUCCESS) { vk_log(VK_ERROR, "Can't start vulkan instance\n"); } vk_log(VK_INFO, "Vulkan instance created\n"); return instance; } #endif /* VKSETUP_IMPLEMENTATION */