From 78f4677cdbd9dc256ed48d2a31192b6e957e832a Mon Sep 17 00:00:00 2001 From: jacob Date: Mon, 30 Mar 2026 06:51:40 -0500 Subject: [PATCH] profiler ui wip --- src/gpu/gpu_core.h | 4 +- src/gpu/gpu_dx12/gpu_dx12_core.c | 88 +++++++++++----- src/gpu/gpu_dx12/gpu_dx12_core.h | 2 +- src/meta/meta_lay.c | 2 +- src/pp/pp_vis/pp_vis.lay | 11 +- src/pp/pp_vis/pp_vis_core.c | 176 ++++++++++++++++++++++--------- src/pp/pp_vis/pp_vis_core.h | 13 +++ src/pp/pp_vis/pp_vis_gpu.g | 115 ++++++++++++-------- src/pp/pp_vis/pp_vis_gpu.gh | 3 + src/pp/pp_vis/pp_vis_shared.cgh | 82 ++++++-------- 10 files changed, 309 insertions(+), 187 deletions(-) diff --git a/src/gpu/gpu_core.h b/src/gpu/gpu_core.h index e366505e..32763226 100644 --- a/src/gpu/gpu_core.h +++ b/src/gpu/gpu_core.h @@ -323,8 +323,8 @@ Enum(G_MemoryFlag) G_MemoryFlag_AllowTextureRW = (1 << 1), G_MemoryFlag_AllowTextureDraw = (1 << 2), G_MemoryFlag_AllowTextureDepthStencil = (1 << 3), - G_MemoryFlag_CpuRead = (1 << 4), - G_MemoryFlag_CpuWrite = (1 << 5), + G_MemoryFlag_HostRead = (1 << 4), + G_MemoryFlag_HostWrite = (1 << 5), G_MemoryFlag_ForceNoReuse = (1 << 6), }; diff --git a/src/gpu/gpu_dx12/gpu_dx12_core.c b/src/gpu/gpu_dx12/gpu_dx12_core.c index 9c57103b..6ce60779 100644 --- a/src/gpu/gpu_dx12/gpu_dx12_core.c +++ b/src/gpu/gpu_dx12/gpu_dx12_core.c @@ -587,7 +587,7 @@ void G_Bootstrap(void) queue->print_readback_buffer = G_PushStructs( cl, gpu_perm, u8, queue->print_buffer_size, - .flags = G_MemoryFlag_CpuRead, + .flags = G_MemoryFlag_HostRead, .name = Lit("Debug print readback buffer") ); } @@ -1296,11 +1296,11 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle { G_D12_ResourceHeapKind heap_kind = G_D12_ResourceHeapKind_Gpu; // Heap flags - if (flags & G_MemoryFlag_CpuRead) + if (flags & G_MemoryFlag_HostRead) { heap_kind = G_D12_ResourceHeapKind_CpuWriteBack; } - else if (flags & G_MemoryFlag_CpuWrite) + else if (flags & G_MemoryFlag_HostWrite) { heap_kind = G_D12_ResourceHeapKind_CpuWriteCombined; } @@ -1388,6 +1388,8 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle //- Check for reset-resource reusability // Pop reset resource + u64 old_buffer_stride = 0; + u64 old_buffer_offset = 0; resource = gpu_arena->reset_resources.first; if (resource) { @@ -1398,6 +1400,8 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle D3D12_RESOURCE_DESC1 compare_d3d_desc = Zi; CopyStruct(&reset_d3d_desc, &resource->d3d_desc); CopyStruct(&compare_d3d_desc, &reset_d3d_desc); + old_buffer_stride = resource->buffer_element_stride; + old_buffer_offset = resource->buffer_element_offset; // Buffers can be reused if size fits if (d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && reset_d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) @@ -1408,9 +1412,30 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle } } + + + + + + + + // FIXME: Remove this + if (memory_desc.buffer.stride == 52) + { + DEBUGBREAKABLE; + } + + + + + + + + // TODO: Less stringent reuse constraints. We could even create textures as placed resources and reset their underlying heaps. can_reuse = can_reuse && MatchStruct(&compare_d3d_desc, &d3d_desc); - if (!can_reuse) + b32 can_reuse_descriptor = can_reuse && (!is_buffer || (MaxU64(memory_desc.buffer.stride, 1) == old_buffer_stride)); + if (!can_reuse || !can_reuse_descriptor) { // Push releasable to command list { @@ -1432,10 +1457,17 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle } ZeroStruct(release); SllQueuePush(cl->releases.first, cl->releases.last, release); - release->d3d_resource = resource->d3d_resource; - release->descriptor = resource->gpu_descriptor; + if (!can_reuse_descriptor) + { + release->descriptor = resource->gpu_descriptor; + resource->gpu_descriptor = 0; + } + if (!can_reuse) + { + release->d3d_resource = resource->d3d_resource; + ZeroStruct(resource); + } } - ZeroStruct(resource); } } else @@ -1513,33 +1545,33 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle Atomic64FetchAdd(&G_D12.cumulative_nonreuse_count, 1); resource->uid = Atomic64FetchAdd(&G_D12.resource_creation_gen.v, d3d_desc.MipLevels); } + } - if (is_buffer) - { - resource->buffer_element_offset = 0; - resource->buffer_element_stride = MaxU64(memory_desc.buffer.stride, 1); - resource->buffer_element_count = buffer_size / resource->buffer_element_stride; - resource->buffer_gpu_address = ID3D12Resource_GetGPUVirtualAddress(resource->d3d_resource); - } - else if (is_texture) - { - resource->is_texture = 1; - resource->texture_format = memory_desc.texture.format; - resource->texture_dims = memory_desc.texture.dims; - resource->texture_mips = RNGI32(0, d3d_desc.MipLevels - 1); - Atomic32Set(&resource->texture_family, initial_family); - } - else if (is_sampler) - { - resource->sampler_desc = memory_desc.sampler; - } + if (is_buffer) + { + resource->buffer_element_offset = 0; + resource->buffer_element_stride = MaxU64(memory_desc.buffer.stride, 1); + resource->buffer_element_count = buffer_size / resource->buffer_element_stride; + resource->buffer_gpu_address = ID3D12Resource_GetGPUVirtualAddress(resource->d3d_resource); + } + else if (is_texture) + { + resource->is_texture = 1; + resource->texture_format = memory_desc.texture.format; + resource->texture_dims = memory_desc.texture.dims; + resource->texture_mips = RNGI32(0, d3d_desc.MipLevels - 1); + Atomic32Set(&resource->texture_family, initial_family); + } + else if (is_sampler) + { + resource->sampler_desc = memory_desc.sampler; } if (should_map && !resource->buffer_cpu_address) { D3D12_RANGE zero_read_range = Zi; D3D12_RANGE *read_range_arg = &zero_read_range; - if (memory_desc.buffer.flags & G_MemoryFlag_CpuRead) + if (memory_desc.buffer.flags & G_MemoryFlag_HostRead) { // Specify NULL read range to signal to D3D12 that any part of address range may be read by CPU read_range_arg = 0; @@ -2046,7 +2078,7 @@ G_D12_StagingRegionNode *G_D12_PushStagingRegion(G_D12_CmdList *cl, u64 size) ring->buffer = G_PushStructs( G_D12_MakeHandle(G_CommandListHandle, cl), gpu_arena_handle, u8, new_ring_size, - .flags = G_MemoryFlag_CpuWrite + .flags = G_MemoryFlag_HostWrite ); ring->base = G_Deref(ring->buffer, u8); } diff --git a/src/gpu/gpu_dx12/gpu_dx12_core.h b/src/gpu/gpu_dx12/gpu_dx12_core.h index 8a0bc5fb..48f65f9c 100644 --- a/src/gpu/gpu_dx12/gpu_dx12_core.h +++ b/src/gpu/gpu_dx12/gpu_dx12_core.h @@ -84,9 +84,9 @@ Struct(G_D12_Resource) // Buffer info D3D12_GPU_VIRTUAL_ADDRESS buffer_gpu_address; void *buffer_cpu_address; - u64 buffer_element_offset; u64 buffer_element_stride; u64 buffer_element_count; + u64 buffer_element_offset; // Texture info b32 is_texture; diff --git a/src/meta/meta_lay.c b/src/meta/meta_lay.c index b8366c59..2b7f7bba 100644 --- a/src/meta/meta_lay.c +++ b/src/meta/meta_lay.c @@ -174,7 +174,7 @@ M_TokenFileList M_TokensFromSrcDirs(Arena *arena, StringList src_dirs) case TokenizerMode_SingleLineComment: { - if (t[p] == '\n') + if (t[p] == '\n' || ((p + 1) < l && t[p + 1] == '\n')) { // End single line comment mode = TokenizerMode_None; p += 1; diff --git a/src/pp/pp_vis/pp_vis.lay b/src/pp/pp_vis/pp_vis.lay index e1774ae4..7a3ae641 100644 --- a/src/pp/pp_vis/pp_vis.lay +++ b/src/pp/pp_vis/pp_vis.lay @@ -15,16 +15,7 @@ ////////////////////////////// //- Resources - - - -// FIXME: Remove this -@ComputeShader V_BlaCS (128, 1) - - - - - +@ComputeShader V_ProfilerGraphCS (128, 1) // Vertical group dims so that sample access is uniform @ComputeShader V_PrepareShadeCS (16, 16) @ComputeShader V_PrepareCellsCS (16, 16) @ComputeShader V_BackdropDownCS (16, 16) diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index 6cd77785..d0e62810 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -730,6 +730,7 @@ void V_TickForever(WaveLaneCtx *lane) Vec2I32 cells_dims = VEC2I32(P_CellsPitch, P_CellsPitch); //- Init gpu state + G_BufferRef gpu_profiler_frames = Zi; G_TextureRef gpu_tiles = Zi; G_BufferRef gpu_particles = Zi; G_TextureRef gpu_particle_cells[V_ParticleLayer_COUNT]; @@ -741,6 +742,14 @@ void V_TickForever(WaveLaneCtx *lane) { G_CommandListHandle cl = G_PrepareCommandList(G_QueueKind_Direct); { + //- Init profiler frames buffer + gpu_profiler_frames = G_PushStructs( + cl, gpu_perm, + V_ProfilerFrame, V_ProfilerFramesCap, + .flags = G_MemoryFlag_HostRead | G_MemoryFlag_HostWrite, + .name = Lit("Profiler frames"), + ); + V.profiler_frames = G_Deref(gpu_profiler_frames, V_ProfilerFrame); //- Init tile map texture gpu_tiles = G_PushTexture2D( cl, gpu_perm, @@ -900,6 +909,7 @@ void V_TickForever(WaveLaneCtx *lane) CopyBytes(frame->real_held_buttons, prev_frame->real_held_buttons, sizeof(frame->real_held_buttons)); CopyBytes(frame->held_buttons, prev_frame->held_buttons, sizeof(frame->held_buttons)); frame->palette = prev_frame->palette; + frame->profiler = prev_frame->profiler; frame->is_editing = prev_frame->is_editing; frame->ui_debug = prev_frame->ui_debug; frame->show_console = prev_frame->show_console; @@ -2556,14 +2566,14 @@ void V_TickForever(WaveLaneCtx *lane) frame->shade_cursor = MulAffineVec2(frame->af.screen_to_shade, frame->screen_cursor); frame->world_cursor = MulAffineVec2(frame->af.screen_to_world, frame->screen_cursor); - b32 show_editor_ui = TweakBool("Show editor UI", 0); + b32 hide_editor_ui = TweakBool("Hide editor UI", 1); frame->world_selection_start = frame->world_cursor; if (frame->is_editing) { b32 m1_held = frame->held_buttons[Button_M1]; b32 m2_held = frame->held_buttons[Button_M2]; - if (show_editor_ui) + if (!hide_editor_ui) { frame->selection_mode = V_SelectionMode_Tile; } @@ -3636,7 +3646,7 @@ void V_TickForever(WaveLaneCtx *lane) // FIXME: Remove this - #define V_ShouldSkipPanel(panel) (panel->is_editor_panel && (!frame->is_editing || !show_editor_ui)) + #define V_ShouldSkipPanel(panel) (panel->is_editor_panel && (hide_editor_ui || !frame->is_editing)) @@ -5390,79 +5400,113 @@ void V_TickForever(WaveLaneCtx *lane) //- Build profiler - - // FIXME: Finalize - + V_Profiler *profiler = &frame->profiler; + UI_Key profiler_graph_box = UI_KeyF("graph"); + if (TweakBool("Show profiler", 1)) { + profiler->is_showing = 1; + + UI_BoxReports profiler_graph_reports = UI_ReportsFromKey(profiler_graph_box); + profiler->graph_dims = DimsFromRng2(profiler_graph_reports.draw.screen_rect); + //- Init test samples + // // FIXME: Remove this + // Struct(SampleState) + // { + // i64 ready_samples_count; + // Arena *samples_arena; + // }; + // Struct(Sample) + // { + // u64 zone_id; + // u64 thread_id; + // i64 start_ns; + // i64 end_ns; + // }; + // PERSIST i64 sample_states_count = 1; + // PERSIST SampleState *sample_states = 0; + // if (!sample_states) + // { + // sample_states = PushStructs(perm, SampleState, sample_states_count); + // for (i64 sample_state_idx = 0; sample_state_idx < sample_states_count; ++sample_state_idx) + // { + // SampleState *ss = &sample_states[sample_state_idx]; + // ss->samples_arena = AcquireArena(Gibi(64)); + + + + + + + // ss->ready_samples_count = 128; + // for (i64 sample_idx = 0; sample_idx < ss->ready_samples_count; ++sample_idx) + // { + // Sample *sample = PushStruct(ss->samples_arena, Sample); + // sample->zone_id = (u64)"Hello there"; + // sample->thread_id = 0; + // sample->start_ns = NsFromSeconds(sample_idx); + // sample->end_ns = NsFromSeconds(sample_idx + 1); + // } + // } + // } + + // FIXME: Remove this - Struct(SampleState) { - i64 ready_samples_count; - Arena *samples_arena; - }; - Struct(Sample) - { - u64 zone_id; - u64 thread_id; - i64 start_ns; - i64 end_ns; - }; - PERSIST i64 sample_states_count = 1; - PERSIST SampleState *sample_states = 0; - if (!sample_states) - { - sample_states = PushStructs(perm, SampleState, sample_states_count); - for (i64 sample_state_idx = 0; sample_state_idx < sample_states_count; ++sample_state_idx) - { - SampleState *ss = &sample_states[sample_state_idx]; - ss->samples_arena = AcquireArena(Gibi(64)); - - - - - - - ss->ready_samples_count = 128; - for (i64 sample_idx = 0; sample_idx < ss->ready_samples_count; ++sample_idx) - { - Sample *sample = PushStruct(ss->samples_arena, Sample); - sample->zone_id = (u64)"Hello there"; - sample->thread_id = 0; - sample->start_ns = NsFromSeconds(sample_idx); - sample->end_ns = NsFromSeconds(sample_idx + 1); - } - } + V_ProfilerFrame *pf = &V.profiler_frames[V.profiler_frame_seq % V_ProfilerFramesCap]; + V.profiler_frame_seq += 1; } + //- Build profiler - UI_PushDF(Tag, HashF("profiler")) + UI_Key profiler_box = UI_KeyF("profiler"); + UI_PushDF(Tag, profiler_box.v) + UI_PushDF(Parent, profiler_box) { UI_Size profiler_height = UI_FNT(20, 1); - UI_Size header_height = UI_FNT(1, 1); + UI_Size header_height = UI_FNT(2, 1); + UI_Size window_padding = UI_FNT(0.5, 1); Vec4 profiler_color = theme.col.window_bg; + profiler_color.a = 0.75; - UI_Key profiler_key = UI_KeyF("profiler"); - + UI_SetNext(Parent, vis_ui_box); UI_SetNext(BackgroundColor, profiler_color); + UI_SetNext(Rounding, UI_RPIX(5 * theme.rounding)); UI_PushDF(Width, UI_GROW(1, 0)) UI_PushDF(Height, profiler_height) - UI_PushDF(Parent, UI_BuildBoxEx(profiler_key)) + UI_PushDF(Parent, UI_BuildColumnEx(profiler_box)) + UI_PushDF(Parent, UI_BuildRow()) { - // UI_PushDF(BackgroundColor, Color_Red) - UI_SetNext(BorderColor, Color_Red); - UI_SetNext(BorderSize, 1); - UI_PushDF(Height, header_height) - UI_PushDF(Parent, UI_BuildBox()) + UI_BuildSpacer(window_padding, Axis_X); + UI_PushDF(Parent, UI_BuildColumn()) { + //- Header + // UI_PushDF(BackgroundColor, Color_Red) + // UI_SetNext(BorderColor, Color_Red); + // UI_SetNext(BorderSize, 1); + UI_SetNext(ChildAlignment, UI_Region_Center); + UI_PushDF(Height, header_height) + UI_PushDF(Parent, UI_BuildBoxF("profiler header")) + { + UI_PushDF(TextColor, theme.col.hint) + UI_BuildLabelF("Profiler"); + } + UI_BuildDivider(UI_PIX(1, 1), theme.col.divider, Axis_Y); + + //- Graph + // UI_SetNext(BackgroundColor, Color_Cyan); + UI_PushDF(Parent, UI_BuildBoxEx(profiler_graph_box)) + { + } } + UI_BuildSpacer(window_padding, Axis_X); } } } @@ -6651,6 +6695,7 @@ void V_TickForever(WaveLaneCtx *lane) 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)); + b32 should_draw_profiler_graph = profiler->is_showing && profiler->graph_dims.x > 0 && profiler->graph_dims.y > 0; { ////////////////////////////// //- GPU upload pass @@ -6708,6 +6753,27 @@ void V_TickForever(WaveLaneCtx *lane) .name = StringF(frame->arena, "Screen target [%F]", FmtSint(frame->tick)) ); + // Profiler graph + // FIXME: Limit dims based on sample buffer capacity + frame->profiler_graph_dims = profiler->graph_dims; + frame->profiler_frame_seq = V.profiler_frame_seq; + + if (should_draw_profiler_graph) + { + frame->profiler_graph = G_PushTexture2D( + cl, gpu_frame_arena, + G_TextureLayout_Family, + G_Format_R16G16B16A16_Float, + profiler->graph_dims, + .flags = G_MemoryFlag_AllowTextureRW, + .name = StringF(frame->arena, "Profiler graph [%F]", FmtSint(frame->tick)) + ); + { + Rng2 uv = RNG2(VEC2(0, 0), VEC2(1, 1)); + UI_SetRawTexture(profiler_graph_box, frame->profiler_graph, uv); + } + } + // Albedo texture frame->albedo = G_PushTexture2D( cl, gpu_frame_arena, @@ -6819,6 +6885,12 @@ void V_TickForever(WaveLaneCtx *lane) G_ZoneDF(cl, "Init") { + // Build profiler graph + if (should_draw_profiler_graph) + { + G_Compute2D(cl, V_ProfilerGraphCS, frame->profiler_graph_dims); + } + // Prepare shade G_Compute2D(cl, V_PrepareShadeCS, frame->shade_dims); diff --git a/src/pp/pp_vis/pp_vis_core.h b/src/pp/pp_vis/pp_vis_core.h index 07a4ad94..2c97d7ac 100644 --- a/src/pp/pp_vis/pp_vis_core.h +++ b/src/pp/pp_vis/pp_vis_core.h @@ -235,6 +235,15 @@ Struct(V_Palette) V_TextboxState search_state; }; +//////////////////////////////////////////////////////////// +//~ Profiler types + +Struct(V_Profiler) +{ + Vec2 graph_dims; + b32 is_showing; +}; + //////////////////////////////////////////////////////////// //~ Window types @@ -348,6 +357,7 @@ Struct(V_Frame) Button held_buttons[Button_COUNT]; // User input state captured for gameplay Button real_held_buttons[Button_COUNT]; // Actual state of user input regardless of keyboard / mouse focus V_Palette palette; + V_Profiler profiler; UI_Key text_input_focus; @@ -394,6 +404,9 @@ Struct(V_Ctx) Atomic32 shutdown; Fence shutdown_complete; + u64 profiler_frame_seq; + V_ProfilerFrame *profiler_frames; + i64 cur_frame_tick; V_Frame frames[2]; }; diff --git a/src/pp/pp_vis/pp_vis_gpu.g b/src/pp/pp_vis/pp_vis_gpu.g index c51dd06e..3da32348 100644 --- a/src/pp/pp_vis/pp_vis_gpu.g +++ b/src/pp/pp_vis/pp_vis_gpu.g @@ -29,75 +29,75 @@ -ComputeShader(V_BlaCS) -{ - // FIXME: Don't use frame slot - BlaParams params = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; - RWTexture2D bla = G_Deref(params.bla_tex, RWTexture2D); +// ComputeShader(V_BlaCS) +// { +// // FIXME: Don't use frame slot +// BlaParams params = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; +// RWTexture2D bla = G_Deref(params.bla_tex, RWTexture2D); - i64 samples_count = params.bla_samples_count; - StructuredBuffer samples = G_Deref(params.bla_samples, StructuredBuffer); +// i64 samples_count = params.bla_samples_count; +// StructuredBuffer samples = G_Deref(params.bla_samples, StructuredBuffer); - Vec2 bla_pos = SV_DispatchThreadID + 0.5; +// Vec2 bla_pos = SV_DispatchThreadID + 0.5; - Vec2 dims = params.bla_dims; +// Vec2 dims = params.bla_dims; - // f32 samp_width = 10 * G_TweakFloat; - f32 samp_width = 3; +// // f32 samp_width = 10 * G_TweakFloat; +// f32 samp_width = 3; - i64 sample_idx = bla_pos.x / samp_width; +// i64 sample_idx = bla_pos.x / samp_width; - if (all(bla_pos < dims) && sample_idx < samples_count) - { - // // Vec4 color = Color_Red; - // Vec4 color = Color_Black; - // color.b = bla_pos.x / dims.x; - // if (MatchFloor(bla_pos, params.cursor)) - // { - // G_PrintF("bla_pos: %F, dims: %F, color: %F", G_Fmt(bla_pos), G_Fmt(dims), G_Fmt(color)); - // } - // bla[bla_pos] = color; +// if (all(bla_pos < dims) && sample_idx < samples_count) +// { +// // // Vec4 color = Color_Red; +// // Vec4 color = Color_Black; +// // color.b = bla_pos.x / dims.x; +// // if (MatchFloor(bla_pos, params.cursor)) +// // { +// // G_PrintF("bla_pos: %F, dims: %F, color: %F", G_Fmt(bla_pos), G_Fmt(dims), G_Fmt(color)); +// // } +// // bla[bla_pos] = color; - BlaSample sample = samples[sample_idx]; - // f32 ratio0 = (f32)sample.bla0 / (f32)samples_count; - // f32 ratio1 = (f32)sample.bla1 / (f32)samples_count; +// BlaSample sample = samples[sample_idx]; +// // f32 ratio0 = (f32)sample.bla0 / (f32)samples_count; +// // f32 ratio1 = (f32)sample.bla1 / (f32)samples_count; - f32 ratio0 = sample.r0; - f32 ratio1 = sample.r1; +// f32 ratio0 = sample.r0; +// f32 ratio1 = sample.r1; - f32 ratio_y = 1.0 - (bla_pos.y / dims.y); +// f32 ratio_y = 1.0 - (bla_pos.y / dims.y); - Vec4 color = 0; - if (ratio_y < ratio0) - { - color = LinearFromSrgb(Vec4(0.82, 0, 0.933, 1)); - } - else if (ratio_y < ratio0 + ratio1) - { - color = LinearFromSrgb(Vec4(0.953, 0.467, 0.208, 1)); - } - else - { - color = 0; - } +// Vec4 color = 0; +// if (ratio_y < ratio0) +// { +// color = LinearFromSrgb(Vec4(0.82, 0, 0.933, 1)); +// } +// else if (ratio_y < ratio0 + ratio1) +// { +// color = LinearFromSrgb(Vec4(0.953, 0.467, 0.208, 1)); +// } +// else +// { +// color = 0; +// } - bla[bla_pos] = color; +// bla[bla_pos] = color; - } -} +// } +// } @@ -180,6 +180,33 @@ Vec4 V_ColorFromParticle(V_ParticleDesc desc, u32 particle_idx, u32 density) return result; } +//////////////////////////////////////////////////////////// +//~ Build profiler graph + +ComputeShader(V_ProfilerGraphCS) +{ + V_SharedFrame frame = G_Deref(V_GpuConst_Frame, StructuredBuffer)[0]; + RWTexture2D graph = G_Deref(frame.profiler_graph, RWTexture2D); + StructuredBuffer profiler_frames = G_Deref(frame.profiler_frames, StructuredBuffer); + + Vec2 graph_dims = frame.profiler_graph_dims; + u32 thread_id = SV_DispatchThreadID.x; + if (thread_id <= frame.profiler_frame_seq && thread_id < graph_dims.x) + { + + Vec2 graph_pos = SV_DispatchThreadID + 0.5; + graph_pos.x = graph_dims.x - graph_pos.x; + + u64 frame_seq = (frame.profiler_frame_seq - thread_id); + u64 frame_idx = frame_seq % V_ProfilerFramesCap; + V_ProfilerFrame prof_frame = profiler_frames[frame_idx]; + + Vec4 color = Color_Red; + color.g = Norm24(MixU64(frame_seq)); + graph[graph_pos] = color; + } +} + //////////////////////////////////////////////////////////// //~ Prepare frame diff --git a/src/pp/pp_vis/pp_vis_gpu.gh b/src/pp/pp_vis/pp_vis_gpu.gh index 04c9906f..25c263a2 100644 --- a/src/pp/pp_vis/pp_vis_gpu.gh +++ b/src/pp/pp_vis/pp_vis_gpu.gh @@ -50,6 +50,9 @@ Vec4 V_ColorFromParticle(V_ParticleDesc desc, u32 particle_idx, u32 density); //////////////////////////////////////////////////////////// //~ Shaders +//- Build profiler graph +ComputeShader(V_ProfilerGraphCS); + //- Prepare frame ComputeShader(V_PrepareShadeCS); ComputeShader(V_PrepareCellsCS); diff --git a/src/pp/pp_vis/pp_vis_shared.cgh b/src/pp/pp_vis/pp_vis_shared.cgh index 7dea3e3d..e4e4325f 100644 --- a/src/pp/pp_vis/pp_vis_shared.cgh +++ b/src/pp/pp_vis/pp_vis_shared.cgh @@ -213,6 +213,33 @@ Struct(V_DVert) Vec4 color_lin; }; +//////////////////////////////////////////////////////////// +//~ Profiler types + +#define V_ProfilerFramesCap Kibi(16) + +#define V_ProfilerZonesXList(X) \ + X(None, Color_Cyan) \ +/* ---------------------------- */ + +Enum(V_ProfilerZone) +{ + #define X(name, ...) CAT(V_ProfilerZone_,name), + V_ProfilerZonesXList(X) + #undef X + V_ProfilerZone_COUNT +}; + +Struct(V_ProfilerZoneInfo) +{ + f32 elapsed_seconds; +}; + +Struct(V_ProfilerFrame) +{ + V_ProfilerZoneInfo zones[V_ProfilerZone_COUNT]; +}; + //////////////////////////////////////////////////////////// //~ State types @@ -267,55 +294,6 @@ Struct(V_Affines) Affine tile_to_world; }; - - - - - - - - - - - - -// FIXME: Remove this - - -Struct(BlaSample) -{ - f32 r0; - f32 r1; -}; - - - - - - - -Struct(BlaParams) -{ - // FIXME: Remove this - i64 bla_samples_count; - G_BufferRef bla_samples; - - Vec2 cursor; - - Vec2 bla_dims; - G_TextureRef bla_tex; -}; - - - - - - - - - - - Struct(V_SharedFrame) { //- Time @@ -406,6 +384,12 @@ Struct(V_SharedFrame) G_SamplerRef basic_samplers[G_BasicSamplerKind_COUNT]; + u64 profiler_frame_seq; + G_BufferRef profiler_frames; + + Vec2 profiler_graph_dims; + G_TextureRef profiler_graph; + V_TileDesc tile_descs[P_TileKind_COUNT]; G_TextureRef tiles;