diff --git a/src/asset_compiler/framegraph_processor.c b/src/asset_compiler/framegraph_processor.c index f304cd7..2d0d044 100644 --- a/src/asset_compiler/framegraph_processor.c +++ b/src/asset_compiler/framegraph_processor.c @@ -1,8 +1,8 @@ -#include "processor.h" #include "description_parser.h" +#include "processor.h" -#include "runtime/buffer_manager.h" #include "gfx/gfx.h" +#include "runtime/buffer_manager.h" #include #include @@ -67,6 +67,7 @@ static rt_result ParseFramegraph(const char *text, rt_render_target_info rt = {0}; rt.id = rtCalculateRenderTargetID(rendertarget_stmt->attribute.start, rendertarget_stmt->attribute.length); + framegraph->names_size += rendertarget_stmt->attribute.length; const rt_parsed_stmt *width_stmt = rtFindStatement(&state, rendertarget_stmt->list_index, "width"); @@ -221,11 +222,10 @@ static rt_result ParseFramegraph(const char *text, return RT_INVALID_VALUE; } + framegraph->names_size += pass_stmt->attribute.length + 1; + passes[i].id = rtCalculateRenderPassID(pass_stmt->attribute.start, pass_stmt->attribute.length); - rtSetRelptr(&passes[i].name, NULL); - passes[i].name_len = 0; - passes[i].type = RT_RENDER_PASS_TYPE_GRAPHICS; const rt_parsed_stmt *type_stmt = rtFindStatement(&state, pass_stmt->list_index, "type"); if (type_stmt) { @@ -592,6 +592,44 @@ static rt_result ParseFramegraph(const char *text, } #pragma region +#pragma region Names + /* Fill the render pass names */ + char *names = rtArenaPush(arena, framegraph->names_size); + rtSetRelptr(&framegraph->names, names); + char *names_at = names; + pass_stmt = &state.statements[pass_list->first]; + for (uint32_t i = 0; i < pass_list->count; + ++i, pass_stmt = &state.statements[pass_stmt->next]) { + if (names) { + memcpy(names_at, pass_stmt->attribute.start, pass_stmt->attribute.length); + names_at[pass_stmt->attribute.length] = '\0'; + rtSetRelptr(&passes[i].name, names_at); + passes[i].name_len = pass_stmt->attribute.length + 1; + names_at += pass_stmt->attribute.length + 1; + } else { + rtSetRelptr(&passes[i].name, NULL); + passes[i].name_len = 0; + } + } + + rendertarget_stmt = &state.statements[rt_list->first]; + for (uint32_t i = 0; i < rt_list->count; + ++i, rendertarget_stmt = &state.statements[rendertarget_stmt->next]) { + if (names) { + memcpy(names_at, + rendertarget_stmt->attribute.start, + rendertarget_stmt->attribute.length); + names_at[rendertarget_stmt->attribute.length] = '\0'; + rtSetRelptr(&render_targets[i].name, names_at); + render_targets[i].name_len = rendertarget_stmt->attribute.length + 1; + names_at += rendertarget_stmt->attribute.length + 1; + } else { + rtSetRelptr(&render_targets[i].name, NULL); + render_targets[i].name_len = 0; + } + } +#pragma region + *p_framegraph = framegraph; return result; } @@ -613,11 +651,11 @@ RT_ASSET_PROCESSOR_FN(FramegraphProcessor) { rt_resource_id id; const char *name = rtGetFilePath(file); - result = rtCreateResources(1, &name, &resource, &id); + result = rtCreateResources(1, &name, &resource, &id); if (result != RT_SUCCESS) goto out; - new_resources[0] = id; + new_resources[0] = id; *new_resource_count = 1; out: diff --git a/src/gfx/gfx.h b/src/gfx/gfx.h index 54a2de6..ebbe2bc 100644 --- a/src/gfx/gfx.h +++ b/src/gfx/gfx.h @@ -84,6 +84,10 @@ typedef struct { uint32_t width; uint32_t height; uint32_t sample_count; + + /* For debug purposes, can be 0 */ + rt_relptr name; + uint32_t name_len; } rt_render_target_info; typedef enum { @@ -144,6 +148,8 @@ typedef struct { rt_relptr render_passes; uint32_t render_target_count; uint32_t render_pass_count; + rt_relptr names; + uint32_t names_size; } rt_framegraph_info; typedef void rt_render_pass_prepare_fn(rt_render_pass_id id, diff --git a/src/gfx/gfx_framegraph.c b/src/gfx/gfx_framegraph.c index ce3d9e5..2cb1195 100644 --- a/src/gfx/gfx_framegraph.c +++ b/src/gfx/gfx_framegraph.c @@ -21,6 +21,7 @@ RT_CVAR_I(rt_MaxFramegraphs, "Maximum number of framegraphs. Default 16", 16); typedef struct { rt_render_target_id id; rt_pixel_format format; + const char *name; unsigned int width; unsigned int height; unsigned int sample_count; @@ -316,10 +317,33 @@ CreateRenderTargets(rt_framegraph *graph, const rt_framegraph_info *info, rt_are graph->render_targets[i].width = render_targets[i].width; graph->render_targets[i].height = render_targets[i].height; graph->render_targets[i].sample_count = render_targets[i].sample_count; + graph->render_targets[i].name = NULL; + + const char *name = rtResolveConstRelptr(&render_targets[i].name); + if (name) { + size_t name_strlen = strlen(name); + if (name_strlen + 1 == render_targets[i].name_len) { + rtLockMutex(_name_lock); + ptrdiff_t name_off = _name_next - _name_buffer; + if ((name_off + render_targets[i].name_len) < NAMES_CAPACITY) { + char *dst_name = _name_next; + memcpy(dst_name, name, render_targets[i].name_len); + _name_next += render_targets[i].name_len; + graph->render_targets[i].name = dst_name; + } else { + rtLog("GFX", "Ran out of storage for debug name %s", name); + } + rtUnlockMutex(_name_lock); + } else { + rtLog("GFX", "Declared name-length for render-target %u does not match strlen()"); + } + } + char sem_name[128]; + rtSPrint(sem_name, 128, "%s - Semaphore", (name) ? name : "Unnamed RT"); rt_gpu_semaphore_info sem_info = { .initial_value = 0, - .name = NULL, + .name = sem_name, }; g_renderer.CreateSemaphores(1, &sem_info, &graph->render_targets[i].semaphore); @@ -489,6 +513,7 @@ BeginGraphicsPass(rt_framegraph *framegraph, uint32_t pass_idx, rt_command_buffe /* Convert reads and writes into the pass begin info for the renderer */ rt_cmd_begin_pass_info begin_info; memset(&begin_info, 0, sizeof(begin_info)); + begin_info.name = framegraph->passes[pass_idx].name; /* All written render targets need to have the same size */ if (write_count > 0) { diff --git a/src/renderer/vk/gpu_sync.c b/src/renderer/vk/gpu_sync.c index c99360d..c1474dd 100644 --- a/src/renderer/vk/gpu_sync.c +++ b/src/renderer/vk/gpu_sync.c @@ -106,6 +106,19 @@ rt_result RT_RENDERER_API_FN(CreateSemaphores)(uint32_t count, } return RT_UNKNOWN_ERROR; } + +#ifdef RT_DEBUG + char name[128]; + rtSPrint(name, 128, "%s (%u)", (info->name) ? info->name : "Unnamed Semaphore", j); + VkDebugUtilsObjectNameInfoEXT name_info = { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, + .objectHandle = (uint64_t)sem->semaphore[j], + .objectType = VK_OBJECT_TYPE_SEMAPHORE, + .pObjectName = name, + }; + vkSetDebugUtilsObjectNameEXT(g_gpu.device, &name_info); +#endif + sem->current_value[j] = 0; } diff --git a/src/renderer/vk/init.c b/src/renderer/vk/init.c index 33b9c40..f75c9ba 100644 --- a/src/renderer/vk/init.c +++ b/src/renderer/vk/init.c @@ -606,6 +606,25 @@ static rt_result CreatePerFrameObjects(void) { &g_gpu.frames[i].swapchain_transitioned) != VK_SUCCESS) { return RT_UNKNOWN_ERROR; } +#ifdef RT_DEBUG + char name[128]; + rtSPrint(name, 128, "Render Finished Semaphore (%u)", i); + VkDebugUtilsObjectNameInfoEXT name_info = { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, + .objectHandle = (uint64_t)g_gpu.frames[i].render_finished, + .objectType = VK_OBJECT_TYPE_SEMAPHORE, + .pObjectName = name, + }; + vkSetDebugUtilsObjectNameEXT(g_gpu.device, &name_info); + + rtSPrint(name, 128, "Image Available Semaphore (%u)", i); + name_info.objectHandle = (uint64_t)g_gpu.frames[i].image_available; + vkSetDebugUtilsObjectNameEXT(g_gpu.device, &name_info); + + rtSPrint(name, 128, "Swapchain Transitioned Semaphore (%u)", i); + name_info.objectHandle = (uint64_t)g_gpu.frames[i].swapchain_transitioned; + vkSetDebugUtilsObjectNameEXT(g_gpu.device, &name_info); +#endif } return RT_SUCCESS; } diff --git a/src/runtime/resource_manager.c b/src/runtime/resource_manager.c index 0bb5a1a..7cd9f0a 100644 --- a/src/runtime/resource_manager.c +++ b/src/runtime/resource_manager.c @@ -102,12 +102,13 @@ static size_t GetResourceDataSize(const rt_resource *resource) { case RT_RESOURCE_FRAMEGRAPH: { const rt_framegraph_info *info = resource->data; size_t size = sizeof(*info) + sizeof(rt_render_target_info) * info->render_target_count + - sizeof(rt_render_pass_info) * info->render_pass_count; + sizeof(rt_render_pass_info) * info->render_pass_count + info->names_size; const rt_render_pass_info *passes = rtResolveConstRelptr(&info->render_passes); for (uint32_t i = 0; i < info->render_pass_count; ++i) { size += passes[i].read_render_target_count * sizeof(rt_render_target_read) + passes[i].write_render_target_count * sizeof(rt_render_target_write); } + return size; } break; default: rtLog("RESMGR", "Tried to get size of an invalid resource type %u", resource->type); @@ -177,6 +178,26 @@ static void CopyResourceData(const rt_resource *resource, void *dest) { rtSetRelptr(&passes_dest[i].write_render_targets, NULL); } } + + char *names_begin = (char *)read_write_dest; + const char *src_names = rtResolveConstRelptr(&info->names); + memcpy(names_begin, src_names, info->names_size); + rtSetRelptr(&dest_info->names, names_begin); + dest_info->names_size = info->names_size; + + const rt_render_target_info *src_rts = rtResolveConstRelptr(&info->render_targets); + rt_render_target_info *rts = (rt_render_target_info *)(dest_info + 1); + for (uint32_t i = 0; i < info->render_target_count; ++i) { + const char *src_name = rtResolveConstRelptr(&src_rts[i].name); + if (src_name) + rtSetRelptr(&rts[i].name, names_begin + (src_name - src_names)); + } + + for (uint32_t i = 0; i < info->render_pass_count; ++i) { + const char *src_name = rtResolveConstRelptr(&passes[i].name); + if (src_name) + rtSetRelptr(&passes_dest[i].name, names_begin + (src_name - src_names)); + } } break; default: rtLog("RESMGR", "Tried to copy a resource of invalid type %u", resource->type); @@ -1017,7 +1038,8 @@ RT_DLLEXPORT void rDebugLogResource(rt_resource_id id, const rt_resource *resour const rt_render_target_info *render_targets = rtResolveConstRelptr(&framegraph->render_targets); for (uint32_t i = 0; i < framegraph->render_target_count; ++i) { - rtLog("RESMGR", " - %x", render_targets[i].id); + const char *name = rtResolveConstRelptr(&render_targets[i].name); + rtLog("RESMGR", " - %s %x", name ? name : "Unnamed RT", render_targets[i].id); if (render_targets[i].width != RT_RENDER_TARGET_SIZE_SWAPCHAIN) rtLog("RESMGR", " size: %u x %u", @@ -1035,7 +1057,8 @@ RT_DLLEXPORT void rDebugLogResource(rt_resource_id id, const rt_resource *resour rtLog("RESMGR", " passes:"); const rt_render_pass_info *render_passes = rtResolveConstRelptr(&framegraph->render_passes); for (uint32_t i = 0; i < framegraph->render_pass_count; ++i) { - rtLog("RESMGR", " - %x", render_passes[i].id); + const char *name = rtResolveConstRelptr(&render_targets[i].name); + rtLog("RESMGR", " - %s %x", name ? name : "Unnamed Pass", render_passes[i].id); rtLog("RESMGR", " reads:"); const rt_render_target_read *reads = rtResolveConstRelptr(&render_passes[i].read_render_targets);