diff options
Diffstat (limited to 'src/vksetup.h')
-rw-r--r-- | src/vksetup.h | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/src/vksetup.h b/src/vksetup.h new file mode 100644 index 0000000..2feb533 --- /dev/null +++ b/src/vksetup.h @@ -0,0 +1,216 @@ +#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_* <https://github.com/nothings/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 <SDL2/SDL.h> +#include <SDL2/SDL_vulkan.h> + +#include <vulkan/vulkan.h> + +#include <shaderc/shaderc.h> + +#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 <stddef.h> +#include <stdlib.h> +#include <time.h> +#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 */ + |