Gears-C/src/render_vulkan.h

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();