Add debug names to framegraph objects

Better renderdoc output
This commit is contained in:
Kevin Trogant 2024-02-28 13:38:41 +01:00
parent 424345374f
commit 9d2987121e
6 changed files with 135 additions and 11 deletions

View File

@ -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 <stdio.h>
#include <string.h>
@ -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;
}

View File

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

View File

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

View File

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

View File

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

View File

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