#pragma once #if __linux__ # define VK_USE_PLATFORM_XCB_KHR #elif _WIN32 # define VK_USE_PLATFORM_WIN32_KHR #endif #define VK_NO_PROTOTYPES #include #ifdef BUILD_DEBUG # include "renderdoc/renderdoc_app.h" #endif // ::Vulkan::Constants::Header:: static const char *_VK_VALIDATION = "VK_LAYER_KHRONOS_validation"; #if __linux__ static char *vulkan_libs[] = { "libvulkan.so.1", "libvulkan.so" }; #define RENDERDOC_LIB "librenderdoc.so" #endif #if _WIN32 static char *vulkan_libs[] = { "vulkan-1.dll", }; #define RENDERDOC_LIB "renderdoc.dll" #endif #if __unix__ && !__linux__ #error Not yet implemented #endif #define V_THREAD_MAX 1 #define VERTEX_BUFFER_CAP MB(32) #define INDEX_BUFFER_CAP MB(8) #define TRANSFER_BUFFER_CAP MB(64) // ::Vulkan::Macros::Header:: #define VK_DECLARE(fn) static PFN_##fn fn = NULL #define STYPE(type) VK_STRUCTURE_TYPE_ ## type #define INIT_FN(name) do { \ name = (PFN_##name)vkGetInstanceProcAddr(NULL, MakeString(name)); \ if (!name) return false; \ } while (0) #define INIT_INST_FN(name) do { \ name = (PFN_##name)vkGetInstanceProcAddr(instance, MakeString(name)); \ if (!name) return false; \ } while (0) #define INIT_DEV_FN(name) do { \ name = (PFN_##name)vkGetDeviceProcAddr(device, MakeString(name)); \ if (!name) return false; \ } while (0) // ::Vulkan::GlobalFunctions::Header:: VK_DECLARE(vkGetInstanceProcAddr); VK_DECLARE(vkCreateInstance); VK_DECLARE(vkEnumerateInstanceLayerProperties); // ::Vulkan::InstanceFunctions::Header:: VK_DECLARE(vkEnumeratePhysicalDevices); VK_DECLARE(vkCreateDevice); VK_DECLARE(vkGetPhysicalDeviceQueueFamilyProperties); VK_DECLARE(vkGetPhysicalDeviceSurfaceSupportKHR); VK_DECLARE(vkGetPhysicalDeviceProperties); VK_DECLARE(vkGetPhysicalDeviceFeatures2); VK_DECLARE(vkEnumerateDeviceExtensionProperties); VK_DECLARE(vkGetPhysicalDeviceSurfacePresentModesKHR); VK_DECLARE(vkGetPhysicalDeviceSurfaceFormatsKHR); VK_DECLARE(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); VK_DECLARE(vkGetPhysicalDeviceImageFormatProperties); // ::Vulkan::PlatformFunctions::Header:: #ifdef __linux__ VK_DECLARE(vkCreateXcbSurfaceKHR); #elif _WIN32 VK_DECLARE(vkCreateWin32SurfaceKHR); #elif __APPLE__ || __MACH__ #error Not yet implemented #elif __unix__ && !__linux__ #error Not yet implemented #endif #ifdef BUILD_DEBUG VK_DECLARE(vkCreateDebugUtilsMessengerEXT); VK_DECLARE(vkDestroyDebugUtilsMessengerEXT); #endif // ::Vulkan::DeviceFunctions::Header:: VK_DECLARE(vkGetDeviceProcAddr); VK_DECLARE(vkCreateSwapchainKHR); VK_DECLARE(vkCreateImage); VK_DECLARE(vkCreateImageView); VK_DECLARE(vkGetSwapchainImagesKHR); VK_DECLARE(vkGetDeviceQueue); VK_DECLARE(vkCreateSemaphore); VK_DECLARE(vkAllocateCommandBuffers); VK_DECLARE(vkCreateCommandPool); VK_DECLARE(vkCreateFence); VK_DECLARE(vkCreateDescriptorPool); VK_DECLARE(vkCreateDescriptorSetLayout); VK_DECLARE(vkAllocateDescriptorSets); VK_DECLARE(vkCreatePipelineLayout); VK_DECLARE(vkResetDescriptorPool); VK_DECLARE(vkCreateShaderModule); VK_DECLARE(vkCreateGraphicsPipelines); VK_DECLARE(vkCreateComputePipelines); VK_DECLARE(vkUpdateDescriptorSets); VK_DECLARE(vkDestroyDevice); VK_DECLARE(vkDestroyInstance); VK_DECLARE(vkDestroySurfaceKHR); VK_DECLARE(vkDestroyDescriptorPool); VK_DECLARE(vkDestroySwapchainKHR); VK_DECLARE(vkDestroyImage); VK_DECLARE(vkDestroyImageView); VK_DECLARE(vkDestroyCommandPool); VK_DECLARE(vkDestroySemaphore); VK_DECLARE(vkDestroyFence); VK_DECLARE(vkDestroyPipelineLayout); VK_DECLARE(vkDestroyPipeline); VK_DECLARE(vkWaitForFences); VK_DECLARE(vkBeginCommandBuffer); VK_DECLARE(vkEndCommandBuffer); VK_DECLARE(vkAcquireNextImageKHR); VK_DECLARE(vkCmdBindPipeline); VK_DECLARE(vkCmdBindDescriptorSets); VK_DECLARE(vkCmdDispatch); VK_DECLARE(vkCmdBeginRendering); VK_DECLARE(vkCmdEndRendering); VK_DECLARE(vkCmdSetViewport); VK_DECLARE(vkCmdSetScissor); VK_DECLARE(vkCmdPushConstants); VK_DECLARE(vkCmdBindIndexBuffer); VK_DECLARE(vkCmdBindVertexBuffers); VK_DECLARE(vkCmdDrawIndexed); VK_DECLARE(vkCmdBlitImage2); VK_DECLARE(vkCmdPipelineBarrier2); VK_DECLARE(vkCmdCopyBufferToImage); VK_DECLARE(vkCmdCopyBuffer); VK_DECLARE(vkQueueSubmit2); VK_DECLARE(vkResetFences); VK_DECLARE(vkResetCommandBuffer); VK_DECLARE(vkFreeCommandBuffers); VK_DECLARE(vkDestroyDescriptorSetLayout); VK_DECLARE(vkDestroyShaderModule); VK_DECLARE(vkQueuePresentKHR); VK_DECLARE(vkCmdDraw); VK_DECLARE(vkDeviceWaitIdle); VK_DECLARE(vkCmdClearColorImage); VK_DECLARE(vkCreateSampler); VK_DECLARE(vkDestroySampler); #include "vma/vk_mem_alloc.h" // ::Vulkan::Defines::Header:: #define FRAME_OVERLAP 2 #define DESC_MAX_BINDINGS 256 #define BUFFER_QUEUE_LEN 32 #define HOST_VISIBLE_BUFFERS (rRBT_UNIFORM | rRBT_STAGING) // ::Vulkan::Types::Header:: typedef enum DescType_e { vDT_SHARED, vDT_SAMPLED_IMAGE, // DO NOT MOVE FROM POSITION 1 !! vDT_MATERIAL, vDT_MAX, } vDescType; typedef struct rDescHandle { u32 asset_id; u32 desc_index; } rDescHandle; typedef struct vAssetInfo { rDescHandle handle; vDescType type; union { u64 asset_id; TextureAsset texture_id; }; } vAssetInfo; typedef struct vDeviceQueues { i32 graphics, transfer; VkQueue graphics_queue, transfer_queue; b8 single_queue; } vDeviceQueues; typedef struct vDescBindings { u32 *free; u32 free_count; HashTable lookup_table; } vDescBindings; typedef struct vImage { VkImage image; VmaAllocation alloc; VkFormat format; VkImageLayout layout; } vImage; typedef struct vImageView { vImage image; VkImageView view; } vImageView; PtrArrayType(vImageView); ArrayType(vImageView); typedef struct vSampler { vImage image; VkImageView view; VkSampler sampler; } vSampler; typedef struct vBufferAlloc { VkBuffer buffer; VmaAllocation alloc; } vBufferAlloc; PtrArrayType(vBufferAlloc); ArrayType(vBufferAlloc); typedef struct vSwapchainState { VkFormat format; VkColorSpaceKHR color_space; VkPresentModeKHR present_mode; VkExtent3D extent; } vSwapchainState; typedef struct vVkState { u32 gfx_queue_idx; u32 tfer_queue_idx; u32 image_idx; b8 single_queue; } vVkState; typedef struct vRendererState { u64 frame_count; rPipelineHandle pipeline; u32 width; u32 height; } vRendererState; typedef struct vState { vSwapchainState swapchain; vRendererState renderer; vVkState vk; } vState; typedef struct vImmHandles { VkCommandPool pool; VkCommandBuffer buffer; VkFence fence; } vImmHandles; ArrayType(vImmHandles); typedef struct vFrameHandles { VkCommandPool pool; VkCommandBuffer buffer; VkSemaphore sc_sem; VkSemaphore r_sem; VkFence r_fence; } vFrameHandles; typedef struct vAsync { u32 thread_idx[V_THREAD_MAX]; #ifdef __linux__ pthread_t threads[V_THREAD_MAX]; pthread_cond_t cond; #elif _WIN32 # error not yet implemented #endif u8 count; u8 sleeping; } vAsync; typedef struct vRHandles { pLibrary lib; VkInstance inst; VkPhysicalDevice phys_device; VkDevice device; VkSurfaceKHR surface; VkSwapchainKHR swapchain; VmaAllocator vma_alloc; VkDescriptorPool desc_pool; VkPipeline pipelines[R_PIPELINE_MAX]; VkPipelineLayout pipeline_layout; VkDescriptorSetLayout desc_layouts[vDT_MAX]; VkDescriptorSet desc_sets[vDT_MAX]; VkQueue gfx_queue; VkQueue tfer_queue; VkSampler nearest_sampler; #ifdef BUILD_DEBUG VkDebugUtilsMessengerEXT debug; #endif } vRHandles; typedef struct vMemory { Arena *perm_arena; Arena *frame_arenas[FRAME_OVERLAP]; } vMemory; typedef struct vRImages { vImageView draw; vImageView depth; vImageViewArray sc; } vRImages; typedef struct vMappedBuffer { vBufferAlloc alloc; rawptr ptr; u64 cap; } vMappedBuffer; typedef struct vRBuffers { HashTable buffers; vBufferAllocPtrArray frame_buffers[FRAME_OVERLAP]; HashTable images; vImageViewPtrArray frame_images[FRAME_OVERLAP]; vMappedBuffer transfer; vMappedBuffer gui_vert; vMappedBuffer gui_idx; } vRBuffers; typedef enum vTransferType : u32 { vTT_NONE, vTT_BUFFER, vTT_IMAGE, } vTransferType; typedef struct vTransfer { vTransferType type; rawptr data; u32 asset_id; union { u64 size; struct { u32 w; u32 h; u8 ch; }; }; union { VkBuffer buffer; VkImage image; }; union { VkBufferCopy buffer_copy; VkBufferImageCopy image_copy; }; } vTransfer; typedef struct vUploadQueue { vTransfer **transfers; TicketMut mut; JobQueue job_queue; } vUploadQueue; typedef struct vRenderer { vRHandles handles; vFrameHandles frame_handles[FRAME_OVERLAP]; vState state; vRBuffers buffers; vImmHandlesArray imm_handles; vDescBindings desc_bindings[vDT_MAX]; vAsync async; vMemory mem; vRImages images; vUploadQueue upload; } vRenderer; // ::Vulkan::FrontEndTypes::Header:: typedef struct rShaderGlobals { Vec2 res; } rShaderGlobals; typedef struct rTextureBuffer { rTextureBufferType type; vImage image; u32 width; u32 height; u32 channels; u32 index; } rTextureBuffer; typedef struct rRenderBuffer { rRenderBufferType type; VkBuffer buffer; VmaAllocation alloc; VmaAllocationInfo info; u32 size; u32 index; // TODO(MA): use this } rRenderBuffer; typedef struct rPushConst { Vec2 res; f32 time; } rPushConst; typedef struct rGlobalUniforms { f32 res[2]; } rGlobalUniforms; // ::Vulkan::Debug::Functions::Header:: static b32 vValidationSupported(); static VKAPI_ATTR VkBool32 vDebugCallback( VkDebugUtilsMessageSeverityFlagBitsEXT message_severity, VkDebugUtilsMessageTypeFlagsEXT message_types, const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData ); const char *vVkResultStr(VkResult result); // ::Vulkan::Init::Functions::Header:: static b32 vInitInstance(); static void vEnableDebug(); static void vArenasInit(); static b32 vLibraryLoad(); static b32 vInstanceFunctionsInit(); static b32 vGlobalFunctionsInit(); static b32 vDeviceFunctionsInit(); static b32 vSurfaceInit(); static b32 vDeviceInit(); static b32 vQueueCheckSurfaceSupport(i32 index, VkPhysicalDevice device, VkSurfaceKHR surface); static vDeviceQueues vQueueCheckSupport(VkPhysicalDevice device, VkSurfaceKHR surface); static b32 vDeviceCheckPropertiesSupport(VkPhysicalDevice device, VkSurfaceKHR surface, b32 *discrete); static b32 vDeviceCheckFeatureSupport(VkPhysicalDevice device); static b32 vVmaAllocatorInit(); static b32 vFrameStructuresInit(); static b32 vImmediateStructuresInit(); static b32 vSwapchainInit(); static b32 vDrawImagesInit(); static VkFormat vImageFormatGet(); static b32 vDescriptorsInit(); static b32 vPipelinesInit(); static b32 vShaderModuleInit(u8 *bytes, u32 len, VkShaderModule *module); static void vUploadQueuesInit(); static void vLoaderStartThreads(); static b32 vBuffersInit(); static b32 vRenderDocInit(); // ::Vulkan::Util::Functions::Header:: static inline VkCommandBuffer vFrameCmdBuf(); static inline VkFence vFrameRenderFence(); static inline VkImage vFrameImage(); static inline Arena *vFrameArena(); static inline VkSemaphore vFrameRenderSem(); static inline VkSemaphore vFrameSwapSem(); static inline u32 vFrameIndex(); static inline VkImage vFrameSwapImage(); static inline vBufferAllocPtrArray *vFrameBuffers(); static inline void vImageTransition(VkCommandBuffer cmd, vImage *img, VkImageLayout new); static inline void vImageTransitionLayout(VkCommandBuffer cmd, VkImage img, VkImageLayout curr, VkImageLayout new); static inline void vImageCopyToImage(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent2D dst_ext); // ::Vulkan::Async::Functions::Header:: static void vBufferQueueWait(); static void vLoaderWake(); static u32 vLoaderProcessBuffers(u32 thread_index); static u32 vLoaderProcessSamplers(u32 thread_index); #ifdef __linux__ void *vLoaderStart(void *thread_data); #elif _WIN32 # error not yet implemented #endif // ::Vulkan::ImmediateSubmit::Functions::Header:: static b32 vImmSubmitBegin(VkDevice device, VkFence fence, VkCommandBuffer cmd); static b32 vImmSubmitFinish(VkDevice device, VkFence fence, VkCommandBuffer cmd, VkQueue queue); // ::Vulkan::Rendering::Functions::Header:: static void vRenderingBegin(); // ::Vulkan::Swapchain::Functions::Header:: static void vSwapchainResize(); // ::Vulkan::Images::Functions::Header:: static b32 vImageViewCreate(vImageView *view, u32 width, u32 height, u32 channels); static b32 vSamplerCreate(rTextureBuffer *buffer); static void vImageUpload(rTextureBuffer *buffer, u8 *data, u32 thread_idx); static vImageView *vImageLookupExisting(TextureAsset asset_id); // ::Vulkan::Descriptors::Functions::Header:: static void vDescIndexPush(vDescType type, u32 index); static u32 vDescIndexPop(vDescType type); static rDescHandle vDescHandleSearch(vDescType type, u32 asset_id); static void vDescHandleInsert(vDescType type, rDescHandle handle); static void vDescHandleDelete(vDescType type, u32 asset_id); static u32 vDescPushImage(vImageView *view); // ::Vulkan::Buffers::Functions::Header:: static VkResult vBufferCreate(vBufferAlloc* buf, rRenderBufferType type, u64 size); static rawptr vMapBuffer(VmaAllocation alloc); // ::Vulkan::CleanUp::Functions::Header:: static void vSwapchainDestroy(); static void vDrawImagesDestroy(); // ::Vulkan::Logging::Functions::Header:: static void vInfo(const char *str); static void vWarn(const char *str); static void vError(const char *str); #include "vulkan_config.c"