Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define GLFW_INCLUDE_VULKAN
- #include <GLFW/glfw3.h>
- #include <inttypes.h>
- #include <stdio.h>
- #include <stdbool.h>
- #include <string.h>
- #include <stddef.h>
- #include "cglm/cglm.h"
- typedef struct
- {
- vec2 pos;
- vec3 color;
- } _vertex;
- typedef struct
- {
- GLFWwindow *window;
- VkInstance instance;
- VkDebugUtilsMessengerEXT debug_messenger;
- VkSurfaceKHR surface;
- VkPhysicalDevice gpu;
- VkDevice gpu_interface;
- VkQueue queue;
- uint32_t queue_index;
- VkSwapchainKHR swapchain;
- VkImage images[256];
- uint32_t image_count;
- VkImageView image_data[256];
- VkFormat format;
- VkExtent2D extent;
- VkRenderPass render_pass;
- VkPipelineLayout pipeline_layout;
- VkPipeline graphics_pipeline;
- VkFramebuffer framebuffers[256];
- VkCommandPool command_pool;
- VkCommandBuffer command_buffers[8];
- VkSemaphore image_available[8];
- VkSemaphore render_finished[8];
- VkFence in_flight[8];
- uint32_t current_frame;
- bool framebuffer_resized;
- VkBuffer vertex_buffer;
- VkDeviceMemory vertex_buffer_memory;
- } _vk;
- bool vk_init(_vk *vk, bool debugging);
- bool vk_instance_init(_vk *vk, bool debugging);
- bool vk_debug_messenger_init(_vk *vk);
- bool vk_surface_init(_vk *vk);
- bool vk_gpu_init(_vk *vk);
- bool vk_gpu_interface_init(_vk *vk, bool debugging);
- bool vk_swapchain_init(_vk *vk);
- bool vk_image_data_init(_vk *vk);
- bool vk_render_pass_init(_vk *vk);
- bool vk_graphics_pipeline_init(_vk *vk);
- bool vk_framebuffers_init(_vk *vk);
- bool vk_command_pool_init(_vk *vk);
- bool vk_vertex_buffer_init(_vk *vk);
- bool vk_command_buffers_init(_vk *vk);
- bool vk_sync_objects_init(_vk *vk);
- GLFWwindow *vk_window_init(const char *title);
- bool vk_validation_layer_support(void);
- void vk_required_extensions(const char **required_extensions, uint32_t *required_extension_count, bool debugging);
- void vk_populate_debug_messenger_create_info(VkDebugUtilsMessengerCreateInfoEXT *debug_info);
- VKAPI_ATTR VkResult VKAPI_CALL vk_create_debug_utils_messenger_ext(_vk *vk, const VkDebugUtilsMessengerCreateInfoEXT debug_info, const VkAllocationCallbacks *allocator);
- VKAPI_ATTR void VKAPI_CALL vk_destroy_debug_utils_messenger_ext(_vk *vk, const VkAllocationCallbacks *allocator);
- const char *vk_debug_severity(VkDebugUtilsMessageSeverityFlagBitsEXT severity);
- const char *vk_debug_type(VkDebugUtilsMessageTypeFlagBitsEXT type);
- bool vk_queue_families(_vk *vk);
- VkSurfaceFormatKHR vk_surface_format(VkSurfaceFormatKHR *formats, uint32_t format_count);
- VkPresentModeKHR vk_present_mode(const VkPresentModeKHR *present_modes, uint32_t present_mode_count);
- VkExtent2D vk_swap_extent(_vk *vk, const VkSurfaceCapabilitiesKHR extent);
- VkShaderModule vk_shader_module_init(_vk *vk, const uint32_t *shader, const size_t shader_size);
- void vk_swapchain_recreation(_vk *vk);
- void vk_swapchain_destruction(_vk *vk);
- VkVertexInputBindingDescription vk_get_binding_description(void);
- VkVertexInputAttributeDescription vk_get_attribute_description(void);
- VkVertexInputAttributeDescription vk_get_color_data(void);
- uint32_t vk_find_memory_type(_vk *vk, uint32_t type_filter, VkMemoryPropertyFlags properties);
- void vk_mainloop(_vk *vk);
- void vk_cleanup(_vk *vk, bool debugging);
- void vk_draw_frame(_vk *vk);
- bool vk_command_buffer_write(_vk *vk, uint32_t current_frame, uint32_t image_index);
- typedef struct
- {
- _vk vk;
- } _app;
- bool app_init(_app *app, bool debugging);
- void app_mainloop(_app *app);
- void app_cleanup(_app *app, bool debugging);
- const _vertex VERTICES[] =
- {
- { {0.0f, -0.5f}, {1.0f, 0.0f, 0.0f}},
- {{ 0.5f, 0.5f}, {0.0f, 1.0f, 0.0f}},
- {{-0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}}
- };
- const uint32_t VALIDATION_LAYER_COUNT = 1;
- const char *VALIDATION_LAYERS[] =
- {
- "VK_LAYER_KHRONOS_validation"
- };
- const uint32_t DEVICE_EXTENSION_COUNT = 1;
- const char *DEVICE_EXTENSIONS[] =
- {
- VK_KHR_SWAPCHAIN_EXTENSION_NAME
- };
- const uint32_t MAX_FRAMES_IN_FLIGHT = 2;
- static void glfw_error_callback(int code, const char *description)
- {
- fprintf(stderr, "GLFW Error %d: %s\n", code, description);
- }
- static void glfw_framebuffer_resize_callback(GLFWwindow *window, int width, int height)
- {
- _vk *vk = (_vk *) glfwGetWindowUserPointer(window);
- vk->framebuffer_resized = true;
- fprintf(stdout, "Current size of window: %d x %d\n", width, height);
- }
- VkVertexInputBindingDescription vk_get_binding_description(void)
- {
- VkVertexInputBindingDescription binding_description =
- {
- .binding = 0,
- .stride = sizeof(_vertex),
- .inputRate = VK_VERTEX_INPUT_RATE_VERTEX
- };
- return binding_description;
- }
- VkVertexInputAttributeDescription vk_get_attribute_description(void)
- {
- VkVertexInputAttributeDescription attribute_description =
- {
- .binding = 0,
- .location = 0,
- .format = VK_FORMAT_R32G32_SFLOAT,
- .offset = offsetof(_vertex, color)
- };
- return attribute_description;
- }
- VkVertexInputAttributeDescription vk_get_color_data(void)
- {
- VkVertexInputAttributeDescription color_data =
- {
- .binding = 0,
- .location = 1,
- .format = VK_FORMAT_R32G32B32_SFLOAT,
- .offset = offsetof(_vertex, color)
- };
- return color_data;
- }
- GLFWwindow *vk_window_init(const char *title)
- {
- const uint32_t WINDOW_WIDTH = 800;
- const uint32_t WINDOW_HEIGHT = 600;
- glfwInit();
- glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
- glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
- glfwSetErrorCallback(glfw_error_callback);
- GLFWwindow *window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, title, NULL, NULL);
- glfwSetFramebufferSizeCallback(window, glfw_framebuffer_resize_callback);
- if (window == NULL)
- {
- fprintf(stderr, "Failed to create window!\n");
- }
- return window;
- }
- bool vk_init(_vk *vk, bool debugging)
- {
- vk->window = vk_window_init("Vulkan Game");
- vk->gpu = VK_NULL_HANDLE;
- bool success = vk_instance_init(vk, debugging);
- if (debugging && success)
- {
- vk_debug_messenger_init(vk);
- }
- success &= vk_surface_init(vk);
- success &= vk_gpu_init(vk);
- success &= vk_gpu_interface_init(vk, debugging);
- success &= vk_swapchain_init(vk);
- success &= vk_image_data_init(vk);
- success &= vk_render_pass_init(vk);
- success &= vk_graphics_pipeline_init(vk);
- success &= vk_framebuffers_init(vk);
- success &= vk_command_pool_init(vk);
- success &= vk_command_buffers_init(vk);
- success &= vk_sync_objects_init(vk);
- return success;
- }
- void vk_mainloop(_vk *vk)
- {
- while (!glfwWindowShouldClose(vk->window))
- {
- glfwPollEvents();
- vk_draw_frame(vk);
- }
- vkDeviceWaitIdle(vk->gpu_interface);
- }
- void vk_cleanup(_vk *vk, bool debugging)
- {
- vk_swapchain_destruction(vk);
- vkDestroyBuffer(vk->gpu_interface, vk->vertex_buffer, NULL);
- vkFreeMemory(vk->gpu_interface, vk->vertex_buffer_memory, NULL);
- vkDestroyPipeline(vk->gpu_interface, vk->graphics_pipeline, NULL);
- vkDestroyPipelineLayout(vk->gpu_interface, vk->pipeline_layout, NULL);
- vkDestroyRenderPass(vk->gpu_interface, vk->render_pass, NULL);
- for (uint32_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
- {
- vkDestroySemaphore(vk->gpu_interface, vk->image_available[i], NULL);
- vkDestroySemaphore(vk->gpu_interface, vk->render_finished[i], NULL);
- vkDestroyFence(vk->gpu_interface, vk->in_flight[i], NULL);
- }
- vkDestroyCommandPool(vk->gpu_interface, vk->command_pool, NULL);
- vkDestroyDevice(vk->gpu_interface, NULL);
- if (debugging)
- {
- vk_destroy_debug_utils_messenger_ext(vk, NULL);
- }
- vkDestroySurfaceKHR(vk->instance, vk->surface, NULL);
- vkDestroyInstance(vk->instance, NULL);
- glfwDestroyWindow(vk->window);
- vk->window = NULL;
- glfwTerminate();
- }
- bool vk_instance_init(_vk *vk, bool debugging)
- {
- if (debugging && !vk_validation_layer_support())
- {
- fprintf(stderr, "Validation layers requested, but are not available!\n");
- }
- VkApplicationInfo app_info =
- {
- .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
- .pApplicationName = "Vulkan App",
- .applicationVersion = VK_MAKE_API_VERSION(0, 1, 3, 239),
- .pEngineName = "No Engine",
- .engineVersion = VK_MAKE_API_VERSION(0, 1, 3, 239),
- .apiVersion = VK_API_VERSION_1_3
- };
- uint32_t required_extension_count = 0;
- vk_required_extensions(NULL, &required_extension_count, debugging);
- const char *required_extensions[required_extension_count];
- vk_required_extensions(required_extensions, &required_extension_count, debugging);
- if (required_extension_count == 0)
- {
- fprintf(stderr, "Failed to find required instance extensions!\n");
- }
- uint32_t available_extension_count = 0;
- vkEnumerateInstanceExtensionProperties(NULL, &available_extension_count, NULL);
- VkExtensionProperties available_extensions[available_extension_count];
- vkEnumerateInstanceExtensionProperties(NULL, &available_extension_count, available_extensions);
- if (available_extension_count == 0)
- {
- fprintf(stderr, "Failed to find any Vulkan extensions!\n");
- }
- fprintf(stdout, "%u available extensions:\n", available_extension_count);
- for (uint32_t i = 0; i < available_extension_count; i++)
- {
- fprintf(stdout, "\t %s (spec version %u)\n", available_extensions[i].extensionName, available_extensions[i].specVersion);
- }
- VkInstanceCreateInfo instance_info =
- {
- .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .pApplicationInfo = &app_info,
- .enabledExtensionCount = required_extension_count,
- .ppEnabledExtensionNames = required_extensions,
- };
- VkDebugUtilsMessengerCreateInfoEXT debug_info = {0};
- if (debugging)
- {
- instance_info.enabledLayerCount = VALIDATION_LAYER_COUNT;
- instance_info.ppEnabledLayerNames = VALIDATION_LAYERS;
- vk_populate_debug_messenger_create_info(&debug_info);
- instance_info.pNext = (VkDebugUtilsMessengerCreateInfoEXT *) &debug_info;
- }
- instance_info.enabledLayerCount = 0;
- instance_info.pNext = NULL;
- VkResult result = vkCreateInstance(&instance_info, NULL, &vk->instance);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to create instance!\n");
- return false;
- }
- return true;
- }
- bool vk_debug_messenger_init(_vk *vk)
- {
- VkDebugUtilsMessengerCreateInfoEXT debug_info = {0};
- vk_populate_debug_messenger_create_info(&debug_info);
- VkResult result = vk_create_debug_utils_messenger_ext(vk, debug_info, NULL);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to create debug messenger!\n");
- return false;
- }
- return true;
- }
- static VKAPI_ATTR VkBool32 VKAPI_CALL vk_debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessageTypeFlagBitsEXT type, const VkDebugUtilsMessengerCallbackDataEXT *callback_data, void *user_data)
- {
- fprintf(stdout, "Validation Layers: %s\n", callback_data->pMessage);
- fprintf(stdout, "\t Severity: %s\n", vk_debug_severity(severity));
- fprintf(stdout, "\t Type: %s\n", vk_debug_type(type));
- fprintf(stdout, "\t Objects: ");
- for (uint32_t i = 0; i < callback_data->objectCount; i++)
- {
- fprintf(stdout, "%lx \n", callback_data->pObjects[i].objectHandle);
- }
- _vk *vk = (_vk *) user_data;
- fprintf(stdout, "Optional user data: %p\n", (void *) vk);
- return VK_FALSE;
- }
- void vk_populate_debug_messenger_create_info(VkDebugUtilsMessengerCreateInfoEXT *debug_info)
- {
- debug_info->sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
- debug_info->pNext = NULL;
- debug_info->flags = 0;
- debug_info->messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
- debug_info->messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
- debug_info->pfnUserCallback = vk_debug_callback;
- debug_info->pUserData = NULL;
- }
- VKAPI_ATTR VkResult VKAPI_CALL vk_create_debug_utils_messenger_ext(_vk *vk, const VkDebugUtilsMessengerCreateInfoEXT debug_info, const VkAllocationCallbacks *allocator)
- {
- PFN_vkCreateDebugUtilsMessengerEXT func = (PFN_vkCreateDebugUtilsMessengerEXT) vkGetInstanceProcAddr(vk->instance, "vkCreateDebugUtilsMessengerEXT");
- if (func != NULL)
- {
- return func(vk->instance, &debug_info, allocator, &vk->debug_messenger);
- }
- return VK_ERROR_EXTENSION_NOT_PRESENT;
- }
- VKAPI_ATTR void VKAPI_CALL vk_destroy_debug_utils_messenger_ext(_vk *vk, const VkAllocationCallbacks *allocator)
- {
- PFN_vkDestroyDebugUtilsMessengerEXT func = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(vk->instance, "vkDestroyDebugUtilsMessengerEXT");
- if (func != NULL)
- {
- func(vk->instance, vk->debug_messenger, allocator);
- }
- }
- bool vk_validation_layer_support(void)
- {
- uint32_t layer_count = 0;
- vkEnumerateInstanceLayerProperties(&layer_count, NULL);
- if (layer_count == 0)
- {
- fprintf(stderr, "Failed to find validation layers!\n");
- return false;
- }
- VkLayerProperties available_layers[layer_count];
- vkEnumerateInstanceLayerProperties(&layer_count, available_layers);
- for (uint32_t i = 0; i < VALIDATION_LAYER_COUNT; i++)
- {
- bool layer_found = false;
- for (uint32_t j = 0; j < layer_count; j++)
- {
- if (strcmp(VALIDATION_LAYERS[i], available_layers[j].layerName) == 0)
- {
- layer_found = true;
- break;
- }
- }
- if (!layer_found)
- {
- return false;
- }
- }
- return true;
- }
- void vk_required_extensions(const char **required_extensions, uint32_t *required_extension_count, bool debugging)
- {
- uint32_t glfw_extension_count = 0;
- const char **glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extension_count);
- if (glfw_extensions == NULL)
- {
- fprintf(stderr, "Failed to find required instance extensions!\n");
- return;
- }
- if (required_extensions == NULL)
- {
- *required_extension_count = glfw_extension_count + debugging;
- return;
- }
- for (uint32_t i = 0; i < glfw_extension_count; i++)
- {
- required_extensions[i] = glfw_extensions[i];
- }
- if (debugging)
- {
- required_extensions[glfw_extension_count] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
- }
- }
- const char *vk_debug_severity(VkDebugUtilsMessageSeverityFlagBitsEXT severity)
- {
- switch (severity)
- {
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT:
- return "Verbose";
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT:
- return "Info";
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
- return "Warning";
- case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
- return "Error";
- default:
- fprintf(stdout, "Invalid severity code: %d\n", severity);
- }
- return "No such severity\n";
- }
- const char *vk_debug_type(VkDebugUtilsMessageTypeFlagBitsEXT type)
- {
- switch (type)
- {
- case VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT:
- return "General";
- case VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT:
- return "Validation";
- case VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT:
- return "Performance";
- default:
- fprintf(stdout, "Invalid type code: %d\n", type);
- }
- return "No such type\n";
- }
- bool vk_gpu_init(_vk *vk)
- {
- uint32_t gpu_count = 0;
- vkEnumeratePhysicalDevices(vk->instance, &gpu_count, NULL);
- if (gpu_count == 0)
- {
- fprintf(stderr, "Failed to find GPUs with Vulkan support!\n");
- return false;
- }
- VkPhysicalDevice gpus[gpu_count];
- vkEnumeratePhysicalDevices(vk->instance, &gpu_count, gpus);
- vk->gpu = gpus[0];
- if (vk->gpu == VK_NULL_HANDLE)
- {
- fprintf(stderr, "Failed to find a suitable GPU!\n");
- return false;
- }
- return true;
- }
- bool vk_queue_families(_vk *vk)
- {
- uint32_t queue_family_count = 0;
- vkGetPhysicalDeviceQueueFamilyProperties(vk->gpu, &queue_family_count, NULL);
- if (queue_family_count == 0)
- {
- fprintf(stderr, "Failed to find queue families!\n");
- }
- VkQueueFamilyProperties queue_families[queue_family_count];
- vkGetPhysicalDeviceQueueFamilyProperties(vk->gpu, &queue_family_count, queue_families);
- for (uint32_t i = 0; i < queue_family_count; i++)
- {
- VkBool32 graphics_support = queue_families[i].queueFlags & VK_QUEUE_GRAPHICS_BIT;
- VkBool32 present_support = false;
- vkGetPhysicalDeviceSurfaceSupportKHR(vk->gpu, i, vk->surface, &present_support);
- if (!graphics_support && !present_support)
- {
- fprintf(stderr, "Failed to find queue families with render support!\n");
- return false;
- }
- vk->queue_index = i;
- }
- return true;
- }
- bool vk_gpu_interface_init(_vk *vk, bool debugging)
- {
- if (!vk_queue_families(vk))
- {
- return false;
- }
- float queue_priority = 1.0f;
- VkDeviceQueueCreateInfo queue_create_info =
- {
- .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .queueFamilyIndex = vk->queue_index,
- .queueCount = 1,
- .pQueuePriorities = &queue_priority
- };
- VkPhysicalDeviceFeatures gpu_features = {0};
- VkDeviceCreateInfo gpu_interface_info =
- {
- .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .pQueueCreateInfos = &queue_create_info,
- .queueCreateInfoCount = 1,
- .pEnabledFeatures = &gpu_features,
- .ppEnabledExtensionNames = DEVICE_EXTENSIONS,
- .enabledExtensionCount = DEVICE_EXTENSION_COUNT,
- .enabledLayerCount = 0
- };
- if (debugging)
- {
- gpu_interface_info.enabledLayerCount = VALIDATION_LAYER_COUNT;
- gpu_interface_info.ppEnabledLayerNames = VALIDATION_LAYERS;
- }
- VkResult result = vkCreateDevice(vk->gpu, &gpu_interface_info, NULL, &vk->gpu_interface);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to create GPU interface!\n");
- return false;
- }
- vkGetDeviceQueue(vk->gpu_interface, vk->queue_index, 0, &vk->queue);
- return true;
- }
- bool vk_surface_init(_vk *vk)
- {
- VkResult result = glfwCreateWindowSurface(vk->instance, vk->window, NULL, &vk->surface);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to create window interface!\n");
- return false;
- }
- return true;
- }
- VkSurfaceFormatKHR vk_surface_format(VkSurfaceFormatKHR *formats, uint32_t format_count)
- {
- for (uint32_t i = 0; i < format_count; i++)
- {
- if (formats[i].format == VK_FORMAT_B8G8R8A8_SRGB && formats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
- {
- return formats[i];
- }
- }
- return formats[0];
- }
- VkPresentModeKHR vk_present_mode(const VkPresentModeKHR *present_modes, uint32_t present_mode_count)
- {
- for (uint32_t i = 0; i < present_mode_count; i++)
- {
- if (present_modes[i] == VK_PRESENT_MODE_MAILBOX_KHR)
- {
- return present_modes[i];
- }
- }
- return VK_PRESENT_MODE_FIFO_KHR;
- }
- VkExtent2D vk_swap_extent(_vk *vk, const VkSurfaceCapabilitiesKHR extent)
- {
- VkExtent2D extents;
- if (extent.currentExtent.width == UINT32_MAX)
- {
- int width, height;
- glfwGetFramebufferSize(vk->window, &width, &height);
- extents.width = width;
- extents.height = height;
- }
- else
- {
- extents = extent.currentExtent;
- }
- return extents;
- }
- bool vk_swapchain_init(_vk *vk)
- {
- VkSurfaceCapabilitiesKHR capabilities;
- vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vk->gpu, vk->surface, &capabilities);
- uint32_t format_count = 0;
- vkGetPhysicalDeviceSurfaceFormatsKHR(vk->gpu, vk->surface, &format_count, NULL);
- VkSurfaceFormatKHR formats[format_count];
- vkGetPhysicalDeviceSurfaceFormatsKHR(vk->gpu, vk->surface, &format_count, formats);
- uint32_t present_mode_count = 0;
- vkGetPhysicalDeviceSurfacePresentModesKHR(vk->gpu, vk->surface, &present_mode_count, NULL);
- VkPresentModeKHR present_modes[present_mode_count];
- vkGetPhysicalDeviceSurfacePresentModesKHR(vk->gpu, vk->surface, &present_mode_count, present_modes);
- VkSurfaceFormatKHR format = vk_surface_format(formats, format_count);
- VkPresentModeKHR present_mode = vk_present_mode(present_modes, present_mode_count);
- VkExtent2D extent = vk_swap_extent(vk, capabilities);
- uint32_t image_count = capabilities.minImageCount + 1;
- if (capabilities.maxImageCount > 0 && image_count > capabilities.maxImageCount)
- {
- image_count = capabilities.maxImageCount;
- }
- VkSwapchainCreateInfoKHR swapchain_info =
- {
- .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
- .pNext = NULL,
- .flags = 0,
- .surface = vk->surface,
- .minImageCount = image_count,
- .imageFormat = format.format,
- .imageColorSpace = format.colorSpace,
- .imageExtent = extent,
- .imageArrayLayers = 1,
- .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
- .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
- .queueFamilyIndexCount = 0,
- .pQueueFamilyIndices = NULL,
- .preTransform = capabilities.currentTransform,
- .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
- .presentMode = present_mode,
- .clipped = VK_TRUE,
- .oldSwapchain = VK_NULL_HANDLE
- };
- VkResult result = vkCreateSwapchainKHR(vk->gpu_interface, &swapchain_info, NULL, &vk->swapchain);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to create swapchain!\n");
- return false;
- }
- vkGetSwapchainImagesKHR(vk->gpu_interface, vk->swapchain, &image_count, NULL);
- VkImage image[image_count];
- vkGetSwapchainImagesKHR(vk->gpu_interface, vk->swapchain, &image_count, image);
- for (uint32_t i = 0; i < image_count; i++)
- {
- vk->images[i] = image[i];
- }
- vk->format = format.format;
- vk->extent = extent;
- vk->image_count = image_count;
- return true;
- }
- bool vk_image_data_init(_vk *vk)
- {
- for (uint32_t i = 0; i < vk->image_count; i++)
- {
- VkImageViewCreateInfo image_info =
- {
- .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .image = vk->images[i],
- .viewType = VK_IMAGE_VIEW_TYPE_2D,
- .format = vk->format,
- .components.r = VK_COMPONENT_SWIZZLE_IDENTITY,
- .components.g = VK_COMPONENT_SWIZZLE_IDENTITY,
- .components.b = VK_COMPONENT_SWIZZLE_IDENTITY,
- .components.a = VK_COMPONENT_SWIZZLE_IDENTITY,
- .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
- .subresourceRange.baseMipLevel = 0,
- .subresourceRange.levelCount = 1,
- .subresourceRange.baseArrayLayer = 0,
- .subresourceRange.layerCount = 1
- };
- VkResult result = vkCreateImageView(vk->gpu_interface, &image_info, NULL, &vk->image_data[i]);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to create image views!\n");
- return false;
- }
- }
- return true;
- }
- static void get_file_size(const char *filename, size_t *length)
- {
- FILE* fptr = fopen(filename, "rb");
- if (fptr == NULL)
- {
- fprintf(stderr, "Failed to query for file size: %s!\n", filename);
- return;
- }
- fseek(fptr, 0L, SEEK_END);
- long len = ftell(fptr);
- *length = (size_t) len;
- if (len < 0)
- {
- fprintf(stderr, "Failed to determine the size of the file!\n");
- return;
- }
- else if (*length != (size_t) len)
- {
- fprintf(stderr, "An conversion overflow has occurred!\n");
- return;
- }
- fseek(fptr, 0L, SEEK_SET);
- fclose(fptr);
- }
- static uint32_t *load_spirv_shaders(const char *filename, size_t length, char *contents)
- {
- FILE* fptr = fopen(filename, "rb");
- if (fptr == NULL)
- {
- fprintf(stderr, "Failed to open file: %s!\n", filename);
- }
- fseek(fptr, 0L, SEEK_END);
- length = ftell(fptr);
- fseek(fptr, 0L, SEEK_SET);
- size_t read_count = fread(contents, length, 1, fptr);
- if (read_count == 0)
- {
- fprintf(stderr, "Failed to read SPIR-V files!\n");
- }
- fclose(fptr);
- return (uint32_t *) contents;
- }
- VkShaderModule vk_shader_module_init(_vk *vk, const uint32_t *shader, const size_t shader_size)
- {
- VkShaderModuleCreateInfo module_info =
- {
- .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .codeSize = shader_size,
- .pCode = shader
- };
- VkShaderModule shader_module = {0};
- VkResult result = vkCreateShaderModule(vk->gpu_interface, &module_info, NULL, &shader_module);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to create shader module!\n");
- }
- return shader_module;
- }
- bool vk_render_pass_init(_vk *vk)
- {
- VkAttachmentDescription color_attachment =
- {
- .format = vk->format,
- .samples = VK_SAMPLE_COUNT_1_BIT,
- .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
- .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
- .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
- .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
- .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
- .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
- };
- VkAttachmentReference color_attachment_ref =
- {
- .attachment = 0,
- .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
- };
- VkSubpassDescription subpass =
- {
- .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
- .colorAttachmentCount = 1,
- .pColorAttachments = &color_attachment_ref
- };
- VkSubpassDependency dependency =
- {
- .srcSubpass = VK_SUBPASS_EXTERNAL,
- .dstSubpass = 0,
- .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
- .srcAccessMask = 0,
- .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
- .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
- };
- VkRenderPassCreateInfo render_pass_info =
- {
- .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .attachmentCount = 1,
- .pAttachments = &color_attachment,
- .subpassCount = 1,
- .pSubpasses = &subpass,
- .dependencyCount = 1,
- .pDependencies = &dependency
- };
- VkResult result = vkCreateRenderPass(vk->gpu_interface, &render_pass_info, NULL, &vk->render_pass);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to create render pass!\n");
- return false;
- }
- return true;
- }
- bool vk_vertex_buffer_init(_vk *vk)
- {
- VkResult result = VK_SUCCESS;
- VkBufferCreateInfo buffer_info =
- {
- .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .size = sizeof(VERTICES[0]) * 3,
- .usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
- .sharingMode = VK_SHARING_MODE_EXCLUSIVE
- };
- result = vkCreateBuffer(vk->gpu_interface, &buffer_info, NULL, &vk->vertex_buffer);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to create vertex buffer!\n");
- return false;
- }
- VkMemoryRequirements memory_requirements = {0};
- vkGetBufferMemoryRequirements(vk->gpu_interface, vk->vertex_buffer, &memory_requirements);
- VkMemoryAllocateInfo alloc_info =
- {
- .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
- .allocationSize = memory_requirements.size,
- .memoryTypeIndex = vk_find_memory_type(vk, memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
- };
- result = vkAllocateMemory(vk->gpu_interface, &alloc_info, NULL, &vk->vertex_buffer_memory);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to allocate vertex buffer memory!\n");
- return false;
- }
- vkBindBufferMemory(vk->gpu_interface, vk->vertex_buffer, vk->vertex_buffer_memory, 0);
- void *data = 0;
- vkMapMemory(vk->gpu_interface, vk->vertex_buffer_memory, 0, buffer_info.size, 0, &data);
- memcpy(data, VERTICES, (size_t) buffer_info.size);
- vkUnmapMemory(vk->gpu_interface, vk->vertex_buffer_memory);
- return true;
- }
- uint32_t vk_find_memory_type(_vk *vk, uint32_t type_filter, VkMemoryPropertyFlags properties)
- {
- VkPhysicalDeviceMemoryProperties memory_properties = {0};
- vkGetPhysicalDeviceMemoryProperties(vk->gpu, &memory_properties);
- for (uint32_t i = 0; i < memory_properties.memoryTypeCount; i++)
- {
- if ((type_filter & (1 << i)) && (memory_properties.memoryTypes[i].propertyFlags & properties) == properties)
- {
- return i;
- }
- }
- fprintf(stderr, "Failed to find suitable memory type!\n");
- return 0;
- }
- bool vk_graphics_pipeline_init(_vk *vk)
- {
- VkResult result = VK_SUCCESS;
- size_t vert_spirv_size = 0;
- get_file_size("vkapp/shaders/vertex.vert.spv", &vert_spirv_size);
- char vert_contents[vert_spirv_size + 1];
- uint32_t *vert_spirv = load_spirv_shaders("vkapp/shaders/vertex.vert.spv", vert_spirv_size, vert_contents);
- if (vert_spirv == NULL)
- {
- fprintf(stderr, "Failed to load SPIR-V vertex shader!\n");
- return false;
- }
- fprintf(stdout, "Size of SPIR-V vertex shader: %lu\n", vert_spirv_size);
- size_t frag_spirv_size = 0;
- get_file_size("vkapp/shaders/fragment.frag.spv", &frag_spirv_size);
- char frag_contents[frag_spirv_size + 1];
- uint32_t *frag_spirv = load_spirv_shaders("vkapp/shaders/fragment.frag.spv", frag_spirv_size, frag_contents);
- if (frag_spirv == NULL)
- {
- fprintf(stderr, "Failed to load SPIR-V fragment shader!\n");
- return false;
- }
- fprintf(stdout, "Size of SPIR-V fragment shader: %lu\n", frag_spirv_size);
- VkShaderModule vert_spirv_module = vk_shader_module_init(vk, vert_spirv, vert_spirv_size);
- VkShaderModule frag_spirv_module = vk_shader_module_init(vk, frag_spirv, frag_spirv_size);
- VkVertexInputBindingDescription binding_description = vk_get_binding_description();
- VkVertexInputAttributeDescription vertex_description = vk_get_attribute_description();
- VkVertexInputAttributeDescription color_data = vk_get_color_data();
- VkVertexInputAttributeDescription attribute_descriptions[] = {vertex_description, color_data};
- VkPipelineShaderStageCreateInfo vert_stage_info =
- {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .stage = VK_SHADER_STAGE_VERTEX_BIT,
- .module = vert_spirv_module,
- .pName = "main",
- .pSpecializationInfo = NULL
- };
- VkPipelineShaderStageCreateInfo frag_stage_info =
- {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
- .module = frag_spirv_module,
- .pName = "main",
- .pSpecializationInfo = NULL
- };
- VkDynamicState dynamic_states[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
- const uint32_t DYNAMIC_STATES_COUNT = 2;
- VkPipelineDynamicStateCreateInfo dynamic_state =
- {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .dynamicStateCount = DYNAMIC_STATES_COUNT,
- .pDynamicStates = dynamic_states
- };
- VkPipelineShaderStageCreateInfo shader_stages[] = {vert_stage_info, frag_stage_info};
- VkPipelineVertexInputStateCreateInfo vertex_input_info =
- {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .vertexBindingDescriptionCount = 1,
- .vertexAttributeDescriptionCount = 2,
- .pVertexBindingDescriptions = &binding_description,
- .pVertexAttributeDescriptions = attribute_descriptions
- };
- VkViewport viewport =
- {
- .x = 0.0f,
- .y = 0.0f,
- .width = (float) vk->extent.width,
- .height = (float) vk->extent.height,
- .minDepth = 0.0f,
- .maxDepth = 1.0f
- };
- VkRect2D scissor =
- {
- .offset = {0, 0},
- .extent = vk->extent
- };
- VkPipelineInputAssemblyStateCreateInfo input_assembly_info =
- {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
- .primitiveRestartEnable = VK_FALSE
- };
- VkPipelineViewportStateCreateInfo viewport_state_info =
- {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .viewportCount = 1,
- .pViewports = &viewport,
- .scissorCount = 1,
- .pScissors = &scissor
- };
- VkPipelineRasterizationStateCreateInfo rasterizer_info =
- {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .depthClampEnable = VK_FALSE,
- .rasterizerDiscardEnable = VK_FALSE,
- .polygonMode = VK_POLYGON_MODE_FILL,
- .lineWidth = 1.0f,
- .cullMode = VK_CULL_MODE_BACK_BIT,
- .frontFace = VK_FRONT_FACE_CLOCKWISE,
- .depthBiasEnable = VK_FALSE,
- .depthBiasConstantFactor = 0.0f,
- .depthBiasClamp = 0.0f,
- .depthBiasSlopeFactor = 0.0f
- };
- VkPipelineMultisampleStateCreateInfo multisampling_info =
- {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .sampleShadingEnable = VK_FALSE,
- .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
- .minSampleShading = 1.0f,
- .pSampleMask = NULL,
- .alphaToCoverageEnable = VK_FALSE,
- .alphaToOneEnable = VK_FALSE
- };
- VkPipelineColorBlendAttachmentState color_blend_attachment =
- {
- .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
- .blendEnable = VK_FALSE,
- .srcColorBlendFactor = VK_BLEND_FACTOR_ONE,
- .dstColorBlendFactor = VK_BLEND_FACTOR_ZERO,
- .colorBlendOp = VK_BLEND_OP_ADD,
- .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE,
- .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
- .alphaBlendOp = VK_BLEND_OP_ADD
- };
- VkPipelineColorBlendStateCreateInfo color_blending_info =
- {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .logicOpEnable = VK_FALSE,
- .logicOp = VK_LOGIC_OP_COPY,
- .attachmentCount = 1,
- .pAttachments = &color_blend_attachment,
- .blendConstants[0] = 0.0f,
- .blendConstants[1] = 0.0f,
- .blendConstants[2] = 0.0f,
- .blendConstants[3] = 0.0f
- };
- VkPipelineLayoutCreateInfo pipeline_layout_info =
- {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .setLayoutCount = 0,
- .pSetLayouts = NULL,
- .pushConstantRangeCount = 0,
- .pPushConstantRanges = NULL
- };
- result = vkCreatePipelineLayout(vk->gpu_interface, &pipeline_layout_info, NULL, &vk->pipeline_layout);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to create pipeline layout!\n");
- return false;
- }
- VkGraphicsPipelineCreateInfo pipeline_info =
- {
- .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .stageCount = 2,
- .pStages = shader_stages,
- .pVertexInputState = &vertex_input_info,
- .pInputAssemblyState = &input_assembly_info,
- .pViewportState = &viewport_state_info,
- .pRasterizationState = &rasterizer_info,
- .pMultisampleState = &multisampling_info,
- .pDepthStencilState = NULL,
- .pColorBlendState = &color_blending_info,
- .pDynamicState = &dynamic_state,
- .layout = vk->pipeline_layout,
- .renderPass = vk->render_pass,
- .subpass = 0,
- .basePipelineHandle = VK_NULL_HANDLE,
- .basePipelineIndex = -1
- };
- result = vkCreateGraphicsPipelines(vk->gpu_interface, VK_NULL_HANDLE, 1, &pipeline_info, NULL, &vk->graphics_pipeline);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to create graphics pipeline!\n");
- return false;
- }
- vkDestroyShaderModule(vk->gpu_interface, vert_spirv_module, NULL);
- vkDestroyShaderModule(vk->gpu_interface, frag_spirv_module, NULL);
- return true;
- }
- bool vk_framebuffers_init(_vk *vk)
- {
- for (uint32_t i = 0; i < vk->image_count; i++)
- {
- VkImageView attachments[] =
- {
- vk->image_data[i]
- };
- VkFramebufferCreateInfo framebuffer_info =
- {
- .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
- .pNext = NULL,
- .flags = 0,
- .renderPass = vk->render_pass,
- .attachmentCount = 1,
- .pAttachments = attachments,
- .width = vk->extent.width,
- .height = vk->extent.height,
- .layers = 1
- };
- VkResult result = vkCreateFramebuffer(vk->gpu_interface, &framebuffer_info, NULL, &vk->framebuffers[i]);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to create frame buffers!\n");
- return false;
- }
- }
- return true;
- }
- bool vk_command_pool_init(_vk *vk)
- {
- VkCommandPoolCreateInfo pool_info =
- {
- .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
- .pNext = NULL,
- .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
- .queueFamilyIndex = vk->queue_index
- };
- VkResult result = vkCreateCommandPool(vk->gpu_interface, &pool_info, NULL, &vk->command_pool);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to create command pool!\n");
- return false;
- }
- return true;
- }
- bool vk_command_buffers_init(_vk *vk)
- {
- VkCommandBufferAllocateInfo alloc_info =
- {
- .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
- .pNext = NULL,
- .commandPool = vk->command_pool,
- .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
- .commandBufferCount = MAX_FRAMES_IN_FLIGHT
- };
- VkResult result = vkAllocateCommandBuffers(vk->gpu_interface, &alloc_info, vk->command_buffers);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to allocate command buffers!\n");
- return false;
- }
- return true;
- }
- bool vk_command_buffer_write(_vk *vk, uint32_t current_frame, uint32_t image_index)
- {
- VkResult result = VK_SUCCESS;
- VkCommandBufferBeginInfo begin_info =
- {
- .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
- .pNext = NULL,
- .flags = 0,
- .pInheritanceInfo = NULL
- };
- result = vkBeginCommandBuffer(vk->command_buffers[current_frame], &begin_info);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to begin writing to command buffer!\n");
- return false;
- }
- VkClearValue clear_color = {{{0.0f, 0.0f, 0.0f, 1.0f}}};
- VkRenderPassBeginInfo render_pass_info =
- {
- .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
- .pNext = NULL,
- .renderPass = vk->render_pass,
- .framebuffer = vk->framebuffers[image_index],
- .renderArea.offset = {0, 0},
- .renderArea.extent = vk->extent,
- .clearValueCount = 1,
- .pClearValues = &clear_color
- };
- vkCmdBeginRenderPass(vk->command_buffers[current_frame], &render_pass_info, VK_SUBPASS_CONTENTS_INLINE);
- vkCmdBindPipeline(vk->command_buffers[current_frame], VK_PIPELINE_BIND_POINT_GRAPHICS, vk->graphics_pipeline);
- VkDeviceSize offsets[] = {0};
- vkCmdBindVertexBuffers(vk->command_buffers[current_frame], 0, 1, &vk->vertex_buffer, offsets);
- VkViewport viewport =
- {
- .x = 0.0f,
- .y = 0.0f,
- .width = (float) vk->extent.width,
- .height = (float) vk->extent.height,
- .minDepth = 0.0f,
- .maxDepth = 1.0f
- };
- vkCmdSetViewport(vk->command_buffers[current_frame], 0, 1, &viewport);
- VkRect2D scissor =
- {
- .offset = {0, 0},
- .extent = vk->extent
- };
- vkCmdSetScissor(vk->command_buffers[current_frame], 0, 1, &scissor);
- vkCmdDraw(vk->command_buffers[current_frame], 3, 1, 0, 0);
- vkCmdEndRenderPass(vk->command_buffers[current_frame]);
- result = vkEndCommandBuffer(vk->command_buffers[current_frame]);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to write to command buffer!\n");
- return false;
- }
- return true;
- }
- bool vk_sync_objects_init(_vk *vk)
- {
- VkResult result = VK_SUCCESS;
- VkSemaphoreCreateInfo semaphore_info =
- {
- .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
- .pNext = NULL,
- .flags = VK_FENCE_CREATE_SIGNALED_BIT
- };
- VkFenceCreateInfo fence_info =
- {
- .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
- .pNext = NULL,
- .flags = 0
- };
- for (uint32_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
- {
- result = vkCreateSemaphore(vk->gpu_interface, &semaphore_info, NULL, &vk->image_available[i]);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to create image semaphore!\n");
- return false;
- }
- result = vkCreateSemaphore(vk->gpu_interface, &semaphore_info, NULL, &vk->render_finished[i]);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to create presentation semaphore!\n");
- return false;
- }
- result = vkCreateFence(vk->gpu_interface, &fence_info, NULL, &vk->in_flight[i]);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to create fence!\n");
- return false;
- }
- }
- return true;
- }
- void vk_swapchain_recreation(_vk *vk)
- {
- int width = 0, height = 0;
- glfwGetFramebufferSize(vk->window, &width, &height);
- while (width == 0 || height == 0)
- {
- glfwGetFramebufferSize(vk->window, &width, &height);
- glfwWaitEvents();
- }
- vkDeviceWaitIdle(vk->gpu_interface);
- vk_swapchain_init(vk);
- vk_image_data_init(vk);
- vk_framebuffers_init(vk);
- }
- void vk_swapchain_destruction(_vk *vk)
- {
- for (uint32_t i = 0; i < vk->image_count; i++)
- {
- vkDestroyFramebuffer(vk->gpu_interface, vk->framebuffers[i], NULL);
- }
- for (uint32_t i = 0; i < vk->image_count; i++)
- {
- vkDestroyImageView(vk->gpu_interface, vk->image_data[i], NULL);
- }
- vkDestroySwapchainKHR(vk->gpu_interface, vk->swapchain, NULL);
- }
- void vk_draw_frame(_vk *vk)
- {
- VkResult result = VK_SUCCESS;
- vk->current_frame = 0;
- vkWaitForFences(vk->gpu_interface, 1, &vk->in_flight[vk->current_frame], VK_TRUE, UINT64_MAX);
- uint32_t image_index = 0;
- result = vkAcquireNextImageKHR(vk->gpu_interface, vk->swapchain, UINT64_MAX, vk->image_available[vk->current_frame], VK_NULL_HANDLE, &image_index);
- if (result == VK_ERROR_OUT_OF_DATE_KHR)
- {
- vk_swapchain_recreation(vk);
- return;
- }
- else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
- {
- fprintf(stderr, "Failed to acquire swap chain images!\n");
- }
- vkResetFences(vk->gpu_interface, 1, &vk->in_flight[vk->current_frame]);
- vkResetCommandBuffer(vk->command_buffers[vk->current_frame], 0);
- vk_command_buffer_write(vk, vk->current_frame, image_index);
- VkPipelineStageFlags wait_stages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
- VkSubmitInfo submit_info =
- {
- .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
- .waitSemaphoreCount = 1,
- .pWaitSemaphores = &vk->image_available[vk->current_frame],
- .signalSemaphoreCount = 1,
- .pSignalSemaphores = &vk->render_finished[vk->current_frame],
- .pWaitDstStageMask = wait_stages,
- .commandBufferCount = 1,
- .pCommandBuffers = &vk->command_buffers[vk->current_frame]
- };
- result = vkQueueSubmit(vk->queue, 1, &submit_info, vk->in_flight[vk->current_frame]);
- if (result != VK_SUCCESS)
- {
- fprintf(stderr, "Failed to submit draw command buffer!\n");
- }
- else if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || vk->framebuffer_resized)
- {
- vk->framebuffer_resized = false;
- vk_swapchain_recreation(vk);
- }
- VkPresentInfoKHR present_info =
- {
- .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
- .waitSemaphoreCount = 1,
- .pWaitSemaphores = &vk->render_finished[vk->current_frame],
- .swapchainCount = 1,
- .pSwapchains = &vk->swapchain,
- .pImageIndices = &image_index,
- .pResults = NULL
- };
- vkQueuePresentKHR(vk->queue, &present_info);
- vk->current_frame = vk->current_frame + 1;
- vk->current_frame *= vk->current_frame < MAX_FRAMES_IN_FLIGHT;
- }
- bool app_init(_app *app, bool debugging)
- {
- bool success = vk_init(&app->vk, debugging);
- return success;
- }
- void app_mainloop(_app *app)
- {
- vk_mainloop(&app->vk);
- }
- void app_cleanup(_app *app, bool debugging)
- {
- vk_cleanup(&app->vk, debugging);
- }
- bool check_build_type(int argc, char **argv)
- {
- if ((argc > 1) && (strcmp(argv[1], "-Debugging") == 0))
- {
- return true;
- }
- return false;
- }
- int main(int argc, char **argv)
- {
- bool debugging = check_build_type(argc, argv);
- _app app = {0};
- bool success = app_init(&app, debugging);
- if (success)
- {
- app_mainloop(&app);
- app_cleanup(&app, debugging);
- }
- else
- {
- fprintf(stderr, "Failed to launch app!\n");
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement