582 lines
13 KiB
C
582 lines
13 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
|
|
|
|
#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"
|
|
|
|
|