abstract ticket mutexes
This commit is contained in:
parent
963554cd85
commit
45b8f96d34
@ -228,8 +228,6 @@ static void FreeListInit(FLAlloc *alloc, usize size)
|
||||
alloc->lists = MemAllocZeroed(sizeof(FreeList *) * 16);
|
||||
alloc->list_count = 1;
|
||||
alloc->list_capacity = 16;
|
||||
alloc->ticket = 0;
|
||||
alloc->next_ticket = 0;
|
||||
alloc->nil = &FL_NIL_NODE;
|
||||
alloc->grow_size = size;
|
||||
|
||||
@ -248,8 +246,7 @@ static void _FreeListInit(FreeList **alloc, usize size)
|
||||
|
||||
static void FreeListFreeAll(FLAlloc *alloc)
|
||||
{
|
||||
u32 ticket = __atomic_fetch_add(&alloc->ticket, 1, __ATOMIC_SEQ_CST);
|
||||
while (ticket != alloc->next_ticket);
|
||||
TicketMutLock(&alloc->mut);
|
||||
|
||||
if (alloc->list_count > 1)
|
||||
{
|
||||
@ -269,9 +266,7 @@ static void FreeListFreeAll(FLAlloc *alloc)
|
||||
alloc->lists[0]->head = node;
|
||||
alloc->lists[0]->used = sizeof(FreeList);
|
||||
|
||||
__atomic_thread_fence(__ATOMIC_RELEASE);
|
||||
|
||||
__atomic_fetch_add(&alloc->next_ticket, 1, __ATOMIC_SEQ_CST);
|
||||
TicketMutUnlock(&alloc->mut);
|
||||
}
|
||||
|
||||
static FLNode *FreeListSearch(FreeList *alloc, usize size, usize alignment, usize *out_padding, FLNode **prev_node)
|
||||
@ -384,8 +379,7 @@ static rawptr FreeListAllocAlign(FLAlloc *alloc, usize size, usize alignment)
|
||||
GlobalFreeListInit(FL_GLOBAL_SIZE);
|
||||
}
|
||||
|
||||
u32 ticket = __atomic_fetch_add(&alloc->ticket, 1, __ATOMIC_SEQ_CST);
|
||||
while (ticket != alloc->next_ticket);
|
||||
TicketMutLock(&alloc->mut);
|
||||
|
||||
FreeList *fl = NULL;
|
||||
for (u32 i = 0; i < alloc->list_count; i++)
|
||||
@ -406,9 +400,7 @@ static rawptr FreeListAllocAlign(FLAlloc *alloc, usize size, usize alignment)
|
||||
|
||||
rawptr ptr = _FreeListAllocAlign(fl, size, alignment);
|
||||
|
||||
__atomic_thread_fence(__ATOMIC_RELEASE);
|
||||
|
||||
__atomic_add_fetch(&alloc->next_ticket, 1, __ATOMIC_SEQ_CST);
|
||||
TicketMutUnlock(&alloc->mut);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
@ -443,8 +435,7 @@ static void FreeListFree(FLAlloc *alloc, rawptr ptr)
|
||||
{
|
||||
if (ptr == NULL) return;
|
||||
|
||||
u32 ticket = __atomic_fetch_add(&alloc->ticket, 1, __ATOMIC_SEQ_CST);
|
||||
while (ticket != alloc->next_ticket);
|
||||
TicketMutLock(&alloc->mut);
|
||||
|
||||
for (u32 i = 0; i < alloc->list_count; i++)
|
||||
{
|
||||
@ -458,7 +449,7 @@ static void FreeListFree(FLAlloc *alloc, rawptr ptr)
|
||||
}
|
||||
}
|
||||
|
||||
__atomic_fetch_add(&alloc->next_ticket, 1, __ATOMIC_SEQ_CST);
|
||||
TicketMutUnlock(&alloc->mut);
|
||||
}
|
||||
|
||||
static void FreeListCoalescence(FreeList *alloc, FLNode *prev_node, FLNode *free_node)
|
||||
|
||||
@ -83,13 +83,12 @@ typedef struct FreeList
|
||||
|
||||
typedef struct FLAlloc
|
||||
{
|
||||
FreeList **lists;
|
||||
u32 list_count;
|
||||
u32 list_capacity;
|
||||
u32 volatile ticket;
|
||||
u32 volatile next_ticket;
|
||||
FLNode *nil;
|
||||
usize grow_size;
|
||||
FreeList **lists;
|
||||
TicketMut mut;
|
||||
u32 list_count;
|
||||
u32 list_capacity;
|
||||
FLNode *nil;
|
||||
usize grow_size;
|
||||
} FLAlloc;
|
||||
|
||||
static void GlobalFreeListInit(usize size);
|
||||
|
||||
14
src/assets.c
14
src/assets.c
@ -14,6 +14,10 @@ static Asset Texture_Asset_Lookup[TEXTURE_ASSET_MAX];
|
||||
static AssetFile Shader_Assets[SHADER_ASSET_MAX];
|
||||
static Asset Shader_Asset_Lookup[SHADER_ASSET_MAX];
|
||||
|
||||
// TODO(MA): Implement async asset handling
|
||||
static u32 Shader_Asset_Ref_Count[SHADER_ASSET_MAX];
|
||||
static u32 Texture_Asset_Ref_Count[TEXTURE_ASSET_MAX];
|
||||
|
||||
static b32 ASSET_HEADER_LOADED = false;
|
||||
|
||||
|
||||
@ -42,7 +46,7 @@ static void LoadAssetPackHeader()
|
||||
|
||||
// ::Assets::Loading::Functions::Start::
|
||||
|
||||
static Asset LoadTextureAsset(TextureAsset asset_id)
|
||||
static Asset AssetPackLoadTexture(TextureAsset asset_id)
|
||||
{
|
||||
if (!ASSET_HEADER_LOADED)
|
||||
{
|
||||
@ -74,7 +78,7 @@ static Asset LoadTextureAsset(TextureAsset asset_id)
|
||||
return asset;
|
||||
}
|
||||
|
||||
static Asset LoadShaderAsset(ShaderAsset asset_id)
|
||||
static Asset AssetPackLoadShader(ShaderAsset asset_id)
|
||||
{
|
||||
if (!ASSET_HEADER_LOADED)
|
||||
{
|
||||
@ -96,7 +100,7 @@ static Asset LoadShaderAsset(ShaderAsset asset_id)
|
||||
return asset;
|
||||
}
|
||||
|
||||
static void UnloadTextureAsset(Asset asset)
|
||||
static void AssetPackUnloadTexture(Asset asset)
|
||||
{
|
||||
Assert(asset.bytes != NULL, "UnloadTextureAsset assert failure: ptr is NULL");
|
||||
|
||||
@ -107,12 +111,13 @@ static void UnloadTextureAsset(Asset asset)
|
||||
Texture_Asset_Lookup[i].bytes = NULL;
|
||||
Texture_Asset_Lookup[i].len = 0;
|
||||
stbi_image_free(asset.bytes);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void UnloadShaderAsset(Asset asset)
|
||||
static void AssetPackUnloadShader(Asset asset)
|
||||
{
|
||||
Assert(asset.bytes != NULL, "UnloadShaderAsset assert failure: ptr is NULL");
|
||||
|
||||
@ -123,6 +128,7 @@ static void UnloadShaderAsset(Asset asset)
|
||||
Shader_Asset_Lookup[i].bytes = NULL;
|
||||
Shader_Asset_Lookup[i].len = 0;
|
||||
FLMemFree(asset.bytes);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
19
src/assets.h
19
src/assets.h
@ -101,10 +101,19 @@ typedef struct FileHeader
|
||||
u64 asset_offsets[ASSET_TYPE_MAX];
|
||||
} FileHeader;
|
||||
|
||||
// ::Assets::Init::Functions::Header::
|
||||
|
||||
static void AssetPackLoadHeader();
|
||||
|
||||
// ::Assets::Loading::Functions::Header::
|
||||
|
||||
static void LoadAssetPackHeader();
|
||||
static Asset LoadTextureAsset(TextureAsset asset_id);
|
||||
static Asset LoadShaderAsset(ShaderAsset asset_id);
|
||||
static void UnloadTextureAsset(Asset asset);
|
||||
static void UnloadShaderAsset(Asset asset);
|
||||
static Asset AssetPackLoadTexture(TextureAsset asset_id);
|
||||
static Asset AssetPackLoadShader(ShaderAsset asset_id);
|
||||
static void AssetPackUnloadTexture(Asset asset);
|
||||
static void AssetPackUnloadShader(Asset asset);
|
||||
|
||||
// ::Assets::Util::Functions::Header::
|
||||
|
||||
// TODO(MA): Implement async asset handling
|
||||
static inline b32 AssetPackMarkUnloaded(AssetType type, u32 index);
|
||||
static inline void AssetPackMarkLoaded(AssetType type, u32 index);
|
||||
|
||||
@ -70,3 +70,8 @@ b8 DirVisible(c8 *dir_name);
|
||||
static u64 GetOSTimerFreq();
|
||||
static u64 ReadOSTimer();
|
||||
static inline u64 ReadCPUTimer();
|
||||
|
||||
// ::Platform::Atomics::Header::
|
||||
|
||||
static inline u32 AtomicFetchIncrU32(u32 *ptr);
|
||||
static inline void AtomicIncrU32(u32 *ptr);
|
||||
|
||||
@ -329,3 +329,19 @@ static inline u64 ReadCPUTimer()
|
||||
}
|
||||
|
||||
// ::Platform::Profiling::Functions::End::
|
||||
|
||||
|
||||
|
||||
// ::Platform::Atomics::Functions::Start::
|
||||
|
||||
static inline u32 AtomicFetchIncrU32(u32 *ptr)
|
||||
{
|
||||
return __atomic_fetch_add(ptr, 1, __ATOMIC_ACQUIRE);
|
||||
}
|
||||
|
||||
static inline void AtomicIncrU32(u32 *ptr)
|
||||
{
|
||||
__atomic_fetch_add(ptr, 1, __ATOMIC_RELEASE);
|
||||
}
|
||||
|
||||
// ::Platform::Atomics::Functions::End::
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
// ::Renderer::Declarations::Header::
|
||||
|
||||
typedef u16 DescHandle;
|
||||
typedef u32 DescHandle;
|
||||
|
||||
// @requirement RenderBuffer type;
|
||||
// @requirement u32 size;
|
||||
@ -50,6 +50,8 @@ typedef struct RenderBuffers
|
||||
u32 len;
|
||||
} RenderBuffers;
|
||||
|
||||
typedef u32 AssetHandle;
|
||||
|
||||
// ::Renderer::Initialization::Header::
|
||||
|
||||
b32 InitRenderer(Arena *arena);
|
||||
@ -63,6 +65,7 @@ static b32 UploadToBuffer(RenderBuffer **buffer, rawptr *ptr, u32 count, u8 thr_
|
||||
static void CreateAndUploadToBuffer(RenderBuffer *buffer, rawptr ptr);
|
||||
static void BindVertexBuffer(RenderBuffer *buffer);
|
||||
static void BindIndexBuffer(RenderBuffer *buffer);
|
||||
static AssetHandle RendererLoadTexture(TextureAsset asset_id);
|
||||
|
||||
// ::Renderer::Uniforms::Header::
|
||||
// ::Renderer::PushConstants::Header::
|
||||
|
||||
@ -11,9 +11,6 @@ static Renderer renderer = {
|
||||
.color_space = INT_MAX,
|
||||
.present_mode = INT_MAX,
|
||||
},
|
||||
.imm = {
|
||||
.next_ticket = 1,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@ -318,6 +315,39 @@ static void ResizeSwapchain()
|
||||
|
||||
|
||||
|
||||
// ::Vulkan::Descriptors::Functions::Start::
|
||||
|
||||
static DescAssetInfo *DescriptorTableSearch(DescType type, u64 asset_id)
|
||||
{
|
||||
DescAssetInfo *asset_info = NULL;
|
||||
|
||||
HashTable *table = &renderer.vk.pipe.bindings[type].lookup_table;
|
||||
|
||||
KeyValuePair *kv_pair = HashTableSearchU64(table, asset_id);
|
||||
if (kv_pair != NULL)
|
||||
{
|
||||
asset_info = (DescAssetInfo *)kv_pair->value_rawptr;
|
||||
}
|
||||
|
||||
return asset_info;
|
||||
}
|
||||
|
||||
static void DescriptorTableInsert(DescType type, u64 asset_id, DescHandle handle)
|
||||
{
|
||||
DescAssetInfo *asset_info = FLMemAlloc(sizeof(DescAssetInfo));
|
||||
|
||||
asset_info->handle = handle;
|
||||
asset_info->type = type;
|
||||
asset_info->asset_id = asset_id;
|
||||
|
||||
HashTable *table = &renderer.vk.pipe.bindings[type].lookup_table;
|
||||
HashTablePushU64Rawptr(table, asset_id, asset_info);
|
||||
}
|
||||
|
||||
// ::Vulkan::Descriptors::Functions::End::
|
||||
|
||||
|
||||
|
||||
// ::Vulkan::Init::Functions::Start::
|
||||
|
||||
static b32 CreateVmaAllocator()
|
||||
@ -1045,7 +1075,8 @@ 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);
|
||||
|
||||
HashTableInit(&bindings[i].lookup_table, 6);
|
||||
|
||||
u16 free_count = 0;
|
||||
for (i32 j = DESC_MAX_BINDINGS-1; j >= 0; j--)
|
||||
@ -1056,6 +1087,7 @@ static b32 CreateDescriptors()
|
||||
bindings[i].free_count = free_count;
|
||||
}
|
||||
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@ -1065,8 +1097,8 @@ static b32 CreatePipelines()
|
||||
VkResult result;
|
||||
VkDevice device = renderer.vk.device;
|
||||
|
||||
Asset quad_vert_shader = LoadShaderAsset(QUAD_VERT_SPIRV_SHADER);
|
||||
Asset quad_frag_shader = LoadShaderAsset(QUAD_FRAG_SPIRV_SHADER);
|
||||
Asset quad_vert_shader = AssetPackLoadShader(QUAD_VERT_SPIRV_SHADER);
|
||||
Asset quad_frag_shader = AssetPackLoadShader(QUAD_FRAG_SPIRV_SHADER);
|
||||
|
||||
VkShaderModule cube_vert, cube_frag;
|
||||
success &= CreateShaderModule(quad_vert_shader.bytes, quad_vert_shader.len, &cube_vert);
|
||||
@ -1109,11 +1141,11 @@ static b32 CreatePipelines()
|
||||
vkDestroyShaderModule(device, cube_vert, NULL);
|
||||
vkDestroyShaderModule(device, cube_frag, NULL);
|
||||
|
||||
UnloadShaderAsset(quad_vert_shader);
|
||||
UnloadShaderAsset(quad_frag_shader);
|
||||
AssetPackUnloadShader(quad_vert_shader);
|
||||
AssetPackUnloadShader(quad_frag_shader);
|
||||
|
||||
Asset gui_vert_shader = LoadShaderAsset(GUI_VERT_SPIRV_SHADER);
|
||||
Asset gui_frag_shader = LoadShaderAsset(GUI_FRAG_SPIRV_SHADER);
|
||||
Asset gui_vert_shader = AssetPackLoadShader(GUI_VERT_SPIRV_SHADER);
|
||||
Asset gui_frag_shader = AssetPackLoadShader(GUI_FRAG_SPIRV_SHADER);
|
||||
|
||||
VkShaderModule gui_vert, gui_frag;
|
||||
success &= CreateShaderModule(gui_vert_shader.bytes, gui_vert_shader.len, &gui_vert);
|
||||
@ -1149,8 +1181,8 @@ static b32 CreatePipelines()
|
||||
vkDestroyShaderModule(device, gui_vert, NULL);
|
||||
vkDestroyShaderModule(device, gui_frag, NULL);
|
||||
|
||||
UnloadShaderAsset(gui_vert_shader);
|
||||
UnloadShaderAsset(gui_frag_shader);
|
||||
AssetPackUnloadShader(gui_vert_shader);
|
||||
AssetPackUnloadShader(gui_frag_shader);
|
||||
|
||||
return success;
|
||||
}
|
||||
@ -1216,20 +1248,17 @@ void *VkLoaderStart(void *i)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// TODO: Benchmark and test with __ATOMIC_RELEASE
|
||||
u32 ticket = __atomic_add_fetch(&renderer.vk.imm.ticket, 1, __ATOMIC_SEQ_CST);
|
||||
|
||||
while (ticket != renderer.vk.imm.next_ticket);
|
||||
TicketMutLock(&renderer.vk.imm.mut);
|
||||
|
||||
u32 job_count = __atomic_load_n(&renderer.vk.imm.job_count, __ATOMIC_SEQ_CST);
|
||||
if (job_count < 0)
|
||||
{
|
||||
__atomic_store_n(&renderer.vk.imm.next_ticket, renderer.vk.imm.next_ticket+1, __ATOMIC_SEQ_CST);
|
||||
TicketMutUnlock(&renderer.vk.imm.mut);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
else if (job_count == 0)
|
||||
{
|
||||
__atomic_store_n(&renderer.vk.imm.next_ticket, renderer.vk.imm.next_ticket+1, __ATOMIC_SEQ_CST);
|
||||
TicketMutUnlock(&renderer.vk.imm.mut);
|
||||
pthread_mutex_lock(&mut);
|
||||
pthread_cond_wait(&cond, &mut);
|
||||
pthread_mutex_unlock(&mut);
|
||||
@ -1247,14 +1276,15 @@ void *VkLoaderStart(void *i)
|
||||
}
|
||||
|
||||
__atomic_sub_fetch(&renderer.vk.imm.job_count, count, __ATOMIC_SEQ_CST);
|
||||
__atomic_store_n(&renderer.vk.imm.next_ticket, renderer.vk.imm.next_ticket+1, __ATOMIC_SEQ_CST);
|
||||
|
||||
TicketMutUnlock(&renderer.vk.imm.mut);
|
||||
|
||||
for (u32 i = 0; i < count; i++)
|
||||
Assert(CreateBuffer(buffers[i]), "VkLoader CreateBuffer failure");
|
||||
|
||||
Assert(UploadToBuffer(buffers, data, count, index), "VkLoader UploadToBuffer failure");
|
||||
|
||||
u32 rem = __atomic_sub_fetch(&renderer.vk.imm.remaining_count, count, __ATOMIC_SEQ_CST);
|
||||
u32 rem = __atomic_sub_fetch(&renderer.vk.imm.remaining_count, count, __ATOMIC_RELEASE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,13 +205,24 @@ typedef struct GlobalUniforms
|
||||
f32 res[2];
|
||||
} GlobalUniforms;
|
||||
|
||||
typedef struct DescAssetInfo
|
||||
{
|
||||
DescHandle handle;
|
||||
DescType type;
|
||||
union
|
||||
{
|
||||
u64 asset_id;
|
||||
TextureAsset texture_id;
|
||||
};
|
||||
} DescAssetInfo;
|
||||
|
||||
typedef struct DescBindings
|
||||
{
|
||||
u16 *free;
|
||||
u16 free_count;
|
||||
u16 *used;
|
||||
u16 used_count;
|
||||
DescHandle *handle_indices;
|
||||
HashTable lookup_table;
|
||||
} DescBindings;
|
||||
|
||||
typedef struct PipelineStructures
|
||||
@ -228,6 +239,7 @@ typedef struct PipelineStructures
|
||||
typedef struct PushConst
|
||||
{
|
||||
Vec2 res;
|
||||
Vec2 img_res;
|
||||
} PushConst;
|
||||
|
||||
typedef struct FrameStructures
|
||||
@ -250,8 +262,7 @@ typedef struct ImmediateStructures
|
||||
rawptr *data;
|
||||
i32 volatile job_count;
|
||||
i32 volatile remaining_count;
|
||||
u32 volatile ticket;
|
||||
u32 volatile next_ticket;
|
||||
TicketMut mut;
|
||||
} ImmediateStructures;
|
||||
|
||||
typedef struct DeviceQueues
|
||||
@ -332,7 +343,7 @@ typedef struct VulkanConfig
|
||||
|
||||
typedef struct Renderer
|
||||
{
|
||||
Vulkan vk;
|
||||
Vulkan vk;
|
||||
VulkanConfig vk_conf;
|
||||
FrameState frame_state;
|
||||
PendingUpdates pending;
|
||||
@ -389,6 +400,7 @@ static inline void TransitionImageLayout(VkCommandBuffer cmd, VkImage img, VkIma
|
||||
static inline void CopyImageToImage(VkCommandBuffer cmd, VkImage src, VkImage dst, VkExtent2D src_ext, VkExtent2D dst_ext);
|
||||
|
||||
// ::Vulkan::Async::Functions::Header::
|
||||
|
||||
#ifdef __linux__
|
||||
void *VkLoaderStart(void *thread_data);
|
||||
#elif _WIN32
|
||||
@ -404,15 +416,19 @@ static b32 FinishImmSubmit(VkDevice device, VkFence *fence, VkCommandBuffer cmd,
|
||||
|
||||
static void BeginRendering();
|
||||
|
||||
// ::Vulkan::Swapchain::Functions::Header::
|
||||
|
||||
static void ResizeSwapchain();
|
||||
|
||||
// ::Vulkan::Descriptors::Functions::Header::
|
||||
|
||||
static DescAssetInfo *DescriptorTableSearch(DescType type, u64 asset_id);
|
||||
|
||||
// ::Vulkan::CleanUp::Functions::Header::
|
||||
|
||||
static void DestroySwapchain();
|
||||
static void DestroyDrawImages();
|
||||
|
||||
// ::Vulkan::Swapchain::Functions::Header::
|
||||
|
||||
static void ResizeSwapchain();
|
||||
|
||||
// ::Vulkan::Logging::Functions::Header::
|
||||
|
||||
static void VkInfo(const char *str);
|
||||
|
||||
@ -251,48 +251,6 @@ static b32 UploadToBuffer(RenderBuffer **buffers, rawptr *ptrs, u32 count, u8 th
|
||||
vmaUnmapMemory(alloc, staging_buffers[i].alloc);
|
||||
vmaDestroyBuffer(alloc, staging_buffers[i].buffer, staging_buffers[i].alloc);
|
||||
}
|
||||
/*
|
||||
if (host_visible)
|
||||
{
|
||||
vmaMapMemory(alloc, buffer->alloc, &mapped_buffer);
|
||||
MemCpy(mapped_buffer, ptr, buffer->size);
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderBuffer staging_buffer = { .type = RENDER_BUFFER_TYPE_STAGING, .size = buffer->size };
|
||||
|
||||
success = CreateBuffer(&staging_buffer);
|
||||
|
||||
b32 buffer_created = success;
|
||||
|
||||
if (success)
|
||||
{
|
||||
vmaMapMemory(alloc, staging_buffer.alloc, &mapped_buffer);
|
||||
MemCpy(mapped_buffer, ptr, staging_buffer.size);
|
||||
}
|
||||
|
||||
if (success)
|
||||
success = BeginImmSubmit(device, &fence, cmd);
|
||||
|
||||
b32 imm_started = success;
|
||||
|
||||
if (success)
|
||||
{
|
||||
VkBufferCopy buffer_copy = { .size = (VkDeviceSize)buffer->size };
|
||||
Printfln("copy buffer: %d", buffer->buffer);
|
||||
vkCmdCopyBuffer(cmd, staging_buffer.buffer, buffer->buffer, 1, &buffer_copy);
|
||||
}
|
||||
|
||||
if (imm_started)
|
||||
FinishImmSubmit(device, &fence, cmd, queue);
|
||||
|
||||
if (buffer_created)
|
||||
{
|
||||
vmaUnmapMemory(alloc, staging_buffer.alloc);
|
||||
vmaDestroyBuffer(alloc, staging_buffer.buffer, staging_buffer.alloc);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return success;
|
||||
}
|
||||
@ -302,9 +260,7 @@ static void CreateAndUploadToBuffer(RenderBuffer *buffer, rawptr ptr)
|
||||
// TODO: revisit this to see if it could be done better
|
||||
Assert(renderer.vk.imm.job_count+1 < BUFFER_QUEUE_LEN, "CreateAndUploadToBuffer out of bounds");
|
||||
|
||||
u32 ticket = __atomic_add_fetch(&renderer.vk.imm.ticket, 1, __ATOMIC_SEQ_CST);
|
||||
|
||||
while (ticket != renderer.vk.imm.next_ticket);
|
||||
TicketMutLock(&renderer.vk.imm.mut);
|
||||
|
||||
u32 i = __atomic_fetch_add(&renderer.vk.imm.job_count, 1, __ATOMIC_SEQ_CST);
|
||||
__atomic_fetch_add(&renderer.vk.imm.remaining_count, 1, __ATOMIC_SEQ_CST);
|
||||
@ -312,9 +268,7 @@ static void CreateAndUploadToBuffer(RenderBuffer *buffer, rawptr ptr)
|
||||
renderer.vk.imm.queued_buffers[i] = buffer;
|
||||
renderer.vk.imm.data[i] = ptr;
|
||||
|
||||
__atomic_thread_fence(__ATOMIC_RELEASE);
|
||||
|
||||
__atomic_add_fetch(&renderer.vk.imm.next_ticket, 1, __ATOMIC_SEQ_CST);
|
||||
TicketMutUnlock(&renderer.vk.imm.mut);
|
||||
}
|
||||
|
||||
static void FreeBuffers(RenderBuffer *buffers, u32 buffer_count)
|
||||
@ -353,6 +307,13 @@ static void BindIndexBuffer(RenderBuffer *buffer)
|
||||
vkCmdBindIndexBuffer(cmd, buffer->buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
}
|
||||
|
||||
static AssetHandle RendererLoadTexture(TextureAsset asset_id)
|
||||
{
|
||||
AssetHandle handle = 0;
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
// ::Vulkan::Renderer::Buffers::Functions::End::
|
||||
|
||||
|
||||
|
||||
@ -272,6 +272,7 @@ typedef struct GUIVertex
|
||||
Vec2 p0;
|
||||
Vec2 p1;
|
||||
Vec4 col;
|
||||
u32 tex_idx;
|
||||
} GUIVertex;
|
||||
|
||||
typedef struct GUIContext
|
||||
|
||||
17
src/util.c
17
src/util.c
@ -297,3 +297,20 @@ static inline void EndProfileBlock(ProfileBlock *block)
|
||||
}
|
||||
|
||||
// ::Util::Profiling::Functions::End::
|
||||
|
||||
|
||||
|
||||
// ::Util::Async::Functions::Start::
|
||||
|
||||
static inline void TicketMutLock(TicketMut *mut)
|
||||
{
|
||||
u32 ticket = AtomicFetchIncrU32(&mut->ticket);
|
||||
while (ticket != mut->next_ticket);
|
||||
}
|
||||
|
||||
static inline void TicketMutUnlock(TicketMut *mut)
|
||||
{
|
||||
AtomicIncrU32(&mut->next_ticket);
|
||||
}
|
||||
|
||||
// ::Util::Async::Functions::End::
|
||||
|
||||
11
src/util.h
11
src/util.h
@ -233,3 +233,14 @@ typedef struct Profiler
|
||||
static inline void StartProfileBlock(ProfileBlock *block, c8 *label, u32 anchor_index);
|
||||
static inline void EndProfileBlock(ProfileBlock *block);
|
||||
|
||||
|
||||
// ::Util::Async::Header::
|
||||
|
||||
typedef struct TicketMut
|
||||
{
|
||||
u32 volatile ticket;
|
||||
u32 volatile next_ticket;
|
||||
} TicketMut;
|
||||
|
||||
static inline void TicketMutLock(TicketMut *mut);
|
||||
static inline void TicketMutUnlock(TicketMut *mut);
|
||||
|
||||
@ -437,6 +437,7 @@ VkVertexInputAttributeDescription gui_input_descriptions[] = {
|
||||
{ .binding = 0, .location = 0, .format = VK_FORMAT_R32G32_SFLOAT, .offset = 0 },
|
||||
{ .binding = 0, .location = 1, .format = VK_FORMAT_R32G32_SFLOAT, .offset = offsetof(GUIVertex, p1) },
|
||||
{ .binding = 0, .location = 2, .format = VK_FORMAT_R32G32B32A32_SFLOAT, .offset = offsetof(GUIVertex, col) },
|
||||
{ .binding = 0, .location = 3, .format = VK_FORMAT_R32_UINT, .offset = offsetof(GUIVertex, tex_idx) },
|
||||
};
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo gui_vertex_input_info = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user