From 3e62de78b16dcc9e06aecd53abf9c65aff018703 Mon Sep 17 00:00:00 2001 From: jacob Date: Wed, 4 Feb 2026 06:48:08 -0600 Subject: [PATCH] move shared frame state to single struct --- src/base/base.cgh | 3 + src/glyph_cache/glyph_cache.c | 8 +- src/glyph_cache/glyph_cache.h | 4 +- src/meta/meta.c | 221 +++++++++++++------------- src/meta/meta.h | 57 +++---- src/pp/pp_vis/pp_vis_core.c | 271 +++++++++++++------------------- src/pp/pp_vis/pp_vis_core.h | 68 +------- src/pp/pp_vis/pp_vis_gpu.g | 145 ++++++++--------- src/pp/pp_vis/pp_vis_shared.cgh | 106 +++++++++---- src/sprite/sprite.c | 8 +- src/sprite/sprite.h | 4 +- src/ui/ui_core.h | 2 +- 12 files changed, 418 insertions(+), 479 deletions(-) diff --git a/src/base/base.cgh b/src/base/base.cgh index e8f0491f..9656d2e4 100644 --- a/src/base/base.cgh +++ b/src/base/base.cgh @@ -423,6 +423,9 @@ #define Enum(name) enum name #endif +//- Embed +#define Embed(type, name) union { type; type name; } + //- alignof #if IsLanguageC && (IsCompilerMsvc || __STDC_VERSION__ < 202311L) #define alignof(type) __alignof(type) diff --git a/src/glyph_cache/glyph_cache.c b/src/glyph_cache/glyph_cache.c index 1f255bc6..ad35496c 100644 --- a/src/glyph_cache/glyph_cache.c +++ b/src/glyph_cache/glyph_cache.c @@ -174,7 +174,7 @@ GC_Run GC_RunFromString32(Arena *arena, String32 str32, GC_FontKey font, f32 fon f32 advance = RoundF32(glyph->advance); Rng2 bounds = glyph->bounds; - rect->tex = glyph->atlas->tex_ref; + rect->tex = glyph->atlas->tex; rect->tex_slice = glyph->atlas_slice; rect->tex_slice_uv = glyph->atlas_slice_uv; @@ -312,14 +312,14 @@ void GC_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame) atlas->dims = VEC2I32(1024, 1024); { G_ArenaHandle gpu_perm = G_PermArena(); - atlas->tex = G_PushTexture2D( + atlas->tex_res = G_PushTexture2D( gpu_perm, cl, G_Format_R8G8B8A8_Unorm_Srgb, atlas->dims, G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present, .name = Lit("Glyph atlas") ); - atlas->tex_ref = G_PushTexture2DRef(gpu_perm, atlas->tex); + atlas->tex = G_PushTexture2DRef(gpu_perm, atlas->tex_res); } SllStackPush(GC.first_atlas, atlas); ++GC.atlases_count; @@ -358,7 +358,7 @@ void GC_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame) { G_CopyCpuToTexture( cl, - glyph->atlas->tex, VEC3I32(glyph->atlas_slice.p0.x, glyph->atlas_slice.p0.y, 0), + glyph->atlas->tex_res, VEC3I32(glyph->atlas_slice.p0.x, glyph->atlas_slice.p0.y, 0), image_pixels, VEC3I32(image_dims.x, image_dims.y, 1), RNG3I32( VEC3I32(0, 0, 0), diff --git a/src/glyph_cache/glyph_cache.h b/src/glyph_cache/glyph_cache.h index de537755..be1e9cfb 100644 --- a/src/glyph_cache/glyph_cache.h +++ b/src/glyph_cache/glyph_cache.h @@ -14,8 +14,8 @@ Struct(GC_Atlas) GC_Atlas *next; Vec2I32 dims; - G_ResourceHandle tex; - G_Texture2DRef tex_ref; + G_ResourceHandle tex_res; + G_Texture2DRef tex; Vec2I32 cur_pos; i32 cur_row_height; }; diff --git a/src/meta/meta.c b/src/meta/meta.c index 3c5bd58c..b88b10bd 100644 --- a/src/meta/meta.c +++ b/src/meta/meta.c @@ -1,21 +1,21 @@ #include "meta.h" -BuildCtx Build = Zi; +M_Ctx M = Zi; //////////////////////////////////////////////////////////// //~ Helpers -i32 GetBuildStatus(void) +i32 M_GetBuildStatus(void) { - return Atomic32Fetch(&Build.status); + return Atomic32Fetch(&M.status); } -void SetBuildStatus(i32 code) +void M_SetBuildStatus(i32 code) { - Atomic32FetchTestSet(&Build.status, 0, code); + Atomic32FetchTestSet(&M.status, 0, code); } -void EchoLine(String msg) +void M_EchoLine(String msg) { TempArena scratch = BeginScratchNoConflict(); { @@ -25,19 +25,19 @@ void EchoLine(String msg) EndScratch(scratch); } -void EchoLineOrNothing(String msg) +void M_EchoLineOrNothing(String msg) { String trimmed_msg = TrimWhitespace(msg); if (trimmed_msg.len > 0) { - EchoLine(trimmed_msg); + M_EchoLine(trimmed_msg); } } -LineCol LineColFromPos(String data, i64 pos) +M_LineCol M_LineColFromPos(String data, i64 pos) { TempArena scratch = BeginScratchNoConflict(); - LineCol result = Zi; + M_LineCol result = Zi; for (u64 cur = 0; cur < data.len && cur <= (u64)pos; ++cur) { u8 c = data.text[cur]; @@ -56,7 +56,7 @@ LineCol LineColFromPos(String data, i64 pos) return result; } -String StringFromMetaErrors(Arena *arena, M_ErrorList errors) +String M_StringFromMetaErrors(Arena *arena, M_ErrorList errors) { TempArena scratch = BeginScratch(arena); @@ -78,10 +78,10 @@ String StringFromMetaErrors(Arena *arena, M_ErrorList errors) { token_pos = token->s.text - token_file_data.text; } - LineCol line_col = Zi; + M_LineCol line_col = Zi; if (token_pos >= 0) { - line_col = LineColFromPos(token_file_data, token_pos); + line_col = M_LineColFromPos(token_file_data, token_pos); } String formatted = StringF( scratch.arena, @@ -105,10 +105,10 @@ String StringFromMetaErrors(Arena *arena, M_ErrorList errors) return result; } -EmbedObj Embed(String store_name, String dir_path) +M_EmbedObj M_Embed(String store_name, String dir_path) { Arena *perm = PermArena(); - EmbedObj result = Zi; + M_EmbedObj result = Zi; // Generate resource archive contents u64 store_hash = HashString(store_name); @@ -239,7 +239,7 @@ EmbedObj Embed(String store_name, String dir_path) result.return_code = cmd_result.code; } - SetBuildStatus(result.return_code); + M_SetBuildStatus(result.return_code); } else { @@ -251,9 +251,9 @@ EmbedObj Embed(String store_name, String dir_path) } //////////////////////////////////////////////////////////// -//~ Build +//~ M -void BuildEntryPoint(WaveLaneCtx *lane) +void M_BuildEntryPoint(WaveLaneCtx *lane) { Arena *perm = PermArena(); @@ -297,8 +297,8 @@ void BuildEntryPoint(WaveLaneCtx *lane) } else { - EchoLine(Lit("Metaprogram is dirty")); - ExitNow(MetaRebuildCode); + M_EchoLine(Lit("Metaprogram is dirty")); + ExitNow(M_RebuildCode); } } @@ -326,7 +326,7 @@ void BuildEntryPoint(WaveLaneCtx *lane) layer_name = Lit("pp"); if (lane->idx == 0) { - EchoLine(Lit("No layer specified, assuming \"pp\" build")); + M_EchoLine(Lit("No layer specified, assuming \"pp\" build")); } } cmdline.leaf_layer_name = layer_name; @@ -334,13 +334,13 @@ void BuildEntryPoint(WaveLaneCtx *lane) if (lane->idx == 0) { - EchoLine(StringF(perm, "Building layer \"%F\"", FmtString(cmdline.leaf_layer_name))); + M_EchoLine(StringF(perm, "Building layer \"%F\"", FmtString(cmdline.leaf_layer_name))); } ////////////////////////////// //- Generate compiler params - CompilerParams cp = Zi; + M_CompilerParams cp = Zi; { //- Common { @@ -452,7 +452,7 @@ void BuildEntryPoint(WaveLaneCtx *lane) // Phase 2/3: Compile (wide) // - Compile C // - Compile & embed shaders - // - Embed resource dirs + // - M_Embed resource dirs // // Phase 3/3: Link (narrow) // - Link @@ -464,7 +464,7 @@ void BuildEntryPoint(WaveLaneCtx *lane) String gpu_out_file = F_GetFull(perm, StringF(perm, "%F_gen.g", FmtString(cmdline.leaf_layer_name))); u64 shader_store_hash = HashString(shader_store_name); - if (lane->idx == 0 && GetBuildStatus() == 0) + if (lane->idx == 0 && M_GetBuildStatus() == 0) { //- Parse layers { @@ -479,9 +479,9 @@ void BuildEntryPoint(WaveLaneCtx *lane) // Flatten StringList starting_layer_names = Zi; PushStringToList(perm, &starting_layer_names, cmdline.leaf_layer_name); - Build.layers_parse = M_FlattenEntries(perm, parsed, starting_layer_names); + M.layers_parse = M_FlattenEntries(perm, parsed, starting_layer_names); - SetBuildStatus(Build.layers_parse.errors.count > 0); + M_SetBuildStatus(M.layers_parse.errors.count > 0); } //- Generate C file @@ -491,7 +491,7 @@ void BuildEntryPoint(WaveLaneCtx *lane) StringList c_include_lines = Zi; StringList c_bootstrap_lines = Zi; { - for (M_Entry *entry = Build.layers_parse.first; entry->valid; entry = entry->next) + for (M_Entry *entry = M.layers_parse.first; entry->valid; entry = entry->next) { M_EntryKind kind = entry->kind; M_Token *entry_tok = entry->name_token; @@ -518,12 +518,12 @@ void BuildEntryPoint(WaveLaneCtx *lane) else { String err = StringF(perm, "Directory '%F' not found", FmtString(full)); - M_PushError(perm, &Build.c_parse.errors, arg1_tok, err); + M_PushError(perm, &M.c_parse.errors, arg1_tok, err); } } else { - M_PushError(perm, &Build.c_parse.errors, entry_tok, Lit("Expected resource store & directory name")); + M_PushError(perm, &M.c_parse.errors, entry_tok, Lit("Expected resource store & directory name")); } } break; case M_EntryKind_VertexShader: @@ -543,7 +543,7 @@ void BuildEntryPoint(WaveLaneCtx *lane) } else { - M_PushError(perm, &Build.c_parse.errors, entry_tok, Lit("Expected shader name")); + M_PushError(perm, &M.c_parse.errors, entry_tok, Lit("Expected shader name")); } } break; case M_EntryKind_IncludeC: @@ -562,12 +562,12 @@ void BuildEntryPoint(WaveLaneCtx *lane) else { String err = StringF(perm, "File '%F' not found", FmtString(full)); - M_PushError(perm, &Build.c_parse.errors, arg0_tok, err); + M_PushError(perm, &M.c_parse.errors, arg0_tok, err); } } else { - M_PushError(perm, &Build.c_parse.errors, entry_tok, Lit("Expected file name")); + M_PushError(perm, &M.c_parse.errors, entry_tok, Lit("Expected file name")); } } break; case M_EntryKind_Bootstrap: @@ -580,13 +580,13 @@ void BuildEntryPoint(WaveLaneCtx *lane) } else { - M_PushError(perm, &Build.c_parse.errors, entry_tok, Lit("Expected bootstrap function name")); + M_PushError(perm, &M.c_parse.errors, entry_tok, Lit("Expected bootstrap function name")); } } break; } } } - if (Build.c_parse.errors.count == 0) + if (M.c_parse.errors.count == 0) { StringList c_out_lines = Zi; PushStringToList(perm, &c_out_lines, Lit("// Auto generated file")); @@ -645,7 +645,7 @@ void BuildEntryPoint(WaveLaneCtx *lane) F_ClearWrite(c_out_file, c_out); } - SetBuildStatus(Build.c_parse.errors.count > 0); + M_SetBuildStatus(M.c_parse.errors.count > 0); } //- Generate HLSL file @@ -677,7 +677,7 @@ void BuildEntryPoint(WaveLaneCtx *lane) { StringList gpu_include_lines = Zi; { - for (M_Entry *entry = Build.layers_parse.first; entry->valid; entry = entry->next) + for (M_Entry *entry = M.layers_parse.first; entry->valid; entry = entry->next) { M_EntryKind kind = entry->kind; M_Token *entry_tok = entry->name_token; @@ -702,12 +702,12 @@ void BuildEntryPoint(WaveLaneCtx *lane) else { String err = StringF(perm, "File '%F' not found", FmtString(full)); - M_PushError(perm, &Build.gpu_parse.errors, arg0_tok, err); + M_PushError(perm, &M.gpu_parse.errors, arg0_tok, err); } } else { - M_PushError(perm, &Build.gpu_parse.errors, entry_tok, Lit("Expected file name")); + M_PushError(perm, &M.gpu_parse.errors, entry_tok, Lit("Expected file name")); } } break; case M_EntryKind_VertexShader: @@ -716,26 +716,26 @@ void BuildEntryPoint(WaveLaneCtx *lane) { if (arg0_tok->valid) { - ShaderEntryKind shader_kind = kind == M_EntryKind_VertexShader ? ShaderEntryKind_VS + M_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); + M_ShaderEntry *e = PushStruct(perm, M_ShaderEntry); e->kind = shader_kind; e->name = shader_name; - SllQueuePush(Build.gpu_parse.first_shader_entry, Build.gpu_parse.last_shader_entry, e); - ++Build.gpu_parse.shader_entries_count; + SllQueuePush(M.gpu_parse.first_shader_entry, M.gpu_parse.last_shader_entry, e); + ++M.gpu_parse.shader_entries_count; } else { - M_PushError(perm, &Build.gpu_parse.errors, entry_tok, Lit("Expected shader name")); + M_PushError(perm, &M.gpu_parse.errors, entry_tok, Lit("Expected shader name")); } } break; } } } - if (Build.gpu_parse.errors.count == 0) + if (M.gpu_parse.errors.count == 0) { StringList gpu_out_lines = Zi; PushStringToList(perm, &gpu_out_lines, Lit("// Auto generated file")); @@ -763,13 +763,13 @@ void BuildEntryPoint(WaveLaneCtx *lane) } } - SetBuildStatus(Build.gpu_parse.errors.count > 0); + M_SetBuildStatus(M.gpu_parse.errors.count > 0); } //- Generate archive info { // Push embedded archive dirs - for (M_Entry *entry = Build.layers_parse.first; entry->valid; entry = entry->next) + for (M_Entry *entry = M.layers_parse.first; entry->valid; entry = entry->next) { M_EntryKind kind = entry->kind; M_Token *entry_tok = entry->name_token; @@ -789,41 +789,41 @@ void BuildEntryPoint(WaveLaneCtx *lane) String full = F_GetFullCrossPlatform(perm, StringF(perm, "%F/%F", FmtString(token_parent_dir), FmtString(arg_dir))); if (F_IsDir(full)) { - ResDir *rd = PushStruct(perm, ResDir); + M_ResDir *rd = PushStruct(perm, M_ResDir); rd->store_name = store_name; rd->dir_path = full; - SllQueuePush(Build.res_dir_parse.first_res_dir, Build.res_dir_parse.last_res_dir, rd); - ++Build.res_dir_parse.res_dirs_count; + SllQueuePush(M.res_dir_parse.first_res_dir, M.res_dir_parse.last_res_dir, rd); + ++M.res_dir_parse.res_dirs_count; } else { String err = StringF(perm, "Directory '%F' not found", FmtString(full)); - M_PushError(perm, &Build.res_dir_parse.errors, arg1_tok, err); + M_PushError(perm, &M.res_dir_parse.errors, arg1_tok, err); } } else { - M_PushError(perm, &Build.res_dir_parse.errors, entry_tok, Lit("Expected resource store & directory name")); + M_PushError(perm, &M.res_dir_parse.errors, entry_tok, Lit("Expected resource store & directory name")); } } break; } } - SetBuildStatus(Build.res_dir_parse.errors.count > 0); + M_SetBuildStatus(M.res_dir_parse.errors.count > 0); } //- Prep obj arrays { // Gpu objs - Build.gpu_objs.count = Build.gpu_parse.shader_entries_count; - Build.gpu_objs.array = PushStructs(perm, GpuObj, Build.gpu_objs.count); + M.gpu_objs.count = M.gpu_parse.shader_entries_count; + M.gpu_objs.array = PushStructs(perm, M_GpuObj, M.gpu_objs.count); - // Embed objs - Build.embed_objs.count += Build.res_dir_parse.res_dirs_count; - if (Build.gpu_parse.shader_entries_count > 0) + // M_Embed objs + M.embed_objs.count += M.res_dir_parse.res_dirs_count; + if (M.gpu_parse.shader_entries_count > 0) { - Build.embed_objs.count += 1; + M.embed_objs.count += 1; } - Build.embed_objs.array = PushStructs(perm, EmbedObj, Build.embed_objs.count); + M.embed_objs.array = PushStructs(perm, M_EmbedObj, M.embed_objs.count); } } @@ -838,14 +838,14 @@ void BuildEntryPoint(WaveLaneCtx *lane) //- Compile C { - if (lane->idx == WaveLaneIdxFromTaskIdx(lane, task_idx++) && GetBuildStatus() == 0) + if (lane->idx == WaveLaneIdxFromTaskIdx(lane, task_idx++) && M_GetBuildStatus() == 0) { - Build.c_obj.obj_file = StringF(perm, "%F_gen_c.obj", FmtString(cmdline.leaf_layer_name)); + M.c_obj.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(Build.c_obj.obj_file), + FmtString(M.c_obj.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(" "))), @@ -853,33 +853,34 @@ void BuildEntryPoint(WaveLaneCtx *lane) ); OS_CommandResult cmd_result = OS_RunCommand(perm, cmd); String cmd_output = TrimWhitespace(cmd_result.output); - Build.c_obj.output = cmd_output; - Build.c_obj.return_code = cmd_result.code; + M.c_obj.output = cmd_output; + M.c_obj.return_code = cmd_result.code; // Ignore MSVC file-name echo - if (MatchString(TrimWhitespace(Build.c_obj.output), F_GetFileName(c_out_file))) + if (MatchString(TrimWhitespace(M.c_obj.output), F_GetFileName(c_out_file))) { - Build.c_obj.output = Zstr; + M.c_obj.output = Zstr; } - SetBuildStatus(Build.c_obj.return_code); + M_SetBuildStatus(M.c_obj.return_code); } } //- Compile shaders { u32 gpu_obj_idx = 0; - for (ShaderEntry *e = Build.gpu_parse.first_shader_entry; e; e = e->next) + for (M_ShaderEntry *e = M.gpu_parse.first_shader_entry; e; e = e->next) { - if (lane->idx == WaveLaneIdxFromTaskIdx(lane, task_idx++) && GetBuildStatus() == 0) + if (lane->idx == WaveLaneIdxFromTaskIdx(lane, task_idx++) && M_GetBuildStatus() == 0) { String shader_name = e->name; - GpuObj *gpu_obj = &Build.gpu_objs.array[gpu_obj_idx]; + M_GpuObj *gpu_obj = &M.gpu_objs.array[gpu_obj_idx]; String out_file = StringF(perm, "%F/%F.dxil", 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") - : e->kind == ShaderEntryKind_CS ? Lit("cs_6_6") - : Lit("vs_6_6"); + String target = ( + e->kind == ShaderEntryKind_VS ? Lit("vs_6_6") : + e->kind == ShaderEntryKind_PS ? Lit("ps_6_6") : + Lit("cs_6_6") + ); String compile_cmd = StringF( perm, "dxc.exe -T %F -E %F -Fo %F %F %F %F %F", @@ -896,34 +897,34 @@ void BuildEntryPoint(WaveLaneCtx *lane) gpu_obj->output = cmd_result.output; gpu_obj->return_code = cmd_result.code; - SetBuildStatus(gpu_obj->return_code); + M_SetBuildStatus(gpu_obj->return_code); // Final shader compilation lane embeds shader archive - u32 finished_count = Atomic32FetchAdd(&Build.gpu_objs.finished_count, 1) + 1; - if (finished_count == Build.gpu_objs.count && GetBuildStatus() == 0) + u32 finished_count = Atomic32FetchAdd(&M.gpu_objs.finished_count, 1) + 1; + if (finished_count == M.gpu_objs.count && M_GetBuildStatus() == 0) { - EmbedObj *embed = &Build.embed_objs.array[embed_idx]; - *embed = Embed(shader_store_name, shader_store_name); + M_EmbedObj *embed = &M.embed_objs.array[embed_idx]; + *embed = M_Embed(shader_store_name, shader_store_name); } } ++gpu_obj_idx; } - if (Build.gpu_parse.shader_entries_count > 0) + if (M.gpu_parse.shader_entries_count > 0) { ++embed_idx; } } - //- Embed resource dirs + //- M_Embed resource dirs { - for (ResDir *rd = Build.res_dir_parse.first_res_dir; rd; rd = rd->next) + for (M_ResDir *rd = M.res_dir_parse.first_res_dir; rd; rd = rd->next) { - if (lane->idx == WaveLaneIdxFromTaskIdx(lane, task_idx++) && GetBuildStatus() == 0) + if (lane->idx == WaveLaneIdxFromTaskIdx(lane, task_idx++) && M_GetBuildStatus() == 0) { String dir_path = rd->dir_path; String store_name = rd->store_name; - EmbedObj *embed = &Build.embed_objs.array[embed_idx]; - *embed = Embed(store_name, dir_path); + M_EmbedObj *embed = &M.embed_objs.array[embed_idx]; + *embed = M_Embed(store_name, dir_path); } ++embed_idx; } @@ -935,7 +936,7 @@ void BuildEntryPoint(WaveLaneCtx *lane) ////////////////////////////// //- Phase 3/3: Link - if (lane->idx == 0 && GetBuildStatus() == 0) + if (lane->idx == 0 && M_GetBuildStatus() == 0) { String exe_file = StringF(perm, "%F.exe", FmtString(cmdline.leaf_layer_name)); { @@ -950,10 +951,10 @@ void BuildEntryPoint(WaveLaneCtx *lane) String obj_files_str = Zi; { StringList obj_files = Zi; - PushStringToList(perm, &obj_files, Build.c_obj.obj_file); - for (u64 embed_obj_idx = 0; embed_obj_idx < Build.embed_objs.count; ++embed_obj_idx) + PushStringToList(perm, &obj_files, M.c_obj.obj_file); + for (u64 embed_obj_idx = 0; embed_obj_idx < M.embed_objs.count; ++embed_obj_idx) { - EmbedObj *embed_obj = &Build.embed_objs.array[embed_obj_idx]; + M_EmbedObj *embed_obj = &M.embed_objs.array[embed_obj_idx]; PushStringToList(perm, &obj_files, embed_obj->obj_file); } obj_files_str = StringFromList(perm, obj_files, Lit(" ")); @@ -968,12 +969,12 @@ void BuildEntryPoint(WaveLaneCtx *lane) FmtString(StringFromList(perm, cp.linker_only_flags_msvc, Lit(" "))) ); OS_CommandResult result = OS_RunCommand(perm, cmd); - Build.link.output = TrimWhitespace(result.output); - Build.link.return_code = result.code; + M.link.output = TrimWhitespace(result.output); + M.link.return_code = result.code; i64 link_elapsed_ns = TimeNs() - start_ns; - // EchoLine(StringF(perm, ">>>>> Linked in %Fs", FmtFloat(SecondsFromNs(link_elapsed_ns)))); + // M_EchoLine(StringF(perm, ">>>>> Linked in %Fs", FmtFloat(SecondsFromNs(link_elapsed_ns)))); - SetBuildStatus(Build.link.return_code); + M_SetBuildStatus(M.link.return_code); } ////////////////////////////// @@ -983,10 +984,10 @@ void BuildEntryPoint(WaveLaneCtx *lane) { String gpu_obj_output = Zi; { - GpuObj *disp_obj = 0; - for (u32 gpu_obj_idx = 0; gpu_obj_idx < Build.gpu_objs.count; ++gpu_obj_idx) + M_GpuObj *disp_obj = 0; + for (u32 gpu_obj_idx = 0; gpu_obj_idx < M.gpu_objs.count; ++gpu_obj_idx) { - GpuObj *gpu_obj = &Build.gpu_objs.array[gpu_obj_idx]; + M_GpuObj *gpu_obj = &M.gpu_objs.array[gpu_obj_idx]; if (!disp_obj || TrimWhitespace(disp_obj->output).len == 0 || gpu_obj->return_code != 0) { disp_obj = gpu_obj; @@ -1000,22 +1001,22 @@ void BuildEntryPoint(WaveLaneCtx *lane) String embed_obj_output = Zi; { StringList embed_obj_outputs = Zi; - for (u32 embed_obj_idx = 0; embed_obj_idx < Build.embed_objs.count; ++embed_obj_idx) + for (u32 embed_obj_idx = 0; embed_obj_idx < M.embed_objs.count; ++embed_obj_idx) { - EmbedObj *embed_obj = &Build.embed_objs.array[embed_obj_idx]; + M_EmbedObj *embed_obj = &M.embed_objs.array[embed_obj_idx]; PushStringToList(perm, &embed_obj_outputs, embed_obj->output); } embed_obj_output = StringFromList(perm, embed_obj_outputs, Lit("\n")); } - EchoLineOrNothing(StringFromMetaErrors(perm, Build.layers_parse.errors)); - EchoLineOrNothing(StringFromMetaErrors(perm, Build.c_parse.errors)); - EchoLineOrNothing(StringFromMetaErrors(perm, Build.gpu_parse.errors)); - EchoLineOrNothing(Build.c_obj.output); - EchoLineOrNothing(gpu_obj_output); - EchoLineOrNothing(StringFromMetaErrors(perm, Build.res_dir_parse.errors)); - EchoLineOrNothing(embed_obj_output); - EchoLineOrNothing(Build.link.output); + M_EchoLineOrNothing(M_StringFromMetaErrors(perm, M.layers_parse.errors)); + M_EchoLineOrNothing(M_StringFromMetaErrors(perm, M.c_parse.errors)); + M_EchoLineOrNothing(M_StringFromMetaErrors(perm, M.gpu_parse.errors)); + M_EchoLineOrNothing(M.c_obj.output); + M_EchoLineOrNothing(gpu_obj_output); + M_EchoLineOrNothing(M_StringFromMetaErrors(perm, M.res_dir_parse.errors)); + M_EchoLineOrNothing(embed_obj_output); + M_EchoLineOrNothing(M.link.output); } ////////////////////////////// @@ -1023,8 +1024,8 @@ void BuildEntryPoint(WaveLaneCtx *lane) if (lane->idx == 0) { - EchoLine(StringF(perm, "Runtime: %Fs", FmtFloat(SecondsFromNs(TimeNs()), .p = 3))); - ExitNow(GetBuildStatus()); + M_EchoLine(StringF(perm, "Runtime: %Fs", FmtFloat(SecondsFromNs(TimeNs()), .p = 3))); + ExitNow(M_GetBuildStatus()); } } @@ -1036,5 +1037,5 @@ void BootstrapLayers(void) OS_Bootstrap(); CpuTopologyInfo cpu_info = GetCpuTopologyInfo(); i32 meta_lanes_count = cpu_info.num_logical_cores - 1; - DispatchWave(Lit("Meta"), MaxI32(meta_lanes_count, 1), BuildEntryPoint, 0); + DispatchWave(Lit("Meta"), MaxI32(meta_lanes_count, 1), M_BuildEntryPoint, 0); } diff --git a/src/meta/meta.h b/src/meta/meta.h index c3b37c53..5d23f1b5 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -1,4 +1,4 @@ -#define MetaRebuildCode 1317212284 +#define M_RebuildCode 1317212284 //////////////////////////////////////////////////////////// //~ Base layer definitions @@ -58,7 +58,7 @@ //////////////////////////////////////////////////////////// //~ Helper types -Struct(LineCol) +Struct(M_LineCol) { i64 line; i64 col; @@ -67,7 +67,7 @@ Struct(LineCol) //////////////////////////////////////////////////////////// //~ Build ctx types -Struct(CompilerParams) +Struct(M_CompilerParams) { StringList defs; @@ -86,41 +86,44 @@ Struct(CompilerParams) StringList linker_only_flags_clang; }; -Enum(ShaderEntryKind) +Enum(M_ShaderEntryKind) { ShaderEntryKind_VS, ShaderEntryKind_PS, ShaderEntryKind_CS, }; -Struct(ShaderEntry) +Struct(M_ShaderEntry) { - ShaderEntry *next; - ShaderEntryKind kind; + M_ShaderEntry *next; + M_ShaderEntryKind kind; String name; }; -Struct(ResDir) +Struct(M_ResDir) { - ResDir *next; + M_ResDir *next; String dir_path; String store_name; }; -Struct(GpuObj) +Struct(M_GpuObj) { String output; i32 return_code; }; -Struct(EmbedObj) +Struct(M_EmbedObj) { String obj_file; String output; i32 return_code; }; -Struct(BuildCtx) +//////////////////////////////////////////////////////////// +//~ State types + +Struct(M_Ctx) { Atomic32 status; @@ -134,16 +137,16 @@ Struct(BuildCtx) struct { M_ErrorList errors; - ShaderEntry *first_shader_entry; - ShaderEntry *last_shader_entry; + M_ShaderEntry *first_shader_entry; + M_ShaderEntry *last_shader_entry; u64 shader_entries_count; } gpu_parse; struct { M_ErrorList errors; - ResDir *first_res_dir; - ResDir *last_res_dir; + M_ResDir *first_res_dir; + M_ResDir *last_res_dir; u64 res_dirs_count; } res_dir_parse; @@ -156,14 +159,14 @@ Struct(BuildCtx) struct { - GpuObj *array; + M_GpuObj *array; u32 count; Atomic32 finished_count; } gpu_objs; struct { - EmbedObj *array; + M_EmbedObj *array; u32 count; } embed_objs; @@ -174,20 +177,20 @@ Struct(BuildCtx) } link; }; -extern BuildCtx Build; +extern M_Ctx M; //////////////////////////////////////////////////////////// //~ Helpers -i32 GetBuildStatus(void); -void SetBuildStatus(i32 code); -void EchoLine(String msg); -void EchoLineOrNothing(String msg); -LineCol LineColFromPos(String data, i64 pos); -String StringFromMetaErrors(Arena *arena, M_ErrorList errors); -EmbedObj Embed(String store_name, String dir_path); +i32 M_GetBuildStatus(void); +void M_SetBuildStatus(i32 code); +void M_EchoLine(String msg); +void M_EchoLineOrNothing(String msg); +M_LineCol M_LineColFromPos(String data, i64 pos); +String M_StringFromMetaErrors(Arena *arena, M_ErrorList errors); +M_EmbedObj M_Embed(String store_name, String dir_path); //////////////////////////////////////////////////////////// //~ Build -void BuildEntryPoint(WaveLaneCtx *lane); +void M_BuildEntryPoint(WaveLaneCtx *lane); diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index f87d639e..b6c07f63 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -390,35 +390,23 @@ void V_TickForever(WaveLaneCtx *lane) Vec2I32 cells_dims = VEC2I32(P_CellsPerMeter * P_WorldPitch, P_CellsPerMeter * P_WorldPitch); // Init gpu state - G_ResourceHandle gpu_state = Zi; - G_ResourceHandle gpu_tiles = Zi; - G_ResourceHandle gpu_particles = Zi; - G_ResourceHandle gpu_cells = Zi; - G_ResourceHandle gpu_stains = Zi; - G_ResourceHandle gpu_drynesses = Zi; - G_RWStructuredBufferRef gpu_state_ref = Zi; - G_Texture2DRef gpu_tiles_ref = Zi; - G_RWStructuredBufferRef gpu_particles_ref = Zi; - G_RWTexture2DRef gpu_cells_ref = Zi; - G_RWTexture2DRef gpu_stains_ref = Zi; - G_RWTexture2DRef gpu_drynesses_ref = Zi; + G_ResourceHandle gpu_tiles_res = Zi; + G_ResourceHandle gpu_particles_res = Zi; + G_ResourceHandle gpu_cells_res = Zi; + G_ResourceHandle gpu_stains_res = Zi; + G_ResourceHandle gpu_drynesses_res = Zi; + + G_Texture2DRef gpu_tiles = Zi; + G_RWStructuredBufferRef gpu_particles = Zi; + G_RWTexture2DRef gpu_cells = Zi; + G_RWTexture2DRef gpu_stains = Zi; + G_RWTexture2DRef gpu_drynesses = Zi; { G_CommandListHandle cl = G_PrepareCommandList(G_QueueKind_Direct); { - // Init state buffer - { - gpu_state = G_PushBuffer( - gpu_perm, cl, - V_GpuState, - 1, - .flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite, - .name = Lit("Gpu state") - ); - gpu_state_ref = G_PushRWStructuredBufferRef(gpu_perm, gpu_state, V_GpuState); - } // Init tile map texture { - gpu_tiles = G_PushTexture2D( + gpu_tiles_res = G_PushTexture2D( gpu_perm, cl, G_Format_R8_Uint, tiles_dims, @@ -426,22 +414,22 @@ void V_TickForever(WaveLaneCtx *lane) .flags = G_ResourceFlag_ZeroMemory, .name = Lit("Tiles") ); - gpu_tiles_ref = G_PushTexture2DRef(gpu_perm, gpu_tiles); + gpu_tiles = G_PushTexture2DRef(gpu_perm, gpu_tiles_res); } // Init particle buffer { - gpu_particles = G_PushBuffer( + gpu_particles_res = G_PushBuffer( gpu_perm, cl, V_Particle, V_ParticlesCap, .flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite, .name = Lit("Particles") ); - gpu_particles_ref = G_PushRWStructuredBufferRef(gpu_perm, gpu_particles, V_Particle); + gpu_particles = G_PushRWStructuredBufferRef(gpu_perm, gpu_particles_res, V_Particle); } // Init cells texture { - gpu_cells = G_PushTexture2D( + gpu_cells_res = G_PushTexture2D( gpu_perm, cl, // G_Format_R8_Uint, // G_Format_R11G11B10_Float, @@ -452,11 +440,11 @@ void V_TickForever(WaveLaneCtx *lane) .flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite, .name = Lit("Cells") ); - gpu_cells_ref = G_PushRWTexture2DRef(gpu_perm, gpu_cells); + gpu_cells = G_PushRWTexture2DRef(gpu_perm, gpu_cells_res); } // Init stain texture { - gpu_stains = G_PushTexture2D( + gpu_stains_res = G_PushTexture2D( gpu_perm, cl, // G_Format_R8_Uint, // G_Format_R11G11B10_Float, @@ -467,11 +455,11 @@ void V_TickForever(WaveLaneCtx *lane) .flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite, .name = Lit("Stains") ); - gpu_stains_ref = G_PushRWTexture2DRef(gpu_perm, gpu_stains); + gpu_stains = G_PushRWTexture2DRef(gpu_perm, gpu_stains_res); } // Init drynesses texture { - gpu_drynesses = G_PushTexture2D( + gpu_drynesses_res = G_PushTexture2D( gpu_perm, cl, // G_Format_R8_Uint, // G_Format_R11G11B10_Float, @@ -483,7 +471,7 @@ void V_TickForever(WaveLaneCtx *lane) .flags = G_ResourceFlag_ZeroMemory | G_ResourceFlag_AllowShaderReadWrite, .name = Lit("Drynesses") ); - gpu_drynesses_ref = G_PushRWTexture2DRef(gpu_perm, gpu_drynesses); + gpu_drynesses = G_PushRWTexture2DRef(gpu_perm, gpu_drynesses_res); } } G_CommitCommandList(cl); @@ -542,9 +530,6 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Begin frame - b32 tiles_dirty = 0; - b32 should_clear_particles = 0; - V.current_frame_tick += 1; V_Frame *prev_frame = V_PrevFrame(); V_Frame *frame = V_CurrentFrame(); @@ -596,6 +581,21 @@ void V_TickForever(WaveLaneCtx *lane) TrueRand(StringFromStruct(&V.player_key)); } + ////////////////////////////// + //- Initialize persistent gpu resources + + { + + // Persistent resources + frame->tiles = gpu_tiles; + frame->pt_clamp_sampler = G_BasicPointClampSampler(); + frame->pt_wrap_sampler = G_BasicPointWrapSampler(); + frame->particles = gpu_particles; + frame->cells = gpu_cells; + frame->stains = gpu_stains; + frame->drynesses = gpu_drynesses; + } + ////////////////////////////// //- Swap @@ -741,14 +741,14 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Process controller events into vis cmds - b32 has_mouse_focus = UI_IsKeyNil(ui_frame->hot_box) || UI_MatchKey(ui_frame->hot_box, vis_box); - b32 has_keyboard_focus = 1; + frame->has_mouse_focus = UI_IsKeyNil(ui_frame->hot_box) || UI_MatchKey(ui_frame->hot_box, vis_box); + frame->has_keyboard_focus = 1; Vec2 mouse_delta = Zi; { if (!window_frame.has_focus) { - has_mouse_focus = 0; - has_keyboard_focus = 0; + frame->has_mouse_focus = 0; + frame->has_keyboard_focus = 0; } //- Reset held buttons @@ -756,14 +756,14 @@ void V_TickForever(WaveLaneCtx *lane) { if (btn == Button_M1 || btn == Button_M2 || btn == Button_M3) { - if (!has_mouse_focus) + if (!frame->has_mouse_focus) { frame->held_buttons[btn] = 0; } } else { - if (!has_keyboard_focus) + if (!frame->has_keyboard_focus) { frame->held_buttons[btn] = 0; } @@ -782,14 +782,14 @@ void V_TickForever(WaveLaneCtx *lane) { if (cev.button == Button_M1 || cev.button == Button_M2 || cev.button == Button_M3) { - if (!has_mouse_focus) + if (!frame->has_mouse_focus) { ignore = 1; } } else { - if (!has_keyboard_focus) + if (!frame->has_keyboard_focus) { ignore = 1; } @@ -860,7 +860,7 @@ void V_TickForever(WaveLaneCtx *lane) { // TODO: Adjustable sensitivity f32 mouse_sensitivity = TweakFloat("Mouse sensitivity", 1.0, 0.1, 5.0); - f32 mouse_scale_factor = 0.005; + f32 mouse_scale_factor = 0.007; look = frame->look; look = AddVec2(look, MulVec2(mouse_delta, mouse_sensitivity * mouse_scale_factor)); look = ClampVec2Len(look, look_radius); @@ -1903,7 +1903,7 @@ void V_TickForever(WaveLaneCtx *lane) { local_world->tiles_hash = predict_world->tiles_hash; CopyStructs(local_world->tiles, predict_world->tiles, P_TilesCount); - tiles_dirty = 1; + frame->tiles_dirty = 1; } local_world->seed = predict_world->seed; @@ -4428,7 +4428,7 @@ void V_TickForever(WaveLaneCtx *lane) case V_CmdKind_clear_particles: { - should_clear_particles = 1; + frame->should_clear_particles = 1; } break; case V_CmdKind_test: @@ -4444,7 +4444,41 @@ void V_TickForever(WaveLaneCtx *lane) { ////////////////////////////// - //- Setup gpu data + //- Build gpu data + + // Tiles + { + for (P_TileKind tile_kind = 0; tile_kind < P_TileKind_COUNT; ++tile_kind) + { + SPR_Sprite tile_sprite = Zi; + { + String tile_name = P_TileNameFromKind(tile_kind); + String sheet_name = StringF(frame->arena, "tile/%F.ase", FmtString(tile_name)); + ResourceKey sheet_resource = ResourceKeyFromStore(&P_Resources, sheet_name); + SPR_SheetKey sheet = SPR_SheetKeyFromResource(sheet_resource); + tile_sprite = SPR_SpriteFromSheet(sheet, SPR_NilSpanKey, 0); + } + V_TileDesc tile_desc = Zi; + { + tile_desc.tex = tile_sprite.tex; + tile_desc.tex_slice_uv = DivRng2Vec2(tile_sprite.tex_rect, tile_sprite.tex_dims); + } + frame->tile_descs[tile_kind] = tile_desc; + } + } + // Upload tiles + if (frame->tiles_dirty) + { + // LogDebugF("Uploading tiles to gpu"); + G_DumbMemoryLayoutSync(frame->cl, gpu_tiles_res, G_Layout_DirectQueue_CopyWrite); + G_CopyCpuToTexture( + frame->cl, + gpu_tiles_res, VEC3I32(0, 0, 0), + local_world->tiles, VEC3I32(tiles_dims.x, tiles_dims.y, 1), + RNG3I32(VEC3I32(0, 0, 0), VEC3I32(tiles_dims.x, tiles_dims.y, 1)) + ); + G_DumbMemoryLayoutSync(frame->cl, gpu_tiles_res, G_Layout_DirectQueue_ShaderRead); + } // Screen texture G_ResourceHandle screen_target = G_PushTexture2D( @@ -4455,7 +4489,7 @@ void V_TickForever(WaveLaneCtx *lane) .flags = G_ResourceFlag_AllowRenderTarget, .name = StringF(frame->arena, "Screen target [%F]", FmtSint(frame->tick)) ); - G_Texture2DRef screen_target_ro = G_PushTexture2DRef(frame->gpu_arena, screen_target); + frame->screen_ro = G_PushTexture2DRef(frame->gpu_arena, screen_target); Rng3 screen_viewport = RNG3(VEC3(0, 0, 0), VEC3(frame->screen_dims.x, frame->screen_dims.y, 1)); Rng2 screen_scissor = RNG2(VEC2(screen_viewport.p0.x, screen_viewport.p0.y), VEC2(screen_viewport.p1.x, screen_viewport.p1.y)); @@ -4468,7 +4502,7 @@ void V_TickForever(WaveLaneCtx *lane) .flags = G_ResourceFlag_AllowRenderTarget, .name = StringF(frame->arena, "Albedo target [%F]", FmtSint(frame->tick)) ); - G_Texture2DRef albedo_target_ro = G_PushTexture2DRef(frame->gpu_arena, albedo_target); + frame->albedo_ro = G_PushTexture2DRef(frame->gpu_arena, albedo_target); // Shade texture G_ResourceHandle shade_target = G_PushTexture2D( @@ -4481,8 +4515,8 @@ void V_TickForever(WaveLaneCtx *lane) // .flags = G_ResourceFlag_AllowShaderReadWrite | G_ResourceFlag_ForceNoReuse, .name = StringF(frame->arena, "Shade target [%F]", FmtSint(frame->tick)) ); - G_Texture2DRef shade_target_ro = G_PushTexture2DRef(frame->gpu_arena, shade_target); - G_RWTexture2DRef shade_target_rw = G_PushRWTexture2DRef(frame->gpu_arena, shade_target); + frame->shade_ro = G_PushTexture2DRef(frame->gpu_arena, shade_target); + frame->shade_rw = G_PushRWTexture2DRef(frame->gpu_arena, shade_target); Rng3 shade_viewport = RNG3(VEC3(0, 0, 0), VEC3(frame->shade_dims.x, frame->shade_dims.y, 1)); Rng2 shade_scissor = RNG2(VEC2(shade_viewport.p0.x, shade_viewport.p0.y), VEC2(shade_viewport.p1.x, shade_viewport.p1.y)); @@ -4492,7 +4526,7 @@ void V_TickForever(WaveLaneCtx *lane) StringFromArena(frame->quads_arena), .name = StringF(frame->arena, "quads [%F]", FmtSint(frame->tick)) ); - G_StructuredBufferRef quads_ref = G_PushStructuredBufferRef(frame->gpu_arena, quads_buff, V_Quad); + frame->quads = G_PushStructuredBufferRef(frame->gpu_arena, quads_buff, V_Quad); // Debug shape buffers G_ResourceHandle dverts_buff = G_PushBufferFromCpuCopy( @@ -4505,10 +4539,10 @@ void V_TickForever(WaveLaneCtx *lane) StringFromArena(frame->dvert_idxs_arena), .name = StringF(frame->arena, "dvert idxs [%F]", FmtSint(frame->tick)) ); - G_StructuredBufferRef dverts_ref = G_PushStructuredBufferRef(frame->gpu_arena, dverts_buff, V_DVert); + frame->dverts = G_PushStructuredBufferRef(frame->gpu_arena, dverts_buff, V_DVert); G_IndexBufferDesc dvert_idxs_ib = G_IdxBuff32(dvert_idxs_buff); - // Emitters + // Particles G_ResourceHandle gpu_emitters = Zi; { // Flatten emitters list @@ -4527,113 +4561,30 @@ void V_TickForever(WaveLaneCtx *lane) .name = StringF(frame->arena, "emitters [%F]", FmtSint(frame->tick)) ); } - G_StructuredBufferRef gpu_emitters_ref = G_PushStructuredBufferRef(frame->gpu_arena, gpu_emitters, V_Emitter); + frame->emitters = G_PushStructuredBufferRef(frame->gpu_arena, gpu_emitters, V_Emitter); - // Params - V_GpuParams params = Zi; + // Upload gpu frame data { - params.dt = frame->dt; - params.tick = frame->tick; - params.seed = RandU64FromState(&frame->rand); - params.af = frame->af; - - params.selection_mode = frame->selection_mode; - params.equipped_tile = frame->equipped_tile; - - params.has_mouse_focus = has_mouse_focus; - params.has_keyboard_focus = has_keyboard_focus; - params.screen_cursor = frame->screen_cursor; - params.shade_cursor = frame->shade_cursor; - params.world_cursor = frame->world_cursor; - params.screen_selection = frame->screen_selection; - params.shade_selection = frame->shade_selection; - params.world_selection = frame->world_selection; - - params.screen_crosshair = frame->screen_crosshair; - params.shade_crosshair = frame->shade_crosshair; - params.world_crosshair = frame->world_crosshair; - - params.camera_pos = frame->camera_pos; - params.camera_zoom = frame->camera_zoom; - - params.pt_clamp_sampler = G_BasicPointClampSampler(); - params.pt_wrap_sampler = G_BasicPointWrapSampler(); - - params.shade_dims = frame->shade_dims; - params.shade_ro = shade_target_ro; - params.shade_rw = shade_target_rw; - - params.screen_dims = frame->screen_dims; - params.albedo_ro = albedo_target_ro; - - params.tiles = gpu_tiles_ref; - params.quads = quads_ref; - params.shape_verts = dverts_ref; - - params.emitters_count = frame->emitters_count; - params.emitters = gpu_emitters_ref; - - params.particles = gpu_particles_ref; - - params.should_clear_stains = should_clear_particles; - params.cells = gpu_cells_ref; - params.stains = gpu_stains_ref; - params.drynesses = gpu_drynesses_ref; - - // Fill tile textures - { - for (P_TileKind tile_kind = 0; tile_kind < P_TileKind_COUNT; ++tile_kind) - { - SPR_Sprite tile_sprite = Zi; - { - String tile_name = P_TileNameFromKind(tile_kind); - String sheet_name = StringF(frame->arena, "tile/%F.ase", FmtString(tile_name)); - ResourceKey sheet_resource = ResourceKeyFromStore(&P_Resources, sheet_name); - SPR_SheetKey sheet = SPR_SheetKeyFromResource(sheet_resource); - tile_sprite = SPR_SpriteFromSheet(sheet, SPR_NilSpanKey, 0); - } - V_TileDesc tile_desc = Zi; - { - tile_desc.tex = tile_sprite.tex; - tile_desc.tex_slice_uv = DivRng2Vec2(tile_sprite.tex_rect, tile_sprite.tex_dims); - } - params.tile_descs[tile_kind] = tile_desc; - } - } - } - G_ResourceHandle gpu_params = G_PushBufferFromCpuCopy( - frame->gpu_arena, frame->cl, - StringFromStruct(¶ms), - .name = StringF(frame->arena, "Gpu params [%F]", FmtSint(frame->tick)) - ); - G_StructuredBufferRef gpu_params_ref = G_PushStructuredBufferRef(frame->gpu_arena, gpu_params, V_GpuParams); - - // Upload tiles - if (tiles_dirty) - { - // LogDebugF("Uploading tiles to gpu"); - G_DumbMemoryLayoutSync(frame->cl, gpu_tiles, G_Layout_DirectQueue_CopyWrite); - G_CopyCpuToTexture( - frame->cl, - gpu_tiles, VEC3I32(0, 0, 0), - local_world->tiles, VEC3I32(tiles_dims.x, tiles_dims.y, 1), - RNG3I32(VEC3I32(0, 0, 0), VEC3I32(tiles_dims.x, tiles_dims.y, 1)) + // Gpu frame + G_ResourceHandle gpu_frame = G_PushBufferFromCpuCopy( + frame->gpu_arena, frame->cl, + StringFromStruct(&frame->shared_frame), + .name = StringF(frame->arena, "Gpu frame [%F]", FmtSint(frame->tick)) ); - G_DumbMemoryLayoutSync(frame->cl, gpu_tiles, G_Layout_DirectQueue_ShaderRead); - } + G_StructuredBufferRef gpu_frame_ref = G_PushStructuredBufferRef(frame->gpu_arena, gpu_frame, V_SharedFrame); - // Flags - V_GpuFlag gpu_flags = 0; - if (frame->show_console) - { - gpu_flags |= V_GpuFlag_DebugDraw; - } + // Gpu flags + V_GpuFlag gpu_flags = 0; + if (frame->show_console) + { + gpu_flags |= V_GpuFlag_DebugDraw; + } - // Constants - G_SetConstant(frame->cl, V_ShaderConst_GpuFlags, gpu_flags); - G_SetConstant(frame->cl, V_ShaderConst_State, gpu_state_ref); - G_SetConstant(frame->cl, V_ShaderConst_Params, gpu_params_ref); - G_SetConstant(frame->cl, V_ShaderConst_NoiseTex, G_BasicNoiseTexture()); + // Set constants + G_SetConstant(frame->cl, V_ShaderConst_GpuFlags, gpu_flags); + G_SetConstant(frame->cl, V_ShaderConst_Frame, gpu_frame_ref); + G_SetConstant(frame->cl, V_ShaderConst_NoiseTex, G_BasicNoiseTexture()); + } // Sync G_DumbGlobalMemorySync(frame->cl); @@ -4649,7 +4600,7 @@ void V_TickForever(WaveLaneCtx *lane) G_Compute(frame->cl, V_PrepareCellsCS, V_ThreadGroupSizeFromTexSize(cells_dims)); // Clear particles - if (should_clear_particles) + if (frame->should_clear_particles) { G_Compute(frame->cl, V_ClearParticlesCS, V_ThreadGroupSizeFromBufferSize(V_ParticlesCap)); } @@ -4686,7 +4637,7 @@ void V_TickForever(WaveLaneCtx *lane) G_Compute(frame->cl, V_EmitParticlesCS, V_ThreadGroupSizeFromBufferSize(frame->emitters_count)); // Barrier particles buffer - G_DumbMemorySync(frame->cl, gpu_particles); + G_DumbMemorySync(frame->cl, gpu_particles_res); // Simulate particles G_Compute(frame->cl, V_SimParticlesCS, V_ThreadGroupSizeFromBufferSize(V_ParticlesCap)); @@ -4749,7 +4700,7 @@ void V_TickForever(WaveLaneCtx *lane) uv.p0 = Vec2FromVec(screen_viewport.p0); uv.p1 = Vec2FromVec(screen_viewport.p1); uv = DivRng2Vec2(uv, Vec2FromVec(frame->screen_dims)); - UI_SetRawTexture(vis_box, screen_target_ro, uv); + UI_SetRawTexture(vis_box, frame->screen_ro, uv); } } diff --git a/src/pp/pp_vis/pp_vis_core.h b/src/pp/pp_vis/pp_vis_core.h index fd23ae13..9e661577 100644 --- a/src/pp/pp_vis/pp_vis_core.h +++ b/src/pp/pp_vis/pp_vis_core.h @@ -215,12 +215,6 @@ Enum(V_DrawFlag) //////////////////////////////////////////////////////////// //~ State types -Enum(V_EditMode) -{ - V_EditMode_None, - V_EditMode_Tile, -}; - Struct(V_Frame) { Arena *arena; @@ -230,77 +224,25 @@ Struct(V_Frame) G_ArenaHandle gpu_arena; G_CommandListHandle cl; - i64 tick; - i64 time_ns; - i64 dt_ns; - f64 dt; + Embed(V_SharedFrame, shared_frame); + RandState rand; NET_Key sim_key; NET_Key desired_sim_key; + f64 predict_tick_accum; Button held_buttons[Button_COUNT]; V_Palette palette; String window_restore; - i32 zooms; - - Vec2 screen_dims; - Vec2 shade_dims; - - // Modes - b32 is_editing; - b32 ui_debug; - b32 show_console; - - // Editor state - V_EditMode edit_mode; - P_TileKind equipped_tile; - - // Editor - b32 is_selecting; - b32 is_panning; - V_SelectionMode selection_mode; - Vec2 world_selection_start; - Vec2 edit_camera_pos; - f32 edit_camera_zoom; - - // Camera - f32 camera_lerp_rate; - Vec2 camera_pos; - f32 camera_zoom; - - // affines; - V_Affines af; - - // Cursor - Vec2 screen_cursor; - Vec2 shade_cursor; - Vec2 world_cursor; - Rng2 screen_selection; - Rng2 shade_selection; - Rng2 world_selection; - - // Crosshair - Vec2 screen_crosshair; - Vec2 shade_crosshair; - Vec2 world_crosshair; // Vis commands i64 cmds_count; V_CmdNode *first_cmd_node; V_CmdNode *last_cmd_node; - f64 predict_tick_accum; - - // Control - Vec2 move; - Vec2 look; - f32 fire_held; - f32 fire_presses; - - // Emitters - i64 emitters_count; + // Unflattened emitters list V_EmitterNode *first_emitter_node; V_EmitterNode *last_emitter_node; }; @@ -320,7 +262,7 @@ Struct(V_Ctx) V_Notif *first_notif; V_Notif *last_notif; - // Atomic monotonically increasing allocation counter sequence for GPU particle ring buffer + // Monotonically increasing allocation counter sequence for GPU particle ring buffer u32 particle_seq; Atomic32 shutdown; diff --git a/src/pp/pp_vis/pp_vis_gpu.g b/src/pp/pp_vis/pp_vis_gpu.g index abcd81f0..34fb7441 100644 --- a/src/pp/pp_vis/pp_vis_gpu.g +++ b/src/pp/pp_vis/pp_vis_gpu.g @@ -23,8 +23,8 @@ Vec4 V_DryColor(Vec4 color, f32 dryness) //- Prepare shade ComputeShader2D(V_PrepareShadeCS, 8, 8) { - V_GpuParams params = G_Dereference(V_ShaderConst_Params)[0]; - RWTexture2D shade = G_Dereference(params.shade_rw); + V_SharedFrame frame = G_Dereference(V_ShaderConst_Frame)[0]; + RWTexture2D shade = G_Dereference(frame.shade_rw); Vec2 shade_pos = SV_DispatchThreadID; if (all(shade_pos < countof(shade))) @@ -37,9 +37,9 @@ ComputeShader2D(V_PrepareShadeCS, 8, 8) //- Prepare cells ComputeShader2D(V_PrepareCellsCS, 8, 8) { - V_GpuParams params = G_Dereference(V_ShaderConst_Params)[0]; - RWTexture2D cells = G_Dereference(params.cells); - RWTexture2D drynesses = G_Dereference(params.drynesses); + V_SharedFrame frame = G_Dereference(V_ShaderConst_Frame)[0]; + RWTexture2D cells = G_Dereference(frame.cells); + RWTexture2D drynesses = G_Dereference(frame.drynesses); Vec2 cells_pos = SV_DispatchThreadID; if (all(cells_pos < countof(cells))) { @@ -47,7 +47,8 @@ ComputeShader2D(V_PrepareCellsCS, 8, 8) cells[cells_pos] = 0; // Increase dryness - f32 dry_rate = params.dt * 0.1; + // TODO: Use simulation dt + f32 dry_rate = frame.dt * 0.1; { f32 old_dryness = drynesses[cells_pos]; f32 new_dryness = lerp(old_dryness, 1, dry_rate); @@ -55,9 +56,9 @@ ComputeShader2D(V_PrepareCellsCS, 8, 8) } // Clear stain - if (params.should_clear_stains) + if (frame.should_clear_stains) { - RWTexture2D stains = G_Dereference(params.stains); + RWTexture2D stains = G_Dereference(frame.stains); stains[cells_pos] = 0; drynesses[cells_pos] = 0; } @@ -67,8 +68,8 @@ ComputeShader2D(V_PrepareCellsCS, 8, 8) //- Clear particles ComputeShader(V_ClearParticlesCS, 64) { - V_GpuParams params = G_Dereference(V_ShaderConst_Params)[0]; - RWStructuredBuffer particles = G_Dereference(params.particles); + V_SharedFrame frame = G_Dereference(V_ShaderConst_Frame)[0]; + RWStructuredBuffer particles = G_Dereference(frame.particles); u32 particle_idx = SV_DispatchThreadID; if (particle_idx < V_ParticlesCap) { @@ -84,8 +85,8 @@ ComputeShader(V_ClearParticlesCS, 64) VertexShader(V_QuadVS, V_QuadPSInput) { - V_GpuParams params = G_Dereference(V_ShaderConst_Params)[0]; - StructuredBuffer quads = G_Dereference(params.quads); + V_SharedFrame frame = G_Dereference(V_ShaderConst_Frame)[0]; + StructuredBuffer quads = G_Dereference(frame.quads); V_Quad quad = quads[SV_InstanceID]; @@ -95,7 +96,7 @@ VertexShader(V_QuadVS, V_QuadPSInput) Vec2 samp_uv = lerp(quad.tex_slice_uv.p0, quad.tex_slice_uv.p1, rect_uv); V_QuadPSInput result; - result.sv_position = Vec4(NdcFromPos(screen_pos, params.screen_dims).xy, 0, 1); + result.sv_position = Vec4(NdcFromPos(screen_pos, frame.screen_dims).xy, 0, 1); result.quad_idx = SV_InstanceID; result.samp_uv = samp_uv; return result; @@ -106,9 +107,9 @@ VertexShader(V_QuadVS, V_QuadPSInput) PixelShader(V_QuadPS, V_QuadPSOutput, V_QuadPSInput input) { - V_GpuParams params = G_Dereference(V_ShaderConst_Params)[0]; - StructuredBuffer quads = G_Dereference(params.quads); - SamplerState clamp_sampler = G_Dereference(params.pt_clamp_sampler); + V_SharedFrame frame = G_Dereference(V_ShaderConst_Frame)[0]; + StructuredBuffer quads = G_Dereference(frame.quads); + SamplerState clamp_sampler = G_Dereference(frame.pt_clamp_sampler); V_Quad quad = quads[input.quad_idx]; @@ -130,13 +131,12 @@ PixelShader(V_QuadPS, V_QuadPSOutput, V_QuadPSInput input) ComputeShader(V_EmitParticlesCS, 64) { - V_GpuParams params = G_Dereference(V_ShaderConst_Params)[0]; - RWStructuredBuffer state_buff = G_Dereference(V_ShaderConst_State); - StructuredBuffer emitters = G_Dereference(params.emitters); - RWStructuredBuffer particles = G_Dereference(params.particles); + V_SharedFrame frame = G_Dereference(V_ShaderConst_Frame)[0]; + StructuredBuffer emitters = G_Dereference(frame.emitters); + RWStructuredBuffer particles = G_Dereference(frame.particles); u32 emitter_idx = SV_DispatchThreadID; - if (emitter_idx < params.emitters_count) + if (emitter_idx < frame.emitters_count) { V_Emitter emitter = emitters[emitter_idx]; for (u32 i = 0; i < emitter.count; ++i) @@ -155,11 +155,11 @@ ComputeShader(V_EmitParticlesCS, 64) ComputeShader(V_SimParticlesCS, 64) { - V_GpuParams params = G_Dereference(V_ShaderConst_Params)[0]; - RWStructuredBuffer particles = G_Dereference(params.particles); - RWTexture2D cells = G_Dereference(params.cells); - RWTexture2D stains = G_Dereference(params.stains); - RWTexture2D drynesses = G_Dereference(params.drynesses); + V_SharedFrame frame = G_Dereference(V_ShaderConst_Frame)[0]; + RWStructuredBuffer particles = G_Dereference(frame.particles); + RWTexture2D cells = G_Dereference(frame.cells); + RWTexture2D stains = G_Dereference(frame.stains); + RWTexture2D drynesses = G_Dereference(frame.drynesses); u32 particle_idx = SV_DispatchThreadID; if (particle_idx < V_ParticlesCap) @@ -172,7 +172,7 @@ ComputeShader(V_SimParticlesCS, 64) if (particle.emitter_init_num != 0) { - V_Emitter emitter = G_Dereference(params.emitters)[particle.emitter_init_num - 1]; + V_Emitter emitter = G_Dereference(frame.emitters)[particle.emitter_init_num - 1]; u64 seed0 = MixU64(particle.seq); u64 seed1 = MixU64(seed0); @@ -214,14 +214,15 @@ ComputeShader(V_SimParticlesCS, 64) f32 prev_exists = particle.exists; { - Vec2 cell_pos = mul(params.af.world_to_cell, Vec3(particle.pos, 1)); + Vec2 cell_pos = mul(frame.af.world_to_cell, Vec3(particle.pos, 1)); b32 is_in_world = all(cell_pos >= 0) && all(cell_pos < countof(cells)); // Simulate { - particle.pos += particle.velocity * params.dt; - particle.velocity = lerp(particle.velocity, 0, particle.velocity_falloff * params.dt); - particle.exists -= params.dt / particle.lifetime; + // TODO: Use simulation dt + particle.pos += particle.velocity * frame.dt; + particle.velocity = lerp(particle.velocity, 0, particle.velocity_falloff * frame.dt); + particle.exists -= frame.dt / particle.lifetime; if ((particle.flags & V_ParticleFlag_PruneWhenStill) && (dot(particle.velocity, particle.velocity) < (0.1 * 0.1))) { particle.exists = 0; @@ -239,10 +240,10 @@ ComputeShader(V_SimParticlesCS, 64) // FIXME: Atomic writes { - Vec2 cell_pos = mul(params.af.world_to_cell, Vec3(particle.pos, 1)); - Vec2 screen_pos = mul(params.af.world_to_screen, Vec3(particle.pos, 1)); + Vec2 cell_pos = mul(frame.af.world_to_cell, Vec3(particle.pos, 1)); + Vec2 screen_pos = mul(frame.af.world_to_screen, Vec3(particle.pos, 1)); b32 is_in_world = all(cell_pos >= 0) && all(cell_pos < countof(cells)); - b32 is_in_screen = all(screen_pos >= 0) && all(screen_pos < params.screen_dims); + b32 is_in_screen = all(screen_pos >= 0) && all(screen_pos < frame.screen_dims); Vec4 color = particle.color; color.a *= prev_exists; @@ -295,18 +296,18 @@ ComputeShader(V_SimParticlesCS, 64) ComputeShader2D(V_ShadeCS, 8, 8) { - V_GpuParams params = G_Dereference(V_ShaderConst_Params)[0]; - RWTexture2D shade_tex = G_Dereference(params.shade_rw); - Texture2D albedo_tex = G_Dereference(params.albedo_ro); - Texture2D tiles = G_Dereference(params.tiles); - RWTexture2D stains = G_Dereference(params.stains); - RWTexture2D drynesses = G_Dereference(params.drynesses); - SamplerState clamp_sampler = G_Dereference(params.pt_clamp_sampler); + V_SharedFrame frame = G_Dereference(V_ShaderConst_Frame)[0]; + RWTexture2D shade_tex = G_Dereference(frame.shade_rw); + Texture2D albedo_tex = G_Dereference(frame.albedo_ro); + Texture2D tiles = G_Dereference(frame.tiles); + RWTexture2D stains = G_Dereference(frame.stains); + RWTexture2D drynesses = G_Dereference(frame.drynesses); + SamplerState clamp_sampler = G_Dereference(frame.pt_clamp_sampler); Vec2 shade_pos = SV_DispatchThreadID + Vec2(0.5, 0.5); - Vec2 world_pos = mul(params.af.shade_to_world, Vec3(shade_pos, 1)); - Vec2 cell_pos = mul(params.af.world_to_cell, Vec3(world_pos, 1)); - Vec2 tile_pos = mul(params.af.world_to_tile, Vec3(world_pos, 1)); + Vec2 world_pos = mul(frame.af.shade_to_world, Vec3(shade_pos, 1)); + Vec2 cell_pos = mul(frame.af.world_to_cell, Vec3(world_pos, 1)); + Vec2 tile_pos = mul(frame.af.world_to_tile, Vec3(world_pos, 1)); P_TileKind tile = tiles.Load(Vec3(tile_pos, 0)); @@ -351,28 +352,28 @@ VertexShader(V_CompositeVS, V_CompositePSInput) PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input) { - V_GpuParams params = G_Dereference(V_ShaderConst_Params)[0]; - // Texture2D shade_tex = G_Dereference(params.shade_ro); - Texture2D albedo_tex = G_Dereference(params.albedo_ro); - RWTexture2D stains = G_Dereference(params.stains); - RWTexture2D cells = G_Dereference(params.cells); - RWTexture2D drynesses = G_Dereference(params.drynesses); - Texture2D tiles = G_Dereference(params.tiles); - SamplerState clamp_sampler = G_Dereference(params.pt_clamp_sampler); + V_SharedFrame frame = G_Dereference(V_ShaderConst_Frame)[0]; + // Texture2D shade_tex = G_Dereference(frame.shade_ro); + Texture2D albedo_tex = G_Dereference(frame.albedo_ro); + RWTexture2D stains = G_Dereference(frame.stains); + RWTexture2D cells = G_Dereference(frame.cells); + RWTexture2D drynesses = G_Dereference(frame.drynesses); + Texture2D tiles = G_Dereference(frame.tiles); + SamplerState clamp_sampler = G_Dereference(frame.pt_clamp_sampler); Vec2 screen_pos = input.sv_position.xy; - Vec2 world_pos = mul(params.af.screen_to_world, Vec3(screen_pos, 1)); - Vec2 tile_pos = mul(params.af.world_to_tile, Vec3(world_pos, 1)); - Vec2 cell_pos = mul(params.af.world_to_cell, Vec3(world_pos, 1)); - Vec2 shade_pos = mul(params.af.screen_to_shade, Vec3(screen_pos.xy, 1)); + Vec2 world_pos = mul(frame.af.screen_to_world, Vec3(screen_pos, 1)); + Vec2 tile_pos = mul(frame.af.world_to_tile, Vec3(world_pos, 1)); + Vec2 cell_pos = mul(frame.af.world_to_cell, Vec3(world_pos, 1)); + Vec2 shade_pos = mul(frame.af.screen_to_shade, Vec3(screen_pos.xy, 1)); Vec2 half_world_dims = Vec2(P_WorldPitch, P_WorldPitch) * 0.5; - Vec2 world_bounds_screen_p0 = mul(params.af.world_to_screen, Vec3(-half_world_dims.xy, 1)); - Vec2 world_bounds_screen_p1 = mul(params.af.world_to_screen, Vec3(half_world_dims.xy, 1)); + Vec2 world_bounds_screen_p0 = mul(frame.af.world_to_screen, Vec3(-half_world_dims.xy, 1)); + Vec2 world_bounds_screen_p1 = mul(frame.af.world_to_screen, Vec3(half_world_dims.xy, 1)); b32 is_in_world = all(cell_pos >= 0) && all(cell_pos < countof(cells)); P_TileKind tile = tiles.Load(Vec3(tile_pos, 0)); - P_TileKind equipped_tile = params.equipped_tile; + P_TileKind equipped_tile = frame.equipped_tile; ////////////////////////////// //- World color @@ -432,7 +433,7 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input) } else if (tile != P_TileKind_Empty) { - V_TileDesc tile_desc = params.tile_descs[tile]; + V_TileDesc tile_desc = frame.tile_descs[tile]; Texture2D tile_tex = G_Dereference(tile_desc.tex); Vec2 tile_samp_uv = lerp(tile_desc.tex_slice_uv.p0, tile_desc.tex_slice_uv.p1, frac(world_pos)); tile_color = tile_tex.SampleLevel(clamp_sampler, tile_samp_uv, 0); @@ -525,18 +526,18 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input) //- Tile selection overlay Vec4 selection_color = 0; - if (params.has_mouse_focus && params.selection_mode == V_SelectionMode_Tile) + if (frame.has_mouse_focus && frame.selection_mode == V_SelectionMode_Tile) { Vec4 border_color = LinearFromSrgb(Vec4(1, 1, 1, 1)); // Vec4 inner_color = LinearFromSrgb(Vec4(0.4, 0.4, 0.4, 0.25)); Vec4 inner_color = LinearFromSrgb(Vec4(0.4, 0.8, 0.4, 0.6)); - Rng2 screen_selection = params.screen_selection; - Rng2 world_selection = params.world_selection; + Rng2 screen_selection = frame.screen_selection; + Rng2 world_selection = frame.world_selection; Rng2 tile_selection; - tile_selection.p0 = floor(mul(params.af.world_to_tile, Vec3(world_selection.p0, 1))); - tile_selection.p1 = ceil(mul(params.af.world_to_tile, Vec3(world_selection.p1, 1))); + tile_selection.p0 = floor(mul(frame.af.world_to_tile, Vec3(world_selection.p0, 1))); + tile_selection.p1 = ceil(mul(frame.af.world_to_tile, Vec3(world_selection.p1, 1))); f32 dist = 100000000; dist = min(dist, screen_pos.x - screen_selection.p0.x); @@ -580,8 +581,8 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input) if (V_ShaderConst_GpuFlags & V_GpuFlag_DebugDraw) { const Vec4 line_color = LinearFromSrgb(Vec4(1, 1, 1, 0.1)); - Vec2 line_screen_p0 = mul(params.af.world_to_screen, Vec3(floor(world_pos), 1)); - Vec2 line_screen_p1 = mul(params.af.world_to_screen, Vec3(ceil(world_pos), 1)); + Vec2 line_screen_p0 = mul(frame.af.world_to_screen, Vec3(floor(world_pos), 1)); + Vec2 line_screen_p1 = mul(frame.af.world_to_screen, Vec3(ceil(world_pos), 1)); f32 line_dist = 100000; line_dist = min(line_dist, abs(screen_pos.x - line_screen_p0.x)); line_dist = min(line_dist, abs(screen_pos.x - line_screen_p1.x)); @@ -599,7 +600,7 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input) const Vec4 x_axis_color = LinearFromSrgb(Vec4(0.75, 0, 0, 1)); const Vec4 y_axis_color = LinearFromSrgb(Vec4(0, 0.75, 0, 1)); - Vec2 zero_screen = mul(params.af.world_to_screen, Vec3(0, 0, 1)); + Vec2 zero_screen = mul(frame.af.world_to_screen, Vec3(0, 0, 1)); f32 x_dist = abs(screen_pos.x - zero_screen.x); f32 y_dist = abs(screen_pos.y - zero_screen.y); if (y_dist <= half_thickness) @@ -637,7 +638,7 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input) Vec4 crosshair_color = 0; { - f32 dist = length(params.screen_crosshair - screen_pos); + f32 dist = length(frame.screen_crosshair - screen_pos); if (dist < 4) { // Adaptive crosshair color based on underlying luminance @@ -686,15 +687,15 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input) VertexShader(V_DVertVS, V_DVertPSInput) { - V_GpuParams params = G_Dereference(V_ShaderConst_Params)[0]; - StructuredBuffer verts = G_Dereference(params.shape_verts); + V_SharedFrame frame = G_Dereference(V_ShaderConst_Frame)[0]; + StructuredBuffer verts = G_Dereference(frame.dverts); V_DVert vert = verts[SV_VertexID]; Vec2 screen_pos = vert.pos; V_DVertPSInput result; - result.sv_position = Vec4(NdcFromPos(screen_pos, params.screen_dims).xy, 0, 1); + result.sv_position = Vec4(NdcFromPos(screen_pos, frame.screen_dims).xy, 0, 1); result.color_lin = vert.color_lin; return result; } diff --git a/src/pp/pp_vis/pp_vis_shared.cgh b/src/pp/pp_vis/pp_vis_shared.cgh index d7fe2b61..bc2559dc 100644 --- a/src/pp/pp_vis/pp_vis_shared.cgh +++ b/src/pp/pp_vis/pp_vis_shared.cgh @@ -4,7 +4,7 @@ // #define V_ParticlesCap Mebi(16) //////////////////////////////////////////////////////////// -//~ Constant types +//~ State types Enum(V_GpuFlag) { @@ -13,9 +13,14 @@ Enum(V_GpuFlag) }; G_DeclConstant(V_GpuFlag, V_ShaderConst_GpuFlags, 0); -G_DeclConstant(G_RWStructuredBufferRef, V_ShaderConst_State, 1); -G_DeclConstant(G_StructuredBufferRef, V_ShaderConst_Params, 2); -G_DeclConstant(G_Texture3DRef, V_ShaderConst_NoiseTex, 3); +G_DeclConstant(G_StructuredBufferRef, V_ShaderConst_Frame, 1); +G_DeclConstant(G_Texture3DRef, V_ShaderConst_NoiseTex, 2); + +Struct(V_TileDesc) +{ + G_Texture2DRef tex; + Rng2 tex_slice_uv; +}; Enum(V_SelectionMode) { @@ -23,6 +28,12 @@ Enum(V_SelectionMode) V_SelectionMode_Tile, }; +Enum(V_EditMode) +{ + V_EditMode_None, + V_EditMode_Tile, +}; + Struct(V_Affines) { // World <-> screen @@ -46,64 +57,91 @@ Struct(V_Affines) Affine tile_to_world; }; -Struct(V_TileDesc) +Struct(V_SharedFrame) { - G_Texture2DRef tex; - Rng2 tex_slice_uv; -}; + //- Time -Struct(V_GpuState) -{ - // u32 particle_seq; // Atomic monotonically increasing allocation counter sequence for particle ring buffer - i32 _; -}; - -Struct(V_GpuParams) -{ - // TODO: Use simulation dt + i64 tick; + i64 time_ns; + i64 dt_ns; f32 dt; - u64 tick; - u64 seed; - V_Affines af; - V_SelectionMode selection_mode; - P_TileKind equipped_tile; + //- Modes + b32 tiles_dirty; + b32 should_clear_particles; + + b32 is_editing; + b32 ui_debug; + b32 show_console; + b32 is_selecting; + b32 is_panning; b32 has_mouse_focus; b32 has_keyboard_focus; + + //- Editor state + + V_EditMode edit_mode; + P_TileKind equipped_tile; + V_SelectionMode selection_mode; + Vec2 world_selection_start; + Vec2 edit_camera_pos; + f32 edit_camera_zoom; + + //- Camera + + i32 zooms; + f32 camera_lerp_rate; + Vec2 camera_pos; + f32 camera_zoom; + + //- Dims + + Vec2 screen_dims; + Vec2 shade_dims; + + //- Affines + + V_Affines af; + + //- Cursor + Vec2 screen_cursor; Vec2 shade_cursor; Vec2 world_cursor; - Rng2 screen_selection; Rng2 shade_selection; Rng2 world_selection; + //- Crosshair + Vec2 screen_crosshair; Vec2 shade_crosshair; Vec2 world_crosshair; - Vec2 camera_pos; - f32 camera_zoom; + //- Control + + Vec2 move; + Vec2 look; + f32 fire_held; + f32 fire_presses; + + //- Gpu data G_SamplerStateRef pt_clamp_sampler; G_SamplerStateRef pt_wrap_sampler; - Vec2 screen_dims; + V_TileDesc tile_descs[P_TileKind_COUNT]; + G_Texture2DRef tiles; - Vec2 shade_dims; + G_Texture2DRef screen_ro; G_Texture2DRef shade_ro; G_RWTexture2DRef shade_rw; G_Texture2DRef albedo_ro; G_RWTexture2DRef albedo_rw; - G_Texture2DRef tiles; - G_StructuredBufferRef quads; - G_StructuredBufferRef shape_verts; - u32 emitters_count; G_StructuredBufferRef emitters; - G_RWStructuredBufferRef particles; b32 should_clear_stains; @@ -111,7 +149,8 @@ Struct(V_GpuParams) G_RWTexture2DRef stains; G_RWTexture2DRef drynesses; - V_TileDesc tile_descs[P_TileKind_COUNT]; + G_StructuredBufferRef dverts; + G_StructuredBufferRef quads; }; //////////////////////////////////////////////////////////// @@ -202,7 +241,6 @@ Struct(V_DVert) Vec4 color_lin; }; - //////////////////////////////////////////////////////////// //~ Helpers diff --git a/src/sprite/sprite.c b/src/sprite/sprite.c index 014100c3..f3d2c352 100644 --- a/src/sprite/sprite.c +++ b/src/sprite/sprite.c @@ -313,7 +313,7 @@ SPR_Sprite SPR_SpriteFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 if (slice_ready) { result.tex_dims = Vec2FromVec(slice->atlas->dims); - result.tex = slice->atlas->tex_ref; + result.tex = slice->atlas->tex; result.tex_rect = RNG2(slice->atlas_pos, AddVec2(slice->atlas_pos, DimsFromRng2(slice->canvas_rect))); } else @@ -425,14 +425,14 @@ void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame) atlas->dims = VEC2I32(atlas_size, atlas_size); { G_ArenaHandle gpu_perm = G_PermArena(); - atlas->tex = G_PushTexture2D( + atlas->tex_res = G_PushTexture2D( gpu_perm, cl, G_Format_R8G8B8A8_Unorm_Srgb, atlas->dims, G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present, .name = Lit("Sprite atlas") ); - atlas->tex_ref = G_PushTexture2DRef(gpu_perm, atlas->tex); + atlas->tex = G_PushTexture2DRef(gpu_perm, atlas->tex_res); } SllStackPush(SPR.first_atlas, atlas); ++SPR.atlases_count; @@ -466,7 +466,7 @@ void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame) // Copy to atlas G_CopyCpuToTexture( cl, - atlas->tex, VEC3I32(atlas_pos.x, atlas_pos.y, 0), + atlas->tex_res, VEC3I32(atlas_pos.x, atlas_pos.y, 0), composite.pixels, VEC3I32(slice_dims.x, slice_dims.y, 1), RNG3I32( VEC3I32(0, 0, 0), diff --git a/src/sprite/sprite.h b/src/sprite/sprite.h index 018d8733..5bc087db 100644 --- a/src/sprite/sprite.h +++ b/src/sprite/sprite.h @@ -15,8 +15,8 @@ Struct(SPR_Atlas) SPR_Atlas *next; Vec2I32 dims; - G_ResourceHandle tex; - G_Texture2DRef tex_ref; + G_ResourceHandle tex_res; + G_Texture2DRef tex; Vec2I32 cur_pos; i32 cur_row_height; }; diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 41fe34b9..536cbaca 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -380,7 +380,7 @@ Struct(UI_Frame) i64 tick; i64 time_ns; i64 dt_ns; - f64 dt; + f32 dt; // Control Vec2 cursor_pos;