big refactor before rewriting buffer handling

This commit is contained in:
Matthew 2025-04-28 22:34:07 +10:00
parent 57db8afb6d
commit abcfb7774c
9 changed files with 749 additions and 493 deletions

View File

@ -51,7 +51,6 @@ int main(int argc, char **argv)
#endif #endif
Arena *arena = ArenaCreateDebug(MB(32), __LINE__); Arena *arena = ArenaCreateDebug(MB(32), __LINE__);
Arena *renderer_arena = ArenaCreateDebug(MB(16), __LINE__);
Arena *game_arena = ArenaCreateDebug(MB(16), __LINE__); Arena *game_arena = ArenaCreateDebug(MB(16), __LINE__);
Assert(pWindowInit(WINDOW_NAME), "Failed to initialize the window"); Assert(pWindowInit(WINDOW_NAME), "Failed to initialize the window");
@ -63,7 +62,7 @@ int main(int argc, char **argv)
gGameCtx ctx = {0}; gGameCtx ctx = {0};
gInit(renderer_arena, &ctx, game_arena); gInit(&ctx);
while (!global_quit) while (!global_quit)
{ {

View File

@ -16,23 +16,23 @@ i16 mouse_pos_y = 0;
// ::Game::Init::Functions::Start:: // ::Game::Init::Functions::Start::
static void gInit(Arena *arena, gGameCtx *ctx, Arena *ctx_arena) static void gInit(gGameCtx *ctx)
{ {
Assert(rInit(arena), "Failed to initialize the renderer"); Assert(rInit(), "Failed to initialize the renderer");
ctx->gui.vertices = MakeArray(ctx_arena, rUIVertex, 128); ctx->arena = ArenaCreateDebug(MB(16), __LINE__);
ctx->gui.vertices = MakeArray(ctx->arena, rUIVertex, 128);
ctx->gui.vertices_len = 0; ctx->gui.vertices_len = 0;
ctx->gui.indices = MakeArray(ctx_arena, u32, 768); ctx->gui.indices = MakeArray(ctx->arena, u32, 768);
ctx->gui.indices_len = 0; ctx->gui.indices_len = 0;
ctx->gui.instance_count = 0; ctx->gui.instance_count = 0;
ctx->windows = MakeArray(ctx_arena, gWindowWidget, 32); ctx->windows = MakeArray(ctx->arena, gWindowWidget, 32);
ctx->window_len = 0; ctx->window_len = 0;
ctx->buttons = MakeArray(ctx_arena, gButtonWidget, 64); ctx->buttons = MakeArray(ctx->arena, gButtonWidget, 64);
ctx->btn_len = 0; ctx->btn_len = 0;
ctx->arena = arena;
} }
static void gDestroy() static void gDestroy()
@ -46,6 +46,11 @@ static void gDestroy()
// ::Game::GameLoop::Functions::Start:: // ::Game::GameLoop::Functions::Start::
static void gFrameStartNew()
{
}
static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count) static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count)
{ {
rBufferQueueReset(); rBufferQueueReset();
@ -75,11 +80,11 @@ static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count)
//rDescHandle pattermon = rTextureCreateAndUpload(PATTERMON_OBESE); //rDescHandle pattermon = rTextureCreateAndUpload(PATTERMON_OBESE);
rRenderBuffer *vertex_buffer = MakeArray(ctx->arena, rRenderBuffer, 1); rRenderBuffer *vertex_buffer = MakeArray(ctx->arena, rRenderBuffer, 1);
vertex_buffer->type = RENDER_BUFFER_TYPE_VERTEX; vertex_buffer->type = rRBT_VERTEX;
vertex_buffer->size = sizeof(rUIVertex) * ctx->gui.vertices_len; vertex_buffer->size = sizeof(rUIVertex) * ctx->gui.vertices_len;
rRenderBuffer *index_buffer = MakeArray(ctx->arena, rRenderBuffer, 1); rRenderBuffer *index_buffer = MakeArray(ctx->arena, rRenderBuffer, 1);
index_buffer->type = RENDER_BUFFER_TYPE_INDEX, index_buffer->type = rRBT_INDEX,
index_buffer->size = sizeof(u32) * ctx->gui.indices_len, index_buffer->size = sizeof(u32) * ctx->gui.indices_len,
rBufferCreateAndUpload(vertex_buffer, ctx->gui.vertices); rBufferCreateAndUpload(vertex_buffer, ctx->gui.vertices);
@ -89,7 +94,7 @@ static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count)
rFrameBegin(); rFrameBegin();
rPipelineBind(PIPELINE_GUI, PIPELINE_TYPE_GRAPHICS); rPipelineBind(R_PIPELINE_GUI, rPT_GRAPHICS);
rPushConstantsSet(&ctx->pc); rPushConstantsSet(&ctx->pc);
@ -98,7 +103,7 @@ static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count)
rDrawIndexed(6, ctx->gui.instance_count); rDrawIndexed(6, ctx->gui.instance_count);
FinishFrame(); rFrameFinish();
rBufferFree(vertex_buffer, 1); rBufferFree(vertex_buffer, 1);
rBufferFree(index_buffer, 1); rBufferFree(index_buffer, 1);

View File

@ -43,7 +43,7 @@ typedef struct gGameCtx
// ::Game::Init::Functions::Header:: // ::Game::Init::Functions::Header::
static void gInit(Arena *arena, gGameCtx *ctx, Arena *ctx_arena); static void gInit(gGameCtx *ctx);
static void gDestroy(); static void gDestroy();
// ::Game::GameLoop::Functions::Header:: // ::Game::GameLoop::Functions::Header::

View File

