#pragma once #include <cstdint>#include "font.h"#include "view.h" constexpr int MiB = 1024 * 1024;constexpr uint64_t MAX_64 = -1; constexpr int GRIDS_POOL_SIZE = 8 * MiB;constexpr int GLYPHSET_POOL_SIZE = 8 * MiB;constexpr int VIEW_PARAMS_INITIAL_CAP = 8; struct uvec2 { uint32_t x, y;};struct ivec2 { int32_t x, y;}; struct View_Params { uvec2 view_origin; uvec2 view_size; uvec2 cell_size; uvec2 thumb_pos; ivec2 cursor; uint32_t thumb_color; uint32_t cursor_color; uint32_t columns; uint32_t grid_cell_offset; uint32_t glyphset_byte_offset; uint32_t glyph_overlap_w; uint32_t glyph_full_w;}; struct Memory_Pool { VkDeviceMemory dev_mem; VkDeviceMemory host_mem; VkBuffer dev_buf; VkBuffer host_buf; uint8_t *staging_area; int size; VkResult result; void close(VkDevice device) { vkUnmapMemory(device, host_mem); vkDestroyBuffer(device, dev_buf, nullptr); vkDestroyBuffer(device, host_buf, nullptr); vkFreeMemory(device, dev_mem, nullptr); vkFreeMemory(device, host_mem, nullptr); }}; enum { ID_GetPhysicalDeviceSurfaceSupport = 0, ID_GetPhysicalDeviceSurfaceCapabilities, ID_GetPhysicalDeviceSurfaceFormats, ID_CreateDebugUtilsMessenger, ID_DestroyDebugUtilsMessenger, ID_CreateSwapchain, ID_DestroySwapchain, ID_GetSwapchainImages, ID_AcquireNextImage, ID_QueuePresent, N_KHR_IDS}; struct Vulkan { View_Params *view_params = nullptr; int n_view_params = 0; int view_param_cap = 0; const VkImageUsageFlags img_usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; void *glfw_monitor = nullptr; void *glfw_window = nullptr; int wnd_width = 0; int wnd_height = 0; VkInstance instance = {0}; VkPhysicalDevice gpu = {0}; VkPhysicalDeviceMemoryProperties gpu_mem = {0}; VkQueue queue = {0}; VkDevice device = {0}; VkDebugUtilsMessengerEXT debug_callback = {0}; VkSurfaceKHR surface = {0}; VkSurfaceFormatKHR sf_color_fmt = {VK_FORMAT_UNDEFINED, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR}; VkSurfaceCapabilitiesKHR sf_caps = {0}; VkSwapchainKHR swapchain = {0}; VkRenderPass renderpass = {0}; VkImage swap_image; VkImageView swap_image_view; VkFramebuffer framebuffer; VkCommandBuffer draw_buffer; VkFence draw_fence; VkCommandPool cmd_pool = {0}; VkFence misc_fence = {0}; VkSemaphore sema_present = {0}; VkSemaphore sema_render = {0}; int queue_index = 0; VkDescriptorPool dpool = {0}; VkDescriptorSetLayout ds_layout = {0}; VkDescriptorSet desc_set = {0}; Memory_Pool glyphset_pool = {0}; Memory_Pool grids_pool = {0}; VkDeviceMemory dst_mem = {0}; VkBuffer mvp_buf = {0}; VkBuffer vert_buf = {0}; VkBuffer index_buf = {0}; VkShaderModule vert_shader = {0}; VkShaderModule frag_shader = {0}; VkPipelineStageFlags wait_stage_mask = 0; VkPipelineLayout pl_layout = {0}; VkPipeline pipeline = {0}; VkSubmitInfo submit_info = {}; VkPresentInfoKHR present_info = {}; PFN_vkVoidFunction khr_table[N_KHR_IDS] = {0}; VkResult GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32* pSupported) { return ((PFN_vkGetPhysicalDeviceSurfaceSupportKHR)khr_table[ID_GetPhysicalDeviceSurfaceSupport])(physicalDevice, queueFamilyIndex, surface, pSupported); } VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) { return ((PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)khr_table[ID_GetPhysicalDeviceSurfaceCapabilities])(physicalDevice, surface, pSurfaceCapabilities); } VkResult GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats) { return ((PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)khr_table[ID_GetPhysicalDeviceSurfaceFormats])(physicalDevice, surface, pSurfaceFormatCount, pSurfaceFormats); } VkResult CreateDebugUtilsMessenger(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pCallback) { return ((PFN_vkCreateDebugUtilsMessengerEXT)khr_table[ID_CreateDebugUtilsMessenger])(instance, pCreateInfo, pAllocator, pCallback); } void DestroyDebugUtilsMessenger(VkInstance instance, VkDebugUtilsMessengerEXT callback, const VkAllocationCallbacks* pAllocator) { auto func = (PFN_vkDestroyDebugUtilsMessengerEXT)khr_table[ID_DestroyDebugUtilsMessenger]; if (func) func(instance, callback, pAllocator); } VkResult CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain) { return ((PFN_vkCreateSwapchainKHR)khr_table[ID_CreateSwapchain])(device, pCreateInfo, pAllocator, pSwapchain); } void DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator) { auto func = (PFN_vkDestroySwapchainKHR)khr_table[ID_DestroySwapchain]; if (func) func(device, swapchain, pAllocator); } VkResult GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages) { return ((PFN_vkGetSwapchainImagesKHR)khr_table[ID_GetSwapchainImages])(device, swapchain, pSwapchainImageCount, pSwapchainImages); } VkResult AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex) { return ((PFN_vkAcquireNextImageKHR)khr_table[ID_AcquireNextImage])(device, swapchain, timeout, semaphore, fence, pImageIndex); } VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* pPresentInfo) { return ((PFN_vkQueuePresentKHR)khr_table[ID_QueuePresent])(queue, pPresentInfo); } void close(); VkResult create_instance(const char *app_name, const char *engine_name, const char **req_inst_exts, uint32_t n_inst_exts); VkResult create_device(const char **dev_exts, uint32_t n_inst_exts); int load_khr_extensions(); VkResult setup_validation(); int select_bgra8_surface_format(); VkResult create_swapchain(); int create_command_pool_and_draw_buffers(); VkResult create_renderpass(); VkResult create_framebuffer(); VkResult create_semaphores(); void create_fences(); Memory_Pool allocate_gpu_memory(int size); int push_to_gpu(Memory_Pool& pool, int offset, int size); int create_descriptor_set(); int construct_pipeline(); int update_command_buffers(); int recreate_swapchain(int width, int height); int render();}; const char **get_required_instance_extensions(uint32_t *n_inst_exts);VkResult create_window_surface(VkInstance& instance, void *window, VkSurfaceKHR *surface); int init_vulkan(Vulkan& vk, VkShaderModuleCreateInfo& vert_shader_buf, VkShaderModuleCreateInfo& frag_shader_buf, int width, int height);