X-Git-Url: https://eleni.mutantstargoat.com/git/?p=demo;a=blobdiff_plain;f=src%2Fvulkan%2Fvk.cc;h=105cabae25dd07f5fd287114dda061288f158e3f;hp=24941b58bc6558dd7c48c2be5cc177668811003b;hb=0c5fa3525b2c8151bf83a215eee992c257d6fa28;hpb=1e8963fc3f8191e328bbecd04cfbcba31d7d0bdf diff --git a/src/vulkan/vk.cc b/src/vulkan/vk.cc index 24941b5..105caba 100644 --- a/src/vulkan/vk.cc +++ b/src/vulkan/vk.cc @@ -1,20 +1,403 @@ -#include "vulkan/vk.h" -extern GLFWwindow win; +#define GLFW_INCLUDE_VULKAN +#include + +#include +#include +#include + +#include +#include + +#include "gfxapi.h" + +/* global variables */ +extern GLFWwindow *win; +extern int win_w; +extern int win_h; + +/* static variables */ +static std::vector enabled_extension_names; +static VkInstance inst; +static VkDevice device; +static VkPhysicalDevice pdev; +static VkSurfaceKHR surface; +static uint32_t device_mem_idx; +static uint32_t num_queues; +static uint32_t qfamily_idx; + +static const char *print_vulkan_error(VkResult error); +static const char *dev_type_str(VkPhysicalDeviceType type); +static const char *heap_flags_str(VkMemoryHeapFlags flags); +static const char *memtype_flags_str(VkMemoryPropertyFlags flags); +static const char *queue_flags_str(VkQueueFlags flags); + +/* static fumctions */ +static bool create_instance(); +static bool create_device(); bool init_vulkan() { + if(!glfwInit()) { + fprintf(stderr, "Failed to initialize GLFW.\n"); + return false; + } + + if(!glfwVulkanSupported()) { + fprintf(stderr, "No Vulkan support on the device.\n"); + return false; + } + + if(!create_instance()) { + fprintf(stderr, "Failed to enable validation.\n"); + return false; + } + + if(!glfwGetPhysicalDevicePresentationSupport(inst, pdev, qfamily_idx)) { + fprintf(stderr, "Presentation support not found.\n"); + return false; + } + + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + if(!(win = glfwCreateWindow(win_w, win_h, "vkcow", 0, 0))) { + fprintf(stderr, "Failed to create window.\n"); + return false; + } + + if(VkResult err = glfwCreateWindowSurface(inst, win, 0, &surface)) { + fprintf(stderr, "Failed to create KHR surface: %s\n", print_vulkan_error(err)); + return false; + } + return true; } void cleanup_vulkan() { + //TODOs according to the book: + // 1- make sure all threads have been terminated (when I add threads) + // 2- destroy objects in *reverse* order + + vkDestroySurfaceKHR(inst, surface, 0); + + if(vkDeviceWaitIdle(device) == VK_SUCCESS) { + vkDestroyDevice(device, 0); + vkDestroyInstance(inst, 0); + } +} + +static bool create_instance() +{ + /* enable layers */ + uint32_t layer_count = 0; + std::vector enabled_layers; + + if(vkEnumerateInstanceLayerProperties(&layer_count, 0) != VK_SUCCESS) { + fprintf(stderr, "Failed to query layer properties.\n"); + return false; + } + + if(layer_count > 0) { + VkLayerProperties *layers = (VkLayerProperties *)alloca(layer_count * sizeof *layers); + vkEnumerateInstanceLayerProperties(&layer_count, layers); + for(uint32_t i=0; i enabled_extensions; + + if(vkEnumerateInstanceExtensionProperties(0, &extensions_count, 0) != VK_SUCCESS) { + fprintf(stderr, "Failed to enumerate instance extension properties\n"); + return false; + } + + if(extensions_count > 0) { + VkExtensionProperties *extensions = (VkExtensionProperties *)alloca(extensions_count * sizeof *extensions); + vkEnumerateInstanceExtensionProperties(0, &extensions_count, extensions); + + for(uint32_t i=0; i 0) { + VkLayerProperties *layers = (VkLayerProperties*)alloca(layer_count * sizeof *layers); + vkEnumerateDeviceLayerProperties(pdev, &layer_count, layers); + printf("%u layers found.\n", layer_count); + for(uint32_t i=0; i