@ -22,39 +22,44 @@ typedef struct rShaderGlobals rShaderGlobals;
typedef enum Pipeline_e typedef enum Pipeline_e
{ {
PIPELINE_CUBE, R_PIPELINE_CUBE,
PIPELINE_GUI, R_PIPELINE_GUI,
PIPELINE_MAX, R_PIPELINE_MAX,
} rPipelineHandle; } rPipelineHandle;
typedef enum PipelineType_e typedef enum PipelineType_e
{ {
PIPELINE_TYPE_GRAPHICS = 0, rPT_GRAPHICS = 0,
PIPELINE_TYPE_COMPUTE = 1, rPT_COMPUTE = 1,
} rPipelineType; } rPipelineType;
typedef enum RenderBufferType_e typedef enum RenderBufferType_e
{ {
RENDER_BUFFER_TYPE_NONE = 0x0000, rRBT_NONE = 0x0000,
RENDER_BUFFER_TYPE_VERTEX = 0x0001, rRBT_VERTEX = 0x0001,
RENDER_BUFFER_TYPE_INDEX = 0x0002, rRBT_INDEX = 0x0002,
RENDER_BUFFER_TYPE_UNIFORM = 0x0004, rRBT_UNIFORM = 0x0004,
RENDER_BUFFER_TYPE_STAGING = 0x0008, rRBT_STORAGE = 0x0008,
RENDER_BUFFER_TYPE_STORAGE = 0x0010, rRBT_HOST = 0x0010,
rRBT_STAGING = 0x0020,
rRBT_HOST_VERTEX = rRBT_HOST | rRBT_VERTEX,
rRBT_HOST_INDEX = rRBT_HOST | rRBT_INDEX,
rRBT_HOST_UNIFORM = rRBT_HOST | rRBT_UNIFORM,
rRBT_HOST_STORAGE = rRBT_HOST | rRBT_STORAGE,
} rRenderBufferType; } rRenderBufferType;
typedef enum TextureBufferType_e typedef enum TextureBufferType_e
{ {
TEXTURE_BUFFER_TYPE_NONE = 0x0000, rTBT_NONE = 0x0000,
TEXTURE_BUFFER_TYPE_IMAGE = 0x0001, rTBT_IMAGE = 0x0001,
TEXTURE_BUFFER_TYPE_SAMPLER = 0x0002, rTBT_SAMPLER = 0x0002,
} rTextureBufferType; } rTextureBufferType;
typedef enum VertexAttrType_e typedef enum VertexAttrType_e
{ {
VERTEX_ATTRIBUTE_TYPE_VERTEX = 0, rVAT_VERTEX = 0,
VERTEX_ATTRIBUTE_TYPE_COLOR = 1, rVAT_COLOR = 1,
} rVertexAttrType; } rVertexAttrType;
// ::Renderer::Types::Header:: // ::Renderer::Types::Header::
@ -75,7 +80,7 @@ typedef struct rUploadQueue
rTextureBuffer **queued_textures; rTextureBuffer **queued_textures;
rawptr *queued_ptrs; rawptr *queued_ptrs;
}; };
rawptr *data; rawptr *data;
TicketMut ticket_mut; TicketMut ticket_mut;
Mut mut; Mut mut;
JobQueue job_queue; JobQueue job_queue;
@ -83,14 +88,17 @@ typedef struct rUploadQueue
typedef u32 rAssetHandle; typedef u32 rAssetHandle;
typedef rawptr rBuffer;
// ::Renderer::Initialization::Header:: // ::Renderer::Initialization::Header::
b32 rInit(Arena *arena); b32 rInit();
void rDestroy(); void rDestroy();
// ::Renderer::Buffers::Header:: // ::Renderer::Buffers::Header::
static b32 rBufferCreate(rRenderBuffer *buffer); static rBuffer rBufferCreate(rRenderBufferType type, u64 size);
static b32 rBufferMap();
static void rBufferFree(rRenderBuffer *buffers, u32 buffer_count); static void rBufferFree(rRenderBuffer *buffers, u32 buffer_count);
static b32 rBufferUpload(rRenderBuffer **buffer, rawptr *ptr, u32 count, u32 thr_ix); static b32 rBufferUpload(rRenderBuffer **buffer, rawptr *ptr, u32 count, u32 thr_ix);
static void rBufferCreateAndUpload(rRenderBuffer *buffer, rawptr ptr); static void rBufferCreateAndUpload(rRenderBuffer *buffer, rawptr ptr);
@ -115,7 +123,7 @@ static void rThreadCountSet(u32 n);
// ::Renderer::Rendering::Header:: // ::Renderer::Rendering::Header::
static b32 rFrameBegin(); static b32 rFrameBegin();
static b32 FinishFrame(); static b32 rFrameFinish();
static void rDrawIndexed(u32 index_count, u32 instance_count); static void rDrawIndexed(u32 index_count, u32 instance_count);
static void rPipelineBind(rPipelineHandle handle, rPipelineType type); static void rPipelineBind(rPipelineHandle handle, rPipelineType type);

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,9 @@
#pragma once #pragma once
#if __linux__ #if __linux__
# define VK_USE_PLATFORM_XCB_KHR
#define VK_USE_PLATFORM_XCB_KHR
#elif _WIN32 #elif _WIN32
# define VK_USE_PLATFORM_WIN32_KHR
#define VK_USE_PLATFORM_WIN32_KHR
#endif #endif
#define VK_NO_PROTOTYPES #define VK_NO_PROTOTYPES
@ -37,6 +33,8 @@ static char *vulkan_libs[] = {
#error Not yet implemented #error Not yet implemented
#endif #endif
#define V_THREAD_MAX 2
// ::Vulkan::Macros::Header:: // ::Vulkan::Macros::Header::
#define VK_DECLARE(fn) static PFN_##fn fn = NULL #define VK_DECLARE(fn) static PFN_##fn fn = NULL
@ -166,64 +164,38 @@ VK_DECLARE(vkCreateSampler);
#define FRAME_OVERLAP 2 #define FRAME_OVERLAP 2
#define DESC_MAX_BINDINGS 256 #define DESC_MAX_BINDINGS 256
#define BUFFER_QUEUE_LEN 32 #define BUFFER_QUEUE_LEN 32
#define HOST_VISIBLE_BUFFERS (RENDER_BUFFER_TYPE_UNIFORM | RENDER_BUFFER_TYPE_STAGING) #define HOST_VISIBLE_BUFFERS (rRBT_UNIFORM | rRBT_STAGING)
// ::Vulkan::Types::Header:: // ::Vulkan::Types::Header::
typedef enum DescType_e typedef enum DescType_e
{ {
DESC_TYPE_SHARED, V_DESC_TYPE_SHARED,
DESC_TYPE_SAMPLER, // DO NOT MOVE FROM POSITION 1 !! V_DESC_TYPE_SAMPLER, // DO NOT MOVE FROM POSITION 1 !!
DESC_TYPE_STORAGE_IMAGE, V_DESC_TYPE_STORAGE_IMAGE,
DESC_TYPE_UNIFORM, V_DESC_TYPE_UNIFORM,
DESC_TYPE_BUFFER, V_DESC_TYPE_BUFFER,
DESC_TYPE_MAX, V_DESC_TYPE_MAX,
} vDescType; } vDescType;
typedef struct vImage /*
{
VkImage img;
VkImageView view;
VkSampler sampler;
VmaAllocation alloc;
VkFormat fmt;
VkImageLayout curr_layout;
} vImage;
typedef struct vMeshBuffer typedef struct vMeshBuffer
{ {
rRenderBuffer index_buf, vertex_buf; //TODO: FIX
//rRenderBuffer index_buf, vertex_buf;
u32 index_count; u32 index_count;
} vMeshBuffer; } vMeshBuffer;
typedef struct vAssetInfo
{
rDescHandle handle;
vDescType type;
union
{
u64 asset_id;
TextureAsset texture_id;
};
} vAssetInfo;
typedef struct vDescBindings
{
u32 *free;
u32 free_count;
HashTable lookup_table;
} vDescBindings;
typedef struct vPipelineStructures typedef struct vPipelineStructures
{ {
VkPipelineLayout pipeline_layout; VkPipelineLayout pipeline_layout;
VkDescriptorPool pool; VkDescriptorPool pool;
VkDescriptorSetLayout layouts[DESC_TYPE_MAX]; VkDescriptorSetLayout layouts[V_DESC_TYPE_MAX];
VkDescriptorSet sets[DESC_TYPE_MAX]; VkDescriptorSet sets[V_DESC_TYPE_MAX];
vDescBindings *bindings; vDescBindings *bindings;
u16 bindings_count; u16 bindings_count;
VkPipeline pipelines[PIPELINE_MAX]; VkPipeline pipelines[R_PIPELINE_MAX];
} vPipelineStructures; } vPipelineStructures;
typedef struct vFrameStructures typedef struct vFrameStructures
@ -244,13 +216,6 @@ typedef struct vImmediateStructures
VkFence *fences; VkFence *fences;
} vImmediateStructures; } vImmediateStructures;
typedef struct vDeviceQueues
{
i32 graphics, transfer;
VkQueue graphics_queue, transfer_queue;
b8 single_queue;
} vDeviceQueues;
typedef struct vSwapchainStructures typedef struct vSwapchainStructures
{ {
VkFormat format; VkFormat format;
@ -312,17 +277,187 @@ typedef struct vVulkanConfig
#endif #endif
} vVulkanConfig; } vVulkanConfig;
typedef struct vRenderer typedef struct vRenderer
{ {
vVulkan vk; vVulkan vk;
vVulkanConfig vk_conf; vVulkanConfig vk_conf;
vFrameState frame_state; vFrameState frame_state;
vPendingUpdates pending; vPendingUpdates pending;
Arena *arena;
Arena *perm_arena; Arena *perm_arena;
rUploadQueue upload_queues[DESC_TYPE_MAX]; Arena *frame_arena[FRAME_OVERLAP];
rUploadQueue upload_queues[V_DESC_TYPE_MAX];
} vRenderer; } vRenderer;
*/
// NEW
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;
typedef struct vSampler
{
vImage image;
VkImageView view;
VkSampler sampler;
} vSampler;
typedef struct vBufferAlloc
{
VkBuffer buffer;
VmaAllocation alloc;
} vBufferAlloc;
ArrayType(vBufferAlloc);
ArrayType(vImageView);
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[V_DESC_TYPE_MAX];
VkDescriptorSet desc_sets[V_DESC_TYPE_MAX];
VkQueue gfx_queue;
VkQueue tfer_queue;
#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 vRenderer2
{
vRHandles handles;
vFrameHandles frame_handles[FRAME_OVERLAP];
vState state;
vBufferAllocArray buffers;
vBufferAlloc frame_buffers[FRAME_OVERLAP];
vImmHandlesArray imm_handles;
vDescBindings desc_bindings[V_DESC_TYPE_MAX];
vAsync async;
vMemory mem;
vRImages images;
} vRenderer2;
// ::Vulkan::FrontEndTypes::Header:: // ::Vulkan::FrontEndTypes::Header::
typedef struct rShaderGlobals typedef struct rShaderGlobals
@ -342,7 +477,7 @@ typedef struct rTextureBuffer
typedef struct rRenderBuffer typedef struct rRenderBuffer
{ {
rRenderBufferType type; rRenderBufferType type;
VkBuffer buffer; VkBuffer buffer;
VmaAllocation alloc; VmaAllocation alloc;
VmaAllocationInfo info; VmaAllocationInfo info;
@ -374,6 +509,9 @@ const char *vVkResultStr(VkResult result);
// ::Vulkan::Init::Functions::Header:: // ::Vulkan::Init::Functions::Header::
static b32 vInitInstance();
static void vEnableDebug();
static void vInitArenas();
static b32 vLibraryLoad(); static b32 vLibraryLoad();
static b32 vInstanceFunctionsInit(); static b32 vInstanceFunctionsInit();
static b32 vGlobalFunctionsInit(); static b32 vGlobalFunctionsInit();
@ -399,13 +537,14 @@ static void vLoaderStartThreads();
// ::Vulkan::Util::Functions::Header:: // ::Vulkan::Util::Functions::Header::
static inline VkCommandBuffer vFrameCmdBuf(); static inline VkCommandBuffer vFrameCmdBuf();
static inline VkFence *vFrameRenderFence(); static inline VkFence vFrameRenderFence();
static inline VkImage vFrameImage();
static inline Arena *vFrameArena();
static inline VkSemaphore vFrameRenderSem(); static inline VkSemaphore vFrameRenderSem();
static inline VkSemaphore vFrameSwapSem(); static inline VkSemaphore vFrameSwapSem();
static inline u32 vFrameIndex(); static inline u32 vFrameIndex();
static inline VkImage vFrameSwapImage(); static inline VkImage vFrameSwapImage();
static inline u32 *vFrameBufferCount(); static inline vBufferAlloc *vFrameBuffers();
static inline rRenderBuffer *vFrameRenderBuffers();
static inline void vImageTransition(VkCommandBuffer cmd, vImage *img, VkImageLayout new); 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 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); static inline void vImageCopyToImage(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent2D dst_ext);

View File

@ -1,38 +1,22 @@
// ::Vulkan::Renderer::Initialization::Functions::Start:: // ::Vulkan::Renderer::Initialization::Functions::Start::
b32 rInit(Arena *arena) b32 rInit()
{ {
rThreadCountSet(pCPUCountGet()); rThreadCountSet(pCPUCountGet());
vInitArenas();
vCustomizePipelines();
CustomizePipelines(); Assert(vInitInstance(), "Unable to initialize instance");
Assert(arena != NULL, "Vulkan memory is null");
renderer.perm_arena = arena;
void *mem = ArenaAlloc(arena, MB(8));
renderer.arena = ArenaInit(mem, MB(8));
Assert(vGlobalFunctionsInit(), "Unable to load vulkan functions");
{
VkResult result = vkCreateInstance(&inst_info, NULL, &renderer.vk.inst);
if (result != VK_SUCCESS)
{
Printfln("vkCreateInstance failure: %s", vVkResultStr(result));
assert(false && "Failed to initialize instance");
}
}
Assert(vInstanceFunctionsInit(), "Unable to initialize instance functions"); Assert(vInstanceFunctionsInit(), "Unable to initialize instance functions");
#ifdef BUILD_DEBUG #ifdef BUILD_DEBUG
{ {
Assert(vValidationSupported(), "DEBUG_BUILD ERROR: Validation layers are not supported"); vEnableDebug();
Assert(vkCreateDebugUtilsMessengerEXT(renderer.vk.inst, &debug_msg_info, NULL, &renderer.vk.debug) == VK_SUCCESS,
"Unable to initialize debug messenger");
} }
#endif #endif
Assert(vSurfaceInit(), "Unable to create surface"); Assert(vSurfaceInit(), "Unable to create surface");
Assert(vDeviceInit(), "Unable to create device"); Assert(vDeviceInit(), "Unable to create device");
Assert(vVmaAllocatorInit(), "Unable to create VMA allocator"); Assert(vVmaAllocatorInit(), "Unable to create VMA allocator");
Assert(vSwapchainInit(), "Unable to initialize swapchain and draw images"); Assert(vSwapchainInit(), "Unable to initialize swapchain and draw images");
Assert(vDrawImagesInit(), "Unable to create draw images"); Assert(vDrawImagesInit(), "Unable to create draw images");
@ -40,78 +24,93 @@ b32 rInit(Arena *arena)
Assert(vImmediateStructuresInit(), "Unable to create immediate structures"); Assert(vImmediateStructuresInit(), "Unable to create immediate structures");
Assert(vDescriptorsInit(), "Unable to initialize descriptors."); Assert(vDescriptorsInit(), "Unable to initialize descriptors.");
Assert(vPipelinesInit(), "Unable to initialize pipelines."); Assert(vPipelinesInit(), "Unable to initialize pipelines.");
vUploadQueuesInit();
vUploadQueuesInit();
vLoaderStartThreads(); vLoaderStartThreads();
ArenaFree(renderer.arena); ArenaFree(vFrameArena());
return true; return true;
} }
void rDestroy() void rDestroy()
{ {
VkDevice device = renderer.vk.device; VkDevice device = v_Renderer.handles.device;
VkInstance instance = renderer.vk.inst; VkInstance instance = v_Renderer.handles.inst;
vFrameStructures data = renderer.vk.frame; vBufferAlloc *frame_buffers = v_Renderer.frame_buffers;
vImmediateStructures imm = renderer.vk.imm; vBufferAllocArray buffers = v_Renderer.buffers;
vSwapchainStructures sc = renderer.vk.sc; vImmHandlesArray imm = v_Renderer.imm_handles;
VmaAllocator vma_alloc = renderer.vk.alloc; VmaAllocator vma_alloc = v_Renderer.handles.vma_alloc;
VkSwapchainKHR swapchain = renderer.vk.swapchain; VkSwapchainKHR swapchain = v_Renderer.handles.swapchain;
vPipelineStructures pipe = renderer.vk.pipe; VkPipeline *pipelines = v_Renderer.handles.pipelines;
VkPipelineLayout pipeline_layout = v_Renderer.handles.pipeline_layout;
VkDescriptorSetLayout *desc_layouts = v_Renderer.handles.desc_layouts;
VkDescriptorPool desc_pool = v_Renderer.handles.desc_pool;
vAsync async = v_Renderer.async;
vkDeviceWaitIdle(device); vkDeviceWaitIdle(device);
for (u32 i = PIPELINE_CUBE; i < PIPELINE_MAX; i++) for (u32 i = R_PIPELINE_CUBE; i < R_PIPELINE_MAX; i++)
vkDestroyPipeline(device, pipe.pipelines[i], NULL); vkDestroyPipeline(device, pipelines[i], NULL);
vkDestroyPipelineLayout(device, pipe.pipeline_layout, NULL); vkDestroyPipelineLayout(device, pipeline_layout, NULL);
for (u32 i = DESC_TYPE_SHARED; i < DESC_TYPE_MAX; i++) for (u32 i = V_DESC_TYPE_SHARED; i < V_DESC_TYPE_MAX; i++)
vkDestroyDescriptorSetLayout(device, pipe.layouts[i], NULL); vkDestroyDescriptorSetLayout(device, desc_layouts[i], NULL);
vkDestroyDescriptorPool(device, pipe.pool, NULL); vkDestroyDescriptorPool(device, desc_pool, NULL);
vDrawImagesDestroy(); vDrawImagesDestroy();
vSwapchainDestroy(); vSwapchainDestroy();
for (u32 i = 0; i < renderer.vk_conf.avail_threads; i++) for (u32 i = 0; i < async.count; i++)
{ {
vkDestroyFence(device, imm.fences[i], NULL); vImmHandles ih = imm.data[i];
vkFreeCommandBuffers(device, imm.pools[i], 1, &imm.cmds[i]);
vkDestroyCommandPool(device, imm.pools[i], NULL); vkDestroyFence(device, ih.fence, NULL);
vkFreeCommandBuffers(device, ih.pool, 1, &ih.buffer);
vkDestroyCommandPool(device, ih.pool, NULL);
} }
for (u32 i = 0; i < FRAME_OVERLAP; i++) for (u32 i = 0; i < FRAME_OVERLAP; i++)
{ {
vkDestroySemaphore(device, data.render_sems[i], NULL); vFrameHandles fh = v_Renderer.frame_handles[i];
vkDestroySemaphore(device, data.swapchain_sems[i], NULL);
vkDestroyFence(device, data.render_fences[i], NULL);
vkFreeCommandBuffers(device, data.pools[i], 1, &data.buffers[i]);
vkDestroyCommandPool(device, data.pools[i], NULL);
vkDestroySemaphore(device, fh.r_sem, NULL);
vkDestroySemaphore(device, fh.sc_sem, NULL);
vkDestroyFence(device, fh.r_fence, NULL);
vkFreeCommandBuffers(device, fh.pool, 1, &fh.buffer);
vkDestroyCommandPool(device, fh.pool, NULL);
// TODO: replace
/*
if (data.buffer_counts[i] > 0) if (data.buffer_counts[i] > 0)
{ {
for (u32 j = 0; j < data.buffer_counts[i]; j++) //for (u32 j = 0; j < data.buffer_counts[i]; j++)
vmaDestroyBuffer(renderer.vk.alloc, data.buffer_destroy_queues[i][j].buffer, data.buffer_destroy_queues[i][j].alloc); //vmaDestroyBuffer(v_Renderer.handles.vma_alloc, data.buffer_destroy_queues[i][j].buffer, data.buffer_destroy_queues[i][j].alloc);
} }
*/
} }
vmaDestroyAllocator(renderer.vk.alloc); vmaDestroyAllocator(v_Renderer.handles.vma_alloc);
vkDestroyDevice(renderer.vk.device, NULL); vkDestroyDevice(v_Renderer.handles.device, NULL);
vkDestroySurfaceKHR(renderer.vk.inst, renderer.vk.surface, NULL); vkDestroySurfaceKHR(v_Renderer.handles.inst, v_Renderer.handles.surface, NULL);
#ifdef BUILD_DEBUG #ifdef BUILD_DEBUG
{ {
vkDestroyDebugUtilsMessengerEXT(renderer.vk.inst, renderer.vk.debug, NULL); vkDestroyDebugUtilsMessengerEXT(v_Renderer.handles.inst, v_Renderer.handles.debug, NULL);
} }
#endif #endif
vkDestroyInstance(renderer.vk.inst, NULL); vkDestroyInstance(v_Renderer.handles.inst, NULL);
ArenaFree(renderer.arena); for (u32 i = 0; i < FRAME_OVERLAP; i++)
ArenaFree(renderer.perm_arena); {
ArenaFree(v_Renderer.mem.frame_arenas[i]);
}
ArenaFree(v_Renderer.mem.perm_arena);
} }
// ::Vulkan::Renderer::Initialization::Functions::End:: // ::Vulkan::Renderer::Initialization::Functions::End::
@ -120,20 +119,28 @@ void rDestroy()
// ::Vulkan::Renderer::Buffers::Functions::Start:: // ::Vulkan::Renderer::Buffers::Functions::Start::
static b32 rBufferCreate(rRenderBuffer *buffer) static rBuffer rBufferCreate(rRenderBufferType type, u64 size)
{ {
Assert(buffer, "rBufferCreate: rRenderBuffer must not be null"); rBuffer buffer = NULL;
Assert(buffer->type != RENDER_BUFFER_TYPE_NONE, "rBufferCreate: rRenderBuffer type must not be RENDER_BUFFER_TYPE_NONE");
return buffer;
}
static b32 rBufferCreateOLD(rRenderBufferType type, u64 size)
{
Assert(type != rRBT_NONE, "rBufferCreate: rRenderBuffer type must not be rRBT_NONE");
b32 success = true; b32 success = true;
VkResult result; VkResult result;
vDeviceQueues *queues = &renderer.vk.queues; u32 gfx_queue = v_Renderer.state.vk.gfx_queue_idx;
VmaAllocator alloc = renderer.vk.alloc; u32 tfer_queue = v_Renderer.state.vk.tfer_queue_idx;
VmaAllocator alloc = v_Renderer.handles.vma_alloc;
VkBufferCreateInfo buffer_info = { VkBufferCreateInfo buffer_info = {
.sType = STYPE(BUFFER_CREATE_INFO), .sType = STYPE(BUFFER_CREATE_INFO),
.size = (VkDeviceSize)buffer->size, //.size = (VkDeviceSize)buffer->size,
}; };
VmaAllocationCreateInfo alloc_info = { VmaAllocationCreateInfo alloc_info = {
@ -141,65 +148,64 @@ static b32 rBufferCreate(rRenderBuffer *buffer)
.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT, .flags = VMA_ALLOCATION_CREATE_MAPPED_BIT,
}; };
switch (buffer->type) switch (type)
{ {
case RENDER_BUFFER_TYPE_VERTEX: case rRBT_VERTEX:
{ {
buffer_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | buffer_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
VK_BUFFER_USAGE_TRANSFER_DST_BIT |
VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
alloc_info.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
} break; } break;
case RENDER_BUFFER_TYPE_INDEX: case rRBT_INDEX:
{ {
buffer_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | buffer_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
VK_BUFFER_USAGE_TRANSFER_DST_BIT |
VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
alloc_info.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
} break; } break;
case RENDER_BUFFER_TYPE_UNIFORM: case rRBT_UNIFORM:
{ {
buffer_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | buffer_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
VK_BUFFER_USAGE_TRANSFER_DST_BIT;
alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
} break; } break;
case RENDER_BUFFER_TYPE_STAGING: case rRBT_STAGING:
{ {
buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
} break; } break;
case RENDER_BUFFER_TYPE_STORAGE: case rRBT_STORAGE:
{ {
buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
VK_BUFFER_USAGE_TRANSFER_DST_BIT;
alloc_info.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
} break; } break;
case RENDER_BUFFER_TYPE_NONE: case rRBT_NONE:
default: default:
Assert(false, "rBufferCreate: Unknown buffer type provided"); Assert(false, "rBufferCreate: Unknown buffer type provided");
} }
if ((type & rRBT_HOST) == rRBT_HOST || type == rRBT_STAGING)
{
alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
alloc_info.preferredFlags = VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
}
else
{
buffer_info.usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
alloc_info.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
}
if (queues->graphics != queues->transfer) if (tfer_queue != gfx_queue)
{ {
buffer_info.sharingMode = VK_SHARING_MODE_CONCURRENT; buffer_info.sharingMode = VK_SHARING_MODE_CONCURRENT;
buffer_info.queueFamilyIndexCount = 2; buffer_info.queueFamilyIndexCount = 2;
buffer_info.pQueueFamilyIndices = (u32[]){queues->graphics, queues->transfer}; buffer_info.pQueueFamilyIndices = (u32[]){gfx_queue, tfer_queue};
} }
result = vmaCreateBuffer(alloc, &buffer_info, &alloc_info, &buffer->buffer, &buffer->alloc, &buffer->info); //result = vmaCreateBuffer(alloc, &buffer_info, &alloc_info, &buffer->buffer, &buffer->alloc, &buffer->info);
if (result != VK_SUCCESS) //if (result != VK_SUCCESS)
{ //{
Printfln("vmaCreateBuffer failure: %s", vVkResultStr(result)); //Printfln("vmaCreateBuffer failure: %s", vVkResultStr(result));
success = false; //}
}
return success; return success;
} }
static b32 rBufferUpload(rRenderBuffer **buffers, rawptr *ptrs, u32 count, u32 thr_ix) static b32 rBufferUpload(rRenderBuffer **buffers, rawptr *ptrs, u32 count, u32 thr_ix)
{ {
// TODO: replace
/*
Assert(buffers, "rBufferUpload: buffer must not be null"); Assert(buffers, "rBufferUpload: buffer must not be null");
Assert(ptrs, "rBufferUpload: ptr must not be null"); Assert(ptrs, "rBufferUpload: ptr must not be null");
@ -207,9 +213,9 @@ static b32 rBufferUpload(rRenderBuffer **buffers, rawptr *ptrs, u32 count, u32 t
VkCommandBuffer cmd = renderer.vk.imm.cmds[thr_ix]; VkCommandBuffer cmd = renderer.vk.imm.cmds[thr_ix];
VkFence fence = renderer.vk.imm.fences[thr_ix]; VkFence fence = renderer.vk.imm.fences[thr_ix];
VkDevice device = renderer.vk.device; VkDevice device = v_Renderer.handles.device;
VkQueue queue = renderer.vk.queues.transfer_queue; VkQueue queue = renderer.vk.queues.transfer_queue;
VmaAllocator alloc = renderer.vk.alloc; VmaAllocator alloc = v_Renderer.handles.vma_alloc;
rawptr mapped_buffers[16] = {0}; rawptr mapped_buffers[16] = {0};
rRenderBuffer staging_buffers[16] = {0}; rRenderBuffer staging_buffers[16] = {0};
@ -226,10 +232,10 @@ static b32 rBufferUpload(rRenderBuffer **buffers, rawptr *ptrs, u32 count, u32 t
} }
else else
{ {
staging_buffers[copy_count].type = RENDER_BUFFER_TYPE_STAGING; staging_buffers[copy_count].type = rRBT_STAGING;
staging_buffers[copy_count].size = buffers[i]->size; staging_buffers[copy_count].size = buffers[i]->size;
success = rBufferCreate(&staging_buffers[i]); //success = rBufferCreate(&staging_buffers[i]);
if (success) if (success)
{ {
@ -252,19 +258,24 @@ static b32 rBufferUpload(rRenderBuffer **buffers, rawptr *ptrs, u32 count, u32 t
vmaUnmapMemory(alloc, staging_buffers[i].alloc); vmaUnmapMemory(alloc, staging_buffers[i].alloc);
vmaDestroyBuffer(alloc, staging_buffers[i].buffer, staging_buffers[i].alloc); vmaDestroyBuffer(alloc, staging_buffers[i].buffer, staging_buffers[i].alloc);
} }
*/
return success; return false;
} }
static void rBufferCreateAndUpload(rRenderBuffer *buffer, rawptr ptr) static void rBufferCreateAndUpload(rRenderBuffer *buffer, rawptr ptr)
{ {
TicketMutLock(&renderer.upload_queues[DESC_TYPE_BUFFER].ticket_mut);
u32 job_idx = JobQueueAdd(&renderer.upload_queues[DESC_TYPE_BUFFER].job_queue, 1); // TODO: replace
renderer.upload_queues[DESC_TYPE_BUFFER].queued_buffers[job_idx] = buffer; /*
renderer.upload_queues[DESC_TYPE_BUFFER].data[job_idx] = ptr; TicketMutLock(&renderer.upload_queues[V_DESC_TYPE_BUFFER].ticket_mut);
TicketMutUnlock(&renderer.upload_queues[DESC_TYPE_BUFFER].ticket_mut); u32 job_idx = JobQueueAdd(&renderer.upload_queues[V_DESC_TYPE_BUFFER].job_queue, 1);
renderer.upload_queues[V_DESC_TYPE_BUFFER].queued_buffers[job_idx] = buffer;
renderer.upload_queues[V_DESC_TYPE_BUFFER].data[job_idx] = ptr;
TicketMutUnlock(&renderer.upload_queues[V_DESC_TYPE_BUFFER].ticket_mut);
*/
vLoaderWake(); vLoaderWake();
} }
@ -273,26 +284,28 @@ static rDescHandle rTextureCreateAndUpload(TextureAsset asset_id)
{ {
rDescHandle handle = 0; rDescHandle handle = 0;
vAssetInfo *info = vDescHandleSearch(DESC_TYPE_SAMPLER, asset_id); // TODO: replace it
/*
vAssetInfo *info = vDescHandleSearch(V_DESC_TYPE_SAMPLER, asset_id);
if (info == NULL) if (info == NULL)
{ {
Asset asset = apLoadTexture(asset_id); Asset asset = apLoadTexture(asset_id);
rTextureBuffer *buffer = FLMemAlloc(sizeof(rTextureBuffer)); rTextureBuffer *buffer = FLMemAlloc(sizeof(rTextureBuffer));
buffer->type = TEXTURE_BUFFER_TYPE_SAMPLER; buffer->type = rTBT_SAMPLER;
buffer->width = asset.texture_meta.w; buffer->width = asset.texture_meta.w;
buffer->height = asset.texture_meta.h; buffer->height = asset.texture_meta.h;
buffer->channels = asset.texture_meta.ch; buffer->channels = asset.texture_meta.ch;
TicketMutLock(&renderer.upload_queues[DESC_TYPE_SAMPLER].ticket_mut); TicketMutLock(&renderer.upload_queues[V_DESC_TYPE_SAMPLER].ticket_mut);
u32 job_idx = JobQueueAdd(&renderer.upload_queues[DESC_TYPE_SAMPLER].job_queue, 1); u32 job_idx = JobQueueAdd(&renderer.upload_queues[V_DESC_TYPE_SAMPLER].job_queue, 1);
renderer.upload_queues[DESC_TYPE_SAMPLER].queued_textures[job_idx] = buffer; renderer.upload_queues[V_DESC_TYPE_SAMPLER].queued_textures[job_idx] = buffer;
renderer.upload_queues[DESC_TYPE_SAMPLER].data[job_idx] = asset.bytes; renderer.upload_queues[V_DESC_TYPE_SAMPLER].data[job_idx] = asset.bytes;
handle = vDescHandlePop(DESC_TYPE_SAMPLER); handle = vDescHandlePop(V_DESC_TYPE_SAMPLER);
TicketMutUnlock(&renderer.upload_queues[DESC_TYPE_SAMPLER].ticket_mut); TicketMutUnlock(&renderer.upload_queues[V_DESC_TYPE_SAMPLER].ticket_mut);
vLoaderWake(); vLoaderWake();
} }
@ -300,30 +313,28 @@ static rDescHandle rTextureCreateAndUpload(TextureAsset asset_id)
{ {
handle = info->handle; handle = info->handle;
} }
*/
return handle; return handle;
} }
static void rBufferFree(rRenderBuffer *buffers, u32 buffer_count) static void rBufferFree(rRenderBuffer *buffers, u32 buffer_count)
{ {
VkDevice device = renderer.vk.device; VkDevice device = v_Renderer.handles.device;
VmaAllocator alloc = renderer.vk.alloc; VmaAllocator alloc = v_Renderer.handles.vma_alloc;
u32 frame_index = renderer.frame_state.begin_rendering ? renderer.frame_state.frame_cnt : renderer.frame_state.prev_frame; u32 frame_index = vFrameIndex();
frame_index = frame_index % FRAME_OVERLAP;
u32 *buf_count = &renderer.vk.frame.buffer_counts[frame_index];
// TODO: make this better at some point // TODO: replace it
for (u32 i = 0; i < buffer_count; i++) //for (u32 i = 0; i < buffer_count; i++)
{ //{
renderer.vk.frame.buffer_destroy_queues[frame_index][*buf_count] = buffers[i]; // *buf_count += 1;
*buf_count += 1; //}
}
} }
static void rBufferBindVertex(rRenderBuffer *buffer) static void rBufferBindVertex(rRenderBuffer *buffer)
{ {
Assert(buffer && buffer->type == RENDER_BUFFER_TYPE_VERTEX, "rBufferBindVertex: invalid buffer provided"); Assert(buffer && buffer->type == rRBT_VERTEX, "rBufferBindVertex: invalid buffer provided");
VkCommandBuffer cmd = vFrameCmdBuf(); VkCommandBuffer cmd = vFrameCmdBuf();
VkDeviceSize offsets = 0; VkDeviceSize offsets = 0;
@ -333,7 +344,7 @@ static void rBufferBindVertex(rRenderBuffer *buffer)
static void rBufferBindIndex(rRenderBuffer *buffer) static void rBufferBindIndex(rRenderBuffer *buffer)
{ {
Assert(buffer && buffer->type == RENDER_BUFFER_TYPE_INDEX, "rBufferBindIndex: invalid buffer provided"); Assert(buffer && buffer->type == rRBT_INDEX, "rBufferBindIndex: invalid buffer provided");
VkCommandBuffer cmd = vFrameCmdBuf(); VkCommandBuffer cmd = vFrameCmdBuf();
@ -349,21 +360,25 @@ static rAssetHandle rTextureLoad(TextureAsset asset_id)
static void WaitForBufferQueue() static void WaitForBufferQueue()
{ {
for (u32 i = 0; i < DESC_TYPE_MAX; i++) for (u32 i = 0; i < V_DESC_TYPE_MAX; i++)
{ {
while (!JobQueueCompleted(&renderer.upload_queues[DESC_TYPE_BUFFER].job_queue)) // TODO: replace
/*
while (!JobQueueCompleted(&renderer.upload_queues[V_DESC_TYPE_BUFFER].job_queue))
{ {
if (renderer.vk_conf.sleeping_threads > 0) if (v_Renderer.state.renderer.height > 0)
vLoaderWake(); vLoaderWake();
} }
*/
} }
} }
static void rBufferQueueReset() static void rBufferQueueReset()
{ {
for (u32 i = 0; i < DESC_TYPE_MAX; i++) for (u32 i = 0; i < V_DESC_TYPE_MAX; i++)
{ {
JobQueueReset(&renderer.upload_queues[i].job_queue); // TODO: replace
//JobQueueReset(&renderer.upload_queues[i].job_queue);
} }
} }
@ -376,8 +391,8 @@ static void rBufferQueueReset()
static void rViewportSize(Vec2 *size) static void rViewportSize(Vec2 *size)
{ {
size->x = (f32)renderer.vk.sc.extent.width; size->x = (f32)v_Renderer.state.swapchain.extent.width;
size->y = (f32)renderer.vk.sc.extent.height; size->y = (f32)v_Renderer.state.swapchain.extent.height;
} }
static void rGlobalUniformSet(rShaderGlobals *globals) static void rGlobalUniformSet(rShaderGlobals *globals)
@ -390,7 +405,7 @@ static void rPushConstantsSet(rPushConst *pc)
VkCommandBuffer cmd = vFrameCmdBuf(); VkCommandBuffer cmd = vFrameCmdBuf();
vkCmdPushConstants(cmd, vkCmdPushConstants(cmd,
renderer.vk.pipe.pipeline_layout, v_Renderer.handles.pipeline_layout,
VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_FRAGMENT_BIT|VK_SHADER_STAGE_COMPUTE_BIT, VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_FRAGMENT_BIT|VK_SHADER_STAGE_COMPUTE_BIT,
0, 0,
sizeof(rPushConst), sizeof(rPushConst),
@ -406,14 +421,13 @@ static void rPushConstantsSet(rPushConst *pc)
static void rResolutionSet(u32 x, u32 y) static void rResolutionSet(u32 x, u32 y)
{ {
renderer.pending.render_width = x; v_Renderer.state.renderer.width = x;
renderer.pending.render_height = y; v_Renderer.state.renderer.height = y;
renderer.pending.resized = true;
} }
static void rThreadCountSet(u32 n) static void rThreadCountSet(u32 n)
{ {
renderer.vk_conf.avail_threads = n; v_Renderer.async.count = n;
} }
// ::Vulkan::Renderer::Config::Functions::End:: // ::Vulkan::Renderer::Config::Functions::End::
@ -427,18 +441,15 @@ b32 rFrameBegin()
b32 success = true; b32 success = true;
VkResult result; VkResult result;
if (renderer.pending.resized) VkDevice device = v_Renderer.handles.device;
vSwapchainResize(); VkSwapchainKHR swapchain = v_Renderer.handles.swapchain;
VkDevice device = renderer.vk.device;
VkSwapchainKHR swapchain = renderer.vk.swapchain;
VkCommandBuffer cmd = vFrameCmdBuf(); VkCommandBuffer cmd = vFrameCmdBuf();
VkFence *fence = vFrameRenderFence(); VkFence fence = vFrameRenderFence();
VkSemaphore sc_sem = vFrameSwapSem(); VkSemaphore sc_sem = vFrameSwapSem();
VkSemaphore rndr_sem = vFrameRenderSem(); VkSemaphore rndr_sem = vFrameRenderSem();
// TODO(MA): make this work with VK_PRESENT_MODE_MAILBOX_KHR and remove assignment of present mode to FIFO // TODO(MA): make this work with VK_PRESENT_MODE_MAILBOX_KHR and remove assignment of present mode to FIFO
result = vkWaitForFences(device, 1, fence, VK_TRUE, 1000000000); result = vkWaitForFences(device, 1, &fence, VK_TRUE, 1000000000);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
{ {
Printf("vkWaitForFences failure: %s", vVkResultStr(result)); Printf("vkWaitForFences failure: %s", vVkResultStr(result));
@ -447,16 +458,19 @@ b32 rFrameBegin()
if (success) if (success)
{ {
// TODO: replace
/*
u32 *buf_count = vFrameBufferCount(); u32 *buf_count = vFrameBufferCount();
if (*buf_count > 0) if (*buf_count > 0)
{ {
rRenderBuffer *buffers = vFrameRenderBuffers(); rRenderBuffer *buffers = vFrameRenderBuffers();
for (u32 i = 0; i < *buf_count; i++) for (u32 i = 0; i < *buf_count; i++)
vmaDestroyBuffer(renderer.vk.alloc, buffers[i].buffer, buffers[i].alloc); vmaDestroyBuffer(v_Renderer.handles.vma_alloc, buffers[i].buffer, buffers[i].alloc);
*buf_count = 0; *buf_count = 0;
} }
*/
result = vkResetFences(device, 1, fence); result = vkResetFences(device, 1, &fence);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
{ {
Printf("vkResetFences failure: %s", vVkResultStr(result)); Printf("vkResetFences failure: %s", vVkResultStr(result));
@ -466,7 +480,7 @@ b32 rFrameBegin()
if (success) if (success)
{ {
result = vkAcquireNextImageKHR(device, swapchain, 1000000000, sc_sem, 0, &renderer.frame_state.img_ix); result = vkAcquireNextImageKHR(device, swapchain, 1000000000, sc_sem, 0, &v_Renderer.state.vk.image_idx);
if (result == VK_ERROR_OUT_OF_DATE_KHR) if (result == VK_ERROR_OUT_OF_DATE_KHR)
vSwapchainResize(); vSwapchainResize();
else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
@ -500,37 +514,35 @@ b32 rFrameBegin()
Printf("vkBeginCommandBuffer failure: %s", vVkResultStr(result)); Printf("vkBeginCommandBuffer failure: %s", vVkResultStr(result));
success = false; success = false;
} }
if (success)
vRenderingBegin();
} }
return success; return success;
} }
b32 FinishFrame() b32 rFrameFinish()
{ {
if (!renderer.frame_state.begin_rendering)
Assert(false, "FinishFrame called without beginning rendering");
renderer.frame_state.begin_rendering = false;
b32 success = true; b32 success = true;
VkResult result; VkResult result;
VkCommandBuffer cmd = vFrameCmdBuf(); VkCommandBuffer cmd = vFrameCmdBuf();
VkSemaphore sc_sem = vFrameSwapSem(); VkSemaphore sc_sem = vFrameSwapSem();
VkSemaphore rndr_sem = vFrameRenderSem(); VkSemaphore rndr_sem = vFrameRenderSem();
VkFence *fence = vFrameRenderFence(); VkFence fence = vFrameRenderFence();
VkImage curr_img = renderer.vk.sc.imgs[renderer.frame_state.img_ix]; VkImage curr_img = vFrameImage();
vkCmdEndRendering(cmd); vkCmdEndRendering(cmd);
vImageTransition(cmd, &renderer.vk.sc.draw_img, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); vImageTransition(cmd, &v_Renderer.images.draw.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
VkExtent2D extent = { VkExtent2D extent = {
.width = renderer.vk.sc.extent.width, .width = v_Renderer.state.swapchain.extent.width,
.height = renderer.vk.sc.extent.height, .height = v_Renderer.state.swapchain.extent.height,
}; };
vImageCopyToImage(cmd, renderer.vk.sc.draw_img.img, curr_img, extent, extent); vImageCopyToImage(cmd, v_Renderer.images.draw.image.image, curr_img, extent, extent);
vImageTransitionLayout(cmd, curr_img, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); vImageTransitionLayout(cmd, curr_img, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
@ -572,7 +584,7 @@ b32 FinishFrame()
.pCommandBufferInfos = &cmd_info, .pCommandBufferInfos = &cmd_info,
}; };
result = vkQueueSubmit2(renderer.vk.queues.graphics_queue, 1, &submit_info, *fence); result = vkQueueSubmit2(v_Renderer.handles.gfx_queue, 1, &submit_info, fence);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
{ {
Printf("vkQueueSubmit2 failure: %s", vVkResultStr(result)); Printf("vkQueueSubmit2 failure: %s", vVkResultStr(result));
@ -584,15 +596,15 @@ b32 FinishFrame()
{ {
VkPresentInfoKHR present_info = { VkPresentInfoKHR present_info = {
.sType = STYPE(PRESENT_INFO_KHR), .sType = STYPE(PRESENT_INFO_KHR),
.pSwapchains = &renderer.vk.swapchain, .pSwapchains = &v_Renderer.handles.swapchain,
.swapchainCount = 1, .swapchainCount = 1,
.pWaitSemaphores = &rndr_sem, .pWaitSemaphores = &rndr_sem,
.waitSemaphoreCount = 1, .waitSemaphoreCount = 1,
.pImageIndices = &renderer.frame_state.img_ix, .pImageIndices = &v_Renderer.state.vk.image_idx,
}; };
result = vkQueuePresentKHR(renderer.vk.queues.graphics_queue, &present_info); result = vkQueuePresentKHR(v_Renderer.handles.gfx_queue, &present_info);
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || renderer.pending.resized) if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
vSwapchainResize(); vSwapchainResize();
else if (result != VK_SUCCESS) else if (result != VK_SUCCESS)
{ {
@ -601,8 +613,7 @@ b32 FinishFrame()
} }
} }
renderer.frame_state.prev_frame = renderer.frame_state.frame_cnt; v_Renderer.state.renderer.frame_count += 1;
renderer.frame_state.frame_cnt++;
return success; return success;
} }
@ -616,19 +627,13 @@ static void rDrawIndexed(u32 index_count, u32 instance_count)
static void rPipelineBind(rPipelineHandle handle, rPipelineType type) static void rPipelineBind(rPipelineHandle handle, rPipelineType type)
{ {
if (!renderer.frame_state.begin_rendering)
{
vRenderingBegin();
renderer.frame_state.begin_rendering = true;
}
VkCommandBuffer cmd = vFrameCmdBuf(); VkCommandBuffer cmd = vFrameCmdBuf();
vkCmdBindPipeline(cmd, (VkPipelineBindPoint)type, renderer.vk.pipe.pipelines[handle]); vkCmdBindPipeline(cmd, (VkPipelineBindPoint)type, v_Renderer.handles.pipelines[handle]);
VkViewport viewport = { VkViewport viewport = {
.width = (f32)renderer.vk.sc.extent.width, .width = (f32)v_Renderer.state.swapchain.extent.width,
.height = (f32)renderer.vk.sc.extent.height, .height = (f32)v_Renderer.state.swapchain.extent.height,
.maxDepth = 1.0, .maxDepth = 1.0,
}; };
@ -636,8 +641,8 @@ static void rPipelineBind(rPipelineHandle handle, rPipelineType type)
VkRect2D scissor = { VkRect2D scissor = {
.extent = { .extent = {
.width = renderer.vk.sc.extent.width, .width = v_Renderer.state.swapchain.extent.width,
.height = renderer.vk.sc.extent.height, .height = v_Renderer.state.swapchain.extent.height,
}, },
}; };

View File

@ -72,6 +72,13 @@ typedef struct Arena Arena;
Def##def(b8); \ Def##def(b8); \
Def##def(b32) Def##def(b32)
#define ArrayType(T) \
typedef struct T##Array \
{ \
T *data; \
u64 length; \
} T##Array
// ::Util::LinkedList::Macros:: // ::Util::LinkedList::Macros::

View File

@ -251,10 +251,10 @@ static VkDescriptorSetLayoutCreateInfo shared_layout_create_info = {
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
}; };
static VkDescriptorType desc_type_map[DESC_TYPE_MAX] = { static VkDescriptorType desc_type_map[V_DESC_TYPE_MAX] = {
[DESC_TYPE_SAMPLER] = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, [V_DESC_TYPE_SAMPLER] = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
[DESC_TYPE_STORAGE_IMAGE] = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, [V_DESC_TYPE_STORAGE_IMAGE] = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
[DESC_TYPE_UNIFORM] = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, [V_DESC_TYPE_UNIFORM] = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
}; };
static VkDescriptorBindingFlags bindless_desc_binding_flags = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT | VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT; static VkDescriptorBindingFlags bindless_desc_binding_flags = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT | VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT;
@ -281,7 +281,7 @@ static VkDescriptorSetLayoutCreateInfo bindless_layout_create_info = {
static VkDescriptorSetAllocateInfo set_allocate_info = { static VkDescriptorSetAllocateInfo set_allocate_info = {
.sType = STYPE(DESCRIPTOR_SET_ALLOCATE_INFO), .sType = STYPE(DESCRIPTOR_SET_ALLOCATE_INFO),
.descriptorSetCount = DESC_TYPE_MAX, .descriptorSetCount = V_DESC_TYPE_MAX,
}; };
static VkPushConstantRange push_const_range = { static VkPushConstantRange push_const_range = {
@ -292,7 +292,7 @@ static VkPushConstantRange push_const_range = {
static VkPipelineLayoutCreateInfo pipeline_layout_create_info = { static VkPipelineLayoutCreateInfo pipeline_layout_create_info = {
.sType = STYPE(PIPELINE_LAYOUT_CREATE_INFO), .sType = STYPE(PIPELINE_LAYOUT_CREATE_INFO),
.setLayoutCount = DESC_TYPE_MAX, .setLayoutCount = V_DESC_TYPE_MAX,
.pushConstantRangeCount = 1, .pushConstantRangeCount = 1,
.pPushConstantRanges = &push_const_range, .pPushConstantRanges = &push_const_range,
}; };
@ -448,7 +448,7 @@ VkPipelineInputAssemblyStateCreateInfo gui_assembly_info = {
.primitiveRestartEnable = VK_FALSE, .primitiveRestartEnable = VK_FALSE,
}; };
static void CustomizePipelines() static void vCustomizePipelines()
{ {
gui_create_info.pVertexInputState = &gui_vertex_input_info; gui_create_info.pVertexInputState = &gui_vertex_input_info;
gui_create_info.pInputAssemblyState = &gui_assembly_info; gui_create_info.pInputAssemblyState = &gui_assembly_info;