work on asset loading queues
This commit is contained in:
parent
72e1b91e2a
commit
fee5f311f2
10
src/ds.c
10
src/ds.c
@ -434,9 +434,15 @@ static void HashTableInit(HashTable *table, u32 init_size)
|
||||
{
|
||||
table->cap = init_size;
|
||||
table->count = 0;
|
||||
table->lists = FLMemAlloc(sizeof(HashList) * init_size);
|
||||
table->free_lists.first = P_HT_NIL;
|
||||
table->free_lists.last = P_HT_NIL;
|
||||
|
||||
table->lists = FLMemAlloc(sizeof(HashList) * init_size);
|
||||
for (u32 i = 0; i < init_size; i++)
|
||||
{
|
||||
table->lists[i].first = P_HT_NIL;
|
||||
table->lists[i].last = P_HT_NIL;
|
||||
}
|
||||
}
|
||||
|
||||
static void HashTableConcatInPlace(HashList *list, HashList *to_concat)
|
||||
@ -561,7 +567,7 @@ static void HashTableDeleteU64(HashTable *table, u64 key)
|
||||
|
||||
node->v.key_u64 = 0;
|
||||
node->v.value_u64 = 0;
|
||||
HTQueuePush(ht->free_lists.first, ht->free_lists.last, node);
|
||||
HTQueuePush(table->free_lists.first, table->free_lists.last, node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,6 +72,7 @@ static void RunCycle(GameContext *ctx, GameInput *inputs, u32 i_count)
|
||||
|
||||
GetViewportSize(&ctx->pc.res);
|
||||
|
||||
//DescHandle pattermon = CreateAndUploadToTexture(PATTERMON_OBESE);
|
||||
|
||||
RenderBuffer *vertex_buffer = MakeArray(ctx->arena, RenderBuffer, 1);
|
||||
vertex_buffer->type = RENDER_BUFFER_TYPE_VERTEX;
|
||||
|
||||
@ -78,7 +78,7 @@ static inline u64 ReadCPUTimer();
|
||||
#define DefSigAtomicIncr(T) static inline void AtomicIncr##T(T *ptr)
|
||||
#define DefSigAtomicStore(T) static inline void AtomicStore##T(T *ptr, T value)
|
||||
#define DefSigAtomicLoad(T) static inline T AtomicLoad##T(T *ptr)
|
||||
#define DefSigAtomicCompareExchange(T) static inline T AtomicCompareExchange##T(T *ptr, T *expected, T desired)
|
||||
#define DefSigAtomicCompareExchange(T) static inline b32 AtomicCompareExchange##T(T *ptr, T *expected, T desired)
|
||||
|
||||
DefScalarSig(AtomicFetchIncr);
|
||||
DefScalarSig(AtomicFetchSub);
|
||||
|
||||
@ -46,9 +46,9 @@ typedef enum RenderBufferType_e
|
||||
|
||||
typedef enum TextureBufferType_e
|
||||
{
|
||||
IMAGE_BUFFER_TYPE_NONE = 0x0000,
|
||||
IMAGE_BUFFER_TYPE_IMAGE = 0x0001,
|
||||
IMAGE_BUFFER_TYPE_SAMPLER = 0x0002,
|
||||
TEXTURE_BUFFER_TYPE_NONE = 0x0000,
|
||||
TEXTURE_BUFFER_TYPE_IMAGE = 0x0001,
|
||||
TEXTURE_BUFFER_TYPE_SAMPLER = 0x0002,
|
||||
} TextureBufferType;
|
||||
|
||||
typedef enum VertexAttrType_e
|
||||
@ -78,7 +78,7 @@ static b32 CreateBuffer(RenderBuffer *buffer);
|
||||
static void FreeBuffers(RenderBuffer *buffers, u32 buffer_count);
|
||||
static b32 UploadToBuffer(RenderBuffer **buffer, rawptr *ptr, u32 count, u32 thr_ix);
|
||||
static void CreateAndUploadToBuffer(RenderBuffer *buffer, rawptr ptr);
|
||||
static DescHandle CreateAndUploadToTexture(TextureBuffer *buffer, rawptr ptr);
|
||||
static DescHandle CreateAndUploadToTexture(TextureAsset asset_id);
|
||||
static void BindVertexBuffer(RenderBuffer *buffer);
|
||||
static void BindIndexBuffer(RenderBuffer *buffer);
|
||||
static AssetHandle RendererLoadTexture(TextureAsset asset_id);
|
||||
|
||||
@ -344,6 +344,7 @@ static b32 CreateVkSampler(TextureBuffer *buffer)
|
||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.extent = {
|
||||
.width = buffer->width,
|
||||
.height = buffer->height,
|
||||
@ -427,14 +428,17 @@ static void UploadToImage(TextureBuffer *buffer, u8 *data, u32 thread_idx)
|
||||
u32 width = buffer->width;
|
||||
u32 height = buffer->height;
|
||||
u32 channels = buffer->channels;
|
||||
RenderBuffer staging_buffer;
|
||||
RenderBuffer staging_buffer = {
|
||||
.type = RENDER_BUFFER_TYPE_STAGING,
|
||||
.size = width * height * channels,
|
||||
};
|
||||
|
||||
TransitionImage(cmd, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
success = CreateBuffer(&staging_buffer);
|
||||
success = BeginImmSubmit(device, fence, cmd);
|
||||
|
||||
if (success)
|
||||
success = BeginImmSubmit(device, fence, cmd);
|
||||
Assert(CreateBuffer(&staging_buffer), "UploadToImage failure: error creating buffer");
|
||||
|
||||
if (success)
|
||||
{
|
||||
@ -471,6 +475,26 @@ static void UploadToImage(TextureBuffer *buffer, u8 *data, u32 thread_idx)
|
||||
|
||||
// ::Vulkan::Descriptors::Functions::Start::
|
||||
|
||||
static void DescriptorHandlePush(DescType type, DescHandle handle)
|
||||
{
|
||||
DescBindings *bindings = renderer.vk.pipe.bindings + type;
|
||||
|
||||
Assert(bindings->free_count < DESC_MAX_BINDINGS-1, "DescriptorHandlePush failure: free_count equal to DESC_MAX_BINDINGS-1");
|
||||
|
||||
bindings->free[bindings->free_count] = handle;
|
||||
bindings->free_count += 1;
|
||||
}
|
||||
|
||||
static DescHandle DescriptorHandlePop(DescType type)
|
||||
{
|
||||
DescBindings *bindings = renderer.vk.pipe.bindings + type;
|
||||
|
||||
Assert(bindings->free_count > 0, "DescriptorHandlePop failure: free_count is 0");
|
||||
|
||||
bindings->free_count -= 1;
|
||||
return bindings->free[bindings->free_count];
|
||||
}
|
||||
|
||||
static DescAssetInfo *DescriptorTableSearch(DescType type, u64 asset_id)
|
||||
{
|
||||
DescAssetInfo *asset_info = NULL;
|
||||
@ -501,9 +525,7 @@ static void DescriptorTableInsert(DescType type, u64 asset_id, DescHandle handle
|
||||
static void DescriptorTableDelete(DescType type, u64 asset_id)
|
||||
{
|
||||
HashTable *table = &renderer.vk.pipe.bindings[type].lookup_table;
|
||||
|
||||
|
||||
|
||||
HashTableDeleteU64(table, asset_id);
|
||||
}
|
||||
|
||||
// ::Vulkan::Descriptors::Functions::End::
|
||||
@ -657,6 +679,7 @@ static b32 CheckDeviceFeatureSupport(VkPhysicalDevice device)
|
||||
result &= (b32)features.shaderSampledImageArrayDynamicIndexing;
|
||||
result &= (b32)features.shaderStorageBufferArrayDynamicIndexing;
|
||||
result &= (b32)features.shaderStorageImageArrayDynamicIndexing;
|
||||
result &= (b32)features.samplerAnisotropy;
|
||||
|
||||
result &= (b32)features_12.descriptorIndexing;
|
||||
result &= (b32)features_12.bufferDeviceAddress;
|
||||
@ -1243,12 +1266,11 @@ static b32 CreateDescriptors()
|
||||
|
||||
for (u32 i = 0; i < DESC_TYPE_MAX; i++)
|
||||
{
|
||||
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].free = ArenaAlloc(renderer.perm_arena, sizeof(u32) * DESC_MAX_BINDINGS);
|
||||
|
||||
HashTableInit(&bindings[i].lookup_table, 6);
|
||||
|
||||
u16 free_count = 0;
|
||||
u32 free_count = 0;
|
||||
for (i32 j = DESC_MAX_BINDINGS-1; j >= 0; j--)
|
||||
{
|
||||
bindings[i].free[j] = free_count++;
|
||||
@ -1422,7 +1444,7 @@ static u32 VkLoaderProcessBuffers(u32 thread_index)
|
||||
|
||||
RenderBuffer *buffers[16];
|
||||
rawptr data[16];
|
||||
for (u32 i = buffer_count; i >= 0 && count < 16; i++)
|
||||
for (i32 i = i32(buffer_count - 1); i >= 0 && count < 16; i--)
|
||||
{
|
||||
buffers[count] = render_buffers[i];
|
||||
data[count] = buffer_data[i];
|
||||
@ -1459,7 +1481,7 @@ static u32 VkLoaderProcessSamplers(u32 thread_index)
|
||||
|
||||
TextureBuffer *buffers[16];
|
||||
rawptr data[16];
|
||||
for (u32 i = buffer_count; i >= 0 && count < 16; i++)
|
||||
for (i32 i = i32(buffer_count - 1); i >= 0 && count < 16; i--)
|
||||
{
|
||||
buffers[count] = texture_buffers[i];
|
||||
data[count] = texture_data[i];
|
||||
@ -1476,7 +1498,12 @@ static u32 VkLoaderProcessSamplers(u32 thread_index)
|
||||
UploadToImage(buffers[i], data[i], thread_index);
|
||||
}
|
||||
|
||||
JobQueueMarkCompleted(&renderer.vk.imm.texture_queue, count);
|
||||
JobQueueMarkCompleted(job_queue, count);
|
||||
|
||||
for (u32 i = 0; i < count; i++)
|
||||
{
|
||||
FLMemFree(buffers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
@ -1526,9 +1553,11 @@ void *VkLoaderStart(void *i)
|
||||
else if (processed_count == 0 && iter_count >= 3)
|
||||
{
|
||||
iter_count = 0;
|
||||
AtomicIncru8(&renderer.vk_conf.sleeping_threads);
|
||||
pthread_mutex_lock(&mut);
|
||||
pthread_cond_wait(&cond, &mut);
|
||||
pthread_mutex_unlock(&mut);
|
||||
AtomicFetchSubu8(&renderer.vk_conf.sleeping_threads, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -240,10 +240,8 @@ typedef struct DescAssetInfo
|
||||
|
||||
typedef struct DescBindings
|
||||
{
|
||||
u16 *free;
|
||||
u16 free_count;
|
||||
u16 *used;
|
||||
u16 used_count;
|
||||
u32 *free;
|
||||
u32 free_count;
|
||||
HashTable lookup_table;
|
||||
} DescBindings;
|
||||
|
||||
@ -294,8 +292,6 @@ typedef struct ImmediateStructures
|
||||
VkCommandPool *pools;
|
||||
VkCommandBuffer *cmds;
|
||||
VkFence *fences;
|
||||
JobQueue buffer_queue;
|
||||
JobQueue texture_queue;
|
||||
} ImmediateStructures;
|
||||
|
||||
typedef struct DeviceQueues
|
||||
@ -358,6 +354,7 @@ typedef struct PendingUpdates
|
||||
typedef struct VulkanConfig
|
||||
{
|
||||
u8 avail_threads;
|
||||
u8 volatile sleeping_threads;
|
||||
#ifdef __linux__
|
||||
pthread_t *threads;
|
||||
#elif _WIN32
|
||||
@ -457,7 +454,10 @@ static void UploadToImage(TextureBuffer *buffer, u8 *data, u32 thread_idx);
|
||||
|
||||
// ::Vulkan::Descriptors::Functions::Header::
|
||||
|
||||
static void DescriptorHandlePush(DescType type, DescHandle handle);
|
||||
static DescHandle DescriptorHandlePop(DescType type);
|
||||
static DescAssetInfo *DescriptorTableSearch(DescType type, u64 asset_id);
|
||||
static void DescriptorTableDelete(DescType type, u64 asset_id);
|
||||
|
||||
// ::Vulkan::CleanUp::Functions::Header::
|
||||
|
||||
|
||||
@ -269,18 +269,40 @@ static void CreateAndUploadToBuffer(RenderBuffer *buffer, rawptr ptr)
|
||||
VkLoaderWake();
|
||||
}
|
||||
|
||||
static DescHandle CreateAndUploadToTexture(TextureBuffer *buffer, rawptr ptr)
|
||||
static DescHandle CreateAndUploadToTexture(TextureAsset asset_id)
|
||||
{
|
||||
DescHandle handle = 0;
|
||||
|
||||
DescAssetInfo *info = DescriptorTableSearch(DESC_TYPE_SAMPLER, asset_id);
|
||||
if (info == NULL)
|
||||
{
|
||||
Asset asset = AssetPackLoadTexture(asset_id);
|
||||
|
||||
TextureBuffer *buffer = FLMemAlloc(sizeof(TextureBuffer));
|
||||
buffer->type = TEXTURE_BUFFER_TYPE_SAMPLER;
|
||||
buffer->width = asset.texture_meta.w;
|
||||
buffer->height = asset.texture_meta.h;
|
||||
buffer->channels = asset.texture_meta.ch;
|
||||
|
||||
TicketMutLock(&renderer.upload_queues[DESC_TYPE_SAMPLER].ticket_mut);
|
||||
|
||||
u32 job_idx = JobQueueAdd(&renderer.upload_queues[DESC_TYPE_SAMPLER].job_queue, 1);
|
||||
renderer.upload_queues[DESC_TYPE_SAMPLER].queued_textures[job_idx] = buffer;
|
||||
renderer.upload_queues[DESC_TYPE_SAMPLER].data[job_idx] = ptr;
|
||||
renderer.upload_queues[DESC_TYPE_SAMPLER].data[job_idx] = asset.bytes;
|
||||
|
||||
handle = DescriptorHandlePop(DESC_TYPE_SAMPLER);
|
||||
|
||||
TicketMutUnlock(&renderer.upload_queues[DESC_TYPE_SAMPLER].ticket_mut);
|
||||
|
||||
VkLoaderWake();
|
||||
}
|
||||
else
|
||||
{
|
||||
handle = info->handle;
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
static void FreeBuffers(RenderBuffer *buffers, u32 buffer_count)
|
||||
{
|
||||
@ -327,14 +349,22 @@ static AssetHandle RendererLoadTexture(TextureAsset asset_id)
|
||||
|
||||
static void WaitForBufferQueue()
|
||||
{
|
||||
JobQueueWaitForCompletion(&renderer.vk.imm.buffer_queue);
|
||||
JobQueueWaitForCompletion(&renderer.vk.imm.texture_queue);
|
||||
for (u32 i = 0; i < DESC_TYPE_MAX; i++)
|
||||
{
|
||||
while (!JobQueueCompleted(&renderer.upload_queues[DESC_TYPE_BUFFER].job_queue))
|
||||
{
|
||||
if (renderer.vk_conf.sleeping_threads > 0)
|
||||
VkLoaderWake();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ResetBufferQueue()
|
||||
{
|
||||
JobQueueReset(&renderer.vk.imm.texture_queue);
|
||||
JobQueueReset(&renderer.vk.imm.buffer_queue);
|
||||
for (u32 i = 0; i < DESC_TYPE_MAX; i++)
|
||||
{
|
||||
JobQueueReset(&renderer.upload_queues[i].job_queue);
|
||||
}
|
||||
}
|
||||
|
||||
// ::Vulkan::Renderer::Buffers::Functions::End::
|
||||
|
||||
14
src/util.c
14
src/util.c
@ -304,13 +304,13 @@ static inline void EndProfileBlock(ProfileBlock *block)
|
||||
|
||||
static inline b32 MutTryLock(Mut *mut)
|
||||
{
|
||||
b32 lock = true;
|
||||
return AtomicCompareExchangeb32(&mut->lock, &lock, false);
|
||||
b32 lock = false;
|
||||
return AtomicCompareExchangeb32(&mut->lock, &lock, 1);
|
||||
}
|
||||
|
||||
static inline void MutUnlock(Mut *mut)
|
||||
{
|
||||
AtomicStoreb32(&mut->lock, false);
|
||||
AtomicStoreb32(&mut->lock, 0);
|
||||
}
|
||||
|
||||
static inline void TicketMutLock(TicketMut *mut)
|
||||
@ -353,12 +353,10 @@ static inline void JobQueueReset(JobQueue *queue)
|
||||
AtomicFetchSubu32(&queue->remaining, queue->remaining);
|
||||
}
|
||||
|
||||
static inline void JobQueueWaitForCompletion(JobQueue *queue)
|
||||
static inline b32 JobQueueCompleted(JobQueue *queue)
|
||||
{
|
||||
u32 remaining;
|
||||
do {
|
||||
remaining = AtomicLoadu32(&queue->remaining);
|
||||
} while (remaining != 0);
|
||||
u32 remaining = AtomicLoadu32(&queue->remaining);
|
||||
return remaining == 0;
|
||||
}
|
||||
|
||||
// ::Util::Async::Functions::End::
|
||||
|
||||
14
src/util.h
14
src/util.h
@ -57,12 +57,8 @@ typedef struct Arena Arena;
|
||||
DefSig##def(u16); \
|
||||
DefSig##def(u32); \
|
||||
DefSig##def(u64); \
|
||||
DefSig##def(f32); \
|
||||
DefSig##def(f64); \
|
||||
DefSig##def(b8); \
|
||||
DefSig##def(b32); \
|
||||
DefSig##def(uintptr); \
|
||||
DefSig##def(intptr)
|
||||
DefSig##def(b32)
|
||||
|
||||
#define DefScalarImpl(def) \
|
||||
Def##def(i8); \
|
||||
@ -73,12 +69,8 @@ typedef struct Arena Arena;
|
||||
Def##def(u16); \
|
||||
Def##def(u32); \
|
||||
Def##def(u64); \
|
||||
Def##def(f32); \
|
||||
Def##def(f64); \
|
||||
Def##def(b8); \
|
||||
Def##def(b32); \
|
||||
Def##def(uintptr); \
|
||||
Def##def(intptr)
|
||||
Def##def(b32)
|
||||
|
||||
|
||||
// ::Util::LinkedList::Macros::
|
||||
@ -273,4 +265,4 @@ static inline u32 JobQueueAdd(JobQueue *queue, u32 count);
|
||||
static inline void JobQueueMarkUnqueued(JobQueue *queue, u32 count);
|
||||
static inline void JobQueueMarkCompleted(JobQueue *queue, u32 count);
|
||||
static inline void JobQueueReset(JobQueue *queue);
|
||||
static inline void JobQueueWaitForCompletion(JobQueue *queue);
|
||||
static inline b32 JobQueueCompleted(JobQueue *queue);
|
||||
|
||||
@ -88,14 +88,6 @@ static VkPhysicalDeviceVulkan11Features vk_11_features = {
|
||||
.pNext = &vk_12_features
|
||||
};
|
||||
|
||||
static const VkPhysicalDeviceFeatures vk_features = {
|
||||
.shaderUniformBufferArrayDynamicIndexing = VK_TRUE,
|
||||
.shaderSampledImageArrayDynamicIndexing = VK_TRUE,
|
||||
.shaderStorageBufferArrayDynamicIndexing = VK_TRUE,
|
||||
.shaderStorageImageArrayDynamicIndexing = VK_TRUE,
|
||||
.samplerAnisotropy = VK_TRUE,
|
||||
};
|
||||
|
||||
static const VkPhysicalDeviceFeatures2 vk_features_2 = {
|
||||
.sType = STYPE(PHYSICAL_DEVICE_FEATURES_2),
|
||||
.pNext = &vk_11_features,
|
||||
@ -103,7 +95,8 @@ static const VkPhysicalDeviceFeatures2 vk_features_2 = {
|
||||
.shaderUniformBufferArrayDynamicIndexing = VK_TRUE,
|
||||
.shaderSampledImageArrayDynamicIndexing = VK_TRUE,
|
||||
.shaderStorageBufferArrayDynamicIndexing = VK_TRUE,
|
||||
.shaderStorageImageArrayDynamicIndexing = VK_TRUE
|
||||
.shaderStorageImageArrayDynamicIndexing = VK_TRUE,
|
||||
.samplerAnisotropy = VK_TRUE,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user