476 lines
12 KiB
C
476 lines
12 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>
|
|
|
|
#include "file_data/spv.c"
|
|
|
|
// ::Vulkan::Constants::Header::
|
|
|
|
static const char *_VK_VALIDATION = "VK_LAYER_KHRONOS_validation";
|
|
|
|
#if __linux__
|
|
static char *vulkan_libs[] = {
|
|
"libvulkan.so.1",
|
|
"libvulkan.so"
|
|
};
|
|
#endif
|
|
|
|
#if _WIN32
|
|
static char *vulkan_libs[] = {
|
|
"vulkan-1.dll",
|
|
};
|
|
#endif
|
|
|
|
#if __unix__ && !__linux__
|
|
#error Not yet implemented
|
|
#endif
|
|
|
|
// ::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);
|
|
|
|
#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 (RENDER_BUFFER_TYPE_UNIFORM | RENDER_BUFFER_TYPE_STAGING)
|
|
|
|
// ::Vulkan::Types::Header::
|
|
|
|
typedef enum DescType_e
|
|
{
|
|
DESC_TYPE_SHARED,
|
|
DESC_TYPE_SAMPLER, // DO NOT MOVE FROM POSITION 1 !!
|
|
DESC_TYPE_STORAGE_IMAGE,
|
|
DESC_TYPE_UNIFORM,
|
|
DESC_TYPE_BUFFER,
|
|
|
|
DESC_TYPE_MAX,
|
|
} DescType;
|
|
|
|
typedef struct ShaderGlobals
|
|
{
|
|
Vec2 res;
|
|
} ShaderGlobals;
|
|
|
|
typedef struct Image
|
|
{
|
|
VkImage img;
|
|
VkImageView view;
|
|
VkSampler sampler;
|
|
VmaAllocation alloc;
|
|
VkFormat fmt;
|
|
VkImageLayout curr_layout;
|
|
} Image;
|
|
|
|
typedef struct TextureBuffer
|
|
{
|
|
TextureBufferType type;
|
|
Image image;
|
|
u32 width;
|
|
u32 height;
|
|
u32 channels;
|
|
u32 index;
|
|
} TextureBuffer;
|
|
|
|
typedef struct RenderBuffer
|
|
{
|
|
RenderBufferType type;
|
|
VkBuffer buffer;
|
|
VmaAllocation alloc;
|
|
VmaAllocationInfo info;
|
|
u32 size;
|
|
u32 index; // TODO(MA): use this
|
|
} RenderBuffer;
|
|
|
|
typedef struct MeshBuffer
|
|
{
|
|
RenderBuffer index_buf, vertex_buf;
|
|
u32 index_count;
|
|
} MeshBuffer;
|
|
|
|
typedef struct GlobalUniforms
|
|
{
|
|
f32 res[2];
|
|
} GlobalUniforms;
|
|
|
|
typedef struct DescAssetInfo
|
|
{
|
|
DescHandle handle;
|
|
DescType type;
|
|
union
|
|
{
|
|
u64 asset_id;
|
|
TextureAsset texture_id;
|
|
};
|
|
} DescAssetInfo;
|
|
|
|
typedef struct DescBindings
|
|
{
|
|
u16 *free;
|
|
u16 free_count;
|
|
u16 *used;
|
|
u16 used_count;
|
|
HashTable lookup_table;
|
|
} DescBindings;
|
|
|
|
typedef struct PipelineStructures
|
|
{
|
|
VkPipelineLayout pipeline_layout;
|
|
VkDescriptorPool pool;
|
|
VkDescriptorSetLayout layouts[DESC_TYPE_MAX];
|
|
VkDescriptorSet sets[DESC_TYPE_MAX];
|
|
DescBindings *bindings;
|
|
u16 bindings_count;
|
|
VkPipeline pipelines[PIPELINE_MAX];
|
|
} PipelineStructures;
|
|
|
|
typedef struct PushConst
|
|
{
|
|
Vec2 res;
|
|
Vec2 img_res;
|
|
} PushConst;
|
|
|
|
typedef struct FrameStructures
|
|
{
|
|
VkCommandPool *pools;
|
|
VkCommandBuffer *buffers;
|
|
VkSemaphore *swapchain_sems;
|
|
VkSemaphore *render_sems;
|
|
VkFence *render_fences;
|
|
RenderBuffer **buffer_destroy_queues;
|
|
u32 *buffer_counts;
|
|
} FrameStructures;
|
|
|
|
typedef struct UploadQueue
|
|
{
|
|
union
|
|
{
|
|
RenderBuffer **queued_buffers;
|
|
TextureBuffer **queued_textures;
|
|
rawptr *queued_ptrs;
|
|
};
|
|
rawptr *data;
|
|
TicketMut ticket_mut;
|
|
Mut mut;
|
|
JobQueue job_queue;
|
|
} UploadQueue;
|
|
|
|
typedef struct ImmediateStructures
|
|
{
|
|
VkCommandPool *pools;
|
|
VkCommandBuffer *cmds;
|
|
VkFence *fences;
|
|
JobQueue buffer_queue;
|
|
JobQueue texture_queue;
|
|
} ImmediateStructures;
|
|
|
|
typedef struct DeviceQueues
|
|
{
|
|
i32 graphics, transfer;
|
|
VkQueue graphics_queue, transfer_queue;
|
|
b8 single_queue;
|
|
} DeviceQueues;
|
|
|
|
typedef struct SwapchainStructures
|
|
{
|
|
VkFormat format;
|
|
VkColorSpaceKHR color_space;
|
|
VkPresentModeKHR present_mode;
|
|
VkExtent3D extent;
|
|
VkImage *imgs;
|
|
VkImageView *views;
|
|
u32 img_count;
|
|
Image draw_img;
|
|
Image depth_img;
|
|
} SwapchainStructures;
|
|
|
|
typedef struct FrameState
|
|
{
|
|
u32 img_ix;
|
|
u64 frame_cnt;
|
|
u64 prev_frame;
|
|
b8 begin_rendering;
|
|
PipelineHandle last_pipeline;
|
|
RenderBuffer *prev_buffers;
|
|
u32 prev_buffer_count;
|
|
} FrameState;
|
|
|
|
typedef struct Vulkan
|
|
{
|
|
Library lib;
|
|
VkInstance inst;
|
|
VkSurfaceKHR surface;
|
|
VkDevice device;
|
|
VkSwapchainKHR swapchain;
|
|
VkPhysicalDevice phys_device;
|
|
DeviceQueues queues;
|
|
VmaAllocator alloc;
|
|
FrameStructures frame;
|
|
ImmediateStructures imm;
|
|
SwapchainStructures sc;
|
|
PipelineStructures pipe;
|
|
#ifdef BUILD_DEBUG
|
|
VkDebugUtilsMessengerEXT debug;
|
|
#endif
|
|
} Vulkan;
|
|
|
|
typedef struct PendingUpdates
|
|
{
|
|
u16 render_width;
|
|
u16 render_height;
|
|
b8 resized;
|
|
} PendingUpdates;
|
|
|
|
typedef struct VulkanConfig
|
|
{
|
|
u8 avail_threads;
|
|
#ifdef __linux__
|
|
pthread_t *threads;
|
|
#elif _WIN32
|
|
#error not yet implemented
|
|
#endif
|
|
} VulkanConfig;
|
|
|
|
typedef struct Renderer
|
|
{
|
|
Vulkan vk;
|
|
VulkanConfig vk_conf;
|
|
FrameState frame_state;
|
|
PendingUpdates pending;
|
|
Arena *arena;
|
|
Arena *perm_arena;
|
|
UploadQueue upload_queues[DESC_TYPE_MAX];
|
|
} Renderer;
|
|
|
|
// ::Vulkan::Debug::Functions::Header::
|
|
|
|
static b32 VLayersSupported();
|
|
static VKAPI_ATTR VkBool32 DebugCallback(
|
|
VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
|
|
VkDebugUtilsMessageTypeFlagsEXT message_types,
|
|
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData,
|
|
void *pUserData
|
|
);
|
|
const char *VkResultStr(VkResult result);
|
|
|
|
// ::Vulkan::Init::Functions::Header::
|
|
|
|
static b32 LoadVulkanLib();
|
|
static b32 InitVkInstanceFunctions();
|
|
static b32 InitVkGlobalFunctions();
|
|
static b32 CreateSurface();
|
|
static b32 CreateDevice();
|
|
static b32 CheckQueueSurfaceSupport(i32 index, VkPhysicalDevice device, VkSurfaceKHR surface);
|
|
static DeviceQueues CheckDeviceQueueSupport(VkPhysicalDevice device, VkSurfaceKHR surface);
|
|
static b32 CheckDevicePropertiesSupport(VkPhysicalDevice device, VkSurfaceKHR surface, b32 *discrete);
|
|
static b32 CheckDeviceFeatureSupport(VkPhysicalDevice device);
|
|
static b32 InitVkDeviceFunctions();
|
|
static b32 CreateVmaAllocator();
|
|
static b32 CreateFrameStructures();
|
|
static b32 CreateImmediateStructures();
|
|
static b32 CreateSwapchain();
|
|
static b32 CreateDrawImages();
|
|
static VkFormat GetImageFormat();
|
|
static b32 CreateDescriptors();
|
|
static b32 CreatePipelines();
|
|
static b32 CreateShaderModule(u8 *bytes, u32 len, VkShaderModule *module);
|
|
static void CreateUploadQueues();
|
|
static void StartVkLoaderThreads();
|
|
|
|
// ::Vulkan::Util::Functions::Header::
|
|
|
|
static inline VkCommandBuffer GetFrameCmdBuf();
|
|
static inline VkFence *GetFrameRenderFence();
|
|
static inline VkSemaphore GetFrameRenderSem();
|
|
static inline VkSemaphore GetFrameSwapSem();
|
|
static inline u32 GetFrameIndex();
|
|
static inline VkImage GetFrameSwapImage();
|
|
static inline u32 *GetFrameBufferCount();
|
|
static inline RenderBuffer *GetFrameRenderBuffers();
|
|
static inline void TransitionImage(VkCommandBuffer cmd, Image *img, VkImageLayout new);
|
|
static inline void TransitionImageLayout(VkCommandBuffer cmd, VkImage img, VkImageLayout curr, VkImageLayout new);
|
|
static inline void CopyImageToImage(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent2D dst_ext);
|
|
|
|
// ::Vulkan::Async::Functions::Header::
|
|
|
|
#ifdef __linux__
|
|
void *VkLoaderStart(void *thread_data);
|
|
#elif _WIN32
|
|
# error not yet implemented
|
|
#endif
|
|
|
|
void VkLoaderWake();
|
|
static u32 VkLoaderProcessBuffers(u32 thread_index);
|
|
static u32 VkLoaderProcessSamplers(u32 thread_index);
|
|
|
|
// ::Vulkan::ImmediateSubmit::Functions::Header::
|
|
|
|
static b32 BeginImmSubmit(VkDevice device, VkFence fence, VkCommandBuffer cmd);
|
|
static b32 FinishImmSubmit(VkDevice device, VkFence fence, VkCommandBuffer cmd, VkQueue queue);
|
|
|
|
// ::Vulkan::Rendering::Functions::Header::
|
|
|
|
static void BeginRendering();
|
|
|
|
// ::Vulkan::Swapchain::Functions::Header::
|
|
|
|
static void ResizeSwapchain();
|
|
|
|
// ::Vulkan::Images::Functions::Header::
|
|
|
|
static b32 CreateVkSampler(TextureBuffer *buffer);
|
|
static void UploadToImage(TextureBuffer *buffer, u8 *data, u32 thread_idx);
|
|
|
|
// ::Vulkan::Descriptors::Functions::Header::
|
|
|
|
static DescAssetInfo *DescriptorTableSearch(DescType type, u64 asset_id);
|
|
|
|
// ::Vulkan::CleanUp::Functions::Header::
|
|
|
|
static void DestroySwapchain();
|
|
static void DestroyDrawImages();
|
|
|
|
// ::Vulkan::Logging::Functions::Header::
|
|
|
|
static void VkInfo(const char *str);
|
|
static void VkWarn(const char *str);
|
|
static void VkError(const char *str);
|
|
|
|
#include "vulkan_config.c"
|
|
|
|
|