diff --git a/build.sh b/build.sh index aa05932..caeb208 100755 --- a/build.sh +++ b/build.sh @@ -76,9 +76,10 @@ mkdir -p build cd build +mkdir -p ../src/file_data + if [ -v vulkan ]; then mkdir -p ./shaders/glsl - mkdir -p ../src/file_data for file in ../src/shaders/glsl/*.glsl; do base_name=$(basename -- "$file" .glsl) @@ -107,6 +108,16 @@ if [ -v vulkan ]; then fi +rm -f ../src/file_data/images.c +touch ../src/file_data/images.c + +for file in ../assets/*.png; do + base_name=$(basename -- "$file" .png) + + xxd -n "image_${base_name}" -i $file >> ../src/file_data/images.c +done + + $cpp_compiler $vma_compile_flags $vma_source_files $vma_out $vma_obj ar rcs libvma.a vma.o diff --git a/src/entry_linux.c b/src/entry_linux.c index ecbbc08..38dd01f 100644 --- a/src/entry_linux.c +++ b/src/entry_linux.c @@ -8,6 +8,45 @@ #include "renderer.c" #include "game.c" +const char *strs[10] = { + "String 1", + "String 2", + "String 3", + "String 4", + "String 5", + "String 6", + "String 7", + "String 8", + "String 9", + "String 10", +}; +u32 volatile str_index = 0; + +#include + +void *ThreadFunc(void *i) +{ + for (;;) + { + u32 val = __atomic_fetch_add(&str_index, 1, __ATOMIC_RELEASE); + if (val < 10) + { + Printfln("Thread %d: %s", *(u32 *)i, strs[val]); + sleep(1); + } + else + break; + + } + + pthread_exit(NULL); +} + +void RunThreadFunc(pthread_t *th, u32 *u, void *func) +{ + pthread_create(th, NULL, func, u); +} + int main(int argc, char **argv) { u8 *mem = (u8 *)MemAllocZeroed(MB(64)); diff --git a/src/entry_linux.h b/src/entry_linux.h index 3c4cdbc..e107561 100644 --- a/src/entry_linux.h +++ b/src/entry_linux.h @@ -2,6 +2,8 @@ #pragma once +#define _GNU_SOURCE + #define STB_SPRINTF_IMPLEMENTATION #define WINDOW_NAME "Video Game" diff --git a/src/platform_linux.c b/src/platform_linux.c index 408bac3..cba3f78 100644 --- a/src/platform_linux.c +++ b/src/platform_linux.c @@ -558,3 +558,10 @@ b32 _ShouldQuit() { return false; } + +u32 AvailableCPUCount() +{ + cpu_set_t cpu_set; + sched_getaffinity(0, sizeof(cpu_set), &cpu_set); + return CPU_COUNT(&cpu_set); +} diff --git a/src/platform_linux.h b/src/platform_linux.h index 76368af..b5ed92d 100644 --- a/src/platform_linux.h +++ b/src/platform_linux.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -17,6 +18,9 @@ #include #include #include +#include + +#include // syscall defines #define SYS_ERR -1 @@ -89,6 +93,7 @@ void RepaintWindow(); // General Utils b32 CheckSyscallErr(void *ptr); +u32 AvailableCPUCount(); // Write Utils i32 Write(int fd, void const *str, isize count); diff --git a/src/renderer.h b/src/renderer.h index 53b3164..ced9085 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -34,6 +34,8 @@ typedef enum VertexAttrType_e // Declarations +typedef u16 DescHandle; + // @requirement RenderBuffer type; // @requirement u32 size; typedef struct RenderBuffer_t RenderBuffer; @@ -51,27 +53,29 @@ typedef struct RenderBuffers_t // Back End API -// Initialization +// ::Initialization::Header:: b32 InitRenderer(Arena *arena); void DestroyRenderer(); -// Buffers +// ::Buffers::Header:: static b32 CreateBuffer(RenderBuffer *buffer); static void FreeBuffers(RenderBuffer *buffers, u32 buffer_count); -static b32 UploadToBuffer(RenderBuffer *buffer, rawptr ptr); +static b32 UploadToBuffer(RenderBuffer *buffer, rawptr ptr, u8 thr_ix); static b32 CreateAndUploadToBuffer(RenderBuffer *buffer, rawptr ptr); static void BindVertexBuffer(RenderBuffer *buffer); static void BindIndexBuffer(RenderBuffer *buffer); -// Uniforms/PushConstants +// ::Uniforms::Header:: ::PushConstants::Header:: static void GetViewportSize(Vec2 *size); static void SetGlobalUniform(ShaderGlobals *globals); static void SetPushConstants(PushConst *pc); +static DescHandle UploadImageUniform(); -// Config +// ::Config::Header:: static void SetRenderResolution(u32 x, u32 y); +static void SetRendererAvailableThreads(u32 n); -// Rendering +// ::Rendering::Header:: static b32 BeginFrame(); static b32 FinishFrame(); static void DrawIndexed(u32 index_count, u32 instance_count); diff --git a/src/renderer_vulkan.c b/src/renderer_vulkan.c index a77e32b..4d8e1f2 100644 --- a/src/renderer_vulkan.c +++ b/src/renderer_vulkan.c @@ -702,19 +702,19 @@ static b32 VLayersSupported() static b32 CreateFrameStructures() { - b32 success = true; + b32 success = true; FrameStructures *data = &renderer.vk.frame; - u32 img_count = renderer.vk.sc.img_count; + u32 img_count = renderer.vk.sc.img_count; pool_create_info.queueFamilyIndex = renderer.vk.queues.graphics; - renderer.vk.frame.pools = ArenaAlloc(renderer.perm_arena, sizeof(VkCommandPool) * img_count); - renderer.vk.frame.buffers = ArenaAlloc(renderer.perm_arena, sizeof(VkCommandBuffer) * img_count); - renderer.vk.frame.swapchain_sems = ArenaAlloc(renderer.perm_arena, sizeof(VkSemaphore) * img_count); - renderer.vk.frame.render_sems = ArenaAlloc(renderer.perm_arena, sizeof(VkSemaphore) * img_count); - renderer.vk.frame.render_fences = ArenaAlloc(renderer.perm_arena, sizeof(VkFence) * img_count); + renderer.vk.frame.pools = ArenaAlloc(renderer.perm_arena, sizeof(VkCommandPool) * img_count); + renderer.vk.frame.buffers = ArenaAlloc(renderer.perm_arena, sizeof(VkCommandBuffer) * img_count); + renderer.vk.frame.swapchain_sems = ArenaAlloc(renderer.perm_arena, sizeof(VkSemaphore) * img_count); + renderer.vk.frame.render_sems = ArenaAlloc(renderer.perm_arena, sizeof(VkSemaphore) * img_count); + renderer.vk.frame.render_fences = ArenaAlloc(renderer.perm_arena, sizeof(VkFence) * img_count); renderer.vk.frame.buffer_destroy_queues = ArenaAlloc(renderer.perm_arena, sizeof(RenderBuffer *) * FRAME_OVERLAP); - renderer.vk.frame.buffer_counts = ArenaAlloc(renderer.perm_arena, sizeof(u32) * FRAME_OVERLAP); + renderer.vk.frame.buffer_counts = ArenaAlloc(renderer.perm_arena, sizeof(u32) * FRAME_OVERLAP); for (u32 i = 0; i < FRAME_OVERLAP; i++) { @@ -751,25 +751,40 @@ static b32 CreateFrameStructures() static b32 CreateImmediateStructures() { - b32 success = true; + b32 success = true; VkResult result; - VkDevice device = renderer.vk.device; - ImmediateStructures *imm = &renderer.vk.imm; + VkDevice device = renderer.vk.device; + ImmediateStructures *imm = &renderer.vk.imm; + u8 thread_count = 1; pool_create_info.queueFamilyIndex = renderer.vk.queues.transfer; - result = vkCreateCommandPool(device, &pool_create_info, NULL, &imm->pool); - if (result != VK_SUCCESS) - success = false; + if (renderer.vk_conf.avail_threads >= 10) + thread_count = 3; + else if (renderer.vk_conf.avail_threads >= 8) + thread_count = 2; - cmd_buf_info.commandPool = imm->pool; + imm->pools = ArenaAlloc(renderer.perm_arena, sizeof(VkCommandPool) * thread_count); + imm->cmds = ArenaAlloc(renderer.perm_arena, sizeof(VkCommandBuffer) * thread_count); + imm->fences = ArenaAlloc(renderer.perm_arena, sizeof(VkFence) * thread_count); + imm->queued_buffers = ArenaAlloc(renderer.perm_arena, sizeof(RenderBuffer) * BUFFER_QUEUE_LEN); + imm->data = ArenaAlloc(renderer.perm_arena, sizeof(void *) * BUFFER_QUEUE_LEN); + + for (u32 i = 0; i < thread_count && success; i++) + { + result = vkCreateCommandPool(device, &pool_create_info, NULL, &imm->pools[i]); + if (result != VK_SUCCESS) + success = false; - result = vkAllocateCommandBuffers(device, &cmd_buf_info, &imm->cmd); - if (result != VK_SUCCESS) - success = false; + cmd_buf_info.commandPool = imm->pools[i]; - result = vkCreateFence(device, &fence_create_info, NULL, &imm->fence); - if (result != VK_SUCCESS) - success = false; + result = vkAllocateCommandBuffers(device, &cmd_buf_info, &imm->cmds[i]); + if (result != VK_SUCCESS) + success = false; + + result = vkCreateFence(device, &fence_create_info, NULL, &imm->fences[i]); + if (result != VK_SUCCESS) + success = false; + } return success; } @@ -997,6 +1012,7 @@ static b32 CreateDescriptors() { bindings[i].free = ArenaAlloc(renderer.perm_arena, sizeof(u16) * DESC_MAX_BINDINGS); bindings[i].used = ArenaAlloc(renderer.perm_arena, sizeof(u16) * DESC_MAX_BINDINGS); + bindings[i].handle_indices = ArenaAlloc(renderer.perm_arena, sizeof(DescHandle) * DESC_MAX_BINDINGS); u16 free_count = 0; for (i32 j = DESC_MAX_BINDINGS-1; j >= 0; j--) @@ -1115,6 +1131,54 @@ static b32 CreateShaderModule(u8 *bytes, u32 len, VkShaderModule *module) return success; } +#ifdef __linux__ + +void *VkLoaderStart(void *i) +{ + u32 index = *(u32 *)i; + pthread_t self = pthread_self(); + + for (;;) + { + u32 job_count = __atomic_load_n(&renderer.vk_conf.job_count, __ATOMIC_RELEASE); + if (job_count < 0) + { + pthread_exit(NULL); + } + + else if (job_count == 0) + { + __atomic_add_fetch(&renderer.vk_conf.sleeping_count, __ATOMIC_RELEASE); + pthread_suspend(self); + } + + else if (__atomic_compare_exchange_n(&renderer.vk_conf.job_count, &job_count, job_count-1, false, __ATOMIC_RELEASE, __ATOMIC_RELAXED)) + { + job_count -= 1; + + } + + } +} + +static b32 StartVkLoaderThreads() +{ + u32 count = renderer.vk_conf.avail_threads; + pthread_t *threads = ArenaAlloc(renderer.perm_arena, sizeof(pthread_t) * count); + + for (u32 i = 0; i < count; i++) + { + vk_thread_indices[i] = i; + pthread_create(&threads[i], NULL, VkLoaderStart, &vk_thread_indices[i]); + } +} + +#elif _WIN32 + +#error not yet implemented + +#endif + static void DestroySwapchain() { for (u32 i = 0; i < renderer.vk.sc.img_count; i++) diff --git a/src/renderer_vulkan.h b/src/renderer_vulkan.h index b2c92dd..f7d3581 100644 --- a/src/renderer_vulkan.h +++ b/src/renderer_vulkan.h @@ -16,7 +16,7 @@ #include "file_data/spv.c" -// Macros +// ::Vulkan::Macros::Header:: #define VK_DECLARE(fn) static PFN_##fn fn = NULL #define STYPE(type) VK_STRUCTURE_TYPE_ ## type @@ -36,19 +36,14 @@ if (!name) return false; \ } while (0) -#define FRAME_OVERLAP 2 -#define DESC_MAX_BINDINGS 256 +// ::Vulkan::GlobalFunctions::Header:: -// Macros END - -// Vulkan Functions - -// Global VK_DECLARE(vkGetInstanceProcAddr); VK_DECLARE(vkCreateInstance); VK_DECLARE(vkEnumerateInstanceLayerProperties); -// Instance +// ::Vulkan::InstanceFunctions::Header:: + VK_DECLARE(vkEnumeratePhysicalDevices); VK_DECLARE(vkCreateDevice); VK_DECLARE(vkGetPhysicalDeviceQueueFamilyProperties); @@ -61,6 +56,8 @@ VK_DECLARE(vkGetPhysicalDeviceSurfaceFormatsKHR); VK_DECLARE(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); VK_DECLARE(vkGetPhysicalDeviceImageFormatProperties); +// ::Vulkan::PlatformFunctions::Header:: + #ifdef __linux__ VK_DECLARE(vkCreateXcbSurfaceKHR); #elif _WIN32 @@ -77,7 +74,8 @@ VK_DECLARE(vkCreateDebugUtilsMessengerEXT); VK_DECLARE(vkDestroyDebugUtilsMessengerEXT); #endif -// Device +// ::Vulkan::DeviceFunctions::Header:: + VK_DECLARE(vkGetDeviceProcAddr); VK_DECLARE(vkCreateSwapchainKHR); VK_DECLARE(vkCreateImage); @@ -139,14 +137,16 @@ VK_DECLARE(vkCmdDraw); VK_DECLARE(vkDeviceWaitIdle); VK_DECLARE(vkCmdClearColorImage); -// Vulkan Functions END - #include "vma/vk_mem_alloc.h" -// Defines +// ::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) -// Types +// ::Vulkan::Types::Header:: typedef enum DescType_e { @@ -165,18 +165,18 @@ typedef struct ShaderGlobals_t typedef struct RenderBuffer_t { - RenderBufferType type; - VkBuffer buffer; - VmaAllocation alloc; + RenderBufferType type; + VkBuffer buffer; + VmaAllocation alloc; VmaAllocationInfo info; - u32 size; - i32 mem_index; // TODO(MA): use this + u32 size; + i32 mem_index; // TODO(MA): use this } RenderBuffer; typedef struct { RenderBuffer index_buf, vertex_buf; - u32 index_count; + u32 index_count; } MeshBuffer; typedef struct @@ -186,21 +186,22 @@ typedef struct typedef struct { - u16 *free; - u16 free_count; - u16 *used; - u16 used_count; + u16 *free; + u16 free_count; + u16 *used; + u16 used_count; + DescHandle *handle_indices; } DescBindings; typedef struct { - VkPipelineLayout pipeline_layout; - VkDescriptorPool pool; + VkPipelineLayout pipeline_layout; + VkDescriptorPool pool; VkDescriptorSetLayout layouts[DESC_TYPE_MAX]; - VkDescriptorSet sets[DESC_TYPE_MAX]; - DescBindings *bindings; - u16 bindings_count; - VkPipeline pipelines[PIPELINE_MAX]; + VkDescriptorSet sets[DESC_TYPE_MAX]; + DescBindings *bindings; + u16 bindings_count; + VkPipeline pipelines[PIPELINE_MAX]; } PipelineStructures; typedef struct PushConst_t @@ -210,70 +211,75 @@ typedef struct PushConst_t typedef struct { - VkCommandPool *pools; + VkCommandPool *pools; VkCommandBuffer *buffers; - VkSemaphore *swapchain_sems; - VkSemaphore *render_sems; - VkFence *render_fences; - RenderBuffer **buffer_destroy_queues; - u32 *buffer_counts; + VkSemaphore *swapchain_sems; + VkSemaphore *render_sems; + VkFence *render_fences; + RenderBuffer **buffer_destroy_queues; + u32 *buffer_counts; } FrameStructures; typedef struct { - VkCommandPool pool; - VkCommandBuffer cmd; - VkFence fence; + VkCommandPool *pools; + VkCommandBuffer *cmds; + VkFence *fences; + RenderBuffer **queued_buffers; + void *data; + i32 volatile job_count; + i32 volatile completed_count; + i32 volatile sleeping_count; } ImmediateStructures; typedef struct { - i32 graphics, transfer; + i32 graphics, transfer; VkQueue graphics_queue, transfer_queue; } DeviceQueues; typedef struct { - VkImage img; - VkImageView view; + VkImage img; + VkImageView view; VmaAllocation alloc; - VkFormat fmt; + VkFormat fmt; VkImageLayout curr_layout; } Image; typedef struct { - VkFormat format; - VkColorSpaceKHR color_space; + VkFormat format; + VkColorSpaceKHR color_space; VkPresentModeKHR present_mode; - VkExtent3D extent; - VkImage *imgs; - VkImageView *views; - u32 img_count; - Image draw_img; - Image depth_img; + VkExtent3D extent; + VkImage *imgs; + VkImageView *views; + u32 img_count; + Image draw_img; + Image depth_img; } SwapchainStructures; typedef struct { - u32 img_ix; - u64 frame_cnt; - u64 prev_frame; - b8 begin_rendering; + u32 img_ix; + u64 frame_cnt; + u64 prev_frame; + b8 begin_rendering; PipelineHandle last_pipeline; - RenderBuffer *prev_buffers; - u32 prev_buffer_count; + RenderBuffer *prev_buffers; + u32 prev_buffer_count; } 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; + 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 @@ -282,21 +288,33 @@ typedef struct { typedef struct { u16 render_width; u16 render_height; - b8 resized; + b8 resized; } PendingUpdates; +typedef struct VulkanConfig_t +{ + u8 avail_threads; +#ifdef __linux__ + pthread_t *threads; +#elif _WIN32 + #error not yet implemented +#endif +} VulkanConfig; + typedef struct Renderer_t { - Vulkan_t vk; - FrameState frame_state; + Vulkan_t vk; + VulkanConfig vk_conf; + FrameState frame_state; PendingUpdates pending; - Arena *arena; - Arena *perm_arena; + Arena *arena; + Arena *perm_arena; } Renderer; -// Renderer Function Declarations +// ::Vulkan::Functions::Header:: + +// ::Vulkan::Debug::Header:: -// Debug static b32 VLayersSupported(); static VKAPI_ATTR VkBool32 DebugCallback( VkDebugUtilsMessageSeverityFlagBitsEXT message_severity, @@ -306,7 +324,8 @@ static VKAPI_ATTR VkBool32 DebugCallback( ); const char *VkResultStr(VkResult result); -// Init +// ::Vulkan::Init::Header:: + static b32 LoadVulkanLib(); static b32 InitVkInstanceFunctions(); static b32 InitVkGlobalFunctions(); @@ -326,8 +345,10 @@ static VkFormat GetImageFormat(); static b32 CreateDescriptors(); static b32 CreatePipelines(); static b32 CreateShaderModule(u8 *bytes, u32 len, VkShaderModule *module); +static b32 StartVkLoaderThreads(); + +// ::Vulkan::Util::Header:: -// Util static inline VkCommandBuffer GetFrameCmdBuf(); static inline VkFence *GetFrameRenderFence(); static inline VkSemaphore GetFrameRenderSem(); @@ -338,36 +359,49 @@ static inline u32 *GetFrameBufferCount(); static inline RenderBuffer *GetFrameRenderBuffers(); static void BeginRendering(); -// Immediate Submit +// ::Vulkan::Async::Header:: +#ifdef __linux__ +void *VkLoaderStart(void *thread_data); +#elif _WIN32 +#error not yet implemented +#endif + +// ::Vulkan::ImmediateSubmit::Header:: + static b32 BeginImmSubmit(VkDevice device, VkFence *fence, VkCommandBuffer cmd); static b32 FinishImmSubmit(VkDevice device, VkFence *fence, VkCommandBuffer cmd, VkQueue queue); -// Buffers +// ::Vulkan::Buffers::Header:: + static b32 UploadGUIBuffer(MeshBuffer *buf, GUIContext *ctx); -// Destroy +// ::Vulkan::Destroy::Header:: + static void DestroySwapchain(); static void DestroyDrawImages(); -// Util +// ::Vulkan::Util::Header:: + static void TransitionImage(VkCommandBuffer cmd, Image *img, VkImageLayout new); static void TransitionImageLayout(VkCommandBuffer cmd, VkImage img, VkImageLayout curr, VkImageLayout new); static void CopyImageToImage(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent2D dst_ext); -// Swapchain +// ::Vulkan::Swapchain::Header:: + static VkExtent2D SelectSwapchainExtent(VkSurfaceCapabilitiesKHR *capabilities); static VkSurfaceFormatKHR SelectSwapchainFormat(VkSurfaceFormatKHR *formats); static void ResizeSwapchain(); -// Logging +// ::Vulkan::Logging::Header:: + static void VkInfo(const char *str); static void VkWarn(const char *str); static void VkError(const char *str); -// Renderer Functions Declarations END - #include "vulkan_config.c" +// ::Vulkan::Globals::Header:: + static Renderer renderer = { .vk = { .queues = { @@ -382,6 +416,10 @@ static Renderer renderer = { } }; +static u32 vk_thread_indices[10] = {}; + +// ::Vulkan::Constants::Header:: + static const char *_VK_VALIDATION = "VK_LAYER_KHRONOS_validation"; #if __linux__ diff --git a/src/renderer_vulkan_public.c b/src/renderer_vulkan_public.c index c88d06b..b45583a 100644 --- a/src/renderer_vulkan_public.c +++ b/src/renderer_vulkan_public.c @@ -3,6 +3,8 @@ */ b32 InitRenderer(Arena *arena) { + SetRendererAvailableThreads(AvailableCPUCount()); + CustomizePipelines(); Assert(arena != NULL, "Vulkan memory is null"); @@ -39,6 +41,7 @@ b32 InitRenderer(Arena *arena) Assert(CreateImmediateStructures(), "Unable to create immediate structures"); Assert(CreateDescriptors(), "Unable to initialize descriptors."); Assert(CreatePipelines(), "Unable to initialize pipelines."); + Assert(StartVkLoaderThreads(), "Unable to initialize vulkan loader threads"); ArenaFree(renderer.arena); @@ -74,9 +77,12 @@ void DestroyRenderer() DestroySwapchain(); - vkDestroyFence(device, imm.fence, NULL); - vkFreeCommandBuffers(device, imm.pool, 1, &imm.cmd); - vkDestroyCommandPool(device, imm.pool, NULL); + for (u32 i = 0; i < renderer.vk_conf.avail_threads; i++) + { + vkDestroyFence(device, imm.fences[i], NULL); + vkFreeCommandBuffers(device, imm.pools[i], 1, &imm.cmds[i]); + vkDestroyCommandPool(device, imm.pools[i], NULL); + } for (u32 i = 0; i < FRAME_OVERLAP; i++) { @@ -196,14 +202,15 @@ static b32 CreateBuffer(RenderBuffer *buffer) return success; } -static b32 UploadToBuffer(RenderBuffer *buffer, rawptr ptr) +static b32 UploadToBuffer(RenderBuffer *buffer, rawptr ptr, u8 thr_ix) { Assert(buffer, "UploadToBuffer: buffer must not be null"); Assert(ptr, "UploadToBuffer: ptr must not be null"); b32 success = true; - ImmediateStructures *imm = &renderer.vk.imm; + VkCommandBuffer cmd = renderer.vk.imm.cmds[thr_ix]; + VkFence fence = renderer.vk.imm.fences[thr_ix]; VkDevice device = renderer.vk.device; VkQueue queue = renderer.vk.queues.transfer_queue; VmaAllocator alloc = renderer.vk.alloc; @@ -231,18 +238,18 @@ static b32 UploadToBuffer(RenderBuffer *buffer, rawptr ptr) } if (success) - success = BeginImmSubmit(device, &imm->fence, imm->cmd); + success = BeginImmSubmit(device, &fence, cmd); b32 imm_started = success; if (success) { VkBufferCopy buffer_copy = { .size = (VkDeviceSize)buffer->size }; - vkCmdCopyBuffer(imm->cmd, staging_buffer.buffer, buffer->buffer, 1, &buffer_copy); + vkCmdCopyBuffer(cmd, staging_buffer.buffer, buffer->buffer, 1, &buffer_copy); } if (imm_started) - FinishImmSubmit(device, &imm->fence, imm->cmd, queue); + FinishImmSubmit(device, &fence, cmd, queue); if (buffer_created) { @@ -254,6 +261,17 @@ static b32 UploadToBuffer(RenderBuffer *buffer, rawptr ptr) return success; } +static void CreateAndUploadToBuffer(RenderBuffer *buffer, rawptr ptr) +{ + // TODO: revisit this to see if it could be done better + + u32 i = __atomic_fetch_add(&renderer.vk.imm.job_count, 1, __ATOMIC_RELEASE); + + renderer.vk.imm.queued_buffers[i] = buffer; + renderer.vk.imm.data[i] = ptr; +} + +/* TODO: DELETE static b32 CreateAndUploadToBuffer(RenderBuffer *buffer, rawptr ptr) { b32 success = true; @@ -261,10 +279,11 @@ static b32 CreateAndUploadToBuffer(RenderBuffer *buffer, rawptr ptr) success = CreateBuffer(buffer); if (success) - success = UploadToBuffer(buffer, ptr); + success = UploadToBuffer(buffer, ptr, 0); // TODO: DELETE this return success; } +*/ static void FreeBuffers(RenderBuffer *buffers, u32 buffer_count) { @@ -348,6 +367,11 @@ static void SetRenderResolution(u32 x, u32 y) renderer.pending.resized = true; } +static void SetRendererAvailableThreads(u32 n) +{ + renderer.vk_conf.avail_threads = n; +} + /* * ::Config::End:: */