325 lines
7.4 KiB
C
325 lines
7.4 KiB
C
#pragma once
|
|
|
|
#define VK_USE_PLATFORM_XCB_KHR
|
|
#define VK_NO_PROTOTYPES
|
|
|
|
#include <vulkan/vulkan.h>
|
|
|
|
#include "file_data/spv.c"
|
|
|
|
// Macros
|
|
|
|
#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)
|
|
|
|
#define FRAME_OVERLAP 2
|
|
#define DESC_MAX_BINDINGS 256
|
|
|
|
// Macros END
|
|
|
|
// Vulkan Functions
|
|
|
|
// Global
|
|
VK_DECLARE(vkGetInstanceProcAddr);
|
|
VK_DECLARE(vkCreateInstance);
|
|
VK_DECLARE(vkEnumerateInstanceLayerProperties);
|
|
|
|
// Instance
|
|
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);
|
|
|
|
#ifdef __linux__
|
|
VK_DECLARE(vkCreateXcbSurfaceKHR);
|
|
#endif
|
|
|
|
#ifdef BUILD_DEBUG
|
|
VK_DECLARE(vkCreateDebugUtilsMessengerEXT);
|
|
VK_DECLARE(vkDestroyDebugUtilsMessengerEXT);
|
|
#endif
|
|
|
|
// Device
|
|
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(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);
|
|
|
|
// Vulkan Functions END
|
|
|
|
#include "vma/vk_mem_alloc.h"
|
|
|
|
// Types
|
|
|
|
typedef enum Pipeline_e
|
|
{
|
|
PIPELINE_CUBE,
|
|
|
|
PIPELINE_MAX,
|
|
} PipelineHandle;
|
|
|
|
typedef enum DescType_e
|
|
{
|
|
DESC_TYPE_SHARED,
|
|
DESC_TYPE_COMBINED_SAMPLER,
|
|
DESC_TYPE_STORAGE_IMAGE,
|
|
DESC_TYPE_UNIFORM,
|
|
|
|
DESC_TYPE_MAX,
|
|
} DescType;
|
|
|
|
typedef struct
|
|
{
|
|
u16 *free;
|
|
u16 *used;
|
|
} DescBindings;
|
|
|
|
typedef struct
|
|
{
|
|
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
|
|
{
|
|
Mat4 view_matrix;
|
|
VkDeviceAddress vertex_buf;
|
|
u32 img_ix;
|
|
u32 samp_ix;
|
|
u32 storage_ix;
|
|
} PushConst;
|
|
|
|
typedef struct
|
|
{
|
|
VkCommandPool pools[FRAME_OVERLAP];
|
|
VkCommandBuffer buffers[FRAME_OVERLAP];
|
|
VkSemaphore swapchain_sems[FRAME_OVERLAP];
|
|
VkSemaphore render_sems[FRAME_OVERLAP];
|
|
VkFence render_fences[FRAME_OVERLAP];
|
|
} FrameStructures;
|
|
|
|
typedef struct
|
|
{
|
|
VkCommandPool pool;
|
|
VkCommandBuffer buffer;
|
|
VkFence fence;
|
|
} ImmediateStructures;
|
|
|
|
typedef struct {
|
|
i32 graphics, transfer;
|
|
VkQueue graphics_queue, transfer_queue;
|
|
} DeviceQueues;
|
|
|
|
typedef struct {
|
|
VkImage img;
|
|
VkImageView view;
|
|
VmaAllocation alloc;
|
|
VkFormat fmt;
|
|
} Image;
|
|
|
|
typedef struct {
|
|
VkFormat format;
|
|
VkColorSpaceKHR color_space;
|
|
VkExtent3D extent;
|
|
VkImage *imgs;
|
|
VkImageView *views;
|
|
u32 img_count;
|
|
Image draw_img;
|
|
Image depth_img;
|
|
} SwapchainStructures;
|
|
|
|
typedef struct {
|
|
u32 img_ix;
|
|
u64 frame_cnt;
|
|
} FrameState;
|
|
|
|
typedef struct {
|
|
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_t;
|
|
|
|
typedef struct {
|
|
Vulkan_t vk;
|
|
FrameState frame_state;
|
|
Arena *arena;
|
|
Arena *perm_arena;
|
|
} Renderer_t;
|
|
|
|
// Renderer Function Declarations
|
|
|
|
// Debug
|
|
static b32 VLayersSupported();
|
|
static VkBool32 DebugCallback(
|
|
VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
|
|
VkDebugUtilsMessageTypeFlagsEXT message_types,
|
|
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData,
|
|
void *pUserData
|
|
);
|
|
const char *VkResultStr(VkResult result);
|
|
|
|
// Init
|
|
static b32 LoadVulkanLib();
|
|
static b32 InitVulkan(Arena *arena);
|
|
static b32 InitVkInstanceFunctions();
|
|
static b32 InitVkGlobalFunctions();
|
|
static b32 CreateSurface();
|
|
static b32 CreateDevice();
|
|
static b32 CheckQueueSurfaceSupport();
|
|
static DeviceQueues CheckDeviceQueueSupport();
|
|
static b32 CheckDevicePropertiesSupport();
|
|
static b32 CheckDeviceFeatureSupport();
|
|
static b32 InitVkDeviceFunctions();
|
|
static b32 CreateVmaAllocator();
|
|
static b32 CreateFrameStructures();
|
|
static b32 CreateImmediateStructures();
|
|
static b32 CreateSwapchain();
|
|
static VkFormat GetImageFormat();
|
|
static b32 CreateDescriptors();
|
|
static b32 CreatePipelines();
|
|
static b32 CreateShaderModule(u8 *bytes, u32 len, VkShaderModule *module);
|
|
|
|
// Destroy
|
|
static void DestroyVulkan();
|
|
|
|
// Util
|
|
static void TransitionImage(VkCommandBuffer cmd, VkImage img, VkImageLayout curr, VkImageLayout new);
|
|
static void CopyImageToImage(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent2D dst_ext);
|
|
|
|
// Renderer Functions Declarations END
|
|
|
|
#include "vulkan_config.c"
|
|
|
|
static Renderer_t renderer = {
|
|
.vk = {
|
|
.queues = {
|
|
.graphics = -1,
|
|
.transfer = -1,
|
|
}
|
|
}
|
|
};
|
|
|
|
static const char *_VK_VALIDATION = "VK_LAYER_KHRONOS_validation";
|
|
|
|
#if __linux__
|
|
static char *vulkan_libs[] = {
|
|
"libvulkan.so.1",
|
|
"libvulkan.so"
|
|
};
|
|
#endif
|
|
|
|
#if _WIN32
|
|
#error Not yet implemented
|
|
#endif
|
|
|
|
#if __APPLE__ || __MACH__
|
|
#error Not yet implemented
|
|
#endif
|
|
|
|
#if __unix__ && !__linux__
|
|
#error Not yet implemented
|
|
#endif
|
|
|
|
|
|
// BACKEND API
|
|
|
|
// Init
|
|
b32 _InitRenderer(Arena *arena);
|
|
void _DestroyRenderer();
|
|
|
|
// Rendering
|
|
static b32 _BeginFrame();
|
|
static void _DrawTriangle();
|
|
static b32 _FinishFrame();
|