From 905cb50e334e4a7880b151a0b6dd971b4eb1ecf0 Mon Sep 17 00:00:00 2001 From: jacob Date: Sun, 7 Dec 2025 04:33:03 -0600 Subject: [PATCH] sync singular build data struct during prep --- src/gpu/gpu_dx12/gpu_dx12.c | 6 + src/meta/meta.c | 970 +++++++++++++++++++----------------- 2 files changed, 519 insertions(+), 457 deletions(-) diff --git a/src/gpu/gpu_dx12/gpu_dx12.c b/src/gpu/gpu_dx12/gpu_dx12.c index 85f51002..dd24b7f4 100644 --- a/src/gpu/gpu_dx12/gpu_dx12.c +++ b/src/gpu/gpu_dx12/gpu_dx12.c @@ -539,6 +539,12 @@ GPU_D12_Pipeline *GPU_D12_PipelineFromDesc(GPU_D12_PipelineDesc desc) } } + if (!ok) + { + /* TOOD: Don't panic */ + Panic(error_str); + } + pipeline->pso = pso; pipeline->error = error_str; pipeline->ok = ok; diff --git a/src/meta/meta.c b/src/meta/meta.c index edd043de..a648be67 100644 --- a/src/meta/meta.c +++ b/src/meta/meta.c @@ -339,11 +339,139 @@ void BuildEntryPoint(WaveLaneCtx *lane, void *udata) } ////////////////////////////// - //- Parse meta layers + //- Prep + + String shader_store_name = Lit("ShadersStore"); + String c_out_file = F_GetFull(perm, StringF(perm, "%F_gen_c.c", FmtString(cmdline.leaf_layer_name))); + String gpu_out_file = F_GetFull(perm, StringF(perm, "%F_gen_gpu.hlsl", FmtString(cmdline.leaf_layer_name))); + + Enum(ShaderEntryKind) + { + ShaderEntryKind_VS, + ShaderEntryKind_PS, + ShaderEntryKind_CS, + }; + + Struct(ShaderEntry) + { + ShaderEntry *next; + ShaderEntryKind kind; + String name; + }; + + Struct(ArcInfoEntry) + { + ArcInfoEntry *next; + String dir_path; + String store_name; + String out_path; + }; + + Struct(GpuComp) + { + String output; + i32 return_code; + }; + + Struct(ResComp) + { + String obj_file; + String output; + i32 return_code; + }; + + /* + * ## Phase 1 + * + * + * + * ------------------------------------------------------------- + * + * ## Phase 2 + * + * + * | + * ------------------------------------------------------------- + * + * ## Phase 3 + * + * | | + * ------------------------------------------------------------- + * + * ## Phase 4 + * + * ------------------------------------------------------------- + * + * ## Phase 5 + * + * + */ + + /* TODO: Dispatch OS Cmds asynchronously rather than synchronously waiting on each lane */ + + Struct(BuildData) + { + M_Layer flattened; + + struct + { + M_ErrorList errors; + } cgen; + + struct + { + M_ErrorList errors; + ShaderEntry *first_shader_entry; + ShaderEntry *last_shader_entry; + u64 shader_entries_count; + } gpugen; + + struct + { + String obj_file; + String output; + i32 return_code; + } ccomp; + + struct + { + GpuComp *array; + u32 count; + } gpucomps; + + struct + { + M_ErrorList errors; + ArcInfoEntry *first_arc_entry; + ArcInfoEntry *last_arc_entry; + u64 arc_entries_count; + } arcinfogen; + + struct + { + ResComp *array; + u32 count; + } rescomps; + + struct + { + String output; + i32 return_code; + } link; + }; + + BuildData *build = 0; + if (lane->idx == 0) + { + build = PushStruct(perm, BuildData); + } + WaveSyncBroadcast(lane, 0, &build); i32 ret = 0; - M_Layer flattened = ZI; + ////////////////////////////// + //- Parse meta layers + if (lane->idx == 0 && !ret) { //- Lex layers @@ -364,259 +492,27 @@ void BuildEntryPoint(WaveLaneCtx *lane, void *udata) { StringList starting_layer_names = ZI; PushStringToList(perm, &starting_layer_names, cmdline.leaf_layer_name); - flattened = M_GetFlattenedEntries(perm, parsed, starting_layer_names); + build->flattened = M_GetFlattenedEntries(perm, parsed, starting_layer_names); } } - WaveSyncBroadcast(lane, 0, &flattened); - if (!ret) ret = flattened.errors.count > 0; + + WaveSync(lane); + if (!ret) ret = build->flattened.errors.count > 0; ////////////////////////////// - //- Prep - - /* - * ## Phase 1 - * - * - * | - * ------------------------------------------------------------- - * - * ## Phase 2 - * - * | | - * ------------------------------------------------------------- - * - * ## Phase 3 - * - * ------------------------------------------------------------- - * - * ## Phase 4 - * - * - */ - - String shader_store_name = Lit("ShadersStore"); - String c_out_file = F_GetFull(perm, StringF(perm, "%F_gen_c.c", FmtString(cmdline.leaf_layer_name))); - String gpu_out_file = F_GetFull(perm, StringF(perm, "%F_gen_gpu.hlsl", FmtString(cmdline.leaf_layer_name))); - - /* TODO: Dispatch OS Cmds asynchronously rather than synchronously waiting on each lane */ - - ////////////////////////////// - //- Generate final C file - - Struct(CGenData) - { - M_ErrorList errors; - }; - CGenData cgen = ZI; + //- Generate C & HLSL files if (lane->idx == 0 && !ret) { - String c_out_file = F_GetFull(perm, StringF(perm, "%F_gen_c.c", FmtString(cmdline.leaf_layer_name))); - StringList c_store_lines = ZI; - StringList c_shader_lines = ZI; - StringList c_include_lines = ZI; - StringList c_startup_lines = ZI; + /* Generate C file */ { - for (M_Entry *entry = flattened.first; entry->valid; entry = entry->next) + String c_out_file = F_GetFull(perm, StringF(perm, "%F_gen_c.c", FmtString(cmdline.leaf_layer_name))); + StringList c_store_lines = ZI; + StringList c_shader_lines = ZI; + StringList c_include_lines = ZI; + StringList c_startup_lines = ZI; { - M_EntryKind kind = entry->kind; - M_Token *entry_tok = entry->name_token; - M_Token *arg0_tok = entry->arg_tokens[0]; - M_Token *arg1_tok = entry->arg_tokens[1]; - switch (kind) - { - default: break; - case M_EntryKind_EmbedDir: - { - if (arg0_tok->valid && arg1_tok->valid) - { - String store_name = arg0_tok->s; - String token_file = arg1_tok->file->name; - String token_parent_dir = F_GetParentDir(token_file); - String arg_dir = arg1_tok->s; - String full = F_GetFullCrossPlatform(perm, StringF(perm, "%F/%F", FmtString(token_parent_dir), FmtString(arg_dir))); - if (F_IsDir(full)) - { - u64 hash = HashFnv64(Fnv64Basis, StringF(perm, "%F/", FmtString(store_name))); - String line = StringF(perm, "ResourceStore %F = { 0x%F };", FmtString(store_name), FmtHex(hash)); - PushStringToList(perm, &c_store_lines, line); - } - else - { - String err = StringF(perm, "Directory '%F' not found", FmtString(full)); - M_PushError(perm, &cgen.errors, arg1_tok, err); - } - } - else - { - M_PushError(perm, &cgen.errors, entry_tok, Lit("Expected resource store & directory name")); - } - } break; - case M_EntryKind_VertexShader: - case M_EntryKind_PixelShader: - case M_EntryKind_ComputeShader: - { - if (arg0_tok->valid) - { - String shader_type = kind == M_EntryKind_VertexShader ? Lit("VertexShader") - : kind == M_EntryKind_PixelShader ? Lit("PixelShader") - : kind == M_EntryKind_ComputeShader ? Lit("ComputeShader") - : Lit(""); - String shader_name = arg0_tok->s; - u64 hash = HashFnv64(Fnv64Basis, StringF(perm, "%F/%F", FmtString(shader_store_name), FmtString(shader_name))); - String line = StringF(perm, "%F %F = { 0x%F };", FmtString(shader_type), FmtString(shader_name), FmtHex(hash)); - PushStringToList(perm, &c_shader_lines, line); - } - else - { - M_PushError(perm, &cgen.errors, entry_tok, Lit("Expected shader name")); - } - } break; - case M_EntryKind_IncludeC: - { - if (arg0_tok->valid) - { - String token_file = arg0_tok->file->name; - String token_parent_dir = F_GetParentDir(token_file); - String arg_file = arg0_tok->s; - String full = F_GetFull(perm, StringF(perm, "%F/%F", FmtString(token_parent_dir), FmtString(arg_file))); - if (F_IsFile(full)) - { - String line = StringF(perm, "#include \"%F\"", FmtString(full)); - PushStringToList(perm, &c_include_lines, line); - } - else - { - String err = StringF(perm, "File '%F' not found", FmtString(full)); - M_PushError(perm, &cgen.errors, arg0_tok, err); - } - } - else - { - M_PushError(perm, &cgen.errors, entry_tok, Lit("Expected file name")); - } - } break; - case M_EntryKind_Startup: - { - if (arg0_tok->valid) - { - String startup = arg0_tok->s; - String line = StringF(perm, " %F();", FmtString(startup)); - PushStringToList(perm, &c_startup_lines, line); - } - else - { - M_PushError(perm, &cgen.errors, entry_tok, Lit("Expected startup function name")); - } - } break; - } - } - } - if (cgen.errors.count == 0) - { - StringList c_out_lines = ZI; - PushStringToList(perm, &c_out_lines, Lit("// Auto generated file")); - /* Include base layer */ - { - String base_inc_path = F_GetFull(perm, Lit("../src/base/base_inc.h")); - PushStringToList(perm, &c_out_lines, Lit("")); - PushStringToList(perm, &c_out_lines, Lit("//- Base layer includes")); - PushStringToList(perm, &c_out_lines, StringF(perm, "#include \"%F\"", FmtString(base_inc_path))); - } - /* Define resource stores */ - if (c_store_lines.count > 0) - { - PushStringToList(perm, &c_out_lines, Lit("")); - PushStringToList(perm, &c_out_lines, Lit("//- Resource stores")); - for (StringListNode *n = c_store_lines.first; n; n = n->next) - { - PushStringToList(perm, &c_out_lines, n->s); - } - } - /* Define shaders */ - if (c_shader_lines.count > 0) - { - PushStringToList(perm, &c_out_lines, Lit("")); - PushStringToList(perm, &c_out_lines, Lit("//- Shaders")); - for (StringListNode *n = c_shader_lines.first; n; n = n->next) - { - PushStringToList(perm, &c_out_lines, n->s); - } - } - /* Include dependency layers */ - if (c_include_lines.count > 0) - { - PushStringToList(perm, &c_out_lines, Lit("")); - PushStringToList(perm, &c_out_lines, Lit("//- Dependency graph includes")); - for (StringListNode *n = c_include_lines.first; n; n = n->next) - { - PushStringToList(perm, &c_out_lines, n->s); - } - } - /* Define StartupLayers */ - { - PushStringToList(perm, &c_out_lines, Lit("")); - PushStringToList(perm, &c_out_lines, Lit("//- Startup")); - PushStringToList(perm, &c_out_lines, Lit("void StartupLayers(void)")); - PushStringToList(perm, &c_out_lines, Lit("{")); - for (StringListNode *n = c_startup_lines.first; n; n = n->next) - { - PushStringToList(perm, &c_out_lines, n->s); - } - PushStringToList(perm, &c_out_lines, Lit("}")); - } - /* Write to file */ - PushStringToList(perm, &c_out_lines, Lit("")); - String c_out = StringFromList(perm, c_out_lines, Lit("\n")); - F_ClearWrite(c_out_file, c_out); - } - } - WaveSyncBroadcast(lane, 0, &cgen); - if (!ret) ret = cgen.errors.count > 0; - - ////////////////////////////// - //- Generate final HLSL file - - Enum(ShaderEntryKind) { ShaderEntryKind_VS, ShaderEntryKind_PS, ShaderEntryKind_CS, }; - Struct(ShaderEntry) { ShaderEntry *next; ShaderEntryKind kind; String name; }; - Struct(GpuGenData) - { - M_ErrorList errors; - ShaderEntry *first_shader_entry; - ShaderEntry *last_shader_entry; - u64 shader_entries_count; - }; - GpuGenData gpugen = ZI; - - if (lane->idx == 0 && !ret) - { - /* Clear shader store */ - OS_Mkdir(shader_store_name); - { - /* Remove all old shaders */ - StringList files = ZI; - F_FilesFromDir(perm, &files, shader_store_name, F_IterFlag_None); - for (StringListNode *n = files.first; n; n = n->next) - { - String file = n->s; - /* Safety check to prevent non-shader files from being removed */ - if (StringEndsWith(file, Lit("VS")) || StringEndsWith(file, Lit("CS")) || StringEndsWith(file, Lit("PS"))) - { - OS_Rm(n->s); - } - else - { - /* Unexpected file in shader store */ - Assert(0); - } - } - } - - /* Generate GPU file & shader entries */ - { - StringList gpu_include_lines = ZI; - { - for (M_Entry *entry = flattened.first; entry->valid; entry = entry->next) + for (M_Entry *entry = build->flattened.first; entry->valid; entry = entry->next) { M_EntryKind kind = entry->kind; M_Token *entry_tok = entry->name_token; @@ -625,7 +521,53 @@ void BuildEntryPoint(WaveLaneCtx *lane, void *udata) switch (kind) { default: break; - case M_EntryKind_IncludeGpu: + case M_EntryKind_EmbedDir: + { + if (arg0_tok->valid && arg1_tok->valid) + { + String store_name = arg0_tok->s; + String token_file = arg1_tok->file->name; + String token_parent_dir = F_GetParentDir(token_file); + String arg_dir = arg1_tok->s; + String full = F_GetFullCrossPlatform(perm, StringF(perm, "%F/%F", FmtString(token_parent_dir), FmtString(arg_dir))); + if (F_IsDir(full)) + { + u64 hash = HashFnv64(Fnv64Basis, StringF(perm, "%F/", FmtString(store_name))); + String line = StringF(perm, "ResourceStore %F = { 0x%F };", FmtString(store_name), FmtHex(hash)); + PushStringToList(perm, &c_store_lines, line); + } + else + { + String err = StringF(perm, "Directory '%F' not found", FmtString(full)); + M_PushError(perm, &build->cgen.errors, arg1_tok, err); + } + } + else + { + M_PushError(perm, &build->cgen.errors, entry_tok, Lit("Expected resource store & directory name")); + } + } break; + case M_EntryKind_VertexShader: + case M_EntryKind_PixelShader: + case M_EntryKind_ComputeShader: + { + if (arg0_tok->valid) + { + String shader_type = kind == M_EntryKind_VertexShader ? Lit("VertexShader") + : kind == M_EntryKind_PixelShader ? Lit("PixelShader") + : kind == M_EntryKind_ComputeShader ? Lit("ComputeShader") + : Lit(""); + String shader_name = arg0_tok->s; + u64 hash = HashFnv64(Fnv64Basis, StringF(perm, "%F/%F", FmtString(shader_store_name), FmtString(shader_name))); + String line = StringF(perm, "%F %F = { 0x%F };", FmtString(shader_type), FmtString(shader_name), FmtHex(hash)); + PushStringToList(perm, &c_shader_lines, line); + } + else + { + M_PushError(perm, &build->cgen.errors, entry_tok, Lit("Expected shader name")); + } + } break; + case M_EntryKind_IncludeC: { if (arg0_tok->valid) { @@ -636,124 +578,251 @@ void BuildEntryPoint(WaveLaneCtx *lane, void *udata) if (F_IsFile(full)) { String line = StringF(perm, "#include \"%F\"", FmtString(full)); - PushStringToList(perm, &gpu_include_lines, line); + PushStringToList(perm, &c_include_lines, line); } else { String err = StringF(perm, "File '%F' not found", FmtString(full)); - M_PushError(perm, &gpugen.errors, arg0_tok, err); + M_PushError(perm, &build->cgen.errors, arg0_tok, err); } } else { - M_PushError(perm, &gpugen.errors, entry_tok, Lit("Expected file name")); + M_PushError(perm, &build->cgen.errors, entry_tok, Lit("Expected file name")); } } break; - case M_EntryKind_VertexShader: - case M_EntryKind_PixelShader: - case M_EntryKind_ComputeShader: + case M_EntryKind_Startup: { if (arg0_tok->valid) { - ShaderEntryKind shader_kind = kind == M_EntryKind_VertexShader ? ShaderEntryKind_VS - : kind == M_EntryKind_PixelShader ? ShaderEntryKind_PS - : kind == M_EntryKind_ComputeShader ? ShaderEntryKind_CS - : ShaderEntryKind_VS; - String shader_name = arg0_tok->s; - ShaderEntry *e = PushStruct(perm, ShaderEntry); - e->kind = shader_kind; - e->name = shader_name; - SllQueuePush(gpugen.first_shader_entry, gpugen.last_shader_entry, e); - ++gpugen.shader_entries_count; + String startup = arg0_tok->s; + String line = StringF(perm, " %F();", FmtString(startup)); + PushStringToList(perm, &c_startup_lines, line); } else { - M_PushError(perm, &gpugen.errors, entry_tok, Lit("Expected shader name")); + M_PushError(perm, &build->cgen.errors, entry_tok, Lit("Expected startup function name")); } } break; } } } - if (gpugen.errors.count == 0) + if (build->cgen.errors.count == 0) { - StringList gpu_out_lines = ZI; - PushStringToList(perm, &gpu_out_lines, Lit("// Auto generated file")); + StringList c_out_lines = ZI; + PushStringToList(perm, &c_out_lines, Lit("// Auto generated file")); /* Include base layer */ { String base_inc_path = F_GetFull(perm, Lit("../src/base/base_inc.h")); - PushStringToList(perm, &gpu_out_lines, Lit("")); - PushStringToList(perm, &gpu_out_lines, Lit("//- Base layer includes")); - PushStringToList(perm, &gpu_out_lines, StringF(perm, "#include \"%F\"", FmtString(base_inc_path))); + PushStringToList(perm, &c_out_lines, Lit("")); + PushStringToList(perm, &c_out_lines, Lit("//- Base layer includes")); + PushStringToList(perm, &c_out_lines, StringF(perm, "#include \"%F\"", FmtString(base_inc_path))); } - /* Include dependency layers */ - if (gpu_out_lines.count > 0) + /* Define resource stores */ + if (c_store_lines.count > 0) { - PushStringToList(perm, &gpu_out_lines, Lit("")); - PushStringToList(perm, &gpu_out_lines, Lit("//- Dependency graph includes")); - for (StringListNode *n = gpu_include_lines.first; n; n = n->next) + PushStringToList(perm, &c_out_lines, Lit("")); + PushStringToList(perm, &c_out_lines, Lit("//- Resource stores")); + for (StringListNode *n = c_store_lines.first; n; n = n->next) { - PushStringToList(perm, &gpu_out_lines, n->s); + PushStringToList(perm, &c_out_lines, n->s); } } + /* Define shaders */ + if (c_shader_lines.count > 0) + { + PushStringToList(perm, &c_out_lines, Lit("")); + PushStringToList(perm, &c_out_lines, Lit("//- Shaders")); + for (StringListNode *n = c_shader_lines.first; n; n = n->next) + { + PushStringToList(perm, &c_out_lines, n->s); + } + } + /* Include dependency layers */ + if (c_include_lines.count > 0) + { + PushStringToList(perm, &c_out_lines, Lit("")); + PushStringToList(perm, &c_out_lines, Lit("//- Dependency graph includes")); + for (StringListNode *n = c_include_lines.first; n; n = n->next) + { + PushStringToList(perm, &c_out_lines, n->s); + } + } + /* Define StartupLayers */ + { + PushStringToList(perm, &c_out_lines, Lit("")); + PushStringToList(perm, &c_out_lines, Lit("//- Startup")); + PushStringToList(perm, &c_out_lines, Lit("void StartupLayers(void)")); + PushStringToList(perm, &c_out_lines, Lit("{")); + for (StringListNode *n = c_startup_lines.first; n; n = n->next) + { + PushStringToList(perm, &c_out_lines, n->s); + } + PushStringToList(perm, &c_out_lines, Lit("}")); + } /* Write to file */ - PushStringToList(perm, &gpu_out_lines, Lit("")); - String c_out = StringFromList(perm, gpu_out_lines, Lit("\n")); - F_ClearWrite(gpu_out_file, c_out); + PushStringToList(perm, &c_out_lines, Lit("")); + String c_out = StringFromList(perm, c_out_lines, Lit("\n")); + F_ClearWrite(c_out_file, c_out); } } + + /* Generate HLSL file */ + { + /* Clear shader store */ + OS_Mkdir(shader_store_name); + { + /* Remove all old shaders */ + StringList files = ZI; + F_FilesFromDir(perm, &files, shader_store_name, F_IterFlag_None); + for (StringListNode *n = files.first; n; n = n->next) + { + String file = n->s; + /* Safety check to prevent non-shader files from being removed */ + if (StringEndsWith(file, Lit("VS")) || StringEndsWith(file, Lit("CS")) || StringEndsWith(file, Lit("PS"))) + { + OS_Rm(n->s); + } + else + { + /* Unexpected file in shader store */ + Assert(0); + } + } + } + + /* Generate GPU file & shader entries */ + { + StringList gpu_include_lines = ZI; + { + for (M_Entry *entry = build->flattened.first; entry->valid; entry = entry->next) + { + M_EntryKind kind = entry->kind; + M_Token *entry_tok = entry->name_token; + M_Token *arg0_tok = entry->arg_tokens[0]; + M_Token *arg1_tok = entry->arg_tokens[1]; + switch (kind) + { + default: break; + case M_EntryKind_IncludeGpu: + { + if (arg0_tok->valid) + { + String token_file = arg0_tok->file->name; + String token_parent_dir = F_GetParentDir(token_file); + String arg_file = arg0_tok->s; + String full = F_GetFull(perm, StringF(perm, "%F/%F", FmtString(token_parent_dir), FmtString(arg_file))); + if (F_IsFile(full)) + { + String line = StringF(perm, "#include \"%F\"", FmtString(full)); + PushStringToList(perm, &gpu_include_lines, line); + } + else + { + String err = StringF(perm, "File '%F' not found", FmtString(full)); + M_PushError(perm, &build->gpugen.errors, arg0_tok, err); + } + } + else + { + M_PushError(perm, &build->gpugen.errors, entry_tok, Lit("Expected file name")); + } + } break; + case M_EntryKind_VertexShader: + case M_EntryKind_PixelShader: + case M_EntryKind_ComputeShader: + { + if (arg0_tok->valid) + { + ShaderEntryKind shader_kind = kind == M_EntryKind_VertexShader ? ShaderEntryKind_VS + : kind == M_EntryKind_PixelShader ? ShaderEntryKind_PS + : kind == M_EntryKind_ComputeShader ? ShaderEntryKind_CS + : ShaderEntryKind_VS; + String shader_name = arg0_tok->s; + ShaderEntry *e = PushStruct(perm, ShaderEntry); + e->kind = shader_kind; + e->name = shader_name; + SllQueuePush(build->gpugen.first_shader_entry, build->gpugen.last_shader_entry, e); + ++build->gpugen.shader_entries_count; + } + else + { + M_PushError(perm, &build->gpugen.errors, entry_tok, Lit("Expected shader name")); + } + } break; + } + } + } + if (build->gpugen.errors.count == 0) + { + StringList gpu_out_lines = ZI; + PushStringToList(perm, &gpu_out_lines, Lit("// Auto generated file")); + /* Include base layer */ + { + String base_inc_path = F_GetFull(perm, Lit("../src/base/base_inc.h")); + PushStringToList(perm, &gpu_out_lines, Lit("")); + PushStringToList(perm, &gpu_out_lines, Lit("//- Base layer includes")); + PushStringToList(perm, &gpu_out_lines, StringF(perm, "#include \"%F\"", FmtString(base_inc_path))); + } + /* Include dependency layers */ + if (gpu_out_lines.count > 0) + { + PushStringToList(perm, &gpu_out_lines, Lit("")); + PushStringToList(perm, &gpu_out_lines, Lit("//- Dependency graph includes")); + for (StringListNode *n = gpu_include_lines.first; n; n = n->next) + { + PushStringToList(perm, &gpu_out_lines, n->s); + } + } + /* Write to file */ + PushStringToList(perm, &gpu_out_lines, Lit("")); + String c_out = StringFromList(perm, gpu_out_lines, Lit("\n")); + F_ClearWrite(gpu_out_file, c_out); + } + } + } + + build->gpucomps.count = build->gpugen.shader_entries_count; + build->gpucomps.array = PushStructs(perm, GpuComp, build->gpucomps.count); } - WaveSyncBroadcast(lane, 0, &gpugen); - if (!ret) ret = gpugen.errors.count > 0; + + WaveSync(lane); + if (!ret) ret = build->cgen.errors.count > 0; + if (!ret) ret = build->gpugen.errors.count > 0; ////////////////////////////// //- Compile C & Shaders - Struct(CComp) - { - String obj_file; - String output; - i32 return_code; - }; - CComp ccomp = ZI; - - Struct(GpuComp) - { - String output; - i32 return_code; - }; - u32 gpucomps_count = gpugen.shader_entries_count; - GpuComp *gpucomps = PushStructs(perm, GpuComp, gpucomps_count); - if (!ret) { /* Compile C */ u64 ccomp_task_idx = 0; if (lane->idx == WaveLaneIdxFromTaskIdx(lane, ccomp_task_idx)) { - ccomp.obj_file = StringF(perm, "%F_gen_c.obj", FmtString(cmdline.leaf_layer_name)); + build->ccomp.obj_file = StringF(perm, "%F_gen_c.obj", FmtString(cmdline.leaf_layer_name)); String cmd = StringF(perm, "cl.exe /c %F -Fo:%F %F %F %F %F", FmtString(c_out_file), - FmtString(ccomp.obj_file), + FmtString(build->ccomp.obj_file), FmtString(StringFromList(perm, cp.flags_msvc, Lit(" "))), FmtString(StringFromList(perm, cp.compiler_only_flags_msvc, Lit(" "))), FmtString(StringFromList(perm, cp.warnings_msvc, Lit(" "))), FmtString(StringFromList(perm, cp.defs, Lit(" ")))); OS_CommandResult cmd_result = OS_RunCommand(perm, cmd); String cmd_output = TrimWhitespace(cmd_result.output); - ccomp.output = cmd_output; - ccomp.return_code = cmd_result.code; + build->ccomp.output = cmd_output; + build->ccomp.return_code = cmd_result.code; } /* Compile shaders */ u32 gpucomp_idx = 0; - for (ShaderEntry *e = gpugen.first_shader_entry; e; e = e->next) + for (ShaderEntry *e = build->gpugen.first_shader_entry; e; e = e->next) { /* NOTE: Using gpucomp_idx + 1 as task index for parralelism w/ C compilation */ u64 gpucomp_task_idx = gpucomp_idx + 1; if (lane->idx == WaveLaneIdxFromTaskIdx(lane, gpucomp_task_idx)) { - GpuComp *gpucomp = &gpucomps[gpucomp_idx]; + GpuComp *gpucomp = &build->gpucomps.array[gpucomp_idx]; String out_file = StringF(perm, "%F/%F", FmtString(shader_store_name), FmtString(e->name)); String target = e->kind == ShaderEntryKind_VS ? Lit("vs_6_6") : e->kind == ShaderEntryKind_PS ? Lit("ps_6_6") @@ -779,31 +848,21 @@ void BuildEntryPoint(WaveLaneCtx *lane, void *udata) ++gpucomp_idx; } } - WaveSyncBroadcast(lane, 0, &ccomp); - WaveSyncBroadcast(lane, 0, &gpucomps); - if (!ret) ret = ccomp.return_code; - for (u32 i = 0; i < gpucomps_count; ++i) + + WaveSync(lane); + if (!ret) ret = build->ccomp.return_code; + for (u32 i = 0; i < build->gpucomps.count; ++i) { - if (!ret) ret = gpucomps[i].return_code; + if (!ret) ret = build->gpucomps.array[i].return_code; } ////////////////////////////// //- Gather resource archive info - Struct(ArcInfoEntry) { ArcInfoEntry *next; String dir_path; String store_name; String out_path; }; - Struct(ArcInfoGen) - { - M_ErrorList errors; - ArcInfoEntry *first_arc_entry; - ArcInfoEntry *last_arc_entry; - u64 arc_entries_count; - }; - ArcInfoGen arcinfogen = ZI; - if (lane->idx == 0 && !ret) { /* Gather archives from embedded dirs */ - for (M_Entry *entry = flattened.first; entry->valid; entry = entry->next) + for (M_Entry *entry = build->flattened.first; entry->valid; entry = entry->next) { M_EntryKind kind = entry->kind; M_Token *entry_tok = entry->name_token; @@ -827,18 +886,18 @@ void BuildEntryPoint(WaveLaneCtx *lane, void *udata) arc->store_name = store_name; arc->dir_path = full; arc->out_path = StringF(perm, "%F.arc", FmtString(store_name)); - SllQueuePush(arcinfogen.first_arc_entry, arcinfogen.last_arc_entry, arc); - ++arcinfogen.arc_entries_count; + SllQueuePush(build->arcinfogen.first_arc_entry, build->arcinfogen.last_arc_entry, arc); + ++build->arcinfogen.arc_entries_count; } else { String err = StringF(perm, "Directory '%F' not found", FmtString(full)); - M_PushError(perm, &arcinfogen.errors, arg1_tok, err); + M_PushError(perm, &build->arcinfogen.errors, arg1_tok, err); } } else { - M_PushError(perm, &arcinfogen.errors, entry_tok, Lit("Expected resource store & directory name")); + M_PushError(perm, &build->arcinfogen.errors, entry_tok, Lit("Expected resource store & directory name")); } } break; } @@ -849,145 +908,147 @@ void BuildEntryPoint(WaveLaneCtx *lane, void *udata) arc->store_name = shader_store_name; arc->dir_path = F_GetFullCrossPlatform(perm, shader_store_name); arc->out_path = StringF(perm, "%F.arc", FmtString(shader_store_name)); - SllQueuePush(arcinfogen.first_arc_entry, arcinfogen.last_arc_entry, arc); - ++arcinfogen.arc_entries_count; + SllQueuePush(build->arcinfogen.first_arc_entry, build->arcinfogen.last_arc_entry, arc); + ++build->arcinfogen.arc_entries_count; } + + build->rescomps.count = build->arcinfogen.arc_entries_count; + build->rescomps.array = PushStructs(perm, ResComp, build->rescomps.count); } - WaveSyncBroadcast(lane, 0, &arcinfogen); - if (!ret) ret = arcinfogen.errors.count > 0; + + WaveSync(lane); + if (!ret) ret = build->arcinfogen.errors.count > 0; ////////////////////////////// //- Generate resource archives - if (lane->idx == 0 && !ret) + if (!ret) { - for (ArcInfoEntry *entry = arcinfogen.first_arc_entry; entry; entry = entry->next) + u32 task_idx = 0; + for (ArcInfoEntry *entry = build->arcinfogen.first_arc_entry; entry; entry = entry->next) { - String dir_path = entry->dir_path; - String store_name = entry->store_name; - String arc_path = entry->out_path; - - Struct(EntryNode) + if (lane->idx == WaveLaneIdxFromTaskIdx(lane, task_idx)) { - EntryNode *next; - String entry_name; - String file_name; - }; + String dir_path = entry->dir_path; + String store_name = entry->store_name; + String arc_path = entry->out_path; - EntryNode *first_entry = 0; - EntryNode *last_entry = 0; - u64 entries_count = 0; - - StringList files = ZI; - F_FilesFromDir(perm, &files, dir_path, F_IterFlag_Recurse); - for (StringListNode *file_node = files.first; file_node; file_node = file_node->next) - { - String file_name = file_node->s; - if (F_IsFile(file_name)) + Struct(EntryNode) { - String entry_name = file_name; - if (entry_name.len > (dir_path.len + 1)) + EntryNode *next; + String entry_name; + String file_name; + }; + + EntryNode *first_entry = 0; + EntryNode *last_entry = 0; + u64 entries_count = 0; + + StringList files = ZI; + F_FilesFromDir(perm, &files, dir_path, F_IterFlag_Recurse); + for (StringListNode *file_node = files.first; file_node; file_node = file_node->next) + { + String file_name = file_node->s; + if (F_IsFile(file_name)) { - entry_name.len -= dir_path.len + 1; - entry_name.text += dir_path.len + 1; - } - entry_name = StringF(perm, "%F/%F", FmtString(store_name), FmtString(entry_name)); - for (u64 i = 0; i < entry_name.len; ++i) - { - if (entry_name.text[i] == '\\') + String entry_name = file_name; + if (entry_name.len > (dir_path.len + 1)) { - entry_name.text[i] = '/'; + entry_name.len -= dir_path.len + 1; + entry_name.text += dir_path.len + 1; } + entry_name = StringF(perm, "%F/%F", FmtString(store_name), FmtString(entry_name)); + for (u64 i = 0; i < entry_name.len; ++i) + { + if (entry_name.text[i] == '\\') + { + entry_name.text[i] = '/'; + } + } + + EntryNode *en = PushStruct(perm, EntryNode); + en->entry_name = entry_name; + en->file_name = file_name; + SllQueuePush(first_entry, last_entry, en); + ++entries_count; + } + } + + String arc_contents = ZI; + { + BB_Buff bb = BB_AcquireBuff(Gibi(2)); + BB_Writer bw = BB_WriterFromBuff(&bb); + + /* Write magic */ + BB_WriteUBits(&bw, ResourceEmbeddedMagic, 64); + + /* Write header */ + BB_WriteUBits(&bw, entries_count, 64); + + /* Reserve entries space */ + u64 entry_size = 8 /* Name start */ + + 8 /* Name end */ + + 8 /* Data start */ + + 8; /* Data end */ + u8 *entries_start = BB_GetWrittenRaw(&bw) + BB_GetNumBytesWritten(&bw); + u64 entries_size = entry_size * entries_count; + String entries_str = STRING(entries_size, entries_start); + BB_WriteSeekBytes(&bw, entries_size); + BB_Buff entries_bb = BB_BuffFromString(entries_str); + BB_Writer entries_bw = BB_WriterFromBuff(&entries_bb); + + /* Write entries */ + for (EntryNode *en = first_entry; en; en = en->next) + { + /* TODO: Copy file data directly into archive file */ + String file_data = F_DataFromFile(perm, en->file_name); + + /* Write name */ + BB_WriteAlignBytes(&bw, 64); + u64 name_start = BB_GetNumBytesWritten(&bw) + 1; + BB_WriteString(&bw, en->entry_name); + u64 name_len = BB_GetNumBytesWritten(&bw) - name_start; + + /* Write data */ + BB_WriteAlignBytes(&bw, 64); + /* FIXME: Why no +1 here? */ + u64 data_start = BB_GetNumBytesWritten(&bw); + BB_WriteBytes(&bw, file_data); + u64 data_len = BB_GetNumBytesWritten(&bw) - data_start; + + /* Write entry */ + BB_WriteUBits(&entries_bw, name_start, 64); + BB_WriteUBits(&entries_bw, name_len, 64); + BB_WriteUBits(&entries_bw, data_start, 64); + BB_WriteUBits(&entries_bw, data_len, 64); } - EntryNode *en = PushStruct(perm, EntryNode); - en->entry_name = entry_name; - en->file_name = file_name; - SllQueuePush(first_entry, last_entry, en); - ++entries_count; - } - } - - String arc_contents = ZI; - { - BB_Buff bb = BB_AcquireBuff(Gibi(2)); - BB_Writer bw = BB_WriterFromBuff(&bb); - - /* Write magic */ - BB_WriteUBits(&bw, ResourceEmbeddedMagic, 64); - - /* Write header */ - BB_WriteUBits(&bw, entries_count, 64); - - /* Reserve entries space */ - u64 entry_size = 8 /* Name start */ - + 8 /* Name end */ - + 8 /* Data start */ - + 8; /* Data end */ - u8 *entries_start = BB_GetWrittenRaw(&bw) + BB_GetNumBytesWritten(&bw); - u64 entries_size = entry_size * entries_count; - String entries_str = STRING(entries_size, entries_start); - BB_WriteSeekBytes(&bw, entries_size); - BB_Buff entries_bb = BB_BuffFromString(entries_str); - BB_Writer entries_bw = BB_WriterFromBuff(&entries_bb); - - /* Write entries */ - for (EntryNode *en = first_entry; en; en = en->next) - { - /* TODO: Copy file data directly into archive file */ - String file_data = F_DataFromFile(perm, en->file_name); - - /* Write name */ - BB_WriteAlignBytes(&bw, 64); - u64 name_start = BB_GetNumBytesWritten(&bw) + 1; - BB_WriteString(&bw, en->entry_name); - u64 name_len = BB_GetNumBytesWritten(&bw) - name_start; - - /* Write data */ - BB_WriteAlignBytes(&bw, 64); - /* FIXME: Why no +1 here? */ - u64 data_start = BB_GetNumBytesWritten(&bw); - BB_WriteBytes(&bw, file_data); - u64 data_len = BB_GetNumBytesWritten(&bw) - data_start; - - /* Write entry */ - BB_WriteUBits(&entries_bw, name_start, 64); - BB_WriteUBits(&entries_bw, name_len, 64); - BB_WriteUBits(&entries_bw, data_start, 64); - BB_WriteUBits(&entries_bw, data_len, 64); + arc_contents.len = BB_GetNumBytesWritten(&bw); + arc_contents.text = BB_GetWrittenRaw(&bw); } - arc_contents.len = BB_GetNumBytesWritten(&bw); - arc_contents.text = BB_GetWrittenRaw(&bw); + /* Write arc file */ + F_ClearWrite(arc_path, arc_contents); } - - /* Write arc file */ - F_ClearWrite(arc_path, arc_contents); } + ++task_idx; } + WaveSync(lane); + ////////////////////////////// //- Compile resource archives - Struct(ResComp) - { - String obj_file; - String output; - i32 return_code; - }; - u32 rescomps_count = arcinfogen.arc_entries_count; - ResComp *rescomps = PushStructs(perm, ResComp, rescomps_count); - if (!ret) { if (IsPlatformWindows) { i32 rescomp_idx = 0; - for (ArcInfoEntry *entry = arcinfogen.first_arc_entry; entry; entry = entry->next) + for (ArcInfoEntry *entry = build->arcinfogen.first_arc_entry; entry; entry = entry->next) { if (lane->idx == WaveLaneIdxFromTaskIdx(lane, rescomp_idx)) { - ResComp *rescomp = &rescomps[rescomp_idx]; + ResComp *rescomp = &build->rescomps.array[rescomp_idx]; String arc_path = entry->out_path; @@ -1021,25 +1082,19 @@ void BuildEntryPoint(WaveLaneCtx *lane, void *udata) else { /* TODO: Compile object files using .incbin on non-windows platforms */ - Panic(Lit("Non-windows embedded format not implemented")); + Panic(Lit("Embedded format not implemented for this platform")); } } - WaveSyncBroadcast(lane, 0, &rescomps); - for (u32 i = 0; i < rescomps_count; ++i) + + WaveSync(lane); + for (u32 i = 0; i < build->rescomps.count; ++i) { - if (!ret) ret = rescomps[i].return_code; + if (!ret) ret = build->rescomps.array[i].return_code; } ////////////////////////////// //- Link - Struct(Link) - { - String output; - i32 return_code; - }; - Link link = ZI; - if (lane->idx == 0 && !ret) { String exe_file = StringF(perm, "%F.exe", FmtString(cmdline.leaf_layer_name)); @@ -1055,10 +1110,10 @@ void BuildEntryPoint(WaveLaneCtx *lane, void *udata) String obj_files_str = ZI; { StringList obj_files = ZI; - PushStringToList(perm, &obj_files, ccomp.obj_file); - for (u64 rescomp_idx = 0; rescomp_idx < rescomps_count; ++rescomp_idx) + PushStringToList(perm, &obj_files, build->ccomp.obj_file); + for (u64 rescomp_idx = 0; rescomp_idx < build->rescomps.count; ++rescomp_idx) { - ResComp *rescomp = &rescomps[rescomp_idx]; + ResComp *rescomp = &build->rescomps.array[rescomp_idx]; PushStringToList(perm, &obj_files, rescomp->obj_file); } obj_files_str = StringFromList(perm, obj_files, Lit(" ")); @@ -1071,13 +1126,14 @@ void BuildEntryPoint(WaveLaneCtx *lane, void *udata) FmtString(StringFromList(perm, cp.flags_msvc, Lit(" "))), FmtString(StringFromList(perm, cp.linker_only_flags_msvc, Lit(" ")))); OS_CommandResult result = OS_RunCommand(perm, cmd); - link.output = TrimWhitespace(result.output); - link.return_code = result.code; + build->link.output = TrimWhitespace(result.output); + build->link.return_code = result.code; i64 link_elapsed_ns = TimeNs() - start_ns; // EchoLine(StringF(perm, ">>>>> Linked in %Fs", FmtFloat(SecondsFromNs(link_elapsed_ns)))); } - WaveSyncBroadcast(lane, 0, &link); - if (!ret) ret = link.return_code; + + WaveSync(lane); + if (!ret) ret = build->link.return_code; ////////////////////////////// //- Process output & errors @@ -1087,9 +1143,9 @@ void BuildEntryPoint(WaveLaneCtx *lane, void *udata) String gpucomp_output = ZI; { StringList gpucomp_outputs = ZI; - for (u32 gpucomp_idx = 0; gpucomp_idx < gpucomps_count; ++gpucomp_idx) + for (u32 gpucomp_idx = 0; gpucomp_idx < build->gpucomps.count; ++gpucomp_idx) { - GpuComp *gpucomp = &gpucomps[gpucomp_idx]; + GpuComp *gpucomp = &build->gpucomps.array[gpucomp_idx]; PushStringToList(perm, &gpucomp_outputs, gpucomp->output); } gpucomp_output = StringFromList(perm, gpucomp_outputs, Lit("\n")); @@ -1097,21 +1153,21 @@ void BuildEntryPoint(WaveLaneCtx *lane, void *udata) String rescomp_output = ZI; { StringList rescomp_outputs = ZI; - for (u32 rescomp_idx = 0; rescomp_idx < rescomps_count; ++rescomp_idx) + for (u32 rescomp_idx = 0; rescomp_idx < build->rescomps.count; ++rescomp_idx) { - ResComp *rescomp = &rescomps[rescomp_idx]; + ResComp *rescomp = &build->rescomps.array[rescomp_idx]; PushStringToList(perm, &rescomp_outputs, rescomp->output); } rescomp_output = StringFromList(perm, rescomp_outputs, Lit("\n")); } - EchoLineOrNothing(StringFromMetaErrors(perm, flattened.errors)); - EchoLineOrNothing(StringFromMetaErrors(perm, cgen.errors)); - EchoLineOrNothing(StringFromMetaErrors(perm, gpugen.errors)); - EchoLineOrNothing(ccomp.output); + EchoLineOrNothing(StringFromMetaErrors(perm, build->flattened.errors)); + EchoLineOrNothing(StringFromMetaErrors(perm, build->cgen.errors)); + EchoLineOrNothing(StringFromMetaErrors(perm, build->gpugen.errors)); + EchoLineOrNothing(build->ccomp.output); EchoLineOrNothing(gpucomp_output); - EchoLineOrNothing(StringFromMetaErrors(perm, arcinfogen.errors)); + EchoLineOrNothing(StringFromMetaErrors(perm, build->arcinfogen.errors)); EchoLineOrNothing(rescomp_output); - EchoLineOrNothing(link.output); + EchoLineOrNothing(build->link.output); } //////////////////////////////