started work on async code

This commit is contained in:
Matthew 2025-03-25 23:06:24 +11:00
parent 0f14ffd37f
commit 4ab1abbc27
9 changed files with 317 additions and 123 deletions

View File

@ -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

View File

@ -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 <unistd.h>
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));

View File

@ -2,6 +2,8 @@
#pragma once
#define _GNU_SOURCE
#define STB_SPRINTF_IMPLEMENTATION
#define WINDOW_NAME "Video Game"

View File

@ -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);
}

View File

@ -1,5 +1,6 @@
#pragma once
#include <pthread.h>
#include <limits.h>
#include <stdint.h>
#include <stdbool.h>
@ -17,6 +18,9 @@
#include <stdlib.h>
#include <dlfcn.h>
#include <nmmintrin.h>
#include <immintrin.h>
#include <sched.h>
// 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);

View File

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

View File

@ -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++)

View File

@ -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__

View File

@ -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::
*/