Gears-C/src/renderer_vulkan.h

599 lines
14 KiB
C++

#pragma once
#if __linux__
# define VK_USE_PLATFORM_XCB_KHR
#elif _WIN32
# define VK_USE_PLATFORM_WIN32_KHR
#endif
#define VK_NO_PROTOTYPES
#include <vulkan/vulkan.h>
#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
constexpr u64 VERTEX_BUFFER_CAP = MB(32);
constexpr u64 INDEX_BUFFER_CAP = MB(8);
constexpr u64 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);
#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);
VK_DECLARE(vkGetBufferDeviceAddress);
#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_MESH,
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);
PtrArrayType(b8);
typedef struct vMesh
{
VkDeviceAddress vertices;
} vMesh;
typedef struct vSampler
{
vImage image;
VkImageView view;
VkSampler sampler;
} vSampler;
typedef struct vBuffer
{
VkBuffer buffer;
VmaAllocation alloc;
} vBuffer;
PtrArrayType(vBuffer);
ArrayType(vBuffer);
typedef struct vMeshBuffer
{
vBuffer mesh, uniform;
} vMeshBuffer;
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;
b32 sleeping;
pThread thread;
} 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[rPIPELINE_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
{
vBuffer alloc;
rawptr ptr;
u64 cap;
} vMappedBuffer;
typedef struct vRBuffers
{
HashTable buffers;
vBufferPtrArray frame_buffers[FRAME_OVERLAP];
HashTable images;
vImageViewPtrArray frame_images[FRAME_OVERLAP];
b8PtrArray tex_destroy_queue;
vMappedBuffer transfer;
vMappedBuffer gui_vert;
vMappedBuffer gui_idx;
} vRBuffers;
typedef struct vModelBuffers
{
vMeshBuffer *mesh;
vBuffer *index;
} vModelBuffers;
typedef enum vTransferType : u32
{
vTT_NONE,
vTT_BUFFER,
vTT_MESH,
vTT_IMAGE,
} vTransferType;
typedef struct vTransfer
{
vTransferType type;
rawptr data;
u32 asset_id;
union
{
u64 size;
struct
{
u32 w;
u32 h;
u8 ch;
};
};
union
{
vMeshBuffer *mesh;
VkBuffer buffer;
VkImage image;
};
} 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;
vImmHandles imm;
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;
u32 mesh_index;
} 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 b8 *vFrameTexDestroyQueue();
static inline b8 *vFrameNextTexDestroyQueue();
static inline vBufferPtrArray *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 void vLoader();
#ifdef __linux__
void *vLoaderStart(void *thread_data);
#elif _WIN32
DWORD WINAPI vLoaderStart(LPVOID thread_data);
#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 vTransfer *vTextureTransferInit(Arena *arena, u32 asset_id, VkImage image, rawptr bytes, TexMeta *meta);
static vImageView *vImageViewCreate(TexMeta meta);
static b32 vImageViewInit(vImageView *view, u32 width, u32 height, u32 channels);
static void vTextureCleanUp();
static void vImagePush(TextureAsset asset_id, vImageView *view);
static vImageView *vImagePop(TextureAsset asset_id);
static vImageView *vImageSearch(TextureAsset asset_id);
// ::Vulkan::Descriptors::Functions::Header::
static void vDescPushImageAndHandle(rDescHandle handle, vImageView *view);
static void vDescPushModelAndHandle(rDescHandle handle, vModelBuffers *buffer);
static void vDescIndexPush(vDescType type, u32 index);
static u32 vDescIndexPop(vDescType type);
static rDescHandle vDescHandleSearch(vDescType type, u32 asset_id);
static void vDescHandlePush(vDescType type, rDescHandle handle);
static rDescHandle vDescHandlePop(vDescType type, u32 asset_id);
static void vDescHandleDelete(vDescType type, u32 asset_id);
static u32 vDescPushImageDesc(vImageView *view);
static u32 vDescPushMeshDesc(vMeshBuffer *buffer);
// ::Vulkan::Buffers::Functions::Header::
static vTransfer *vMeshTransferInit(Arena *arena, u32 asset_id, vMeshBuffer *mesh, rawptr bytes, u64 size);
static vTransfer *vBufferTransferInit(Arena *arena, u32 asset_id, vBuffer *index, rawptr bytes, u64 size);
static VkResult vBufferCreate(vBuffer* buf, rRenderBufferType type, u64 size);
static rawptr vMapBuffer(VmaAllocation alloc);
static void vModelPush(c8 *name, vModelBuffers *buffer);
static vModelBuffers *vModelPop(c8 *name);
static vModelBuffers *vModelSearch(c8 *name);
// ::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"