rtengine/src/asset_compiler/framegraph_processor.c
2024-06-05 11:54:35 +02:00

664 lines
31 KiB
C

#include "description_parser.h"
#include "processor.h"
#if 0
#include "gfx/gfx.h"
#include "runtime/buffer_manager.h"
#include <stdio.h>
#include <string.h>
static int RenderTargetExists(const rt_framegraph_info *framegraph, rt_render_target_id id) {
const rt_render_target_info *render_targets = rtResolveConstRelptr(&framegraph->render_targets);
for (uint32_t i = 0; i < framegraph->render_target_count; ++i) {
if (render_targets[i].id == id)
return 1;
}
return 0;
}
static rt_result ParseFramegraph(const char *text,
size_t size,
const char *file_path,
rt_framegraph_info **p_framegraph,
rt_arena *arena) {
rt_parse_state state;
unsigned int root_list;
rt_result result = rtParseDescription(text, size, file_path, &root_list, &state, arena);
if (result != RT_SUCCESS)
return result;
/* Push on the arena to ensure a continous memory layout */
rt_framegraph_info *framegraph = RT_ARENA_PUSH_STRUCT_ZERO(arena, rt_framegraph_info);
if (!framegraph)
return RT_OUT_OF_MEMORY;
/* ~~~~ Render Targets ~~~~ */
const rt_parsed_stmt *rt_list_stmt = rtFindStatement(&state, root_list, "render_targets");
if (!rt_list_stmt) {
rtLog("AC",
"Framegraph %s does not contain a list of render targets. (\"render_targets\")",
file_path);
return RT_INVALID_VALUE;
}
if (rt_list_stmt->form != RT_STMT_FORM_LIST) {
rtLog("AC", "Expected a list as the value of \"render_targets\" in %s", file_path);
return RT_INVALID_VALUE;
}
const rt_parsed_stmt_list *rt_list = &state.statement_lists[rt_list_stmt->list_index];
framegraph->render_target_count = rt_list->count;
rt_render_target_info *render_targets =
RT_ARENA_PUSH_ARRAY_ZERO(arena, rt_render_target_info, framegraph->render_target_count);
if (!render_targets)
return RT_OUT_OF_MEMORY;
rtSetRelptr(&framegraph->render_targets, render_targets);
const rt_parsed_stmt *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 (rendertarget_stmt->form != RT_STMT_FORM_LIST) {
rtLog("AC",
"Expected a list as the value of \"render_targets.%.*s\" in %s",
rendertarget_stmt->attribute.length,
rendertarget_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
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");
if (!width_stmt) {
rtLog("AC",
"Could not find \"render_targets.%.*s.width\" in %s",
rendertarget_stmt->attribute.length,
rendertarget_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
if (width_stmt->form != RT_STMT_FORM_VALUE) {
rtLog("AC",
"Expected a simple value for \"render_targets.%.*s.width\" in %s",
rendertarget_stmt->attribute.length,
rendertarget_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
if (rtCompareSpanToString(width_stmt->value, "SWAPCHAIN") == 0)
rt.width = RT_RENDER_TARGET_SIZE_SWAPCHAIN;
else
sscanf(width_stmt->value.start, "%u", &rt.width);
const rt_parsed_stmt *height_stmt =
rtFindStatement(&state, rendertarget_stmt->list_index, "height");
if (!height_stmt) {
rtLog("AC",
"Could not find \"render_targets.%.*s.height\" in %s",
rendertarget_stmt->attribute.length,
rendertarget_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
if (height_stmt->form != RT_STMT_FORM_VALUE) {
rtLog("AC",
"Expected a simple value for \"render_targets.%.*s.height\" in %s",
rendertarget_stmt->attribute.length,
rendertarget_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
if (rtCompareSpanToString(height_stmt->value, "SWAPCHAIN") == 0)
rt.height = RT_RENDER_TARGET_SIZE_SWAPCHAIN;
else
sscanf(height_stmt->value.start, "%u", &rt.height);
const rt_parsed_stmt *samples_stmt =
rtFindStatement(&state, rendertarget_stmt->list_index, "sample_count");
if (!samples_stmt) {
rtLog("AC",
"Could not find \"render_targets.%.*s.sample_count\" in %s",
rendertarget_stmt->attribute.length,
rendertarget_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
if (samples_stmt->form != RT_STMT_FORM_VALUE) {
rtLog("AC",
"Expected a simple value for \"render_targets.%.*s.sample_count\" in %s",
rendertarget_stmt->attribute.length,
rendertarget_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
sscanf(samples_stmt->value.start, "%u", &rt.sample_count);
const rt_parsed_stmt *format_stmt =
rtFindStatement(&state, rendertarget_stmt->list_index, "format");
if (!format_stmt) {
rtLog("AC",
"Could not find \"render_targets.%.*s.format\" in %s",
rendertarget_stmt->attribute.length,
rendertarget_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
if (format_stmt->form != RT_STMT_FORM_VALUE) {
rtLog("AC",
"Expected a simple value for \"render_targets.%.*s.format\" in %s",
rendertarget_stmt->attribute.length,
rendertarget_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
if (rtCompareSpanToString(format_stmt->value, "R8G8B8A8_UNORM") == 0)
rt.format = RT_PIXEL_FORMAT_R8G8B8A8_UNORM;
else if (rtCompareSpanToString(format_stmt->value, "B8G8R8A8_UNORM") == 0)
rt.format = RT_PIXEL_FORMAT_B8G8R8A8_UNORM;
else if (rtCompareSpanToString(format_stmt->value, "R8G8B8A8_SRGB") == 0)
rt.format = RT_PIXEL_FORMAT_R8G8B8A8_SRGB;
else if (rtCompareSpanToString(format_stmt->value, "B8G8R8A8_SRGB") == 0)
rt.format = RT_PIXEL_FORMAT_B8G8R8A8_SRGB;
else if (rtCompareSpanToString(format_stmt->value, "R8G8B8_UNORM") == 0)
rt.format = RT_PIXEL_FORMAT_R8G8B8_UNORM;
else if (rtCompareSpanToString(format_stmt->value, "B8G8R8_UNORM") == 0)
rt.format = RT_PIXEL_FORMAT_B8G8R8_UNORM;
else if (rtCompareSpanToString(format_stmt->value, "R8G8B8_SRGB") == 0)
rt.format = RT_PIXEL_FORMAT_R8G8B8_SRGB;
else if (rtCompareSpanToString(format_stmt->value, "B8G8R8_SRGB") == 0)
rt.format = RT_PIXEL_FORMAT_B8G8R8_SRGB;
else if (rtCompareSpanToString(format_stmt->value, "DEPTH24_STENCIL8") == 0)
rt.format = RT_PIXEL_FORMAT_DEPTH24_STENCIL8;
else if (rtCompareSpanToString(format_stmt->value, "DEPTH32") == 0)
rt.format = RT_PIXEL_FORMAT_DEPTH32;
else if (rtCompareSpanToString(format_stmt->value, "SWAPCHAIN") == 0)
rt.format = RT_PIXEL_FORMAT_SWAPCHAIN;
else {
rt.format = RT_PIXEL_FORMAT_INVALID;
rtLog("AC",
"Invalid format value \"%.*s\" in \"render_targets.%.*s.format\" in %s",
format_stmt->value.length,
format_stmt->value.start,
rendertarget_stmt->attribute.length,
rendertarget_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
render_targets[i] = rt;
}
/* ~~~~ Render Passes ~~~~ */
/* First count the total number of reads and writes */
uint32_t total_reads = 0, total_writes = 0;
const rt_parsed_stmt *pass_list_stmt = rtFindStatement(&state, root_list, "passes");
if (!pass_list_stmt) {
rtLog("Framegraph %s does not contain a list of passes (\"passes\")", file_path);
return RT_INVALID_VALUE;
}
if (pass_list_stmt->form != RT_STMT_FORM_LIST) {
rtLog("AC", "Expected a list as the value of \"passes\" in %s", file_path);
return RT_INVALID_VALUE;
}
const rt_parsed_stmt_list *pass_list = &state.statement_lists[pass_list_stmt->list_index];
rt_render_pass_info *passes =
RT_ARENA_PUSH_ARRAY_ZERO(arena, rt_render_pass_info, pass_list->count);
if (!passes)
return RT_OUT_OF_MEMORY;
rtSetRelptr(&framegraph->render_passes, passes);
framegraph->render_pass_count = pass_list->count;
const rt_parsed_stmt *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 (pass_stmt->form != RT_STMT_FORM_LIST) {
rtLog("AC",
"Expected a list as the value of \"passes.%.*s\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
framegraph->names_size += pass_stmt->attribute.length + 1;
passes[i].id =
rtCalculateRenderPassID(pass_stmt->attribute.start, pass_stmt->attribute.length);
passes[i].type = RT_RENDER_PASS_TYPE_GRAPHICS;
const rt_parsed_stmt *type_stmt = rtFindStatement(&state, pass_stmt->list_index, "type");
if (type_stmt) {
if (type_stmt->form != RT_STMT_FORM_VALUE) {
rtLog("AC",
"Expected GRAPHICS or COMPUTE as the value of \"passes.%.*s.type\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
if (rtCompareSpanToString(type_stmt->value, "GRAPHICS") == 0) {
passes[i].type = RT_RENDER_PASS_TYPE_GRAPHICS;
} else if (rtCompareSpanToString(type_stmt->value, "COMPUTE") == 0) {
passes[i].type = RT_RENDER_PASS_TYPE_COMPUTE;
} else {
rtLog("AC",
"Expected GRAPHICS or COMPUTE as the value of \"passes.%.*s.type\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
}
const rt_parsed_stmt *write_list_stmt =
rtFindStatement(&state, pass_stmt->list_index, "writes");
if (write_list_stmt) {
if (write_list_stmt->form != RT_STMT_FORM_LIST) {
rtLog("AC",
"Expected a list as the value of \"passes.%.*s.writes\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
const rt_parsed_stmt_list *write_list =
&state.statement_lists[write_list_stmt->list_index];
passes[i].write_render_target_count = write_list->count;
total_writes += write_list->count;
} else {
passes[i].write_render_target_count = 0;
rtSetRelptr(&passes[i].write_render_targets, NULL);
}
const rt_parsed_stmt *read_list_stmt =
rtFindStatement(&state, pass_stmt->list_index, "reads");
if (read_list_stmt) {
if (read_list_stmt->form != RT_STMT_FORM_LIST) {
rtLog("AC",
"Expected a list as the value of \"passes.%.*s.reads\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
const rt_parsed_stmt_list *read_list =
&state.statement_lists[read_list_stmt->list_index];
passes[i].read_render_target_count = read_list->count;
total_reads += read_list->count;
} else {
passes[i].read_render_target_count = 0;
rtSetRelptr(&passes[i].read_render_targets, NULL);
}
}
/* Now fill the read & write lists */
rt_render_target_read *reads =
RT_ARENA_PUSH_ARRAY_ZERO(arena, rt_render_target_read, total_reads);
rt_render_target_write *writes =
RT_ARENA_PUSH_ARRAY_ZERO(arena, rt_render_target_write, total_writes);
if (!reads && total_reads != 0)
return RT_OUT_OF_MEMORY;
if (!writes && total_writes != 0)
return RT_OUT_OF_MEMORY;
uint32_t reads_at = 0;
uint32_t writes_at = 0;
pass_stmt = &state.statements[pass_list->first];
for (uint32_t i = 0; i < pass_list->count;
++i, pass_stmt = &state.statements[pass_stmt->next]) {
RT_ASSERT(pass_stmt->form == RT_STMT_FORM_LIST, "");
const rt_parsed_stmt *write_list_stmt =
rtFindStatement(&state, pass_stmt->list_index, "writes");
if (write_list_stmt) {
RT_ASSERT(write_list_stmt->form == RT_STMT_FORM_LIST, "");
const rt_parsed_stmt_list *write_list =
&state.statement_lists[write_list_stmt->list_index];
rtSetRelptr(&passes[i].write_render_targets, &writes[writes_at]);
const rt_parsed_stmt *write_stmt = &state.statements[write_list->first];
for (uint32_t j = 0; j < write_list->count;
++j, write_stmt = &state.statements[write_stmt->next]) {
if (write_stmt->form != RT_STMT_FORM_LIST) {
rtLog("AC",
"Expected a list as the value of \"passes.%.*s.writes.%.*s\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
write_stmt->attribute.length,
write_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
rt_render_target_write *write = &writes[writes_at++];
memset(write, 0, sizeof(*write));
write->render_target = rtCalculateRenderTargetID(write_stmt->attribute.start,
write_stmt->attribute.length);
if (!RenderTargetExists(framegraph, write->render_target)) {
rtLog("AC",
"Referenced unknown render target \"%.s\" in \"passes.%.*s.writes.%.*s\" "
"in %s",
write_stmt->attribute.length,
write_stmt->attribute.start,
pass_stmt->attribute.length,
pass_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
const rt_parsed_stmt *clear_value_stmt =
rtFindStatement(&state, write_stmt->list_index, "clear_value");
if (clear_value_stmt) {
if (clear_value_stmt->form != RT_STMT_FORM_LIST) {
rtLog("AC",
"Expected a list as the value of "
"\"passes.%.*s.writes.%.*s.clear_value\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
write_stmt->attribute.length,
write_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
const rt_parsed_stmt *r_stmt =
rtFindStatement(&state, clear_value_stmt->list_index, "r");
if (r_stmt) {
if (r_stmt->form != RT_STMT_FORM_VALUE) {
rtLog("AC",
"Expected a float as the value of "
"\"passes.%.*s.writes.%.*s.clear_value.r\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
write_stmt->attribute.length,
write_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
sscanf(r_stmt->value.start, "%f", &write->clear.color.r);
}
const rt_parsed_stmt *g_stmt =
rtFindStatement(&state, clear_value_stmt->list_index, "g");
if (g_stmt) {
if (g_stmt->form != RT_STMT_FORM_VALUE) {
rtLog("AC",
"Expected a float as the value of "
"\"passes.%.*s.writes.%.*s.clear_value.g\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
write_stmt->attribute.length,
write_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
sscanf(g_stmt->value.start, "%f", &write->clear.color.g);
}
const rt_parsed_stmt *b_stmt =
rtFindStatement(&state, clear_value_stmt->list_index, "b");
if (b_stmt) {
if (b_stmt->form != RT_STMT_FORM_VALUE) {
rtLog("AC",
"Expected a float as the value of "
"\"passes.%.*s.writes.%.*s.clear_value.b\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
write_stmt->attribute.length,
write_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
sscanf(b_stmt->value.start, "%f", &write->clear.color.b);
}
const rt_parsed_stmt *a_stmt =
rtFindStatement(&state, clear_value_stmt->list_index, "a");
if (a_stmt) {
if (a_stmt->form != RT_STMT_FORM_VALUE) {
rtLog("AC",
"Expected a float as the value of "
"\"passes.%.*s.writes.%.*s.clear_value.a\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
write_stmt->attribute.length,
write_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
sscanf(a_stmt->value.start, "%f", &write->clear.color.a);
}
const rt_parsed_stmt *d_stmt =
rtFindStatement(&state, clear_value_stmt->list_index, "d");
if (d_stmt) {
if (d_stmt->form != RT_STMT_FORM_VALUE) {
rtLog("AC",
"Expected a float as the value of "
"\"passes.%.*s.writes.%.*s.clear_value.d\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
write_stmt->attribute.length,
write_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
sscanf(d_stmt->value.start, "%f", &write->clear.depth_stencil.depth);
}
const rt_parsed_stmt *s_stmt =
rtFindStatement(&state, clear_value_stmt->list_index, "s");
if (s_stmt) {
if (s_stmt->form != RT_STMT_FORM_VALUE) {
rtLog("AC",
"Expected an integer as the value of "
"\"passes.%.*s.writes.%.*s.clear_value.s\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
write_stmt->attribute.length,
write_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
sscanf(s_stmt->value.start, "%d", &write->clear.depth_stencil.stencil);
}
}
const rt_parsed_stmt *clear_stmt =
rtFindStatement(&state, write_stmt->list_index, "clear");
if (clear_stmt) {
if (clear_stmt->form != RT_STMT_FORM_VALUE) {
rtLog("AC",
"Expected a YES or NO as the value of "
"\"passes.%.*s.writes.%.*s.clear\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
write_stmt->attribute.length,
write_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
if (rtCompareSpanToString(clear_stmt->value, "YES") == 0) {
write->flags |= RT_RENDER_TARGET_WRITE_CLEAR;
} else if (rtCompareSpanToString(clear_stmt->value, "NO") != 0) {
rtLog("AC",
"Expected a YES or NO as the value of "
"\"passes.%.*s.writes.%.*s.clear\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
write_stmt->attribute.length,
write_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
}
const rt_parsed_stmt *discard_stmt =
rtFindStatement(&state, write_stmt->list_index, "discard");
if (discard_stmt) {
if (discard_stmt->form != RT_STMT_FORM_VALUE) {
rtLog("AC",
"Expected YES or NO as the value of "
"\"passes.%.*s.writes.%.*s.clear\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
write_stmt->attribute.length,
write_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
if (rtCompareSpanToString(discard_stmt->value, "YES") == 0) {
write->flags |= RT_RENDER_TARGET_WRITE_DISCARD;
} else if (rtCompareSpanToString(discard_stmt->value, "NO") != 0) {
rtLog("AC",
"Expected YES or NO as the value of "
"\"passes.%.*s.writes.%.*s.discard\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
write_stmt->attribute.length,
write_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
}
}
}
const rt_parsed_stmt *read_list_stmt =
rtFindStatement(&state, pass_stmt->list_index, "reads");
if (read_list_stmt) {
RT_ASSERT(read_list_stmt->form == RT_STMT_FORM_LIST, "");
const rt_parsed_stmt_list *read_list =
&state.statement_lists[read_list_stmt->list_index];
rtSetRelptr(&passes[i].read_render_targets, &reads[reads_at]);
const rt_parsed_stmt *read_stmt = &state.statements[read_list->first];
for (uint32_t j = 0; j < read_list->count;
++j, read_stmt = &state.statements[read_stmt->next]) {
if (read_stmt->form != RT_STMT_FORM_LIST) {
rtLog("AC",
"Expected a list as the value of \"passes.%.*s.reads.%.*s\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
read_stmt->attribute.length,
read_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
rt_render_target_read *read = &reads[reads_at++];
memset(read, 0, sizeof(*read));
read->render_target = rtCalculateRenderTargetID(read_stmt->attribute.start,
read_stmt->attribute.length);
if (!RenderTargetExists(framegraph, read->render_target)) {
rtLog("AC",
"Referenced unknown render target \"%.s\" in \"passes.%.*s.reads.%.*s\" "
"in %s",
read_stmt->attribute.length,
read_stmt->attribute.start,
pass_stmt->attribute.length,
pass_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
const rt_parsed_stmt *mode_stmt =
rtFindStatement(&state, read_stmt->list_index, "mode");
if (mode_stmt) {
if (mode_stmt->form != RT_STMT_FORM_VALUE) {
rtLog("AC",
"Expected SAMPLED or INPUT_ATTACHMENT as the value of "
"\"passes.%.*s.writes.%.*s.mode\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
read_stmt->attribute.length,
read_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
if (rtCompareSpanToString(mode_stmt->value, "SAMPLED") == 0) {
read->mode = RT_RENDER_TARGET_READ_SAMPLED;
} else if (rtCompareSpanToString(mode_stmt->value, "DIRECT") == 0) {
read->mode = RT_RENDER_TARGET_READ_DIRECT;
} else {
rtLog("AC",
"Expected SAMPLED or DIRECT as the value of "
"\"passes.%.*s.writes.%.*s.mode\" in %s",
pass_stmt->attribute.length,
pass_stmt->attribute.start,
read_stmt->attribute.length,
read_stmt->attribute.start,
file_path);
return RT_INVALID_VALUE;
}
}
}
}
}
/* ~~~~ 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;
}
}
*p_framegraph = framegraph;
return result;
}
RT_ASSET_PROCESSOR_FN(FramegraphProcessor) {
rt_loaded_asset asset = LoadAsset(file);
if (!asset.buffer)
return RT_UNKNOWN_ERROR;
rt_framegraph_info *framegraph = NULL;
rt_result result =
ParseFramegraph(asset.buffer, asset.size, rtGetFilePath(file), &framegraph, arena);
if (result != RT_SUCCESS)
goto out;
rt_resource resource = {0};
resource.type = RT_RESOURCE_FRAMEGRAPH;
resource.data = framegraph;
rt_resource_id id;
const char *name = rtGetFilePath(file);
result = rtCreateResources(1, &name, &resource, &id);
if (result != RT_SUCCESS)
goto out;
new_resources[0] = id;
*new_resource_count = 1;
out:
rtReleaseBuffer(asset.buffer, asset.size);
return result;
}
#endif