summaryrefslogtreecommitdiffstats
path: root/src/game.c
diff options
context:
space:
mode:
authorgramanas <anastasis.gramm2@gmail.com>2024-05-24 15:09:53 +0300
committergramanas <anastasis.gramm2@gmail.com>2024-05-24 15:09:53 +0300
commitfcbd6e48a2a291be1d15c87b94d0045771dbb088 (patch)
treeb72b16d58fd30f2c2b70a347d0b7f7f1a1c5746e /src/game.c
parent0898bfdf5d8e1c468a2d0aa8a3a7e320c4578dd3 (diff)
downloadcgame-fcbd6e48a2a291be1d15c87b94d0045771dbb088.tar.gz
cgame-fcbd6e48a2a291be1d15c87b94d0045771dbb088.tar.bz2
cgame-fcbd6e48a2a291be1d15c87b94d0045771dbb088.zip
rename
Diffstat (limited to 'src/game.c')
-rw-r--r--src/game.c1950
1 files changed, 0 insertions, 1950 deletions
diff --git a/src/game.c b/src/game.c
deleted file mode 100644
index 50f686e..0000000
--- a/src/game.c
+++ /dev/null
@@ -1,1950 +0,0 @@
-#include <stddef.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include <shaderc/shaderc.h>
-
-#define SDL_MAIN_HANDLED
-#define VK_USE_PLATFORM_XCB_KHR
-#include <SDL2/SDL.h>
-#include <SDL2/SDL_vulkan.h>
-
-#include <vulkan/vulkan.h>
-
-#define VMA_STATIC_VULKAN_FUNCTIONS 0
-#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
-#include "vk_mem_alloc.h"
-
-#define STB_IMAGE_IMPLEMENTATION
-#include "../lib/stb_image.h"
-
-//#include "cplusplus.h"
-#include "vkutil.h"
-#include "state.h"
-
-// embedded clgm library
-uint32_t currentFrame = 0;
-state_t s;
-
-const char *const validation_layers[] = {
- "VK_LAYER_KHRONOS_validation"
-};
-const uint32_t validation_layer_count = VK_ARRAY_LEN(validation_layers);
-
-const char *const device_extensions[] = {
- VK_KHR_SWAPCHAIN_EXTENSION_NAME,
-};
-const uint32_t deviceExtensionCount = VK_ARRAY_LEN(device_extensions);
-
-
-#ifdef VKDEBUG
- const bool enableValidationLayers = true;
-#else
- const bool enableValidationLayers = false;
-#endif
-
-typedef struct {
- float x;
- float y;
-} V2;
-
-typedef struct {
- float x;
- float y;
- float z;
-} V3;
-
-typedef struct {
- V3 pos;
- V3 color;
- V2 texCoord;
-} Vertex;
-
-/* Vertex vertices[] = { */
-/* (Vertex) { (V2) {-0.2f, -0.5f}, (V3) {0.0f, 1.0f, 0.0f}}, */
-/* (Vertex) { (V2) {0.5f, 0.3f}, (V3) {0.0f, 0.0f, 1.0f}}, */
-/* (Vertex) { (V2) {-0.5f, 0.7f}, (V3) {1.0f, 0.0f, 0.0f}}, */
-
-/* (Vertex) { (V2) {0.2f, -0.5f}, (V3) {0.0f, 0.0f, 1.0f}}, */
-/* (Vertex) { (V2) {0.5f, 0.7f}, (V3) {1.0f, 0.0f, 0.0f}}, */
-/* (Vertex) { (V2) {-0.5f, 0.3f}, (V3) {0.0f, 1.0f, 0.0f}}, */
-
-/* (Vertex) { (V2) {0.0f, -0.5f}, (V3) {1.0f, 0.0f, 0.0f}}, */
-/* (Vertex) { (V2) {0.5f, 0.5f}, (V3) {0.0f, 1.0f, 0.0f}}, */
-/* (Vertex) { (V2) {-0.5f, 0.5f}, (V3) {0.0f, 0.0f, 1.0f}}, */
-/* }; */
-/* const int VERTICES_SIZE = VK_ARRAY_LEN(vertices); */
-
-/* const uint16_t indices[] = { */
-/* 0, 1, 2, 3, 4, 5, 6, 7, 8, */
-/* }; */
-/* const int INDICES_SIZE = VK_ARRAY_LEN(indices); */
-
-Vertex vertices[] = {
- (Vertex) { (V3) {-0.5f, -0.5f, 0.0f}, (V3) {1.0f, 0.0f, 0.0f}, (V2) {0.0f, 0.0f}},
- (Vertex) { (V3) {0.5f, -0.5f, 0.0f}, (V3) {0.0f, 1.0f, 0.0f}, (V2) {1.0f, 0.0f}},
- (Vertex) { (V3) {0.5f, 0.5f, 0.0f}, (V3) {0.0f, 0.0f, 1.0f}, (V2) {1.0f, 1.0f}},
- (Vertex) { (V3) {-0.5f, 0.5f, 0.0f}, (V3) {1.0f, 1.0f, 1.0f}, (V2) {0.0f, 1.0f}},
- (Vertex) { (V3) {-0.5f, -0.5f, -0.5f}, (V3) {1.0f, 0.0f, 0.0f}, (V2) {0.0f, 0.0f}},
- (Vertex) { (V3) {0.5f, -0.5f, -0.5f}, (V3) {0.0f, 1.0f, 0.0f}, (V2) {1.0f, 0.0f}},
- (Vertex) { (V3) {0.5f, 0.5f, -0.5f}, (V3) {0.0f, 0.0f, 1.0f}, (V2) {1.0f, 1.0f}},
- (Vertex) { (V3) {-0.5f, 0.5f, -0.5f}, (V3) {1.0f, 1.0f, 1.0f}, (V2) {0.0f, 1.0f}},
-};
-const int VERTICES_SIZE = VK_ARRAY_LEN(vertices);
-
-const uint16_t indices[] = {
- 0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4
-};
-const int INDICES_SIZE = VK_ARRAY_LEN(indices);
-
-static int resizing_event_watcher(void* data, SDL_Event* event) {
- if (event->type == SDL_WINDOWEVENT &&
- event->window.event == SDL_WINDOWEVENT_RESIZED) {
- s.sdl_window_resized = 1;
- }
- return 0;
-}
-
-bool
-init()
-{
- if (SDL_Init(SDL_INIT_VIDEO) < 0) {
- vk_log(VK_INFO, "SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
- return false;
- }
-
- s.sdl_window = SDL_CreateWindow("Vulkanizater",
- SDL_WINDOWPOS_UNDEFINED,
- SDL_WINDOWPOS_UNDEFINED,
- s.window_w,
- s.window_h,
- SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_VULKAN);
- if (s.sdl_window == NULL) {
- vk_log(VK_INFO, "Window could not be created! SDL_Error: %s\n", SDL_GetError());
- return false;
- }
-
- SDL_AddEventWatch(resizing_event_watcher,NULL);
-
- return true;
-}
-
-void
-closeSDL()
-{
- SDL_DestroyWindow(s.sdl_window);
- s.sdl_window = NULL;
- SDL_Quit();
-}
-
-bool
-checkValidationLayerSupport()
-{
- 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;
-}
-
-static VKAPI_ATTR VkBool32 VKAPI_CALL
-debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
- VkDebugUtilsMessageTypeFlagsEXT messageType,
- const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
- void* pUserData)
-{
- vk_log(VK_ERROR, "validation layer: %s\n", pCallbackData->pMessage);
- return VK_FALSE;
-}
-
-void
-vulkan_setup_debug_messenger()
-{
- if (!enableValidationLayers) return;
- VkDebugUtilsMessengerCreateInfoEXT createInfo = {0};
- createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
- createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
- createInfo.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;
- createInfo.pfnUserCallback = debugCallback;
- createInfo.pUserData = NULL; // Optional
-
-
- // TODO: func pointers returned are NULL
- s.pfnCreateDebugUtilsMessengerEXT = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(s.vk_instance, "vkCreateDebugUtilsMessengerEXT");
- s.pfnDestroyDebugUtilsMessengerEXT = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(s.vk_instance, "vkDestroyDebugUtilsMessengerEXT");
-
- VkResult result = s.pfnCreateDebugUtilsMessengerEXT(s.vk_instance, &createInfo, NULL, &s.vk_debug_messenger);
- if (result != VK_SUCCESS) {
- vk_log(VK_WARN, "failed to set up debug messenger!\n");
- } else {
- vk_log(VK_INFO, "Debug messanger created!\n");
- }
-}
-
-void
-vulkan_create_instance()
-{
- if (enableValidationLayers && !checkValidationLayerSupport()) {
- 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(s.sdl_window, &sdlExtensionCount, NULL) == SDL_FALSE) {
- vk_log(VK_ERROR, "SDL_Vulkan_GetInstanceExtensions failed: %s\n", SDL_GetError());
- }
-
- // make space for debug extenetion
- if (enableValidationLayers) {
- sdlExtensionCount++;
- }
-
- const char* sdlExtensions[sdlExtensionCount];
-
- if (SDL_Vulkan_GetInstanceExtensions(s.sdl_window, &sdlExtensionCount, sdlExtensions) == SDL_FALSE) {
- vk_log(VK_ERROR, "SDL_Vulkan_GetInstanceExtensions failed: %s\n", SDL_GetError());
- }
-
- // add debug extenetion
- if (enableValidationLayers) {
- 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 (enableValidationLayers) {
- createInfo.enabledLayerCount = validation_layer_count;
- createInfo.ppEnabledLayerNames = validation_layers;
- }
-
- if (vkCreateInstance(&createInfo, NULL, &s.vk_instance) != VK_SUCCESS) {
- vk_log(VK_ERROR, "Can't start vulkan instance\n");
- }
- vk_log(VK_INFO, "Vulkan instance created\n");
-}
-
-VkExtent2D
-chooseSwapExtent(const VkSurfaceCapabilitiesKHR * capabilities)
-{
- if (capabilities->currentExtent.width != UINT32_MAX) {
- return capabilities->currentExtent;
- } else {
- int width, height;
- SDL_GetWindowSize(s.sdl_window, &width, &height);
-
- VkExtent2D actualExtent;
- actualExtent.width = (uint32_t) width;
- actualExtent.height = (uint32_t) height;
-
- // Manual implementation of std::clamp since it is not available in C
- actualExtent.width = (actualExtent.width < capabilities->minImageExtent.width) ? capabilities->minImageExtent.width :
- (actualExtent.width > capabilities->maxImageExtent.width) ? capabilities->maxImageExtent.width :
- actualExtent.width;
-
- actualExtent.height = (actualExtent.height < capabilities->minImageExtent.height) ? capabilities->minImageExtent.height :
- (actualExtent.height > capabilities->maxImageExtent.height) ? capabilities->maxImageExtent.height :
- actualExtent.height;
-
- return actualExtent;
- }
-}
-
-VkSurfaceFormatKHR
-chooseSwapSurfaceFormat(const VkSurfaceFormatKHR * availableFormats, uint32_t formatCount)
-{
- for (uint32_t i = 0 ; i < formatCount; i ++) {
- if (availableFormats[i].format == VK_FORMAT_B8G8R8A8_SRGB &&
- availableFormats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
- return availableFormats[i];
- }
- }
-
- // if it fails pick the first one
- return availableFormats[0];
-}
-
-VkPresentModeKHR
-chooseSwapPresentMode(const VkPresentModeKHR * presentModes, uint32_t presentModeCount)
-{
- for (uint32_t i = 0 ; i < presentModeCount; i ++) {
- if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
- return presentModes[i];
- }
- }
-
- // if it fails pick the the FIFO one
- return VK_PRESENT_MODE_FIFO_KHR;
-}
-
-typedef struct SwapChainSupportDetails {
- VkSurfaceCapabilitiesKHR capabilities;
- VkSurfaceFormatKHR formats[100];
- uint32_t formatCount;
- VkPresentModeKHR presentModes[100];
- uint32_t presentModeCount;
-} SwapChainSupportDetails;
-
-SwapChainSupportDetails
-querySwapChainSupport(VkPhysicalDevice device)
-{
- // TODO Make SwapChainSupportDetails malloc it;s arrays and free it after it is used.
- SwapChainSupportDetails details;
-
- vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, s.vk_surface, &details.capabilities);
-
- vkGetPhysicalDeviceSurfaceFormatsKHR(device, s.vk_surface, &details.formatCount, NULL);
-
- if (details.formatCount != 0) {
- // todo alloc format arrray
- vkGetPhysicalDeviceSurfaceFormatsKHR(device, s.vk_surface, &details.formatCount, details.formats);
- }
-
- vkGetPhysicalDeviceSurfacePresentModesKHR(device, s.vk_surface, &details.presentModeCount, NULL);
-
- if (details.presentModeCount != 0) {
- // todo alloc presentModes array
- vkGetPhysicalDeviceSurfacePresentModesKHR(device, s.vk_surface, &details.presentModeCount, details.presentModes);
- }
-
- return details;
-}
-
-typedef struct QueueFamilyIndices {
- uint32_t graphicsFamily;
- bool graphicsFlag;
- uint32_t presentFamily;
- bool presentFlag;
-} QueueFamilyIndices;
-
-bool
-vulkan_queue_family_check_flags(QueueFamilyIndices x)
-{
- return x.graphicsFlag && x.presentFlag;
-}
-
-QueueFamilyIndices vulkan_find_queue_families(VkPhysicalDevice device) {
- QueueFamilyIndices indices;
- indices.graphicsFlag = false;
- indices.presentFlag = false;
-
- uint32_t queueFamilyCount = 0;
- vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, NULL);
-
- VkQueueFamilyProperties queueFamilies[queueFamilyCount];
- vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies);
-
- for (uint32_t i = 0; i < queueFamilyCount; i++) {
- if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
- indices.graphicsFamily = i;
- indices.graphicsFlag = true;
- }
-
- VkBool32 presentSupport = false;
- vkGetPhysicalDeviceSurfaceSupportKHR(device, i, s.vk_surface, &presentSupport);
- if (presentSupport) {
- indices.presentFamily = i;
- indices.presentFlag = true;
- }
-
- if (vulkan_queue_family_check_flags(indices)) break;
- }
-
- return indices;
-}
-
-bool
-vulkan_check_device_extension_support(VkPhysicalDevice device)
-{
- uint32_t extensionCount;
- vkEnumerateDeviceExtensionProperties(device, NULL, &extensionCount, NULL);
-
- VkExtensionProperties availableExtensions[extensionCount];
- vkEnumerateDeviceExtensionProperties(device, NULL, &extensionCount, availableExtensions);
-
- uint32_t flag = 0;
-
- for (uint32_t i = 0; i < deviceExtensionCount; i++) {
- for (uint32_t j = 0; j < extensionCount; j++) {
- if (strcmp(device_extensions[i], availableExtensions[j].extensionName) == 0) {
- flag++;
- break;
- }
- }
- }
-
- return flag == deviceExtensionCount;
-}
-
-bool
-vulkan_is_device_suitable(VkPhysicalDevice device)
-{
- QueueFamilyIndices indices = vulkan_find_queue_families(device);
- bool extensionsSupported = vulkan_check_device_extension_support(device);
-
- bool swapChainAdequate = false;
- if (extensionsSupported) {
- SwapChainSupportDetails swapChainSupport = querySwapChainSupport(device);
- swapChainAdequate = !(swapChainSupport.formatCount == 0) && !(swapChainSupport.presentModeCount == 0);
- }
-
-
- VkPhysicalDeviceFeatures supportedFeatures;
- vkGetPhysicalDeviceFeatures(device, &supportedFeatures);
-
- return vulkan_queue_family_check_flags(indices) && extensionsSupported
- && swapChainAdequate && supportedFeatures.samplerAnisotropy;
-}
-
-void
-vulkan_pick_physical_device()
-{
- uint32_t deviceCount = 0;
- vkEnumeratePhysicalDevices(s.vk_instance, &deviceCount, NULL);
- if (deviceCount == 0) {
- vk_log(VK_INFO, "failed to find GPUs with Vulkan support!\n");
- }
-
- VkPhysicalDevice devices[deviceCount];
- vkEnumeratePhysicalDevices(s.vk_instance, &deviceCount, devices);
-
- for (uint32_t i = 0; i < deviceCount; i++) {
- if (vulkan_is_device_suitable(devices[i])) {
- s.vk_physical_device = devices[i];
- break;
- }
- }
-
- if (s.vk_physical_device == VK_NULL_HANDLE) {
- vk_log(VK_ERROR, "failed to find a suitable GPU!\n");
- }
-
- VkPhysicalDeviceProperties deviceProperties;
- vkGetPhysicalDeviceProperties(s.vk_physical_device, &deviceProperties);
- vk_log(VK_INFO, "Picked [%s] physical device.\n", deviceProperties.deviceName);
-
- uint32_t extensionCount = 0;
- vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, NULL);
- VkExtensionProperties extensions[extensionCount];
- VkResult result = vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, extensions);
-
- vk_log(VK_INFO, "Vulkan enabled extensions: %s\n", string_VkResult(result));
- for (uint32_t i = 0; i < extensionCount; i++) {
- vk_log(VK_INFO, "\t%s\n", extensions[i].extensionName);
- }
-
-}
-
-void
-vulkan_create_logical_device()
-{
- QueueFamilyIndices indices = vulkan_find_queue_families(s.vk_physical_device);
-
- // TODO CREATE MULPILE QUEUES
- // https://vulkan-tutorial.com/en/Drawing_a_triangle/Presentation/Window_surface#page_Creating-the-presentation-queue
-
- VkDeviceQueueCreateInfo queueCreateInfo = {
- .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
- .queueFamilyIndex = indices.graphicsFamily,
- .queueCount = 1,
- };
-
- float queuePriority = 1.0f;
- queueCreateInfo.pQueuePriorities = &queuePriority;
-
- VkPhysicalDeviceFeatures deviceFeatures = {0};
- vkGetPhysicalDeviceFeatures(s.vk_physical_device, &deviceFeatures);
- deviceFeatures.samplerAnisotropy = VK_TRUE;
-#ifndef NDEBUG
- /* Disable robust buffer access when building without debug */
- deviceFeatures.robustBufferAccess = VK_FALSE;
-#endif
-
- VkPhysicalDeviceDynamicRenderingFeaturesKHR dynamic_rendering_feature = {
- .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR,
- .dynamicRendering = VK_TRUE,
- };
-
- VkDeviceCreateInfo createInfo = {
- .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
- .pQueueCreateInfos = &queueCreateInfo,
- .queueCreateInfoCount = 1,
- .pNext = &dynamic_rendering_feature,
- .pEnabledFeatures = &deviceFeatures,
- .enabledExtensionCount = deviceExtensionCount,
- .ppEnabledExtensionNames = device_extensions,
- .enabledLayerCount = 0,
- };
-
- if (vkCreateDevice(s.vk_physical_device, &createInfo, NULL, &s.vk_device) != VK_SUCCESS) {
- vk_log(VK_ERROR, "failed to create logical device!\n");
- }
- vk_log(VK_INFO, "Vulkan logical device created\n");
-
- vkGetDeviceQueue(s.vk_device, indices.graphicsFamily, 0, &s.vk_graphics_queue);
- vkGetDeviceQueue(s.vk_device, indices.presentFamily, 0, &s.vk_present_queue);
-}
-
-void
-update_camera(float xoffset, float yoffset)
-{
- s.camera.yaw += xoffset;
- s.camera.pitch += yoffset;
-
- // Make sure that when pitch is out of bounds, the screen doesn't get flipped
- if (s.camera.pitch > 89.0f)
- s.camera.pitch = 89.0f;
- if (s.camera.pitch < -89.0f)
- s.camera.pitch = -89.0f;
-
- /* vec3 front; */
- /* front[0] = -sin(glm_rad(s.camera.yaw)) * cos(glm_rad(s.camera.pitch)); */
- /* front[1] = sin(glm_rad(s.camera.pitch)); */
- /* front[2] = -cos(glm_rad(s.camera.yaw)) * cos(glm_rad(s.camera.pitch)); */
- /* glm_normalize_to(front, s.camera.front); */
-}
-
-void
-mouseCallback(SDL_Event *event)
-{
- if (event->type != SDL_MOUSEMOTION) return;
- if (!s.mouse_pressed) return;
- float xoffset = event->motion.xrel;
- float yoffset = -event->motion.yrel; // Reversed since y-coordinates range from bottom to top
-
- float sensitivity = 0.1f; // Change this value to your liking
- xoffset *= sensitivity;
- yoffset *= sensitivity;
-
- update_camera(xoffset, yoffset);
-}
-
-void
-vulkan_create_surface()
-{
- if (SDL_Vulkan_CreateSurface(s.sdl_window, s.vk_instance, &s.vk_surface) == SDL_FALSE) {
- vk_log(VK_ERROR, "Failed to create surface\n");
- } else {
- vk_log(VK_INFO, "Vulkan surface created\n");
- }
-}
-
-void
-vulkan_create_swap_chain()
-{
- SwapChainSupportDetails swapChainSupport = querySwapChainSupport(s.vk_physical_device);
-
- VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats, swapChainSupport.formatCount);
- VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes, swapChainSupport.presentModeCount);
- VkExtent2D extent = chooseSwapExtent(&swapChainSupport.capabilities);
-
- uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1;
-
- if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount) {
- imageCount = swapChainSupport.capabilities.maxImageCount;
- }
-
- VkSwapchainCreateInfoKHR createInfo = {
- .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
- .surface = s.vk_surface,
- .minImageCount = imageCount,
- .imageFormat = surfaceFormat.format,
- .imageColorSpace = surfaceFormat.colorSpace,
- .imageExtent = extent,
- .imageArrayLayers = 1,
- .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
- };
-
- QueueFamilyIndices indices = vulkan_find_queue_families(s.vk_physical_device);
-
- uint32_t queueFamilyIndices[] = {indices.graphicsFamily, indices.presentFamily};
-
- if (indices.graphicsFamily != indices.presentFamily) {
- createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
- createInfo.queueFamilyIndexCount = 2;
- createInfo.pQueueFamilyIndices = queueFamilyIndices;
- } else {
- createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
- createInfo.queueFamilyIndexCount = 0; // Optional
- createInfo.pQueueFamilyIndices = NULL; // Optional
- }
-
- createInfo.preTransform = swapChainSupport.capabilities.currentTransform;
- createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
- createInfo.presentMode = presentMode;
- createInfo.clipped = VK_TRUE;
- createInfo.oldSwapchain = VK_NULL_HANDLE;
-
- VK_CHECK(vkCreateSwapchainKHR(s.vk_device, &createInfo, NULL, &s.vk_swap_chain));
- /* if (result != VK_SUCCESS) { */
- /* vk_log(VK_ERROR, "ERROR: failed to create swap chain! %s\n", string_VkResult(result)); */
- /* } */
-
- VK_CHECK(vkGetSwapchainImagesKHR(s.vk_device, s.vk_swap_chain, &s.vk_swap_chain_image_count, NULL));
- //vk_log(VK_INFO, "vk_swap_chain_images count: %d\n", s.vk_swap_chain_image_count);
- // todo alloc space for images
- VK_CHECK(vkGetSwapchainImagesKHR(s.vk_device, s.vk_swap_chain, &s.vk_swap_chain_image_count, s.vk_swap_chain_images));
-
- s.vk_swap_chain_image_format = surfaceFormat.format;
- s.vk_swap_chain_extent = extent;
-
- vk_log(VK_INFO, "Vulkan swapchain created!\n");
-}
-
-
-VkImageView
-create_image_view(VkImage image, VkFormat format, VkImageAspectFlags aspectFlags)
-{
- VkImageViewCreateInfo viewInfo = {0};
- viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
- viewInfo.image = image;
- viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
- viewInfo.format = format;
- viewInfo.subresourceRange.aspectMask = aspectFlags;
- viewInfo.subresourceRange.baseMipLevel = 0;
- viewInfo.subresourceRange.levelCount = 1;
- viewInfo.subresourceRange.baseArrayLayer = 0;
- viewInfo.subresourceRange.layerCount = 1;
-
- VkImageView imageView;
- VK_CHECK(vkCreateImageView(s.vk_device, &viewInfo, NULL, &imageView));
-
- return imageView;
-}
-
-void
-vulkan_create_image_views()
-{
- for (size_t i = 0; i < s.vk_swap_chain_image_count; i++) {
- s.vk_swap_chain_image_views[i] = create_image_view(s.vk_swap_chain_images[i], s.vk_swap_chain_image_format, VK_IMAGE_ASPECT_COLOR_BIT);
- }
- vk_log(VK_INFO, "Vulkan image views created!\n");
-}
-
-VkShaderModule
-createShaderModule(const char * code, long size)
-{
- VkShaderModuleCreateInfo createInfo = {0};
- createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
- createInfo.codeSize = size;
- createInfo.pCode = (const uint32_t *)code;
-
- VkShaderModule shaderModule;
- if (vkCreateShaderModule(s.vk_device, &createInfo, NULL, &shaderModule) != VK_SUCCESS) {
- vk_log(VK_ERROR, "failed to create shader module!\n");
- }
-
- return shaderModule;
-}
-
-shaderc_compilation_result_t
-load_compile_shader_data(const char * path, shaderc_shader_kind shader_kind)
-{
- FILE* file = fopen(path, "r");
- if (!file) {
- vk_log(VK_ERROR, "SHADER COMPILATION: Failed to open file: %s\n", path);
- return NULL;
- }
-
- fseek(file, 0, SEEK_END);
- long glsl_length = ftell(file);
- fseek(file, 0, SEEK_SET);
-
- char* glsl_src = (char*)malloc(glsl_length + 1);
- if (!glsl_src) {
- vk_log(VK_ERROR, "SHADER COMPILATION: Failed to allocate memory\n");
- fclose(file);
- return NULL;
- }
-
- fread(glsl_src, 1, glsl_length, file);
- glsl_src[glsl_length] = '\0';
- fclose(file);
-
- shaderc_compiler_t compiler = shaderc_compiler_initialize();
- if (!compiler) {
- vk_log(VK_ERROR, "SHADER COMPILATION: Failed to initialize shader compiler\n");
- free(glsl_src);
- return NULL;
- }
-
- shaderc_compile_options_t options = shaderc_compile_options_initialize();
- shaderc_compilation_result_t result = shaderc_compile_into_spv(compiler,
- glsl_src,
- glsl_length,
- shader_kind,
- path, "main", options);
-
- if (shaderc_result_get_compilation_status(result) != shaderc_compilation_status_success) {
- vk_log(VK_ERROR, "SHADER COMPILATION: error: %s\n", shaderc_result_get_error_message(result));
- shaderc_result_release(result);
- shaderc_compiler_release(compiler);
- free(glsl_src);
- return NULL;
- }
-
- shaderc_compiler_release(compiler);
- free(glsl_src);
-
- return result;
-}
-
-uint32_t
-findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties)
-{
- VkPhysicalDeviceMemoryProperties memProperties;
- vkGetPhysicalDeviceMemoryProperties(s.vk_physical_device, &memProperties);
-
- for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
- if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
- return i;
- }
- }
-
- vk_log(VK_ERROR, "failed to find suitable memory type!\n");
- return 9999;
-}
-
-void
-createImage(uint32_t width, uint32_t height, VkFormat format,
- VkImageTiling tiling, VkImageUsageFlags usage,
- VkMemoryPropertyFlags properties, VkImage *image,
- VkDeviceMemory *imageMemory)
-{
- 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 = 1;
- imageInfo.arrayLayers = 1;
- imageInfo.format = format;
- imageInfo.tiling = tiling;
- imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- imageInfo.usage = usage;
- imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
- imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
-
- VK_CHECK(vkCreateImage(s.vk_device, &imageInfo, NULL, image));
-
- VkMemoryRequirements memRequirements;
- vkGetImageMemoryRequirements(s.vk_device, *image, &memRequirements);
-
- VkMemoryAllocateInfo allocInfo = {0};
- allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
- allocInfo.allocationSize = memRequirements.size;
- allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties);
-
- VK_CHECK(vkAllocateMemory(s.vk_device, &allocInfo, NULL, imageMemory));
-
- vkBindImageMemory(s.vk_device, *image, *imageMemory , 0);
-}
-
-VkCommandBuffer
-beginSingleTimeCommands()
-{
- VkCommandBufferAllocateInfo allocInfo = {0};
- allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
- allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
- allocInfo.commandPool = s.vk_command_pool;
- allocInfo.commandBufferCount = 1;
-
- VkCommandBuffer commandBuffer;
- VK_CHECK(vkAllocateCommandBuffers(s.vk_device, &allocInfo, &commandBuffer));
-
- VkCommandBufferBeginInfo beginInfo = {0};
- beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
-
- VK_CHECK(vkBeginCommandBuffer(commandBuffer, &beginInfo));
-
- return commandBuffer;
-}
-
-void
-endSingleTimeCommands(VkCommandBuffer commandBuffer)
-{
- VK_CHECK(vkEndCommandBuffer(commandBuffer));
-
- VkSubmitInfo submitInfo = {0};
- submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submitInfo.commandBufferCount = 1;
- submitInfo.pCommandBuffers = &commandBuffer;
-
- VK_CHECK(vkQueueSubmit(s.vk_graphics_queue, 1, &submitInfo, VK_NULL_HANDLE));
- VK_CHECK(vkQueueWaitIdle(s.vk_graphics_queue));
-
- vkFreeCommandBuffers(s.vk_device, s.vk_command_pool, 1, &commandBuffer);
-}
-
-int
-hasStencilComponent(VkFormat format)
-{
- return format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT;
-}
-
-void
-transitionImageLayout(VkImage image, VkFormat format,
- VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask,
- VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
- VkImageLayout oldLayout, VkImageLayout newLayout)
-{
- VkCommandBuffer commandBuffer = beginSingleTimeCommands();
-
- VkImageMemoryBarrier barrier = {0};
- barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
- barrier.srcAccessMask = srcAccessMask;
- barrier.dstAccessMask = dstAccessMask;
- barrier.oldLayout = oldLayout;
- barrier.newLayout = newLayout;
- barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- barrier.image = image;
-
- // barrier.subresourceRange.aspectMask =
- if (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
- barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
-
- if (hasStencilComponent(format)) {
- barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
- }
- } else {
- barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- }
-
- barrier.subresourceRange.baseMipLevel = 0;
- barrier.subresourceRange.levelCount = 1;
- barrier.subresourceRange.baseArrayLayer = 0;
- barrier.subresourceRange.layerCount = 1;
-
- vkCmdPipelineBarrier(commandBuffer,
- srcStageMask, dstStageMask,
- 0,
- 0, NULL,
- 0, NULL,
- 1, &barrier);
- endSingleTimeCommands(commandBuffer);
-}
-
-VkFormat
-findSupportedFormat(VkFormat *candidates, size_t n,
- VkImageTiling tiling,
- VkFormatFeatureFlags features)
-{
- for (size_t i = 0; i < n; i++) {
- VkFormat format = candidates[i];
- VkFormatProperties props;
- vkGetPhysicalDeviceFormatProperties(s.vk_physical_device, format, &props);
-
- if (tiling == VK_IMAGE_TILING_LINEAR && (props.linearTilingFeatures & features) == features) {
- return format;
- } else if (tiling == VK_IMAGE_TILING_OPTIMAL && (props.optimalTilingFeatures & features) == features) {
- return format;
- }
- }
-
- vk_log(VK_ERROR, "failed to find supported format!\n");
- abort();
-}
-
-VkFormat
-findDepthFormat()
-{
- VkFormat formats[] = { VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT};
- return findSupportedFormat(formats, VK_ARRAY_LEN(formats),
- VK_IMAGE_TILING_OPTIMAL,
- VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
-}
-
-void
-vulkan_create_depth_resources()
-{
- VkFormat depthFormat = findDepthFormat();
- createImage(s.vk_swap_chain_extent.width, s.vk_swap_chain_extent.height,
- depthFormat, VK_IMAGE_TILING_OPTIMAL,
- VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
- VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
- &s.vk_depth_image, &s.vk_depth_image_memory);
- s.vk_depth_image_view = create_image_view(s.vk_depth_image, depthFormat,
- VK_IMAGE_ASPECT_DEPTH_BIT);
-
- transitionImageLayout(s.vk_depth_image, depthFormat,
- VK_ACCESS_NONE, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
- VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
- VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
-}
-
-void
-vulkan_create_graphics_pipeline()
-{
- shaderc_compilation_result_t vert_result = load_compile_shader_data("src/shader.vert", shaderc_vertex_shader);
- if (!vert_result) {
- vk_log(VK_ERROR, "Can't load vertex shader\n");
- if (s.prev_vert_result) {
- vert_result = s.prev_vert_result;
- }
- }
- if (s.prev_vert_result && vert_result != s.prev_vert_result) shaderc_result_release(s.prev_vert_result);
- s.prev_vert_result = vert_result;
- shaderc_compilation_result_t frag_result = load_compile_shader_data("src/shader.frag", shaderc_fragment_shader);
- if (!frag_result) {
- vk_log(VK_ERROR, "Can't load fragment shader\n");
- if (s.prev_frag_result) {
- frag_result = s.prev_frag_result;
- }
- }
- if (s.prev_frag_result && frag_result != s.prev_frag_result) shaderc_result_release(s.prev_frag_result);
- s.prev_frag_result = frag_result;
-
- const char * vert_data = shaderc_result_get_bytes(vert_result);
- long vert_size = shaderc_result_get_length(vert_result);
- const char * frag_data = shaderc_result_get_bytes(frag_result);
- long frag_size = shaderc_result_get_length(frag_result);
-
- vk_log(VK_INFO, "Shaders loaded\n");
-
- VkShaderModule vertShaderModule = createShaderModule(vert_data, vert_size);
- VkShaderModule fragShaderModule = createShaderModule(frag_data, frag_size);
-
- VkPipelineShaderStageCreateInfo vertShaderStageInfo = {0};
- vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
- vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
- vertShaderStageInfo.module = vertShaderModule;
- vertShaderStageInfo.pName = "main";
-
- VkPipelineShaderStageCreateInfo fragShaderStageInfo = {0};
- fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
- fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
- fragShaderStageInfo.module = fragShaderModule;
- fragShaderStageInfo.pName = "main";
-
- VkPipelineShaderStageCreateInfo shaderStages[] = {vertShaderStageInfo, fragShaderStageInfo};
-
- VkDynamicState dynamicStates[] = {
- VK_DYNAMIC_STATE_VIEWPORT,
- VK_DYNAMIC_STATE_SCISSOR,
- VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE,
- VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE
- };
-
- VkPipelineDynamicStateCreateInfo dynamicState = {0};
- dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
- dynamicState.dynamicStateCount = VK_ARRAY_LEN(dynamicStates);
- dynamicState.pDynamicStates = dynamicStates;
-
- VkVertexInputBindingDescription bindingDescription = {0};
- bindingDescription.binding = 0;
- bindingDescription.stride = sizeof(Vertex);
- bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
-
- VkVertexInputAttributeDescription attributeDescriptions[3] = {0};
- attributeDescriptions[0].binding = 0;
- attributeDescriptions[0].location = 0;
- attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
- attributeDescriptions[0].offset = offsetof(Vertex, pos);
-
- attributeDescriptions[1].binding = 0;
- attributeDescriptions[1].location = 1;
- attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
- attributeDescriptions[1].offset = offsetof(Vertex, color);
-
- attributeDescriptions[2].binding = 0;
- attributeDescriptions[2].location = 2;
- attributeDescriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
- attributeDescriptions[2].offset = offsetof(Vertex, texCoord);
-
- VkPipelineVertexInputStateCreateInfo vertexInputInfo = {0};
- vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
- vertexInputInfo.vertexBindingDescriptionCount = 1;
- vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
- vertexInputInfo.vertexAttributeDescriptionCount = VK_ARRAY_LEN(attributeDescriptions);
- vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions;
-
- VkPipelineInputAssemblyStateCreateInfo inputAssembly = {};
- inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
- inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
- inputAssembly.primitiveRestartEnable = VK_FALSE;
-
- VkViewport viewport = {0};
- viewport.x = 0.0f;
- viewport.y = 0.0f;
- viewport.width = (float) s.vk_swap_chain_extent.width;
- viewport.height = (float) s.vk_swap_chain_extent.height;
- viewport.minDepth = 0.0f;
- viewport.maxDepth = 1.0f;
-
- VkRect2D scissor = {0};
- scissor.offset = (VkOffset2D){0, 0};
- scissor.extent = s.vk_swap_chain_extent;
-
- VkPipelineViewportStateCreateInfo viewportState = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
- .viewportCount = 1,
- .pViewports = &viewport,
- .scissorCount = 1,
- .pScissors = &scissor,
- };
-
- VkPipelineRasterizationStateCreateInfo rasterizer = {0};
- rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
- rasterizer.depthClampEnable = VK_FALSE;
- rasterizer.rasterizerDiscardEnable = VK_FALSE;
- rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
- rasterizer.lineWidth = 1.0f;
- rasterizer.cullMode = VK_CULL_MODE_NONE;
- //rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
- //rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
- rasterizer.depthBiasEnable = VK_FALSE;
- rasterizer.depthBiasConstantFactor = 0.0f; // Optional
- rasterizer.depthBiasClamp = 0.0f; // Optional
- rasterizer.depthBiasSlopeFactor = 0.0f; // Optional
-
- VkPipelineMultisampleStateCreateInfo multisampling = {0};
- multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
- multisampling.sampleShadingEnable = VK_FALSE;
- multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
- multisampling.minSampleShading = 1.0f; // Optional
- multisampling.pSampleMask = NULL; // Optional
- multisampling.alphaToCoverageEnable = VK_FALSE; // Optional
- multisampling.alphaToOneEnable = VK_FALSE; // Optional
-
- VkPipelineColorBlendAttachmentState colorBlendAttachment = {0};
- colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
- colorBlendAttachment.blendEnable = VK_TRUE;
- colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
- colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
- colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
- colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
- colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
- colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
- /* colorBlendAttachment.blendEnable = VK_FALSE; */
- /* colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; // Optional */
- /* colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; // Optional */
- /* colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD; // Optional */
- /* colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; // Optional */
- /* colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; // Optional */
- /* colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD; // Optional */
-
- VkPipelineColorBlendStateCreateInfo colorBlending = {0};
- colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
- colorBlending.logicOpEnable = VK_TRUE;
- colorBlending.logicOp = VK_LOGIC_OP_COPY; // Optional
- colorBlending.attachmentCount = 1;
- colorBlending.pAttachments = &colorBlendAttachment;
- colorBlending.blendConstants[0] = 0.0f; // Optional
- colorBlending.blendConstants[1] = 0.0f; // Optional
- colorBlending.blendConstants[2] = 0.0f; // Optional
- colorBlending.blendConstants[3] = 0.0f; // Optional
-
- VkPipelineLayoutCreateInfo pipelineLayoutInfo = {0};
- pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
- pipelineLayoutInfo.setLayoutCount = 1;
- pipelineLayoutInfo.pSetLayouts = &s.vk_descriptor_set_layout;
- pipelineLayoutInfo.pushConstantRangeCount = 0; // Optional
- pipelineLayoutInfo.pPushConstantRanges = NULL; // Optional
-
- if (vkCreatePipelineLayout(s.vk_device, &pipelineLayoutInfo, NULL, &s.vk_pipeline_layout) != VK_SUCCESS) {
- vk_log(VK_ERROR, "failed to create pipeline layout!\n");
- }
-
- VkPipelineDepthStencilStateCreateInfo depthStencil = {0};
- depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
- depthStencil.depthTestEnable = VK_TRUE;
- depthStencil.depthWriteEnable = VK_TRUE;
- depthStencil.depthBoundsTestEnable = VK_FALSE;
- depthStencil.stencilTestEnable = VK_FALSE;
- depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
- depthStencil.minDepthBounds = 0.0f; // Optional
- depthStencil.maxDepthBounds = 1.0f; // Optional
- depthStencil.front = (VkStencilOpState){0}; // Optional
- depthStencil.back = (VkStencilOpState){0}; // Optional
-
- // TODO depthAttachment
- VkPipelineRenderingCreateInfo pipeline_rendering_create_info = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
- .colorAttachmentCount = 1,
- .pColorAttachmentFormats = &s.vk_swap_chain_image_format,
- .depthAttachmentFormat = findDepthFormat(),
- };
- VkGraphicsPipelineCreateInfo pipelineInfo = {0};
- pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
- pipelineInfo.stageCount = 2;
- pipelineInfo.pStages = shaderStages;
-
- pipelineInfo.pNext = &pipeline_rendering_create_info,
- pipelineInfo.pVertexInputState = &vertexInputInfo;
- pipelineInfo.pInputAssemblyState = &inputAssembly;
- pipelineInfo.pViewportState = &viewportState;
- pipelineInfo.pRasterizationState = &rasterizer;
- pipelineInfo.pMultisampleState = &multisampling;
- pipelineInfo.pDepthStencilState = &depthStencil;
- pipelineInfo.pColorBlendState = &colorBlending;
- pipelineInfo.pDynamicState = &dynamicState;
- pipelineInfo.layout = s.vk_pipeline_layout;
- pipelineInfo.renderPass = VK_NULL_HANDLE;
- pipelineInfo.subpass = 0;
- pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; // Optional
- pipelineInfo.basePipelineIndex = -1; // Optional
-
- if (vkCreateGraphicsPipelines(s.vk_device, VK_NULL_HANDLE, 1, &pipelineInfo, NULL, &s.vk_graphics_pipeline) != VK_SUCCESS) {
- vk_log(VK_ERROR, "failed to create graphics pipeline!\n");
- }
-
- if (s.prev_vert_result != vert_result) {
- shaderc_result_release(vert_result);
- }
- if (s.prev_frag_result != frag_result) {
- shaderc_result_release(frag_result);
- }
-
- vkDestroyShaderModule(s.vk_device, fragShaderModule, NULL);
- vkDestroyShaderModule(s.vk_device, vertShaderModule, NULL);
-}
-
-void
-vulkan_create_command_pool()
-{
- QueueFamilyIndices queueFamilyIndices = vulkan_find_queue_families(s.vk_physical_device);
-
- VkCommandPoolCreateInfo poolInfo = {0};
- poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
- poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
- poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily;
-
- VK_CHECK(vkCreateCommandPool(s.vk_device, &poolInfo, NULL, &s.vk_command_pool));
-}
-
-void
-vulkan_create_command_buffer()
-{
- // TODO Find a way to group allocation
- for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
- VkCommandBufferAllocateInfo allocInfo = {0};
- allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
- allocInfo.commandPool = s.vk_command_pool;
- allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
- allocInfo.commandBufferCount = 1;
-
- VK_CHECK(vkAllocateCommandBuffers(s.vk_device, &allocInfo, &s.frames[i].vk_command_buffer));
- }
-}
-
-void
-recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex)
-{
- VkCommandBufferBeginInfo beginInfo = {0};
- beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- beginInfo.flags = 0; // Optional
- beginInfo.pInheritanceInfo = NULL; // Optional
-
- VK_CHECK(vkBeginCommandBuffer(commandBuffer, &beginInfo));
- vkCmdSetDepthTestEnable(commandBuffer, 1);
- vkCmdSetDepthWriteEnable(commandBuffer, 1);
-
- transitionImageLayout(
- s.vk_swap_chain_images[imageIndex], VK_FORMAT_R8G8B8A8_SRGB, 0,
- VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
- VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
- VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
-
- VkRenderingAttachmentInfo colorAttachment = {0};
- colorAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
- colorAttachment.imageView = s.vk_swap_chain_image_views[imageIndex];
- colorAttachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
- colorAttachment.clearValue.color =
- (VkClearColorValue){0.0f, 0.0f, 0.0f, 1.0f};
-
- VkRenderingAttachmentInfo depthAttachment = {0};
- depthAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
- depthAttachment.imageView = s.vk_depth_image_view;
- depthAttachment.imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
- depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
- depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
- depthAttachment.clearValue.depthStencil = (VkClearDepthStencilValue){1.0f, 0u};
-
- VkRenderingInfo renderingInfo = {};
- renderingInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
- renderingInfo.renderArea =
- (VkRect2D){{0, 0}, s.vk_swap_chain_extent};
- renderingInfo.layerCount = 1;
- renderingInfo.colorAttachmentCount = 1;
- renderingInfo.pColorAttachments = &colorAttachment;
- renderingInfo.pDepthAttachment = &depthAttachment;
-
- vkCmdBeginRendering(commandBuffer, &renderingInfo);
-
- vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
- s.vk_graphics_pipeline);
-
- VkViewport viewport = {0};
- viewport.x = 0.0f;
- viewport.y = 0.0f;
- viewport.width = (float)(s.vk_swap_chain_extent.width);
- viewport.height = (float)(s.vk_swap_chain_extent.height);
- viewport.minDepth = 0.0f;
- viewport.maxDepth = 1.0f;
- vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
-
- VkRect2D scissor = {0};
- scissor.offset = (VkOffset2D){0, 0};
- scissor.extent = s.vk_swap_chain_extent;
- vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
-
- VkBuffer vertexBuffers[] = {s.vk_vertex_buffer};
- VkDeviceSize offsets[] = {0};
- vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets);
- vkCmdBindIndexBuffer(commandBuffer, s.vk_index_buffer, 0,
- VK_INDEX_TYPE_UINT16);
- vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
- s.vk_pipeline_layout, 0, 1,
- &s.frames[currentFrame].vk_descriptor_set, 0, NULL);
-
-
- vkCmdDrawIndexed(commandBuffer, INDICES_SIZE, 1, 0, 0, 0);
- vkCmdEndRendering(commandBuffer);
-
- transitionImageLayout(s.vk_swap_chain_images[imageIndex],
- VK_FORMAT_R8G8B8A8_SRGB,
- VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 0,
- VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
- VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
- VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
- VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
-
- VK_CHECK(vkEndCommandBuffer(commandBuffer));
-}
-
-void
-vulkan_create_sync_objects()
-{
- VkSemaphoreCreateInfo semaphoreInfo = {0};
- semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
-
- VkFenceCreateInfo fenceInfo = {0};
- fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
- fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
-
- for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
- VK_CHECK(vkCreateSemaphore(s.vk_device, &semaphoreInfo, NULL, &s.frames[i].image_available_semaphore));
- VK_CHECK(vkCreateSemaphore(s.vk_device, &semaphoreInfo, NULL, &s.frames[i].render_finished_semaphore));
- VK_CHECK(vkCreateFence(s.vk_device, &fenceInfo, NULL, &s.frames[i].in_flight_fence));
- }
-}
-
-void
-createBuffer(VkDeviceSize size,
- VkBufferUsageFlags usage,
- VkMemoryPropertyFlags properties,
- VkBuffer *buffer, VkDeviceMemory *bufferMemory)
-{
- 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(s.vk_device, &bufferInfo, NULL, buffer));
-
- VkMemoryRequirements memRequirements;
- vkGetBufferMemoryRequirements(s.vk_device, *buffer, &memRequirements);
-
- VkMemoryAllocateInfo allocInfo = {0};
- allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
- allocInfo.allocationSize = memRequirements.size;
- allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties);
-
- // TODO: group allocations etc... (allocations limited by hardware)
- VK_CHECK(vkAllocateMemory(s.vk_device, &allocInfo, NULL, bufferMemory));
-
- VK_CHECK(vkBindBufferMemory(s.vk_device, *buffer, *bufferMemory, 0));
-}
-
-void copy_buffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size) {
- VkCommandBuffer commandBuffer = beginSingleTimeCommands();
- VkBufferCopy copyRegion = {0};
- copyRegion.srcOffset = 0; // Optional
- copyRegion.dstOffset = 0; // Optional
- copyRegion.size = size;
- vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, &copyRegion);
- endSingleTimeCommands(commandBuffer);
-}
-
-void
-vulkan_create_vertex_buffer()
-{
- VkDeviceSize bufferSize = sizeof(vertices[0]) * VERTICES_SIZE;
-
- VkBuffer stagingBuffer;
- VkDeviceMemory stagingBufferMemory;
-
- createBuffer(bufferSize,
- VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
- VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
- &stagingBuffer, &stagingBufferMemory);
-
- void* data;
- VK_CHECK(vkMapMemory(s.vk_device, stagingBufferMemory, 0, bufferSize, 0, &data));
- memcpy(data, vertices, (size_t) bufferSize);
- vkUnmapMemory(s.vk_device, stagingBufferMemory);
-
- createBuffer(bufferSize,
- VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
- VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
- &s.vk_vertex_buffer, &s.vk_vertex_buffer_memory);
-
- copy_buffer(stagingBuffer, s.vk_vertex_buffer, bufferSize);
-
- vkDestroyBuffer(s.vk_device, stagingBuffer, NULL);
- vkFreeMemory(s.vk_device, stagingBufferMemory, NULL);
-}
-
-void
-vulkan_create_index_buffer()
-{
- VkDeviceSize bufferSize = sizeof(indices[0]) * INDICES_SIZE;
-
- VkBuffer stagingBuffer;
- VkDeviceMemory stagingBufferMemory;
-
- createBuffer(bufferSize,
- VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
- VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
- &stagingBuffer, &stagingBufferMemory);
-
- void* data;
- VK_CHECK(vkMapMemory(s.vk_device, stagingBufferMemory, 0, bufferSize, 0, &data));
- memcpy(data, indices, (size_t) bufferSize);
- vkUnmapMemory(s.vk_device, stagingBufferMemory);
-
- createBuffer(bufferSize,
- VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
- VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
- &s.vk_index_buffer, &s.vk_index_buffer_memory);
-
- copy_buffer(stagingBuffer, s.vk_index_buffer, bufferSize);
-
- vkDestroyBuffer(s.vk_device, stagingBuffer, NULL);
- vkFreeMemory(s.vk_device, stagingBufferMemory, NULL);
-}
-
-void
-vulkan_create_descriptor_set_layout()
-{
- VkDescriptorSetLayoutBinding uboLayoutBinding = {0};
- uboLayoutBinding.binding = 0;
- uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- uboLayoutBinding.descriptorCount = 1;
- uboLayoutBinding.stageFlags = VK_SHADER_STAGE_ALL;
- //uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
- uboLayoutBinding.pImmutableSamplers = NULL; // optional
-
- VkDescriptorSetLayoutBinding samplerLayoutBinding = {0};
- samplerLayoutBinding.binding = 1;
- samplerLayoutBinding.descriptorCount = 1;
- samplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- samplerLayoutBinding.pImmutableSamplers = NULL;
- samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
-
- VkDescriptorSetLayoutBinding bindings[2] = {uboLayoutBinding, samplerLayoutBinding};
-
- VkDescriptorSetLayoutCreateInfo layoutInfo = {0};
- layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
- layoutInfo.bindingCount = VK_ARRAY_LEN(bindings);
- layoutInfo.pBindings = bindings;
-
- VK_CHECK(vkCreateDescriptorSetLayout(s.vk_device, &layoutInfo, NULL, &s.vk_descriptor_set_layout));
-}
-
-void
-vulkan_create_uniform_buffers()
-{
- VkDeviceSize bufferSize = sizeof(UniformBufferObject);
-
- for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
- createBuffer(bufferSize,
- VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
- VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
- &s.frames[i].vk_uniform_buffer, &s.frames[i].vk_uniform_buffer_memory);
-
- VK_CHECK(vkMapMemory(s.vk_device, s.frames[i].vk_uniform_buffer_memory, 0, bufferSize, 0, &s.frames[i].vk_uniform_buffer_mapped));
- }
-}
-
-void
-vulkan_create_descriptor_pool()
-{
- VkDescriptorPoolSize poolSizes[2] = {0};
- poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- poolSizes[0].descriptorCount = MAX_FRAMES_IN_FLIGHT;
- poolSizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- poolSizes[1].descriptorCount = MAX_FRAMES_IN_FLIGHT;
-
- VkDescriptorPoolCreateInfo poolInfo = {0};
- poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
- poolInfo.poolSizeCount = VK_ARRAY_LEN(poolSizes);
- poolInfo.pPoolSizes = poolSizes;
- poolInfo.maxSets = MAX_FRAMES_IN_FLIGHT;
-
- VK_CHECK(vkCreateDescriptorPool(s.vk_device, &poolInfo, NULL, &s.vk_descriptor_pool));
-}
-
-void
-vulkan_create_descriptor_sets()
-{
- VkDescriptorSetLayout layouts[MAX_FRAMES_IN_FLIGHT] = {0};
-
- for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
- layouts[i] = s.vk_descriptor_set_layout;
- }
-
- // TODO Find a way to group allocation
- for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
- VkDescriptorSetAllocateInfo allocInfo = {0};
- allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
- allocInfo.descriptorPool = s.vk_descriptor_pool;
- allocInfo.descriptorSetCount = 1;
- allocInfo.pSetLayouts = layouts;
-
- VK_CHECK(vkAllocateDescriptorSets(s.vk_device, &allocInfo, &s.frames[i].vk_descriptor_set));
- }
-
- for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
- VkDescriptorBufferInfo bufferInfo = {0};
- bufferInfo.buffer = s.frames[i].vk_uniform_buffer;
- bufferInfo.offset = 0;
- bufferInfo.range = sizeof(UniformBufferObject);
-
- VkDescriptorImageInfo imageInfo = {0};
- imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
- imageInfo.imageView = s.vk_texture_image_view;
- imageInfo.sampler = s.vk_texture_sampler;
-
- VkWriteDescriptorSet descriptorWrites[2] = {0};
- descriptorWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- descriptorWrites[0].dstSet = s.frames[i].vk_descriptor_set;
- descriptorWrites[0].dstBinding = 0;
- descriptorWrites[0].dstArrayElement = 0;
- descriptorWrites[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- descriptorWrites[0].descriptorCount = 1;
- descriptorWrites[0].pBufferInfo = &bufferInfo;
-
- descriptorWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- descriptorWrites[1].dstSet = s.frames[i].vk_descriptor_set;
- descriptorWrites[1].dstBinding = 1;
- descriptorWrites[1].dstArrayElement = 0;
- descriptorWrites[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- descriptorWrites[1].descriptorCount = 1;
- descriptorWrites[1].pImageInfo = &imageInfo;
-
- vkUpdateDescriptorSets(s.vk_device, VK_ARRAY_LEN(descriptorWrites), descriptorWrites, 0, NULL);
- }
-}
-
-void
-cleanupSwapChain()
-{
- vkDestroyImageView(s.vk_device, s.vk_depth_image_view, NULL);
- vkDestroyImage(s.vk_device, s.vk_depth_image, NULL);
- vkFreeMemory(s.vk_device, s.vk_depth_image_memory, NULL);
-
- for (uint32_t i = 0; i < s.vk_swap_chain_image_count; i++) {
- vkDestroyImageView(s.vk_device, s.vk_swap_chain_image_views[i], NULL);
- }
- vkDestroySwapchainKHR(s.vk_device, s.vk_swap_chain, NULL);
-}
-
-void
-recreateSwapChain()
-{
- vkDeviceWaitIdle(s.vk_device);
-
- cleanupSwapChain();
-
- vulkan_create_swap_chain();
- vulkan_create_image_views();
- vulkan_create_depth_resources();
-}
-
-void
-handle_input(bool * quit)
-{
- SDL_Event e;
-
- while (SDL_PollEvent(&e) != 0) {
- // User requests quit
- if (e.type == SDL_QUIT) {
- *quit = true;
- }
- // User presses a key
- else if (e.type == SDL_KEYDOWN) {
- switch (e.key.keysym.sym) {
- case SDLK_w:
- s.camera.pos[0] += 0.1f;
- break;
- case SDLK_s:
- s.camera.pos[0] -= 0.1f;
- break;
- case SDLK_LEFT:
- break;
- case SDLK_g: // reload shaders
- recreateSwapChain();
- vkDestroyPipeline(s.vk_device, s.vk_graphics_pipeline, NULL);
- vkDestroyPipelineLayout(s.vk_device, s.vk_pipeline_layout, NULL);
- vulkan_create_graphics_pipeline();
- break;
- case SDLK_l:
- s.rotate = s.rotate ? 0 : 1;
- break;
- case SDLK_r:
- s.camera.pos[0] = 1.0f;
- s.camera.pos[1] = 1.0f;
- s.camera.pos[2] = 1.0f;
-
- s.camera.front[0] = 0.0f;
- s.camera.front[1] = 0.0f;
- s.camera.front[2] = 0.0f;
-
- s.camera.up[0] = 0.0f;
- s.camera.up[1] = 0.0f;
- s.camera.up[2] = 1.0f;
-
- s.camera.yaw = 0.0f;
- s.camera.pitch = 90.0f;
- s.camera.lastX = 400.0f;
- s.camera.lastY = 300.0f;
- s.camera.fov = 45.0f;
- update_camera(0,0);
- break;
- }
- }
- else if (e.type == SDL_MOUSEWHEEL) {
- if(e.wheel.y > 0) // scroll up
- {
- s.zoom += 1;
- }
- else if(e.wheel.y < 0) // scroll down
- {
- s.zoom -= 1;
- if (s.zoom == -100) s.zoom = 1;
- }
- }
- else if (e.type == SDL_MOUSEBUTTONDOWN) {
- s.mouse_pressed = 1;
- }
- else if (e.type == SDL_MOUSEBUTTONUP) {
- s.mouse_pressed = 0;
- }
- mouseCallback(&e);
- }
-}
-
-void
-copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width,
- uint32_t height)
-{
- VkCommandBuffer commandBuffer = beginSingleTimeCommands();
-
- VkBufferImageCopy region = {0};
- region.bufferOffset = 0;
- region.bufferRowLength = 0;
- region.bufferImageHeight = 0;
-
- region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- region.imageSubresource.mipLevel = 0;
- region.imageSubresource.baseArrayLayer = 0;
- region.imageSubresource.layerCount = 1;
-
- region.imageOffset = (VkOffset3D){0, 0, 0};
- region.imageExtent = (VkExtent3D){width, height, 1};
-
- vkCmdCopyBufferToImage(commandBuffer,
- buffer,
- image,
- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
- 1,
- &region
- );
-
- endSingleTimeCommands(commandBuffer);
-}
-
-void
-vulkan_create_texture_image()
-{
- int texWidth, texHeight, texChannels;
- stbi_uc* pixels = stbi_load("assets/texture.jpg", &texWidth, &texHeight, &texChannels, STBI_rgb_alpha);
- VkDeviceSize imageSize = texWidth * texHeight * 4;
-
- if (!pixels) {
- vk_log(VK_ERROR, "failed to load texture image!\n");
- }
-
- VkBuffer stagingBuffer;
- VkDeviceMemory stagingBufferMemory;
-
- createBuffer(imageSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &stagingBuffer, &stagingBufferMemory);
- void* data;
- vkMapMemory(s.vk_device, stagingBufferMemory, 0, imageSize, 0, &data);
- memcpy(data, pixels, (size_t)imageSize);
- vkUnmapMemory(s.vk_device, stagingBufferMemory);
-
- stbi_image_free(pixels);
-
- createImage(texWidth, texHeight, VK_FORMAT_R8G8B8A8_SRGB,
- VK_IMAGE_TILING_OPTIMAL,
- VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
- VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &s.vk_texture_image,
- &s.vk_texture_image_memory);
-
- transitionImageLayout(
- s.vk_texture_image, VK_FORMAT_R8G8B8A8_SRGB, 0,
- VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
- VK_PIPELINE_STAGE_TRANSFER_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
- copyBufferToImage(stagingBuffer, s.vk_texture_image, (uint32_t)texWidth,
- (uint32_t)texHeight);
- transitionImageLayout(
- s.vk_texture_image, VK_FORMAT_R8G8B8A8_SRGB,
- VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
- VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
- VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
-
- vkDestroyBuffer(s.vk_device, stagingBuffer, NULL);
- vkFreeMemory(s.vk_device, stagingBufferMemory, NULL);
-}
-
-void
-vulkan_create_texture_image_view()
-{
- s.vk_texture_image_view = create_image_view(s.vk_texture_image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT);
-}
-
-void vulkan_create_texture_sampler() {
- VkSamplerCreateInfo samplerInfo = {0};
- samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
- samplerInfo.magFilter = VK_FILTER_LINEAR;
- samplerInfo.minFilter = VK_FILTER_LINEAR;
- samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
- samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
- samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
- samplerInfo.anisotropyEnable = VK_TRUE;
-
- VkPhysicalDeviceProperties properties = {0};
- vkGetPhysicalDeviceProperties(s.vk_physical_device, &properties);
-
- samplerInfo.maxAnisotropy = properties.limits.maxSamplerAnisotropy;
- samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
- samplerInfo.unnormalizedCoordinates = VK_FALSE;
- samplerInfo.compareEnable = VK_FALSE;
- samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
- samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
- samplerInfo.mipLodBias = 0.0f;
- samplerInfo.minLod = 0.0f;
- samplerInfo.maxLod = 0.0f;
-
- VK_CHECK(vkCreateSampler(s.vk_device, &samplerInfo, NULL, &s.vk_texture_sampler));
-}
-
-void
-init_vulkan()
-{
- vk_log(VK_WARN, "====================================\n");
- vk_log(VK_WARN, " DEBUG ON \n");
- vk_log(VK_WARN, "====================================\n");
-
- vulkan_create_instance();
- // vulkan_setup_debug_messenger();
- vulkan_create_surface();
- vulkan_pick_physical_device();
- vulkan_create_logical_device();
- vulkan_create_swap_chain();
- vulkan_create_image_views();
- vulkan_create_descriptor_set_layout();
- vulkan_create_graphics_pipeline();
- vulkan_create_command_pool();
- vulkan_create_depth_resources();
- vulkan_create_texture_image();
- vulkan_create_texture_image_view();
- vulkan_create_texture_sampler();
- vulkan_create_vertex_buffer();
- vulkan_create_index_buffer();
- vulkan_create_uniform_buffers();
- vulkan_create_descriptor_pool();
- vulkan_create_descriptor_sets();
- vulkan_create_command_buffer();
- vulkan_create_sync_objects();
-}
-
-void
-close_vulkan()
-{
- vkDeviceWaitIdle(s.vk_device);
- // Cleanup
- for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
- vkDestroySemaphore(s.vk_device, s.frames[i].image_available_semaphore, NULL);
- vkDestroySemaphore(s.vk_device, s.frames[i].render_finished_semaphore, NULL);
- vkDestroyFence(s.vk_device, s.frames[i].in_flight_fence, NULL);
- }
-
- vkDestroyCommandPool(s.vk_device, s.vk_command_pool, NULL);
-
- cleanupSwapChain();
-
- vkDestroySampler(s.vk_device, s.vk_texture_sampler, NULL);
- vkDestroyImageView(s.vk_device, s.vk_texture_image_view, NULL);
-
- vkDestroyImage(s.vk_device, s.vk_texture_image, NULL);
- vkFreeMemory(s.vk_device, s.vk_texture_image_memory, NULL);
-
- for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
- vkDestroyBuffer(s.vk_device, s.frames[i].vk_uniform_buffer, NULL);
- vkFreeMemory(s.vk_device, s.frames[i].vk_uniform_buffer_memory, NULL);
- }
- vkDestroyDescriptorPool(s.vk_device, s.vk_descriptor_pool, NULL);
- vkDestroyDescriptorSetLayout(s.vk_device, s.vk_descriptor_set_layout, NULL);
-
- vkDestroyBuffer(s.vk_device, s.vk_vertex_buffer, NULL);
- vkFreeMemory(s.vk_device, s.vk_vertex_buffer_memory, NULL);
-
- vkDestroyBuffer(s.vk_device, s.vk_index_buffer, NULL);
- vkFreeMemory(s.vk_device, s.vk_index_buffer_memory, NULL);
-
- vkDestroyPipeline(s.vk_device, s.vk_graphics_pipeline, NULL);
- vkDestroyPipelineLayout(s.vk_device, s.vk_pipeline_layout, NULL);
- vkDestroyDevice(s.vk_device, NULL);
- vkDestroySurfaceKHR(s.vk_instance, s.vk_surface, NULL);
- /* if (enableValidationLayers) { */
- /* DestroyDebugUtilsMessengerEXT(s.vk_instance, s.vk_debug_messenger, NULL); */
- /* } */
- vkDestroyInstance(s.vk_instance, NULL);
-
- if (s.prev_vert_result) {
- shaderc_result_release(s.prev_vert_result);
- }
- if (s.prev_frag_result) {
- shaderc_result_release(s.prev_frag_result);
- }
-}
-
-float
-current_time()
-{
- static struct timespec startTime;
- static int isStartTimeInitialized = 0;
-
- if (!isStartTimeInitialized) {
- clock_gettime(CLOCK_MONOTONIC, &startTime);
- isStartTimeInitialized = 1;
- }
-
- struct timespec currentTime;
- clock_gettime(CLOCK_MONOTONIC, &currentTime);
-
- return (currentTime.tv_sec - startTime.tv_sec) +
- (currentTime.tv_nsec - startTime.tv_nsec) / 1e9f;
-}
-
-void
-updateUniformBuffer(uint32_t currentImage)
-{
- float time = current_time();
-
- UniformBufferObject ubo = {0};
-
- ubo.resolution[0] = s.vk_swap_chain_extent.width;
- ubo.resolution[1] = s.vk_swap_chain_extent.height;
-
- glm_mat4_identity(ubo.model);
-
- if (s.rotate)
- glm_rotate(ubo.model, glm_rad(50 * time * glm_rad(90.0f)), GLM_ZUP);
-
- vec3 eye = GLM_VEC3_ONE_INIT;
- vec3 center = GLM_VEC3_ZERO_INIT;
-
-// vk_log(VK_INFO, "{%.2f, %.2f, %.2f}\n", s.camera.front[0], s.camera.front[1], s.camera.front[2]);
- /* glm_vec3_add(s.camera.pos, s.camera.front, center); */
- glm_lookat(s.camera.pos, s.camera.front, s.camera.up, ubo.view);
-
- /* glm_lookat(eye, center, GLM_ZUP, ubo.view); */
-
- float aspect = s.vk_swap_chain_extent.width / (float)s.vk_swap_chain_extent.height;
- glm_perspective(glm_rad(45.0f ), aspect, 1.0f, 10.0f, ubo.proj);
-
- // Inverting the Y axis for Vulkan
- ubo.proj[1][1] *= -1;
-
- memcpy(s.frames[currentImage].vk_uniform_buffer_mapped, &ubo, sizeof(ubo));
-}
-
-void
-draw_frame() {
- vkWaitForFences(s.vk_device, 1, &s.frames[currentFrame].in_flight_fence, VK_TRUE, UINT64_MAX);
-
- uint32_t imageIndex;
- VkResult result = vkAcquireNextImageKHR(s.vk_device, s.vk_swap_chain, UINT64_MAX, s.frames[currentFrame].image_available_semaphore, VK_NULL_HANDLE, &imageIndex);
-
- if (result == VK_ERROR_OUT_OF_DATE_KHR) {
- recreateSwapChain();
- return;
- } else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
- vk_log(VK_ERROR, "failed to acquire swap chain image!\n");
- }
-
- updateUniformBuffer(currentFrame);
-
- vkResetFences(s.vk_device, 1, &s.frames[currentFrame].in_flight_fence);
-
- vkResetCommandBuffer(s.frames[currentFrame].vk_command_buffer, 0);
- recordCommandBuffer(s.frames[currentFrame].vk_command_buffer, imageIndex);
-
- VkSubmitInfo submitInfo = {0};
- submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-
- VkSemaphore waitSemaphores[] = {s.frames[currentFrame].image_available_semaphore};
- VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
- submitInfo.waitSemaphoreCount = 1;
- submitInfo.pWaitSemaphores = waitSemaphores;
- submitInfo.pWaitDstStageMask = waitStages;
- submitInfo.commandBufferCount = 1;
- submitInfo.pCommandBuffers = &s.frames[currentFrame].vk_command_buffer;
-
- VkSemaphore signalSemaphores[] = {s.frames[currentFrame].render_finished_semaphore};
- submitInfo.signalSemaphoreCount = 1;
- submitInfo.pSignalSemaphores = signalSemaphores;
-
- if (vkQueueSubmit(s.vk_graphics_queue, 1, &submitInfo, s.frames[currentFrame].in_flight_fence) != VK_SUCCESS) {
- vk_log(VK_ERROR, "failed to submit draw command buffer!\n");
- }
-
- VkSwapchainKHR swapChains[] = {s.vk_swap_chain};
- VkPresentInfoKHR presentInfo = {0};
- presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
- presentInfo.waitSemaphoreCount = 1;
- presentInfo.pWaitSemaphores = signalSemaphores;
- presentInfo.swapchainCount = 1;
- presentInfo.pSwapchains = swapChains;
- presentInfo.pImageIndices = &imageIndex;
- presentInfo.pResults = NULL;
-
- result = vkQueuePresentKHR(s.vk_present_queue, &presentInfo);
-
- if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || s.sdl_window_resized) {
- s.sdl_window_resized = 0;
- recreateSwapChain();
- } else if (result != VK_SUCCESS) {
- vk_log(VK_ERROR, "failed to present swap chain image!\n");
- }
-
- currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
-}
-
-int
-main(int argc, char* args[])
-{
- init_state(&s);
- if (!init()) {
- vk_log(VK_INFO, "Failed to initialize!\n");
- }
- else {
- init_vulkan();
-
- bool quit = false;
-
-
- /* VMA POC */
- VmaVulkanFunctions vulkanFunctions = {0};
- vulkanFunctions.vkGetInstanceProcAddr = &vkGetInstanceProcAddr;
- vulkanFunctions.vkGetDeviceProcAddr = &vkGetDeviceProcAddr;
-
- VmaAllocatorCreateInfo allocatorCreateInfo = {0};
- allocatorCreateInfo.flags = VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT;
- allocatorCreateInfo.vulkanApiVersion = VK_API_VERSION_1_2;
- allocatorCreateInfo.physicalDevice = s.vk_physical_device;
- allocatorCreateInfo.device = s.vk_device;
- allocatorCreateInfo.instance = s.vk_instance;
- allocatorCreateInfo.pVulkanFunctions = &vulkanFunctions;
-
- VmaAllocator allocator;
- vmaCreateAllocator(&allocatorCreateInfo, &allocator);
-
- // Entire program...
-
- // At the end, don't forget to:
- vmaDestroyAllocator(allocator);
-
- // Game loop
- update_camera(0, 0);
- while (!quit) {
- handle_input(&quit);
- draw_frame();
- //SDL_Delay(16);
- }
-
- close_vulkan();
- }
-
- // Free resources and close SDL
- closeSDL();
-
- return 0;
-
-}