asset loading completed (finally)
This commit is contained in:
parent
ec4eb4502a
commit
c28116ff60
43
src/assets.c
43
src/assets.c
@ -86,8 +86,6 @@ static Asset apLoadShader(ShaderAsset asset_id)
|
|||||||
{
|
{
|
||||||
AssetFile *asset_info = Shader_Assets + asset_id;
|
AssetFile *asset_info = Shader_Assets + asset_id;
|
||||||
|
|
||||||
Printfln("%llu %llu", asset_info->len, asset_info->data_offset);
|
|
||||||
|
|
||||||
asset.bytes = FLMemAlloc(asset_info->len);
|
asset.bytes = FLMemAlloc(asset_info->len);
|
||||||
MemCpy(asset.bytes, &ASSET_PACK[asset_info->data_offset], asset_info->len);
|
MemCpy(asset.bytes, &ASSET_PACK[asset_info->data_offset], asset_info->len);
|
||||||
asset.len = asset_info->len;
|
asset.len = asset_info->len;
|
||||||
@ -97,36 +95,31 @@ static Asset apLoadShader(ShaderAsset asset_id)
|
|||||||
return asset;
|
return asset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apUnloadTexture(Asset asset)
|
static TextureAssetMeta apGetTextureMeta(TextureAsset asset_id)
|
||||||
{
|
{
|
||||||
Assert(asset.bytes != NULL, "UnloadTextureAsset assert failure: ptr is NULL");
|
AssetFile *asset_file = Texture_Assets + asset_id;
|
||||||
|
return asset_file->texture_meta;
|
||||||
for (u32 i = 0; i < TEXTURE_ASSET_MAX; i++)
|
|
||||||
{
|
|
||||||
if (asset.bytes == Texture_Asset_Lookup[i].bytes)
|
|
||||||
{
|
|
||||||
Texture_Asset_Lookup[i].bytes = NULL;
|
|
||||||
Texture_Asset_Lookup[i].len = 0;
|
|
||||||
FLMemFree(asset.bytes);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void apUnloadTexture(TextureAsset asset_id)
|
||||||
|
{
|
||||||
|
Asset *asset = Texture_Asset_Lookup + asset_id;
|
||||||
|
if (asset->bytes != NULL)
|
||||||
|
{
|
||||||
|
FLMemFree(asset->bytes);
|
||||||
|
asset->bytes = NULL;
|
||||||
|
asset->len = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apUnloadShader(Asset asset)
|
static void apUnloadShader(ShaderAsset asset_id)
|
||||||
{
|
{
|
||||||
Assert(asset.bytes != NULL, "UnloadShaderAsset assert failure: ptr is NULL");
|
Asset *asset = Shader_Asset_Lookup + asset_id;
|
||||||
|
if (asset->bytes != NULL)
|
||||||
for (u32 i = 0; i < SHADER_ASSET_MAX; i++)
|
|
||||||
{
|
{
|
||||||
if (asset.bytes == Shader_Asset_Lookup[i].bytes)
|
FLMemFree(asset->bytes);
|
||||||
{
|
asset->bytes = NULL;
|
||||||
Shader_Asset_Lookup[i].bytes = NULL;
|
asset->len = 0;
|
||||||
Shader_Asset_Lookup[i].len = 0;
|
|
||||||
FLMemFree(asset.bytes);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -117,8 +117,9 @@ static void apInit();
|
|||||||
|
|
||||||
static Asset apLoadTexture(TextureAsset asset_id);
|
static Asset apLoadTexture(TextureAsset asset_id);
|
||||||
static Asset apLoadShader(ShaderAsset asset_id);
|
static Asset apLoadShader(ShaderAsset asset_id);
|
||||||
static void apUnloadTexture(Asset asset);
|
static TextureAssetMeta apGetTextureMeta(TextureAsset asset_id);
|
||||||
static void apUnloadShader(Asset asset);
|
static void apUnloadTexture(TextureAsset asset_id);
|
||||||
|
static void apUnloadShader(ShaderAsset asset_id);
|
||||||
|
|
||||||
// ::Assets::Util::Functions::Header::
|
// ::Assets::Util::Functions::Header::
|
||||||
|
|
||||||
|
|||||||
27
src/game.c
27
src/game.c
@ -77,7 +77,7 @@ static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count)
|
|||||||
|
|
||||||
rViewportSize(&ctx->pc.res);
|
rViewportSize(&ctx->pc.res);
|
||||||
|
|
||||||
//rDescHandle pattermon = rTextureCreateAndUpload(PATTERMON_OBESE);
|
rDescHandle pattermon = rTextureCreateAndUpload(PATTERMON_OBESE);
|
||||||
|
|
||||||
rawptr vert_buffer = rBufferGUIVertMapping();
|
rawptr vert_buffer = rBufferGUIVertMapping();
|
||||||
rawptr idx_buffer = rBufferGUIIdxMapping();
|
rawptr idx_buffer = rBufferGUIIdxMapping();
|
||||||
@ -85,20 +85,7 @@ static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count)
|
|||||||
MemCpy(vert_buffer, ctx->gui.vertices, sizeof(rUIVertex) * ctx->gui.vertices_len);
|
MemCpy(vert_buffer, ctx->gui.vertices, sizeof(rUIVertex) * ctx->gui.vertices_len);
|
||||||
MemCpy(idx_buffer, ctx->gui.indices, sizeof(u32) * ctx->gui.indices_len);
|
MemCpy(idx_buffer, ctx->gui.indices, sizeof(u32) * ctx->gui.indices_len);
|
||||||
|
|
||||||
/*
|
vBufferQueueWait();
|
||||||
rRenderBuffer *vertex_buffer = MakeArray(ctx->arena, rRenderBuffer, 1);
|
|
||||||
vertex_buffer->type = rRBT_VERTEX;
|
|
||||||
vertex_buffer->size = sizeof(rUIVertex) * ctx->gui.vertices_len;
|
|
||||||
|
|
||||||
rRenderBuffer *index_buffer = MakeArray(ctx->arena, rRenderBuffer, 1);
|
|
||||||
index_buffer->type = rRBT_INDEX,
|
|
||||||
index_buffer->size = sizeof(u32) * ctx->gui.indices_len,
|
|
||||||
|
|
||||||
rBufferCreateAndUpload(vertex_buffer, ctx->gui.vertices);
|
|
||||||
rBufferCreateAndUpload(index_buffer, ctx->gui.indices);
|
|
||||||
*/
|
|
||||||
|
|
||||||
WaitForBufferQueue();
|
|
||||||
|
|
||||||
rFrameBegin();
|
rFrameBegin();
|
||||||
|
|
||||||
@ -106,11 +93,6 @@ static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count)
|
|||||||
|
|
||||||
rPushConstantsSet(&ctx->pc);
|
rPushConstantsSet(&ctx->pc);
|
||||||
|
|
||||||
/*
|
|
||||||
rBufferBindVertex(vertex_buffer);
|
|
||||||
rBufferBindIndex(index_buffer);
|
|
||||||
*/
|
|
||||||
|
|
||||||
rBufferBindGUIVertex();
|
rBufferBindGUIVertex();
|
||||||
rBufferBindGUIIndex();
|
rBufferBindGUIIndex();
|
||||||
|
|
||||||
@ -118,11 +100,6 @@ static void gRunCycle(gGameCtx *ctx, pGameInput *inputs, u32 i_count)
|
|||||||
|
|
||||||
rFrameFinish();
|
rFrameFinish();
|
||||||
|
|
||||||
/*
|
|
||||||
rBufferFree(vertex_buffer, 1);
|
|
||||||
rBufferFree(index_buffer, 1);
|
|
||||||
*/
|
|
||||||
|
|
||||||
ctx->gui.vertices_len = 0;
|
ctx->gui.vertices_len = 0;
|
||||||
ctx->gui.indices_len = 0;
|
ctx->gui.indices_len = 0;
|
||||||
ctx->gui.instance_count = 0;
|
ctx->gui.instance_count = 0;
|
||||||
|
|||||||
@ -81,7 +81,7 @@ static inline VkSemaphore vFrameSwapSem()
|
|||||||
|
|
||||||
static inline vBufferAllocPtrArray *vFrameBuffers()
|
static inline vBufferAllocPtrArray *vFrameBuffers()
|
||||||
{
|
{
|
||||||
return v_Renderer.buffers.frame + vFrameIndex();
|
return v_Renderer.buffers.frame_buffers + vFrameIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
@ -331,6 +331,85 @@ static void vSwapchainResize()
|
|||||||
|
|
||||||
// ::Vulkan::Images::Functions::Start::
|
// ::Vulkan::Images::Functions::Start::
|
||||||
|
|
||||||
|
static b32 vImageViewCreate(vImageView *view, u32 width, u32 height, u32 channels)
|
||||||
|
{
|
||||||
|
b32 success = true;
|
||||||
|
|
||||||
|
VmaAllocationCreateInfo alloc_create_info = {
|
||||||
|
.usage = VMA_MEMORY_USAGE_GPU_ONLY,
|
||||||
|
.requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkImageCreateInfo image_info = {
|
||||||
|
.sType = STYPE(IMAGE_CREATE_INFO),
|
||||||
|
.imageType = VK_IMAGE_TYPE_2D,
|
||||||
|
.mipLevels = 1,
|
||||||
|
.arrayLayers = 1,
|
||||||
|
.format = VK_FORMAT_R8G8B8A8_SRGB,
|
||||||
|
.tiling = VK_IMAGE_TILING_OPTIMAL,
|
||||||
|
.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 = width,
|
||||||
|
.height = height,
|
||||||
|
.depth = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (v_Renderer.state.vk.single_queue)
|
||||||
|
{
|
||||||
|
image_info.sharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||||
|
image_info.queueFamilyIndexCount = 2;
|
||||||
|
image_info.pQueueFamilyIndices = (u32[]){v_Renderer.state.vk.gfx_queue_idx, v_Renderer.state.vk.tfer_queue_idx};
|
||||||
|
}
|
||||||
|
|
||||||
|
VkResult result = vmaCreateImage(v_Renderer.handles.vma_alloc, &image_info, &alloc_create_info,
|
||||||
|
&view->image.image, &view->image.alloc, NULL);
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
Printfln("vImageViewCreate error: vmaCreateImage failure: %s", vVkResultStr(result));
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkImageViewCreateInfo view_info = {
|
||||||
|
.sType = STYPE(IMAGE_VIEW_CREATE_INFO),
|
||||||
|
.image = view->image.image,
|
||||||
|
.viewType = VK_IMAGE_VIEW_TYPE_2D,
|
||||||
|
.format = VK_FORMAT_R8G8B8A8_SRGB,
|
||||||
|
.subresourceRange = {
|
||||||
|
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
.levelCount = 1,
|
||||||
|
.layerCount = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
result = vkCreateImageView(v_Renderer.handles.device, &view_info, NULL, &view->view);
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
Printfln("vImageViewCreate error: vkCreateImageView failure: %s", vVkResultStr(result));
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static vImageView *vImageLookupExisting(TextureAsset asset_id)
|
||||||
|
{
|
||||||
|
vImageView *view = NULL;
|
||||||
|
|
||||||
|
HashTable *table = &v_Renderer.buffers.images;
|
||||||
|
|
||||||
|
KeyValuePair *pair = HashTableSearchU64(table, asset_id);
|
||||||
|
if (pair != NULL)
|
||||||
|
{
|
||||||
|
view = (vImageView *)pair->value_rawptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
static b32 vSamplerCreate(rTextureBuffer *buffer)
|
static b32 vSamplerCreate(rTextureBuffer *buffer)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -494,6 +573,30 @@ static void vImageUpload(rTextureBuffer *buffer, u8 *data, u32 thread_idx)
|
|||||||
|
|
||||||
// ::Vulkan::Descriptors::Functions::Start::
|
// ::Vulkan::Descriptors::Functions::Start::
|
||||||
|
|
||||||
|
static u32 vDescPushImage(vImageView *view)
|
||||||
|
{
|
||||||
|
u32 index = vDescIndexPop(vDT_SAMPLED_IMAGE);
|
||||||
|
|
||||||
|
VkDescriptorImageInfo image_info = {
|
||||||
|
.imageView = view->view,
|
||||||
|
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkWriteDescriptorSet desc_write = {
|
||||||
|
.sType = STYPE(WRITE_DESCRIPTOR_SET),
|
||||||
|
.dstSet = v_Renderer.handles.desc_sets[vDT_SAMPLED_IMAGE],
|
||||||
|
.dstBinding = 0,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.dstArrayElement = index,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||||
|
.pImageInfo = &image_info,
|
||||||
|
};
|
||||||
|
|
||||||
|
vkUpdateDescriptorSets(v_Renderer.handles.device, 1, &desc_write, 0, NULL);
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
static void vDescIndexPush(vDescType type, u32 index)
|
static void vDescIndexPush(vDescType type, u32 index)
|
||||||
{
|
{
|
||||||
vDescBindings *bindings = v_Renderer.desc_bindings + type;
|
vDescBindings *bindings = v_Renderer.desc_bindings + type;
|
||||||
@ -532,7 +635,7 @@ static rDescHandle vDescHandleSearch(vDescType type, u32 asset_id)
|
|||||||
return asset_info;
|
return asset_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DescriptorTableInsert(vDescType type, rDescHandle handle)
|
static void vDescHandleInsert(vDescType type, rDescHandle handle)
|
||||||
{
|
{
|
||||||
HashTable *table = &v_Renderer.desc_bindings[type].lookup_table;
|
HashTable *table = &v_Renderer.desc_bindings[type].lookup_table;
|
||||||
HashTablePushU64U64Split(table, handle.asset_id, handle.asset_id, handle.desc_index);
|
HashTablePushU64U64Split(table, handle.asset_id, handle.asset_id, handle.desc_index);
|
||||||
@ -1048,6 +1151,7 @@ static b32 vDeviceFunctionsInit() {
|
|||||||
INIT_DEV_FN(vkDeviceWaitIdle);
|
INIT_DEV_FN(vkDeviceWaitIdle);
|
||||||
INIT_DEV_FN(vkCmdClearColorImage);
|
INIT_DEV_FN(vkCmdClearColorImage);
|
||||||
INIT_DEV_FN(vkCreateSampler);
|
INIT_DEV_FN(vkCreateSampler);
|
||||||
|
INIT_DEV_FN(vkDestroySampler);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1530,8 +1634,8 @@ static b32 vPipelinesInit()
|
|||||||
vkDestroyShaderModule(device, cube_vert, NULL);
|
vkDestroyShaderModule(device, cube_vert, NULL);
|
||||||
vkDestroyShaderModule(device, cube_frag, NULL);
|
vkDestroyShaderModule(device, cube_frag, NULL);
|
||||||
|
|
||||||
apUnloadShader(quad_vert_shader);
|
apUnloadShader(QUAD_VERT_SPIRV_SHADER);
|
||||||
apUnloadShader(quad_frag_shader);
|
apUnloadShader(QUAD_FRAG_SPIRV_SHADER);
|
||||||
|
|
||||||
Asset gui_vert_shader = apLoadShader(GUI_VERT_SPIRV_SHADER);
|
Asset gui_vert_shader = apLoadShader(GUI_VERT_SPIRV_SHADER);
|
||||||
Asset gui_frag_shader = apLoadShader(GUI_FRAG_SPIRV_SHADER);
|
Asset gui_frag_shader = apLoadShader(GUI_FRAG_SPIRV_SHADER);
|
||||||
@ -1570,8 +1674,8 @@ static b32 vPipelinesInit()
|
|||||||
vkDestroyShaderModule(device, gui_vert, NULL);
|
vkDestroyShaderModule(device, gui_vert, NULL);
|
||||||
vkDestroyShaderModule(device, gui_frag, NULL);
|
vkDestroyShaderModule(device, gui_frag, NULL);
|
||||||
|
|
||||||
apUnloadShader(gui_vert_shader);
|
apUnloadShader(GUI_VERT_SPIRV_SHADER);
|
||||||
apUnloadShader(gui_frag_shader);
|
apUnloadShader(GUI_FRAG_SPIRV_SHADER);
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@ -1602,15 +1706,13 @@ static b32 vBuffersInit()
|
|||||||
vRBuffers *buf = &v_Renderer.buffers;
|
vRBuffers *buf = &v_Renderer.buffers;
|
||||||
Arena *arena = v_Renderer.mem.perm_arena;
|
Arena *arena = v_Renderer.mem.perm_arena;
|
||||||
|
|
||||||
buf->perm.data = MakeArray(arena, vBufferAlloc *, 1024);
|
HashTableInit(&buf->buffers, 8);
|
||||||
buf->perm.cap = 1024;
|
HashTableInit(&buf->images, 8);
|
||||||
buf->perm.length = 0;
|
|
||||||
|
|
||||||
for (u32 i = 0; i < FRAME_OVERLAP; i++)
|
for (u32 i = 0; i < FRAME_OVERLAP; i++)
|
||||||
{
|
{
|
||||||
buf->frame[i].data = MakeArray(arena, vBufferAlloc *, 512);
|
InitArrayType(buf->frame_buffers[i], arena, vBufferAlloc *, 128);
|
||||||
buf->frame[i].cap = 512;
|
InitArrayType(buf->frame_images[i], arena, vImageView *, 128);
|
||||||
buf->frame[i].length = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
b32 success = true;
|
b32 success = true;
|
||||||
@ -1618,28 +1720,31 @@ static b32 vBuffersInit()
|
|||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
result = vBufferCreate(&buf->gui_vert.alloc, rRBT_VERTEX | rRBT_HOST, MB(32));
|
result = vBufferCreate(&buf->gui_vert.alloc, rRBT_VERTEX | rRBT_HOST, VERTEX_BUFFER_CAP);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
result = vBufferCreate(&buf->gui_idx.alloc, rRBT_INDEX | rRBT_HOST, MB(8)); // TODO: figure out ratio of memory alloc from vertex -> index
|
result = vBufferCreate(&buf->gui_idx.alloc, rRBT_INDEX | rRBT_HOST, INDEX_BUFFER_CAP); // TODO: figure out ratio of memory alloc from vertex -> index
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
result = vBufferCreate(&buf->transfer.alloc, rRBT_STAGING, MB(64));
|
result = vBufferCreate(&buf->transfer.alloc, rRBT_STAGING, TRANSFER_BUFFER_CAP);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf->gui_vert.ptr = vMapBuffer(buf->gui_vert.alloc.alloc);
|
buf->gui_vert.ptr = vMapBuffer(buf->gui_vert.alloc.alloc);
|
||||||
|
buf->gui_vert.cap = MB(32);
|
||||||
buf->gui_idx.ptr = vMapBuffer(buf->gui_idx.alloc.alloc);
|
buf->gui_idx.ptr = vMapBuffer(buf->gui_idx.alloc.alloc);
|
||||||
|
buf->gui_idx.cap = MB(8);
|
||||||
buf->transfer.ptr = vMapBuffer(buf->transfer.alloc.alloc);
|
buf->transfer.ptr = vMapBuffer(buf->transfer.alloc.alloc);
|
||||||
|
buf->transfer.cap = MB(64);
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@ -1764,6 +1869,110 @@ static u32 vLoaderProcessSamplers(u32 thread_index)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vTransferUpload(vTransfer **transfers, u32 count, u32 idx)
|
||||||
|
{
|
||||||
|
VkCommandPool pool = v_Renderer.imm_handles.data[idx].pool;
|
||||||
|
VkCommandBuffer buffer = v_Renderer.imm_handles.data[idx].buffer;
|
||||||
|
VkFence fence = v_Renderer.imm_handles.data[idx].fence;
|
||||||
|
VkDevice device = v_Renderer.handles.device;
|
||||||
|
VkQueue queue = v_Renderer.handles.tfer_queue;
|
||||||
|
vMappedBuffer *transfer = &v_Renderer.buffers.transfer;
|
||||||
|
|
||||||
|
rawptr data_ptr = NULL;
|
||||||
|
u64 data_len = 0;
|
||||||
|
|
||||||
|
rawptr ptr = transfer->ptr;
|
||||||
|
u64 ptr_pos = 0;
|
||||||
|
b32 imm_started = false;
|
||||||
|
u32 i = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (i == count)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (data_ptr == NULL)
|
||||||
|
{
|
||||||
|
data_ptr = transfers[i]->data;
|
||||||
|
|
||||||
|
if (transfers[i]->type == vTT_IMAGE)
|
||||||
|
{
|
||||||
|
data_len = transfers[i]->w * transfers[i]->h * transfers[i]->ch;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data_len = transfers[i]->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptr_pos == transfer->cap)
|
||||||
|
{
|
||||||
|
vImmSubmitFinish(device, fence, buffer, queue);
|
||||||
|
vkWaitForFences(device, 1, &fence, VK_TRUE, 999999999);
|
||||||
|
imm_started = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!imm_started)
|
||||||
|
{
|
||||||
|
Assert(vImmSubmitBegin(device, fence, buffer), "vTransferUpload failure: vImmSubmitBegin failed"); // TODO: handle this
|
||||||
|
imm_started = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transfers[i]->type == vTT_NONE) {}
|
||||||
|
else if (transfers[i]->type == vTT_IMAGE)
|
||||||
|
{
|
||||||
|
u64 remaining = Diff(TRANSFER_BUFFER_CAP, ptr_pos);
|
||||||
|
u64 transfer_size = data_len;
|
||||||
|
if (transfer_size > remaining)
|
||||||
|
transfer_size = remaining;
|
||||||
|
|
||||||
|
MemCpy(ptr, transfers[i]->data, transfer_size);
|
||||||
|
|
||||||
|
ptr = PtrAdd(ptr, transfer_size);
|
||||||
|
PtrAddAdjustLen(data_ptr, data_len, transfer_size);
|
||||||
|
|
||||||
|
MemZero(&transfers[i]->image_copy, sizeof(VkBufferImageCopy));
|
||||||
|
|
||||||
|
transfers[i]->image_copy.bufferRowLength = transfers[i]->w;
|
||||||
|
transfers[i]->image_copy.bufferImageHeight = transfers[i]->h;
|
||||||
|
transfers[i]->image_copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
transfers[i]->image_copy.imageSubresource.layerCount = 1;
|
||||||
|
transfers[i]->image_copy.imageExtent.width = transfers[i]->w;
|
||||||
|
transfers[i]->image_copy.imageExtent.height = transfers[i]->h;
|
||||||
|
transfers[i]->image_copy.imageExtent.depth = 1;
|
||||||
|
|
||||||
|
vImageTransitionLayout(buffer,
|
||||||
|
transfers[i]->image,
|
||||||
|
VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
|
|
||||||
|
vkCmdCopyBufferToImage(buffer,
|
||||||
|
transfer->alloc.buffer,
|
||||||
|
transfers[i]->image,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
1,
|
||||||
|
&transfers[i]->image_copy);
|
||||||
|
|
||||||
|
vImageTransitionLayout(buffer,
|
||||||
|
transfers[i]->image,
|
||||||
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
|
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
|
|
||||||
|
if (data_len == 0)
|
||||||
|
{
|
||||||
|
data_ptr = NULL;
|
||||||
|
data_len = 0;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (transfers[i]->type == vTT_BUFFER)
|
||||||
|
{
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imm_started)
|
||||||
|
vImmSubmitFinish(device, fence, buffer, queue);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
|
||||||
@ -1774,54 +1983,56 @@ void *vLoaderStart(void *i)
|
|||||||
pthread_mutex_t mut;
|
pthread_mutex_t mut;
|
||||||
pthread_mutex_init(&mut, NULL);
|
pthread_mutex_init(&mut, NULL);
|
||||||
|
|
||||||
u32 processed_count = 0;
|
|
||||||
u32 iter_count = 0;
|
|
||||||
/*
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < vDT_MAX; i++)
|
|
||||||
|
TicketMutLock(&v_Renderer.upload.mut);
|
||||||
|
u32 job_count = JobQueueGetCount(&v_Renderer.upload.job_queue);
|
||||||
|
if (job_count > 0)
|
||||||
{
|
{
|
||||||
Mut *mut = &renderer.upload_queues[i].mut;
|
vTransfer **transfers = MakeArray(vFrameArena(), vTransfer *, job_count);
|
||||||
if (MutTryLock(mut))
|
|
||||||
|
u32 unqueued_count = 0;
|
||||||
|
for (u32 i = 0; i < job_count; i++)
|
||||||
{
|
{
|
||||||
switch (i)
|
unqueued_count += 1;
|
||||||
{
|
transfers[i] = v_Renderer.upload.transfers[i];
|
||||||
case vDT_MATERIAL:
|
|
||||||
{
|
|
||||||
processed_count += vLoaderProcessBuffers(index);
|
|
||||||
} break;
|
|
||||||
case vDT_SAMPLED_IMAGE:
|
|
||||||
{
|
|
||||||
processed_count += vLoaderProcessSamplers(index);
|
|
||||||
} break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MutUnlock(mut);
|
JobQueueMarkUnqueued(&v_Renderer.upload.job_queue, unqueued_count);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
iter_count += 1;
|
TicketMutUnlock(&v_Renderer.upload.mut);
|
||||||
|
|
||||||
if (processed_count < 0)
|
vTransferUpload(transfers, job_count, index);
|
||||||
pthread_exit(NULL);
|
|
||||||
else if (processed_count == 0 && iter_count >= 3)
|
for (u32 i = 0; i < job_count; i++)
|
||||||
|
{
|
||||||
|
if (transfers[i]->type == vTT_IMAGE)
|
||||||
|
apUnloadTexture(transfers[i]->asset_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
JobQueueMarkCompleted(&v_Renderer.upload.job_queue, job_count);
|
||||||
|
}
|
||||||
|
else if (job_count == 0)
|
||||||
{
|
{
|
||||||
iter_count = 0;
|
|
||||||
pu8AtomicIncr(&v_Renderer.async.sleeping);
|
pu8AtomicIncr(&v_Renderer.async.sleeping);
|
||||||
|
TicketMutUnlock(&v_Renderer.upload.mut);
|
||||||
pthread_mutex_lock(&mut);
|
pthread_mutex_lock(&mut);
|
||||||
pthread_cond_wait(&v_Renderer.async.cond, &mut);
|
pthread_cond_wait(&v_Renderer.async.cond, &mut);
|
||||||
pthread_mutex_unlock(&mut);
|
pthread_mutex_unlock(&mut);
|
||||||
pu8AtomicFetchSub(&v_Renderer.async.sleeping, 1);
|
pu8AtomicFetchSub(&v_Renderer.async.sleeping, 1);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TicketMutUnlock(&v_Renderer.upload.mut);
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vLoaderWake()
|
static void vLoaderWake()
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < v_Renderer.async.count; i++)
|
for (u32 i = 0; i < v_Renderer.async.count; i++)
|
||||||
pthread_cond_signal(&v_Renderer.async.cond);
|
pthread_cond_signal(&v_Renderer.async.cond);
|
||||||
|
|||||||
@ -31,7 +31,11 @@ static char *vulkan_libs[] = {
|
|||||||
#error Not yet implemented
|
#error Not yet implemented
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define V_THREAD_MAX 2
|
#define V_THREAD_MAX 1
|
||||||
|
|
||||||
|
#define VERTEX_BUFFER_CAP MB(32)
|
||||||
|
#define INDEX_BUFFER_CAP MB(8)
|
||||||
|
#define TRANSFER_BUFFER_CAP MB(64)
|
||||||
|
|
||||||
// ::Vulkan::Macros::Header::
|
// ::Vulkan::Macros::Header::
|
||||||
|
|
||||||
@ -154,6 +158,7 @@ VK_DECLARE(vkCmdDraw);
|
|||||||
VK_DECLARE(vkDeviceWaitIdle);
|
VK_DECLARE(vkDeviceWaitIdle);
|
||||||
VK_DECLARE(vkCmdClearColorImage);
|
VK_DECLARE(vkCmdClearColorImage);
|
||||||
VK_DECLARE(vkCreateSampler);
|
VK_DECLARE(vkCreateSampler);
|
||||||
|
VK_DECLARE(vkDestroySampler);
|
||||||
|
|
||||||
#include "vma/vk_mem_alloc.h"
|
#include "vma/vk_mem_alloc.h"
|
||||||
|
|
||||||
@ -220,6 +225,7 @@ typedef struct vImageView
|
|||||||
VkImageView view;
|
VkImageView view;
|
||||||
} vImageView;
|
} vImageView;
|
||||||
|
|
||||||
|
PtrArrayType(vImageView);
|
||||||
ArrayType(vImageView);
|
ArrayType(vImageView);
|
||||||
|
|
||||||
typedef struct vSampler
|
typedef struct vSampler
|
||||||
@ -339,14 +345,15 @@ typedef struct vMappedBuffer
|
|||||||
{
|
{
|
||||||
vBufferAlloc alloc;
|
vBufferAlloc alloc;
|
||||||
rawptr ptr;
|
rawptr ptr;
|
||||||
u64 used;
|
|
||||||
u64 cap;
|
u64 cap;
|
||||||
} vMappedBuffer;
|
} vMappedBuffer;
|
||||||
|
|
||||||
typedef struct vRBuffers
|
typedef struct vRBuffers
|
||||||
{
|
{
|
||||||
vBufferAllocPtrArray perm;
|
HashTable buffers;
|
||||||
vBufferAllocPtrArray frame[FRAME_OVERLAP];
|
vBufferAllocPtrArray frame_buffers[FRAME_OVERLAP];
|
||||||
|
HashTable images;
|
||||||
|
vImageViewPtrArray frame_images[FRAME_OVERLAP];
|
||||||
vMappedBuffer transfer;
|
vMappedBuffer transfer;
|
||||||
vMappedBuffer gui_vert;
|
vMappedBuffer gui_vert;
|
||||||
vMappedBuffer gui_idx;
|
vMappedBuffer gui_idx;
|
||||||
@ -363,12 +370,27 @@ typedef struct vTransfer
|
|||||||
{
|
{
|
||||||
vTransferType type;
|
vTransferType type;
|
||||||
rawptr data;
|
rawptr data;
|
||||||
|
u32 asset_id;
|
||||||
|
union
|
||||||
|
{
|
||||||
u64 size;
|
u64 size;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
u32 w;
|
||||||
|
u32 h;
|
||||||
|
u8 ch;
|
||||||
|
};
|
||||||
|
};
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
VkBuffer buffer;
|
VkBuffer buffer;
|
||||||
VkImage image;
|
VkImage image;
|
||||||
};
|
};
|
||||||
|
union
|
||||||
|
{
|
||||||
|
VkBufferCopy buffer_copy;
|
||||||
|
VkBufferImageCopy image_copy;
|
||||||
|
};
|
||||||
} vTransfer;
|
} vTransfer;
|
||||||
|
|
||||||
typedef struct vUploadQueue
|
typedef struct vUploadQueue
|
||||||
@ -486,7 +508,8 @@ static inline void vImageCopyToImage(VkCommandBuffer cmd, VkImage src, VkImage d
|
|||||||
|
|
||||||
// ::Vulkan::Async::Functions::Header::
|
// ::Vulkan::Async::Functions::Header::
|
||||||
|
|
||||||
void vLoaderWake();
|
static void vBufferQueueWait();
|
||||||
|
static void vLoaderWake();
|
||||||
static u32 vLoaderProcessBuffers(u32 thread_index);
|
static u32 vLoaderProcessBuffers(u32 thread_index);
|
||||||
static u32 vLoaderProcessSamplers(u32 thread_index);
|
static u32 vLoaderProcessSamplers(u32 thread_index);
|
||||||
|
|
||||||
@ -511,15 +534,19 @@ static void vSwapchainResize();
|
|||||||
|
|
||||||
// ::Vulkan::Images::Functions::Header::
|
// ::Vulkan::Images::Functions::Header::
|
||||||
|
|
||||||
|
static b32 vImageViewCreate(vImageView *view, u32 width, u32 height, u32 channels);
|
||||||
static b32 vSamplerCreate(rTextureBuffer *buffer);
|
static b32 vSamplerCreate(rTextureBuffer *buffer);
|
||||||
static void vImageUpload(rTextureBuffer *buffer, u8 *data, u32 thread_idx);
|
static void vImageUpload(rTextureBuffer *buffer, u8 *data, u32 thread_idx);
|
||||||
|
static vImageView *vImageLookupExisting(TextureAsset asset_id);
|
||||||
|
|
||||||
// ::Vulkan::Descriptors::Functions::Header::
|
// ::Vulkan::Descriptors::Functions::Header::
|
||||||
|
|
||||||
static void vDescIndexPush(vDescType type, u32 index);
|
static void vDescIndexPush(vDescType type, u32 index);
|
||||||
static u32 vDescIndexPop(vDescType type);
|
static u32 vDescIndexPop(vDescType type);
|
||||||
static rDescHandle vDescHandleSearch(vDescType type, u32 asset_id);
|
static rDescHandle vDescHandleSearch(vDescType type, u32 asset_id);
|
||||||
|
static void vDescHandleInsert(vDescType type, rDescHandle handle);
|
||||||
static void vDescHandleDelete(vDescType type, u32 asset_id);
|
static void vDescHandleDelete(vDescType type, u32 asset_id);
|
||||||
|
static u32 vDescPushImage(vImageView *view);
|
||||||
|
|
||||||
// ::Vulkan::Buffers::Functions::Header::
|
// ::Vulkan::Buffers::Functions::Header::
|
||||||
|
|
||||||
|
|||||||
@ -38,8 +38,7 @@ void rDestroy()
|
|||||||
{
|
{
|
||||||
VkDevice device = v_Renderer.handles.device;
|
VkDevice device = v_Renderer.handles.device;
|
||||||
VkInstance instance = v_Renderer.handles.inst;
|
VkInstance instance = v_Renderer.handles.inst;
|
||||||
vBufferAllocPtrArray *frame_buffers = v_Renderer.buffers.frame;
|
vBufferAllocPtrArray *frame_buffers = v_Renderer.buffers.frame_buffers;
|
||||||
vBufferAllocPtrArray buffers = v_Renderer.buffers.perm;
|
|
||||||
vImmHandlesArray imm = v_Renderer.imm_handles;
|
vImmHandlesArray imm = v_Renderer.imm_handles;
|
||||||
VmaAllocator vma_alloc = v_Renderer.handles.vma_alloc;
|
VmaAllocator vma_alloc = v_Renderer.handles.vma_alloc;
|
||||||
VkSwapchainKHR swapchain = v_Renderer.handles.swapchain;
|
VkSwapchainKHR swapchain = v_Renderer.handles.swapchain;
|
||||||
@ -48,9 +47,12 @@ void rDestroy()
|
|||||||
VkDescriptorSetLayout *desc_layouts = v_Renderer.handles.desc_layouts;
|
VkDescriptorSetLayout *desc_layouts = v_Renderer.handles.desc_layouts;
|
||||||
VkDescriptorPool desc_pool = v_Renderer.handles.desc_pool;
|
VkDescriptorPool desc_pool = v_Renderer.handles.desc_pool;
|
||||||
vAsync async = v_Renderer.async;
|
vAsync async = v_Renderer.async;
|
||||||
|
VkSampler nearest_sampler = v_Renderer.handles.nearest_sampler;
|
||||||
|
|
||||||
vkDeviceWaitIdle(device);
|
vkDeviceWaitIdle(device);
|
||||||
|
|
||||||
|
vkDestroySampler(device, nearest_sampler, NULL);
|
||||||
|
|
||||||
for (u32 i = R_PIPELINE_CUBE; i < R_PIPELINE_MAX; i++)
|
for (u32 i = R_PIPELINE_CUBE; i < R_PIPELINE_MAX; i++)
|
||||||
vkDestroyPipeline(device, pipelines[i], NULL);
|
vkDestroyPipeline(device, pipelines[i], NULL);
|
||||||
|
|
||||||
@ -289,39 +291,45 @@ static void rBufferCreateAndUpload(ModelAsset asset_id)
|
|||||||
|
|
||||||
static rDescHandle rTextureCreateAndUpload(TextureAsset asset_id)
|
static rDescHandle rTextureCreateAndUpload(TextureAsset asset_id)
|
||||||
{
|
{
|
||||||
|
rDescHandle handle = vDescHandleSearch(vDT_SAMPLED_IMAGE, asset_id);
|
||||||
|
|
||||||
// TODO: replace it, store asset information (vertex count, res, etc) in asset header files and pull them for use in draw commands, etc.
|
if (handle.asset_id == UINT32_MAX)
|
||||||
/*
|
|
||||||
vAssetInfo *info = vDescHandleSearch(vDT_SAMPLED_IMAGE, asset_id);
|
|
||||||
if (info == NULL)
|
|
||||||
{
|
{
|
||||||
|
vImageView *view = FLMemAlloc(sizeof(vImageView));
|
||||||
|
|
||||||
Asset asset = apLoadTexture(asset_id);
|
Asset asset = apLoadTexture(asset_id);
|
||||||
|
TextureAssetMeta meta = apGetTextureMeta(asset_id);
|
||||||
|
|
||||||
rTextureBuffer *buffer = FLMemAlloc(sizeof(rTextureBuffer));
|
// TODO: handle errors instead of failing
|
||||||
buffer->type = rTBT_SAMPLER;
|
Assert(vImageViewCreate(view, meta.w, meta.h, meta.ch), "rTextureCreateAndUpload failure: vImageViewCreate failed");
|
||||||
buffer->width = asset.texture_meta.w;
|
|
||||||
buffer->height = asset.texture_meta.h;
|
|
||||||
buffer->channels = asset.texture_meta.ch;
|
|
||||||
|
|
||||||
TicketMutLock(&renderer.upload_queues[vDT_SAMPLED_IMAGE].ticket_mut);
|
handle.asset_id = asset_id;
|
||||||
|
handle.desc_index = vDescPushImage(view);
|
||||||
|
|
||||||
u32 job_idx = JobQueueAdd(&renderer.upload_queues[vDT_SAMPLED_IMAGE].job_queue, 1);
|
TicketMutLock(&v_Renderer.upload.mut);
|
||||||
renderer.upload_queues[vDT_SAMPLED_IMAGE].queued_textures[job_idx] = buffer;
|
|
||||||
renderer.upload_queues[vDT_SAMPLED_IMAGE].data[job_idx] = asset.bytes;
|
|
||||||
|
|
||||||
handle = vDescIndexPop(vDT_SAMPLED_IMAGE);
|
Arena *arena = vFrameArena();
|
||||||
|
|
||||||
TicketMutUnlock(&renderer.upload_queues[vDT_SAMPLED_IMAGE].ticket_mut);
|
vTransfer *transfer = MakeArray(arena, vTransfer, 1);
|
||||||
|
|
||||||
|
transfer->type = vTT_IMAGE;
|
||||||
|
transfer->data = asset.bytes;
|
||||||
|
transfer->w = meta.w;
|
||||||
|
transfer->h = meta.h;
|
||||||
|
transfer->ch = meta.ch;
|
||||||
|
transfer->asset_id = asset_id;
|
||||||
|
transfer->image = view->image.image;
|
||||||
|
|
||||||
|
u32 job_idx = JobQueueAdd(&v_Renderer.upload.job_queue, 1);
|
||||||
|
|
||||||
|
v_Renderer.upload.transfers[job_idx] = transfer;
|
||||||
|
|
||||||
|
vDescHandleInsert(vDT_SAMPLED_IMAGE, handle);
|
||||||
|
|
||||||
|
TicketMutUnlock(&v_Renderer.upload.mut);
|
||||||
|
|
||||||
vLoaderWake();
|
vLoaderWake();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
handle = info->handle;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
rDescHandle handle = {UINT32_MAX};
|
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
@ -366,19 +374,13 @@ static rAssetHandle rTextureLoad(TextureAsset asset_id)
|
|||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WaitForBufferQueue()
|
static void vBufferQueueWait()
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < vDT_MAX; i++)
|
while (!JobQueueCompleted(&v_Renderer.upload.job_queue))
|
||||||
{
|
{
|
||||||
// TODO: replace
|
if (v_Renderer.async.sleeping > 0)
|
||||||
/*
|
|
||||||
while (!JobQueueCompleted(&renderer.upload_queues[vDT_MATERIAL].job_queue))
|
|
||||||
{
|
|
||||||
if (v_Renderer.state.renderer.height > 0)
|
|
||||||
vLoaderWake();
|
vLoaderWake();
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rBufferQueueReset()
|
static void rBufferQueueReset()
|
||||||
|
|||||||
@ -339,11 +339,13 @@ static inline u32 JobQueueGetCount(JobQueue *queue)
|
|||||||
|
|
||||||
static inline void JobQueueMarkUnqueued(JobQueue *queue, u32 count)
|
static inline void JobQueueMarkUnqueued(JobQueue *queue, u32 count)
|
||||||
{
|
{
|
||||||
|
Assert(queue->queued != 0, "queue queued is 0 before trying to mark dequeued");
|
||||||
pu32AtomicFetchSub(&queue->queued, count);
|
pu32AtomicFetchSub(&queue->queued, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void JobQueueMarkCompleted(JobQueue *queue, u32 count)
|
static inline void JobQueueMarkCompleted(JobQueue *queue, u32 count)
|
||||||
{
|
{
|
||||||
|
Assert(queue->remaining != 0, "queue remaining is 0 before trying to mark completed");
|
||||||
pu32AtomicFetchSub(&queue->remaining, count);
|
pu32AtomicFetchSub(&queue->remaining, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,8 +16,12 @@ typedef struct Arena Arena;
|
|||||||
#define BitEq(var, bits) (((var) & (bits)) == (bits))
|
#define BitEq(var, bits) (((var) & (bits)) == (bits))
|
||||||
#define AlignPow2(x, b) (((x) + (b) - 1) & (~((b) - 1)))
|
#define AlignPow2(x, b) (((x) + (b) - 1) & (~((b) - 1)))
|
||||||
#define IsPow2(x) ((x) != 0 && ((x) &((x) - 1)) == 0)
|
#define IsPow2(x) ((x) != 0 && ((x) &((x) - 1)) == 0)
|
||||||
#define PtrAdd(ptr, add) (((char *)ptr) + add)
|
#define PtrAdd(ptr, add) (((u8 *)ptr) + add)
|
||||||
|
#define PtrAddAdjustLen(ptr, len, add) \
|
||||||
|
ptr = PtrAdd(ptr, add); \
|
||||||
|
len -= add
|
||||||
|
|
||||||
|
#define Diff(value, sub) (value - sub)
|
||||||
#define MakeArray(arena, type, count) ArenaAlloc(arena, (isize)(sizeof(type)) * (isize)(count))
|
#define MakeArray(arena, type, count) ArenaAlloc(arena, (isize)(sizeof(type)) * (isize)(count))
|
||||||
#define Len(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
|
#define Len(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
|
||||||
|
|
||||||
@ -282,6 +286,7 @@ static inline void MutUnlock(Mut *mut);
|
|||||||
static inline void TicketMutLock(TicketMut *mut);
|
static inline void TicketMutLock(TicketMut *mut);
|
||||||
static inline void TicketMutUnlock(TicketMut *mut);
|
static inline void TicketMutUnlock(TicketMut *mut);
|
||||||
static inline u32 JobQueueAdd(JobQueue *queue, u32 count);
|
static inline u32 JobQueueAdd(JobQueue *queue, u32 count);
|
||||||
|
static inline u32 JobQueueGetCount(JobQueue *queue);
|
||||||
static inline void JobQueueMarkUnqueued(JobQueue *queue, u32 count);
|
static inline void JobQueueMarkUnqueued(JobQueue *queue, u32 count);
|
||||||
static inline void JobQueueMarkCompleted(JobQueue *queue, u32 count);
|
static inline void JobQueueMarkCompleted(JobQueue *queue, u32 count);
|
||||||
static inline void JobQueueReset(JobQueue *queue);
|
static inline void JobQueueReset(JobQueue *queue);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user