diff options
Diffstat (limited to 'src/vksetup.h')
-rw-r--r-- | src/vksetup.h | 207 |
1 files changed, 181 insertions, 26 deletions
diff --git a/src/vksetup.h b/src/vksetup.h index 88f579a..4f05347 100644 --- a/src/vksetup.h +++ b/src/vksetup.h @@ -34,6 +34,7 @@ */ +#include <vulkan/vulkan_core.h> #define SDL_MAIN_HANDLED #define VK_USE_PLATFORM_XCB_KHR #include <stdarg.h> @@ -144,14 +145,62 @@ extern "C" { // TODO Create structs for vulkan data -typedef struct {void * a;} vks_vulkan; -typedef struct {void * a;} vks_image; -typedef struct {void * a;} vks_; +typedef struct vks_swapchain { + VkSwapchainKHR handle; -/** - Create a VkInstance - */ + VkFormat image_format; + VkExtent2D extent; + + uint32_t image_count; + VkImage images[5]; + VkImageView image_views[5]; // 5 for some reason +} vks_swapchain; + +typedef struct vks_buffer { + VkBuffer handle; + VkDeviceMemory memory; +} vks_buffer; + +typedef struct vks_image { + VkImage handle; + VkDeviceMemory memory; + VkImageView view; +} vks_image; + +typedef struct vks_pipeline { + VkPipeline handle; + VkPipelineLayout layout; +} vks_pipeline; + +typedef struct vks_context { + VkInstance instance; + VkPhysicalDevice physical_device; + VkDevice device; + + SDL_Window *window; + VkSurfaceKHR surface; + + vks_swapchain swapchain; +} vks_context; + +typedef struct vks_frame_data { + VkCommandBuffer vk_command_buffer; + + VkSemaphore image_available_semaphore; + VkSemaphore render_finished_semaphore; + VkFence in_flight_fence; + + vks_buffer uniform_buffer; + void * uniform_buffer_mapped; + + VkDescriptorSet vk_descriptor_set; +} vks_frame_data; + + +/* Exported API */ VKSDEF VkInstance vks_create_instance(bool validation_layers_toggle, const char * const validation_layers[], uint32_t validation_layer_count, SDL_Window *window); +VKSDEF void vks_create_buffer(const vks_context vk, const VkDeviceSize size, const VkBufferUsageFlags usage, const VkMemoryPropertyFlags properties, vks_buffer *buffer); +VKSDEF void vks_create_image(const vks_context vk, const uint32_t width, const uint32_t height, const uint32_t mipLevels, const VkFormat format, const VkImageTiling tiling, const VkImageUsageFlags usage, const VkMemoryPropertyFlags properties, const VkSampleCountFlagBits numSamples, vks_image *image); /* VKSDEF void vulkan_create_surface(); */ /* VKSDEF void vulkan_pick_physical_device(); */ /* VKSDEF void vulkan_create_logical_device(); */ @@ -188,7 +237,8 @@ VKSDEF VkInstance vks_create_instance(bool validation_layers_toggle, const char /* Vks helpers */ bool -vks_check_validation_layer_support(const char * const validation_layers[], uint32_t validation_layer_count) +vks_check_validation_layer_support(const char* const validation_layers[], + uint32_t validation_layer_count) { uint32_t layerCount; vkEnumerateInstanceLayerProperties(&layerCount, NULL); @@ -209,13 +259,109 @@ vks_check_validation_layer_support(const char * const validation_layers[], uint3 return layerFound; } +uint32_t +find_memory_type(const vks_context vk, + const uint32_t typeFilter, + const VkMemoryPropertyFlags properties) +{ + VkPhysicalDeviceMemoryProperties mem_properties; + vkGetPhysicalDeviceMemoryProperties(vk.physical_device, &mem_properties); + + for (uint32_t i = 0; i < mem_properties.memoryTypeCount; i++) { + if ((typeFilter & (1 << i)) && + (mem_properties.memoryTypes[i].propertyFlags & properties) == + properties) { + return i; + } + } + + vk_log(VK_ERROR, "failed to find suitable memory type!\n"); + return 9999; +} + /* Vks API implementation */ +VKSDEF void +vks_create_image(const vks_context vk, + const uint32_t width, + const uint32_t height, + const uint32_t mipLevels, + const VkFormat format, + const VkImageTiling tiling, + const VkImageUsageFlags usage, + const VkMemoryPropertyFlags properties, + const VkSampleCountFlagBits numSamples, + vks_image* image) +{ + VkImageCreateInfo imageInfo = { 0 }; + imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + imageInfo.imageType = VK_IMAGE_TYPE_2D; + imageInfo.extent.width = width; + imageInfo.extent.height = height; + imageInfo.extent.depth = 1; + imageInfo.mipLevels = mipLevels; + imageInfo.arrayLayers = 1; + imageInfo.format = format; + imageInfo.tiling = tiling; + imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + imageInfo.usage = usage; + imageInfo.samples = numSamples; + imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + + VK_CHECK(vkCreateImage(vk.device, &imageInfo, NULL, &image->handle)); + + VkMemoryRequirements memRequirements; + vkGetImageMemoryRequirements(vk.device, image->handle, &memRequirements); + + VkMemoryAllocateInfo allocInfo = { 0 }; + allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + allocInfo.allocationSize = memRequirements.size; + allocInfo.memoryTypeIndex = + find_memory_type(vk, memRequirements.memoryTypeBits, properties); + + // TODO: group allocations etc... (allocations limited by hardware) + VK_CHECK(vkAllocateMemory(vk.device, &allocInfo, NULL, &image->memory)); + + vkBindImageMemory(vk.device, image->handle, image->memory, 0); +} + +VKSDEF void +vks_create_buffer(const vks_context vk, + const VkDeviceSize size, + const VkBufferUsageFlags usage, + const VkMemoryPropertyFlags properties, + vks_buffer* buffer) +{ + VkBufferCreateInfo bufferInfo = { 0 }; + bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bufferInfo.size = size; + bufferInfo.usage = usage; + bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + + VK_CHECK(vkCreateBuffer(vk.device, &bufferInfo, NULL, &buffer->handle)); + + VkMemoryRequirements mem_requirements; + vkGetBufferMemoryRequirements(vk.device, buffer->handle, &mem_requirements); + + VkMemoryAllocateInfo allocInfo = { 0 }; + allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + allocInfo.allocationSize = mem_requirements.size; + allocInfo.memoryTypeIndex = + find_memory_type(vk, mem_requirements.memoryTypeBits, properties); + + // TODO: group allocations etc... (allocations limited by hardware) + VK_CHECK(vkAllocateMemory(vk.device, &allocInfo, NULL, &buffer->memory)); + VK_CHECK(vkBindBufferMemory(vk.device, buffer->handle, buffer->memory, 0)); +} VKSDEF VkInstance -vks_create_instance(bool validation_layers_toggle, const char * const validation_layers[], - uint32_t validation_layer_count, SDL_Window *window) +vks_create_instance(bool validation_layers_toggle, + const char* const validation_layers[], + uint32_t validation_layer_count, + SDL_Window* window) { - if (validation_layers_toggle && !vks_check_validation_layer_support(validation_layers, validation_layer_count)) { + if (validation_layers_toggle && + !vks_check_validation_layer_support(validation_layers, + validation_layer_count)) { vk_log(VK_ERROR, "validation layers requested, but not available!\n"); abort(); } @@ -227,30 +373,36 @@ vks_create_instance(bool validation_layers_toggle, const char * const validation 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_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"); + 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", + .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), + .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()); + if (SDL_Vulkan_GetInstanceExtensions(window, &sdlExtensionCount, NULL) == + SDL_FALSE) { + vk_log(VK_ERROR, + "SDL_Vulkan_GetInstanceExtensions failed: %s\n", + SDL_GetError()); abort(); } @@ -261,8 +413,11 @@ vks_create_instance(bool validation_layers_toggle, const char * const validation 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()); + if (SDL_Vulkan_GetInstanceExtensions( + window, &sdlExtensionCount, sdlExtensions) == SDL_FALSE) { + vk_log(VK_ERROR, + "SDL_Vulkan_GetInstanceExtensions failed: %s\n", + SDL_GetError()); abort(); } @@ -277,15 +432,15 @@ vks_create_instance(bool validation_layers_toggle, const char * const validation } VkInstanceCreateInfo createInfo = { - .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, - .pApplicationInfo = &appInfo, - .enabledExtensionCount = sdlExtensionCount, + .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + .pApplicationInfo = &appInfo, + .enabledExtensionCount = sdlExtensionCount, .ppEnabledExtensionNames = sdlExtensions, - .enabledLayerCount = 0, + .enabledLayerCount = 0, }; if (validation_layers_toggle) { - createInfo.enabledLayerCount = validation_layer_count; + createInfo.enabledLayerCount = validation_layer_count; createInfo.ppEnabledLayerNames = validation_layers; } |