From e3ae1a789fd374817d9925e85feb7bf660a95d5d Mon Sep 17 00:00:00 2001 From: jacob Date: Sun, 1 Feb 2026 21:50:22 -0600 Subject: [PATCH] draw crosshair via shader sdf --- src/base/base_shader.gh | 10 ++++ src/gpu/gpu_dx12/gpu_dx12_core.c | 47 ++++++++------- src/meta/meta.c | 6 +- src/pp/pp_vis/pp_vis_core.c | 98 +++++++++++++++++++------------- src/pp/pp_vis/pp_vis_core.h | 7 ++- src/pp/pp_vis/pp_vis_gpu.g | 62 ++++++++++++++------ src/pp/pp_vis/pp_vis_shared.cgh | 5 ++ 7 files changed, 153 insertions(+), 82 deletions(-) diff --git a/src/base/base_shader.gh b/src/base/base_shader.gh index 6149c852..2b52504c 100644 --- a/src/base/base_shader.gh +++ b/src/base/base_shader.gh @@ -163,6 +163,16 @@ Inline Vec4 LinearFromSrgb(Vec4 srgb) return result; } +Inline f32 LuminanceFromColor(Vec4 v) +{ + return 0.2126 * v.r + 0.7152 * v.g + 0.0722 * v.b; +}; + +Inline Vec4 InvertColor(Vec4 v) +{ + return Vec4(Vec3(1, 1, 1) - v.rgb, v.a); +}; + Inline Vec4 Premul(Vec4 v) { Vec4 result; diff --git a/src/gpu/gpu_dx12/gpu_dx12_core.c b/src/gpu/gpu_dx12/gpu_dx12_core.c index 67027293..7e081408 100644 --- a/src/gpu/gpu_dx12/gpu_dx12_core.c +++ b/src/gpu/gpu_dx12/gpu_dx12_core.c @@ -908,7 +908,7 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle ////////////////////////////// //- Initialize heap info - b32 can_reuse = 0; + b32 can_reuse = 1; D3D12_HEAP_FLAGS heap_flags = 0; D3D12_HEAP_PROPERTIES heap_props = Zi; @@ -931,7 +931,6 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle } else { - can_reuse = 1; heap_flags |= D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; } // Heap props @@ -2389,11 +2388,11 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) { if (G_D12.pending_releases.last) { - G_D12.pending_releases.last->next = cl->releases.last; + G_D12.pending_releases.last->next = cl->releases.first; } else { - G_D12.pending_releases.first = cl->releases.last; + G_D12.pending_releases.first = cl->releases.first; } G_D12.pending_releases.last = cl->releases.last; } @@ -2664,11 +2663,14 @@ void G_MemorySyncEx(G_CommandListHandle cl_handle, G_MemoryBarrierDesc desc) void G_Compute(G_CommandListHandle cl_handle, ComputeShader cs, Vec3I32 groups) { - G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle); - G_D12_Cmd *cmd = G_D12_PushCmd(cl); - cmd->kind = G_D12_CmdKind_Compute; - cmd->compute.cs = cs; - cmd->compute.groups = groups; + if (groups.x > 0 && groups.y > 0 && groups.z > 0) + { + G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle); + G_D12_Cmd *cmd = G_D12_PushCmd(cl); + cmd->kind = G_D12_CmdKind_Compute; + cmd->compute.cs = cs; + cmd->compute.groups = groups; + } } //- Rasterize @@ -2682,20 +2684,23 @@ void G_Rasterize( G_RasterMode raster_mode ) { - G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle); - G_D12_Cmd *cmd = G_D12_PushCmd(cl); - cmd->kind = G_D12_CmdKind_Rasterize; - cmd->rasterize.vs = vs; - cmd->rasterize.ps = ps; - cmd->rasterize.instances_count = instances_count; - cmd->rasterize.index_buffer_desc = index_buffer; - for (u32 rt_idx = 0; rt_idx < MinU32(render_targets_count, G_MaxRenderTargets); ++rt_idx) + if (instances_count > 0 && index_buffer.index_count > 0) { - cmd->rasterize.render_target_descs[rt_idx] = render_targets[rt_idx]; + G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle); + G_D12_Cmd *cmd = G_D12_PushCmd(cl); + cmd->kind = G_D12_CmdKind_Rasterize; + cmd->rasterize.vs = vs; + cmd->rasterize.ps = ps; + cmd->rasterize.instances_count = instances_count; + cmd->rasterize.index_buffer_desc = index_buffer; + for (u32 rt_idx = 0; rt_idx < MinU32(render_targets_count, G_MaxRenderTargets); ++rt_idx) + { + cmd->rasterize.render_target_descs[rt_idx] = render_targets[rt_idx]; + } + cmd->rasterize.viewport = viewport; + cmd->rasterize.scissor = scissor; + cmd->rasterize.raster_mode = raster_mode; } - cmd->rasterize.viewport = viewport; - cmd->rasterize.scissor = scissor; - cmd->rasterize.raster_mode = raster_mode; } //- Clear diff --git a/src/meta/meta.c b/src/meta/meta.c index 0d769e74..e0b3753e 100644 --- a/src/meta/meta.c +++ b/src/meta/meta.c @@ -536,7 +536,7 @@ void BuildEntryPoint(WaveLaneCtx *lane) : kind == M_EntryKind_ComputeShader ? Lit("ComputeShader") : Lit(""); String shader_name = arg0_tok->s; - u64 shader_resource_hash = HashStringEx(shader_store_hash, shader_name); + u64 shader_resource_hash = HashStringEx(shader_store_hash, StringF(perm, "%F.dxil", FmtString(shader_name))); String line = StringF(perm, "%F %F = { 0x%F };", FmtString(shader_type), FmtString(shader_name), FmtHex(shader_resource_hash)); PushStringToList(perm, &c_shader_lines, line); } @@ -660,7 +660,7 @@ void BuildEntryPoint(WaveLaneCtx *lane) { 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"))) + if (StringEndsWith(file, Lit(".dxil"))) { OS_Rm(n->s); } @@ -874,7 +874,7 @@ void BuildEntryPoint(WaveLaneCtx *lane) { String shader_name = e->name; GpuObj *gpu_obj = &Build.gpu_objs.array[gpu_obj_idx]; - String out_file = StringF(perm, "%F/%F", FmtString(shader_store_name), FmtString(e->name)); + 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") diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index 29c32db6..5cc3f42a 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -831,16 +831,7 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Compute movement & look - f32 look_radius = 0; - { - Vec2 world_screen_dims = MulAffineBasisVec2(prev_frame->af.screen_to_world, prev_frame->screen_dims); - // look_radius = MinF32(world_screen_dims.x, world_screen_dims.y) * 0.5; - look_radius = MinF32(world_screen_dims.x, world_screen_dims.y) * 0.75; - - // FIXME: Lower - f32 max_look_radius = 10; - look_radius = ClampF32(look_radius, 1, max_look_radius); - } + f32 look_radius = 5; if (!frame->is_editing && !frame->palette.is_showing) { @@ -961,30 +952,51 @@ void V_TickForever(WaveLaneCtx *lane) // } // } + + + + + // Vec2 look_ratio = Zi; + // { + // Vec2 max_look = Vec2WithLen(frame->look, look_radius); + + // Vec2 look_ratio_of_radius = DivVec2Vec2(frame->look, Vec2WithLen(frame->look, look_radius)); + + // look_ratio = look_ratio_of_radius; + + // // Vec2 screen_look = MulAffineVec2(frame->af.world_to_screen, frame->look); + // // Vec2 screen_max_look = MulAffineVec2(frame->af.world_to_screen, frame->look) + + // // look_ratio.x = screen_look.x / frame->screen_dims.x; + // // look_ratio.x = frame->look.x / look_radius; + + + // if (IsNan(look_ratio.x) || IsNan(look_ratio.y)) + // { + // look_ratio = VEC2(0, 0); + // } + + // // look_ratio = MulVec2(look_ratio, 0.5); + // look_ratio = VEC2(0.5, 0.5); + // } + + + + + + + Vec2 look_ratio = Zi; { - Vec2 max_look = Vec2WithLen(frame->look, look_radius); - - Vec2 look_ratio_of_radius = DivVec2Vec2(frame->look, Vec2WithLen(frame->look, look_radius)); - - look_ratio = look_ratio_of_radius; - - // Vec2 screen_look = MulAffineVec2(frame->af.world_to_screen, frame->look); - // Vec2 screen_max_look = MulAffineVec2(frame->af.world_to_screen, frame->look) - - // look_ratio.x = screen_look.x / frame->screen_dims.x; - // look_ratio.x = frame->look.x / look_radius; - - - if (IsNan(look_ratio.x) || IsNan(look_ratio.y)) - { - look_ratio = VEC2(0, 0); - } - - // look_ratio = MulVec2(look_ratio, 0.5); look_ratio = VEC2(0.5, 0.5); + // look_ratio = VEC2(0.5, 0.5 * (16.0 / 9.0)); } + + + + + P_Ent *player = P_EntFromKey(local_world->last_frame, V.player_key); P_Ent *guy = P_EntFromKey(local_world->last_frame, player->guy); Vec2 guy_center = P_WorldShapeFromEnt(guy).centroid; @@ -2154,11 +2166,13 @@ void V_TickForever(WaveLaneCtx *lane) // f32 cross_dist = 1.0; f32 cross_dist = Vec2Len(look) - Vec2Len(SubVec2(desired_fire_pos, desired_ent_to_world_af.og)); - Vec2 cross = AddVec2(desired_fire_pos, MulVec2(look_rot, cross_dist)); + frame->world_crosshair = AddVec2(desired_fire_pos, MulVec2(look_rot, cross_dist)); + frame->screen_crosshair = MulAffineVec2(frame->af.world_to_screen, frame->world_crosshair); + frame->shade_crosshair = MulAffineVec2(frame->af.world_to_shade, frame->world_crosshair); // P_DebugDrawPoint(AddVec2(MulAffineVec2(frame->af.screen_to_world, MulVec2(frame->screen_dims, 0.5)), look), Color_Red); // P_DebugDrawPoint(AddVec2(desired_ent_to_world_af.og, look), Color_Red); - P_DebugDrawPoint(cross, Color_Green); + // P_DebugDrawPoint(frame->crosshair, Color_Green); } @@ -4507,6 +4521,10 @@ void V_TickForever(WaveLaneCtx *lane) 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; @@ -4645,14 +4663,6 @@ void V_TickForever(WaveLaneCtx *lane) G_DumbGlobalMemorySync(frame->cl); } - ////////////////////////////// - //- Transition G-buffers - - { - // Make albedo readonly - G_DumbMemoryLayoutSync(frame->cl, albedo_target, G_Layout_DirectQueue_ShaderRead); - } - ////////////////////////////// //- Shading pass @@ -4662,11 +4672,19 @@ void V_TickForever(WaveLaneCtx *lane) G_Compute(frame->cl, V_ShadeCS, V_ThreadGroupSizeFromTexSize(frame->shade_dims)); } + ////////////////////////////// + //- Transition G-buffers to readonly + + { + G_DumbMemoryLayoutSync(frame->cl, albedo_target, G_Layout_DirectQueue_ShaderRead); + G_DumbMemoryLayoutSync(frame->cl, shade_target, G_Layout_DirectQueue_ShaderRead); + } + + ////////////////////////////// //- Composite pass G_DumbMemoryLayoutSync(frame->cl, screen_target, G_Layout_DirectQueue_RenderTargetWrite); - G_DumbMemoryLayoutSync(frame->cl, shade_target, G_Layout_DirectQueue_ShaderRead); { G_Rasterize( diff --git a/src/pp/pp_vis/pp_vis_core.h b/src/pp/pp_vis/pp_vis_core.h index 97a2c852..fd23ae13 100644 --- a/src/pp/pp_vis/pp_vis_core.h +++ b/src/pp/pp_vis/pp_vis_core.h @@ -273,7 +273,7 @@ Struct(V_Frame) // affines; V_Affines af; - // Cursors + // Cursor Vec2 screen_cursor; Vec2 shade_cursor; Vec2 world_cursor; @@ -281,6 +281,11 @@ Struct(V_Frame) 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; diff --git a/src/pp/pp_vis/pp_vis_gpu.g b/src/pp/pp_vis/pp_vis_gpu.g index 0c878178..644df199 100644 --- a/src/pp/pp_vis/pp_vis_gpu.g +++ b/src/pp/pp_vis/pp_vis_gpu.g @@ -746,25 +746,25 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input) } ////////////////////////////// - //- Grid overlay + //- Grid - Vec4 overlay_color = 0; + Vec4 grid_color = 0; if (is_in_world_bounds) { // Grid outline if (V_ShaderConst_GpuFlags & V_GpuFlag_DebugDraw) { - const Vec4 grid_color = LinearFromSrgb(Vec4(1, 1, 1, 0.1)); - Vec2 grid_screen_p0 = mul(params.af.world_to_screen, Vec3(floor(world_pos), 1)); - Vec2 grid_screen_p1 = mul(params.af.world_to_screen, Vec3(ceil(world_pos), 1)); - f32 grid_dist = 100000; - grid_dist = min(grid_dist, abs(screen_pos.x - grid_screen_p0.x)); - grid_dist = min(grid_dist, abs(screen_pos.x - grid_screen_p1.x)); - grid_dist = min(grid_dist, abs(screen_pos.y - grid_screen_p0.y)); - grid_dist = min(grid_dist, abs(screen_pos.y - grid_screen_p1.y)); - if (grid_dist <= half_thickness * 0.5) + 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)); + 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)); + line_dist = min(line_dist, abs(screen_pos.y - line_screen_p0.y)); + line_dist = min(line_dist, abs(screen_pos.y - line_screen_p1.y)); + if (line_dist <= half_thickness * 0.5) { - overlay_color = grid_color; + grid_color = line_color; } } @@ -779,11 +779,11 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input) f32 y_dist = abs(screen_pos.y - zero_screen.y); if (y_dist <= half_thickness) { - overlay_color = x_axis_color; + grid_color = x_axis_color; } else if (x_dist <= half_thickness) { - overlay_color = y_axis_color; + grid_color = y_axis_color; } } @@ -797,12 +797,27 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input) bounds_dist = min(bounds_dist, abs(screen_pos.y - world_bounds_screen_p1.y)); if (bounds_dist <= half_thickness) { - overlay_color = bounds_color; + grid_color = bounds_color; } } // Premultiply - overlay_color.rgb *= overlay_color.a; + grid_color.rgb *= grid_color.a; + } + + ////////////////////////////// + //- Crosshair + + Vec4 crosshair_color = 0; + { + f32 screen_dist = length(params.screen_crosshair - screen_pos); + + if (screen_dist < 5) + { + crosshair_color = Color_White; + } + + crosshair_color.rgb *= crosshair_color.a; } ////////////////////////////// @@ -813,7 +828,20 @@ PixelShader(V_CompositePS, V_CompositePSOutput, V_CompositePSInput input) result = BlendPremul(albedo_color, result); result = BlendPremul(particle_color, result); result = BlendPremul(selection_color, result); - result = BlendPremul(overlay_color, result); + result = BlendPremul(grid_color, result); + + // Adaptively blend crosshair + { + f32 luminance = LuminanceFromColor(result); + f32 adaptive_threshold = 0.5; + Vec4 adapted_crosshair_color = crosshair_color; + if (luminance > adaptive_threshold) + { + adapted_crosshair_color = InvertColor(Unpremul(crosshair_color)); + adapted_crosshair_color = Premul(adapted_crosshair_color); + } + result = BlendPremul(adapted_crosshair_color, result); + } result = Unpremul(result); diff --git a/src/pp/pp_vis/pp_vis_shared.cgh b/src/pp/pp_vis/pp_vis_shared.cgh index 93823af8..d7fe2b61 100644 --- a/src/pp/pp_vis/pp_vis_shared.cgh +++ b/src/pp/pp_vis/pp_vis_shared.cgh @@ -74,10 +74,15 @@ Struct(V_GpuParams) Vec2 screen_cursor; Vec2 shade_cursor; Vec2 world_cursor; + Rng2 screen_selection; Rng2 shade_selection; Rng2 world_selection; + Vec2 screen_crosshair; + Vec2 shade_crosshair; + Vec2 world_crosshair; + Vec2 camera_pos; f32 camera_zoom;