diff --git a/src/config.h b/src/config.h index 19d12830..580ea6fa 100644 --- a/src/config.h +++ b/src/config.h @@ -72,6 +72,8 @@ #define GPU_DEBUG 1 #define GPU_DEBUG_VALIDATION 0 +#define UI_DEBUG 0 + /* If virtual fibers are enabled, each fiber will get its own OS thread, * and fiber suspend/resume will be emulated using OS thread primitives. * This is slow but allows for easier debugging in tricky cases diff --git a/src/font/font.c b/src/font/font.c index 97b31068..be5ed1d9 100644 --- a/src/font/font.c +++ b/src/font/font.c @@ -248,24 +248,31 @@ F_Run F_RunFromString(Arena *arena, F_Font *font, String str) for (CodepointIter it = InitCodepointIter(str); NextCodepoint(&it);) { u32 codepoint = it.codepoint; - u16 index = font->lookup[codepoint]; - F_Glyph glyph = font->glyphs[index]; - F_RunRect *rect = PushStruct(arena, F_RunRect); - ++result.count; + if (codepoint < 0 || font->glyphs_count <= codepoint) + { + codepoint = '?'; + } + if (0 <= codepoint && codepoint < font->glyphs_count) + { + u16 index = font->lookup[codepoint]; + F_Glyph glyph = font->glyphs[index]; + F_RunRect *rect = PushStruct(arena, F_RunRect); + ++result.count; - rect->atlas_p0 = glyph.atlas_p0; - rect->atlas_p1 = glyph.atlas_p1; - Vec2I32 size = SubVec2I32(glyph.atlas_p1, glyph.atlas_p0); + rect->atlas_p0 = glyph.atlas_p0; + rect->atlas_p1 = glyph.atlas_p1; + Vec2I32 size = SubVec2I32(glyph.atlas_p1, glyph.atlas_p0); - rect->baseline_start_offset = glyph.baseline_offset; - rect->baseline_start_offset.x += result.baseline_length; + rect->baseline_start_offset = glyph.baseline_offset; + rect->baseline_start_offset.x += result.baseline_length; - result.p0.x = MinF32(result.p0.x, rect->baseline_start_offset.x); /* Left run bounds */ - result.p1.x = MaxF32(result.p1.x, rect->baseline_start_offset.x + size.x); /* Right run bounds */ - result.p0.y = MinF32(result.p0.y, rect->baseline_start_offset.y); /* Top run bounds */ - result.p1.y = MaxF32(result.p1.y, rect->baseline_start_offset.y + size.y); /* Bottom run bounds */ + result.p0.x = MinF32(result.p0.x, rect->baseline_start_offset.x); /* Left run bounds */ + result.p1.x = MaxF32(result.p1.x, rect->baseline_start_offset.x + size.x); /* Right run bounds */ + result.p0.y = MinF32(result.p0.y, rect->baseline_start_offset.y); /* Top run bounds */ + result.p1.y = MaxF32(result.p1.y, rect->baseline_start_offset.y + size.y); /* Bottom run bounds */ - result.baseline_length += glyph.advance; + result.baseline_length += glyph.advance; + } } return result; diff --git a/src/gpu/gpu_core.h b/src/gpu/gpu_core.h index dc82b651..aa7e57b7 100644 --- a/src/gpu/gpu_core.h +++ b/src/gpu/gpu_core.h @@ -327,7 +327,9 @@ Enum(GPU_RasterizeMode) GPU_RasterizeMode_LineList, GPU_RasterizeMode_LineStrip, GPU_RasterizeMode_TriangleList, + GPU_RasterizeMode_WireTriangleList, GPU_RasterizeMode_TriangleStrip, + GPU_RasterizeMode_WireTriangleStrip, }; Struct(GPU_Viewport) diff --git a/src/gpu/gpu_dx12/gpu_dx12.c b/src/gpu/gpu_dx12/gpu_dx12.c index 436d0521..86dd29f3 100644 --- a/src/gpu/gpu_dx12/gpu_dx12.c +++ b/src/gpu/gpu_dx12/gpu_dx12.c @@ -403,7 +403,14 @@ JobDef(GPU_D12_LoadPipeline, sig, _) if (ok && (!IsResourceNil(desc.vs.resource) != 0 || !IsResourceNil(desc.ps.resource))) { D3D12_RASTERIZER_DESC raster_desc = ZI; - raster_desc.FillMode = D3D12_FILL_MODE_SOLID; + if (desc.is_wireframe) + { + raster_desc.FillMode = D3D12_FILL_MODE_WIREFRAME; + } + else + { + raster_desc.FillMode = D3D12_FILL_MODE_SOLID; + } raster_desc.CullMode = D3D12_CULL_MODE_NONE; raster_desc.FrontCounterClockwise = 0; raster_desc.DepthBias = D3D12_DEFAULT_DEPTH_BIAS; @@ -891,7 +898,7 @@ GPU_Resource *GPU_AcquireResource(GPU_ResourceDesc desc) d3d_desc.SampleDesc.Count = 1; d3d_desc.SampleDesc.Quality = 0; d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS * !!(desc.flags & GPU_ResourceFlag_Writable); - r->state = desc.buffer.heap_kind == GPU_HeapKind_Upload ? D3D12_RESOURCE_STATE_GENERIC_READ : D3D12_RESOURCE_STATE_COPY_DEST; + r->state = desc.buffer.heap_kind == GPU_HeapKind_Download ? D3D12_RESOURCE_STATE_COPY_DEST : D3D12_RESOURCE_STATE_COMMON; HRESULT hr = ID3D12Device_CreateCommittedResource(g->device, &heap_props, heap_flags, &d3d_desc, r->state, 0, &IID_ID3D12Resource, (void **)&r->d3d_resource); Atomic64FetchAdd(&g->driver_resources_allocated, 1); if (FAILED(hr)) @@ -924,7 +931,7 @@ GPU_Resource *GPU_AcquireResource(GPU_ResourceDesc desc) d3d_desc.SampleDesc.Quality = 0; d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS * !!(desc.flags & GPU_ResourceFlag_Writable); d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET * !!(desc.flags & GPU_ResourceFlag_Renderable); - r->state = D3D12_RESOURCE_STATE_COPY_DEST; + r->state = D3D12_RESOURCE_STATE_COMMON; D3D12_CLEAR_VALUE clear_value = { .Format = d3d_desc.Format, .Color = { 0 } }; clear_value.Color[0] = desc.clear_color.x; clear_value.Color[1] = desc.clear_color.y; @@ -1280,12 +1287,23 @@ i64 GPU_EndCommandList(GPU_CommandList *gpu_cl) } b32 skip = 0; + /* Skip UAV transitions on resources that already have transition in the batch */ if (type == D3D12_RESOURCE_BARRIER_TYPE_UAV && resource->barrier_gen == barrier_gen) { - /* Skip UAV transitions on resources that already have transition in the batch */ skip = 1; } - if (type == D3D12_RESOURCE_BARRIER_TYPE_TRANSITION && resource->barrier_state_after == state_after) + /* Skip redundant transitions */ + if (type == D3D12_RESOURCE_BARRIER_TYPE_TRANSITION && ((resource->barrier_state_after & state_after) == state_after)) + { + skip = 1; + } + /* Skip transitions that will occur via implicit promotion */ + if (type == D3D12_RESOURCE_BARRIER_TYPE_TRANSITION && resource->state == D3D12_RESOURCE_STATE_COMMON && + (state_after != D3D12_RESOURCE_STATE_RENDER_TARGET && + state_after != D3D12_RESOURCE_STATE_DEPTH_WRITE && + state_after != D3D12_RESOURCE_STATE_UNORDERED_ACCESS && + state_after != D3D12_RESOURCE_STATE_RESOLVE_DEST && + state_after != D3D12_RESOURCE_STATE_PRESENT)) { /* Skip transitions into existing state */ skip = 1; @@ -1375,6 +1393,9 @@ i64 GPU_EndCommandList(GPU_CommandList *gpu_cl) if (cpy_len > 0) { ID3D12GraphicsCommandList_CopyBufferRegion(rcl, dst->d3d_resource, 0, src->d3d_resource, 0, cpy_len); + /* Implicit promotion */ + if (dst->state == D3D12_RESOURCE_STATE_COMMON) dst->state = D3D12_RESOURCE_STATE_COPY_DEST; + if (src->state == D3D12_RESOURCE_STATE_COMMON) src->state = D3D12_RESOURCE_STATE_COPY_SOURCE; } } else if (src_desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) @@ -1393,6 +1414,9 @@ i64 GPU_EndCommandList(GPU_CommandList *gpu_cl) src_loc.PlacedFootprint = dst_placed_footprint; ID3D12GraphicsCommandList_CopyTextureRegion(rcl, &dst_loc, 0, 0, 0, &src_loc, 0); + /* Implicit promotion */ + if (dst->state == D3D12_RESOURCE_STATE_COMMON) dst->state = D3D12_RESOURCE_STATE_COPY_DEST; + if (src->state == D3D12_RESOURCE_STATE_COMMON) src->state = D3D12_RESOURCE_STATE_COPY_SOURCE; } else if (dst_desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) { /* Copy texture -> buffer */ @@ -1421,13 +1445,19 @@ i64 GPU_EndCommandList(GPU_CommandList *gpu_cl) switch (cmd->rasterize.mode) { default: Assert(0); break; - case GPU_RasterizeMode_PointList: pipeline_desc.topology_type = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT; break; - case GPU_RasterizeMode_LineList: pipeline_desc.topology_type = D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; break; - case GPU_RasterizeMode_LineStrip: pipeline_desc.topology_type = D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; break; - case GPU_RasterizeMode_TriangleList: pipeline_desc.topology_type = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; break; - case GPU_RasterizeMode_TriangleStrip: pipeline_desc.topology_type = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; break; + case GPU_RasterizeMode_PointList: pipeline_desc.topology_type = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT; break; + case GPU_RasterizeMode_LineList: pipeline_desc.topology_type = D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; break; + case GPU_RasterizeMode_LineStrip: pipeline_desc.topology_type = D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; break; + case GPU_RasterizeMode_TriangleList: pipeline_desc.topology_type = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; break; + case GPU_RasterizeMode_WireTriangleList: pipeline_desc.topology_type = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; break; + case GPU_RasterizeMode_TriangleStrip: pipeline_desc.topology_type = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; break; + case GPU_RasterizeMode_WireTriangleStrip: pipeline_desc.topology_type = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; break; } } + if (cmd->rasterize.mode == GPU_RasterizeMode_WireTriangleList || cmd->rasterize.mode == GPU_RasterizeMode_WireTriangleStrip) + { + pipeline_desc.is_wireframe = 1; + } for (u32 i = 0; i < cmd->rasterize.rts_count; ++i) { GPU_D12_Resource *r = slotted_render_targets[i]; @@ -1504,11 +1534,13 @@ i64 GPU_EndCommandList(GPU_CommandList *gpu_cl) switch (cmd->rasterize.mode) { default: Assert(0); break; - case GPU_RasterizeMode_PointList: topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST; break; - case GPU_RasterizeMode_LineList: topology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; break; - case GPU_RasterizeMode_LineStrip: topology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; break; - case GPU_RasterizeMode_TriangleList: topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; break; - case GPU_RasterizeMode_TriangleStrip: topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; break; + case GPU_RasterizeMode_PointList: topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST; break; + case GPU_RasterizeMode_LineList: topology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; break; + case GPU_RasterizeMode_LineStrip: topology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; break; + case GPU_RasterizeMode_TriangleList: topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; break; + case GPU_RasterizeMode_WireTriangleList: topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; break; + case GPU_RasterizeMode_TriangleStrip: topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; break; + case GPU_RasterizeMode_WireTriangleStrip: topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; break; } ID3D12GraphicsCommandList_IASetPrimitiveTopology(rcl, topology); } diff --git a/src/gpu/gpu_dx12/gpu_dx12.h b/src/gpu/gpu_dx12/gpu_dx12.h index 94da7941..8a3bc183 100644 --- a/src/gpu/gpu_dx12/gpu_dx12.h +++ b/src/gpu/gpu_dx12/gpu_dx12.h @@ -30,6 +30,7 @@ Struct(GPU_D12_PipelineDesc) VertexShader vs; PixelShader ps; ComputeShader cs; + b32 is_wireframe; D3D12_PRIMITIVE_TOPOLOGY_TYPE topology_type; GPU_Format render_target_formats[GPU_MaxRenderTargets]; }; diff --git a/src/pp/pp.c b/src/pp/pp.c index a39a2d73..5e2144fa 100644 --- a/src/pp/pp.c +++ b/src/pp/pp.c @@ -359,13 +359,13 @@ void DrawDebugConsole(b32 minimized) i64 now_ns = TimeNs(); UI_PushCheckpoint(); { - UI_Box *console_box = 0; { UI_SetNext(LayoutAxis, Axis_Y); // UI_SetNext(Tint, 0); // UI_SetNext(BorderColor, Rgba32F(1, 1, 1, 0.25)); UI_SetNext(Border, 0); // UI_SetNext(Width, UI_FIT(1)); + // UI_ForceNext(BackgroundColor, Color_Purple); if (minimized) { UI_SetNext(BackgroundColor, 0); @@ -376,21 +376,17 @@ void DrawDebugConsole(b32 minimized) { UI_SetNext(BackgroundColor, Rgba32F(1, 1, 1, 0.02)); UI_SetNext(Width, UI_FILL(1, 0)); - UI_SetNext(Height, UI_FILL(0.33, 1)); + // UI_SetNext(Height, UI_FILL(0.33, 1)); + UI_SetNext(Height, UI_FIT(1)); } - console_box = UI_BuildBox(0, UI_NilKey); + UI_Box *console_box = UI_BuildBox(0, UI_NilKey); UI_Push(Parent, console_box); - if (!minimized) - { - UI_BuildSpacer(UI_FILL(1, 0)); - } } // UI_Push(Width, UI_TXT(0)); - UI_Push(Width, UI_FIT(1)); - UI_Push(Height, UI_FIT(1)); - UI_Push(BorderColor, Rgba32F(0.25, 0.25, 0.25, 1)); - UI_Push(Rounding, 0); - UI_Push(TextPadding, 6); + // UI_Push(Width, UI_FIT(1)); + // UI_Push(Height, UI_FIT(1)); + // UI_Push(BorderColor, Rgba32F(0.25, 0.25, 0.25, 1)); + // UI_Push(Rounding, 0); Lock lock = LockE(&g->console_logs_mutex); { /* Gather display logs */ @@ -440,30 +436,30 @@ void DrawDebugConsole(b32 minimized) FmtUintZ(datetime.milliseconds, 3), FmtString(text)); } - u32 color = colors[log->level][log->color_index]; - UI_SetNext(BackgroundColor, color); - UI_SetNext(Tint, Alpha32F(0xFFFFFFFF, opacity)); - UI_SetNext(LayoutAxis, Axis_X); - UI_Box *log_box = UI_BuildBox(UI_BoxFlag_None, UI_NilKey); UI_PushCheckpoint(); { - UI_Push(Parent, log_box); - UI_Push(BackgroundColor, 0); - UI_Push(Border, 0); - f32 spacer = 50; + UI_Push(Tint, Alpha32F(0xFFFFFFFF, opacity)); { - // UI_BuildSpacer(UI_PIX(spacer, 0)); + u32 color = colors[log->level][log->color_index]; + UI_SetNext(BackgroundColor, color); + UI_SetNext(LayoutAxis, Axis_X); + UI_SetNext(Width, UI_FILL(1, 1)); + UI_SetNext(Height, UI_FIT(1)); + UI_SetNext(BorderColor, Rgba32F(0.25, 0.25, 0.25, 1)); + UI_SetNext(Rounding, 0); + UI_SetNext(Border, 1); + UI_Box *log_box = UI_BuildBox(UI_BoxFlag_None, UI_NilKey); + UI_Push(Parent, log_box); } { + UI_SetNext(BackgroundColor, 0); + UI_SetNext(Border, 0); + UI_SetNext(TextPadding, 6); + UI_SetNext(Text, text); UI_SetNext(Width, UI_FILL(1, 1)); UI_SetNext(Height, UI_TXT(1)); UI_Box *log_textbox = UI_BuildBox(UI_BoxFlag_DrawText, UI_NilKey); - UI_SetDisplayText(log_textbox, text); } - // { - // UI_BuildSpacer(UI_PIX(spacer, 0)); - // } - UI_Pop(Parent, log_box); } UI_PopCheckpoint(); } @@ -2122,6 +2118,7 @@ void UpdateUser(void) UI_SetNext(BorderColor, 0); UI_SetNext(Width, UI_FIT(1)); UI_SetNext(Height, UI_FIT(1)); + UI_SetNext(Tint, 0); UI_Box *dbg_box = UI_BuildBox(0, UI_NilKey); UI_PushCheckpoint(); { diff --git a/src/pp/pp.h b/src/pp/pp.h index f16dcd3c..357770d5 100644 --- a/src/pp/pp.h +++ b/src/pp/pp.h @@ -203,7 +203,6 @@ Struct(SharedUserState) ConsoleLog *first_console_log; ConsoleLog *last_console_log; i32 console_log_color_indices[P_LogLevel_Count]; - b32 debug_console; //- Window -> user Mutex sys_window_events_mutex; @@ -258,6 +257,9 @@ Struct(SharedUserState) Vec2 debug_camera_pan_start; b32 debug_draw; + //- Debug console + b32 debug_console; + //- Per frame Vec2I32 screen_size; diff --git a/src/ui/ui_common.c b/src/ui/ui_common.c index b1509174..bdbe1d43 100644 --- a/src/ui/ui_common.c +++ b/src/ui/ui_common.c @@ -6,8 +6,8 @@ UI_Box *UI_BuildLabel(String text) UI_Key key = UI_KeyFromString(0, text); UI_SetNext(Width, UI_TXT(0)); UI_SetNext(Height, UI_TXT(0)); + UI_SetNext(Text, text); UI_Box *box = UI_BuildBox(UI_BoxFlag_DrawText, UI_NilKey); - UI_SetDisplayText(box, text); return box; } @@ -35,11 +35,9 @@ UI_Box *UI_BuildSpacer(UI_Size size) if (UI_PeekTop(Parent)->layout_axis == Axis_X) { UI_SetNext(Width, size); - UI_SetNext(Height, UI_FILL(1, 0)); } else { - UI_SetNext(Width, UI_FILL(1, 0)); UI_SetNext(Height, size); } UI_Box *box = UI_BuildBox(0, UI_NilKey); diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 7feb06d8..b2c2ecf1 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -94,24 +94,43 @@ void UI_PopCheckpoint(void) //////////////////////////////////////////////////////////// //~ Style stack helpers -UI_StyleNode *UI_PushStyleNode(UI_StyleKind kind, b32 pop_when_used, UI_Style desc) +UI_StyleNode *UI_PushStyleNode(UI_Style desc) { UI_SharedState *g = &UI_shared_state; - UI_StyleNode *n = g->first_free_style_node; - if (n) + UI_StyleNode *n = g->style_tops[desc.kind]; + if (!n->style.forced) { - g->first_free_style_node = n->next; - ZeroStruct(n); + if (n->style.pop_when_used) + { + ZeroStruct(n); + } + else + { + n = g->first_free_style_node; + if (n) + { + g->first_free_style_node = n->next; + ZeroStruct(n); + } + else + { + n = PushStruct(g->build_arena, UI_StyleNode); + } + n->next = g->style_tops[desc.kind]; + } + n->style = desc; + n->checkpoint = g->top_checkpoint->v; + switch (desc.kind) + { + default: break; + + case UI_StyleKind_Text: + { + n->style.Text = PushString(g->build_arena, desc.Text); + } break; + } } - else - { - n = PushStruct(g->build_arena, UI_StyleNode); - } - n->pop_when_used = pop_when_used; - n->style = desc; - n->next = g->style_tops[kind]; - n->checkpoint = g->top_checkpoint->v; - g->style_tops[kind] = n; + g->style_tops[desc.kind] = n; return n; } @@ -138,7 +157,7 @@ UI_Style UI_StyleFromTopNode(UI_StyleKind kind, b32 use) UI_SharedState *g = &UI_shared_state; UI_StyleNode *n = g->style_tops[kind]; UI_Style style = n->style; - if (use && n->pop_when_used) + if (use && n->style.pop_when_used) { g->style_tops[kind] = n->next; n->next = g->first_free_style_node; @@ -203,16 +222,16 @@ UI_Box *UI_BuildBox(UI_BoxFlag flags, UI_Key key) box->layout_axis = UI_UseTop(LayoutAxis); box->background_color = UI_UseTop(BackgroundColor); box->border_color = UI_UseTop(BorderColor); - box->text_color = UI_UseTop(TextColor); box->tint = UI_UseTop(Tint); box->border = UI_UseTop(Border); box->font_resource = UI_UseTop(Font); box->font_size = UI_UseTop(FontSize); box->text_padding = UI_UseTop(TextPadding); box->rounding = UI_UseTop(Rounding); + box->display_text = UI_UseTop(Text); /* Prefetch font */ - if (box->flags & UI_BoxFlag_DrawText) + if (box->display_text.len > 0) { box->font = F_LoadFontAsync(box->font_resource, box->font_size); } @@ -223,13 +242,6 @@ UI_Box *UI_BuildBox(UI_BoxFlag flags, UI_Key key) return box; } -void UI_SetDisplayText(UI_Box *box, String str) -{ - UI_SharedState *g = &UI_shared_state; - String text = PushString(g->build_arena, str); - box->display_text = text; -} - void UI_SetBackgroundTexture(UI_Box *box, GPU_Resource *texture, Vec2 uv0, Vec2 uv1) { box->background_texture = texture; @@ -422,9 +434,8 @@ i64 UI_EndBuild(GPU_Resource *render_target) UI_Size pref_size = box->pref_size[axis]; if (pref_size.kind == UI_SizeKind_Fill) { - UI_Box *ancestor = box->parent; f32 ancestor_size = 0; - for (; ancestor; ancestor = ancestor->parent) + for (UI_Box *ancestor = box->parent; ancestor; ancestor = ancestor->parent) { UI_Size tmp = ancestor->pref_size[axis]; if (tmp.kind == UI_SizeKind_Pixel || tmp.kind == UI_SizeKind_TextContents) @@ -464,61 +475,6 @@ i64 UI_EndBuild(GPU_Resource *render_target) } } - /* TODO: Remove this */ -#if 0 - - /* Calculate upwards-dependent sizes */ - for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index) - { - UI_Box *box = boxes_pre[pre_index]; - for (Axis axis = 0; axis < Axis_CountXY; ++axis) - { - UI_Size pref_size = box->pref_size[axis]; - if (pref_size.kind == UI_SizeKind_Fill) - { - UI_Box *ancestor = box->parent; - f32 ancestor_size = 0; - for (; ancestor; ancestor = ancestor->parent) - { - UI_Size tmp = ancestor->pref_size[axis]; - if (tmp.kind == UI_SizeKind_Pixel || tmp.kind == UI_SizeKind_TextContents) - { - ancestor_size = ancestor->solved_dims[axis]; - break; - } - } - box->solved_dims[axis] = pref_size.v * ancestor_size; - } - } - } - - /* Calculate downwards-dependent sizes */ - for (u64 post_index = 0; post_index < boxes_count; ++post_index) - { - UI_Box *box = boxes_post[post_index]; - for (Axis axis = 0; axis < Axis_CountXY; ++axis) - { - UI_Size pref_size = box->pref_size[axis]; - if (pref_size.kind == UI_SizeKind_Fit) - { - f32 accum = 0; - for (UI_Box *child = box->first; child; child = child->next) - { - if (axis == box->layout_axis) - { - accum += child->solved_dims[axis]; - } - else - { - accum = MaxF32(child->solved_dims[axis], accum); - } - } - box->solved_dims[axis] = accum; - } - } - } -#endif - /* Solve violations */ for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index) { @@ -597,7 +553,7 @@ i64 UI_EndBuild(GPU_Resource *render_target) is_visible = is_visible && ((box->tint & 0xFF000000) != 0); is_visible = is_visible && (box->p1.x > box->p0.x); is_visible = is_visible && (box->p1.y > box->p0.y); - if (is_visible) + if (is_visible || UI_DEBUG) { /* Push box rect */ { @@ -685,19 +641,41 @@ i64 UI_EndBuild(GPU_Resource *render_target) GPU_Viewport viewport = GPU_ViewportFromRect(render_viewport); GPU_Scissor scissor = GPU_ScissorFromRect(render_viewport); - UI_RectSig sig = ZI; - sig.viewport_size = RoundVec2ToVec2I32(render_viewport.size); - sig.sampler = GPU_SamplerStateRidFromResource(GPU_GetCommonPointSampler()); - sig.rects = GPU_StructuredBufferRidFromResource(draw_rects_buffer); - GPU_Rasterize(cl, - &sig, - UI_RectVS, UI_RectPS, - 1, - viewport, - scissor, - draw_rects_count, - GPU_GetCommonQuadIndices(), - GPU_RasterizeMode_TriangleList); + /* Render rects */ + { + UI_RectSig sig = ZI; + sig.viewport_size = RoundVec2ToVec2I32(render_viewport.size); + sig.sampler = GPU_SamplerStateRidFromResource(GPU_GetCommonPointSampler()); + sig.rects = GPU_StructuredBufferRidFromResource(draw_rects_buffer); + GPU_Rasterize(cl, + &sig, + UI_RectVS, UI_RectPS, + 1, + viewport, + scissor, + draw_rects_count, + GPU_GetCommonQuadIndices(), + GPU_RasterizeMode_TriangleList); + } + + /* Render rect wireframes */ + if (UI_DEBUG) + { + UI_RectSig sig = ZI; + sig.viewport_size = RoundVec2ToVec2I32(render_viewport.size); + sig.sampler = GPU_SamplerStateRidFromResource(GPU_GetCommonPointSampler()); + sig.rects = GPU_StructuredBufferRidFromResource(draw_rects_buffer); + sig.debug_srgb = Rgba32F(1, 0, 1, 0.5); + GPU_Rasterize(cl, + &sig, + UI_RectVS, UI_RectPS, + 1, + viewport, + scissor, + draw_rects_count, + GPU_GetCommonQuadIndices(), + GPU_RasterizeMode_WireTriangleList); + } } //- Prep post pass diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index f7f765cb..f109347b 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -39,11 +39,11 @@ Struct(UI_Size) x(Size, UI_Size) \ x(BackgroundColor, u32) \ x(BorderColor, u32) \ - x(TextColor, u32) \ x(Tint, u32) \ x(Border, f32) \ x(Font, ResourceKey) \ x(FontSize, u32) \ + x(Text, String) \ x(TextPadding, f32) \ x(Rounding, f32) \ /* ------------------------------------------- */ @@ -60,6 +60,8 @@ Enum(UI_StyleKind) Struct(UI_Style) { UI_StyleKind kind; + b32 pop_when_used; + b32 forced; /* Union of all style fields */ union { @@ -72,7 +74,6 @@ Struct(UI_Style) Struct(UI_StyleNode) { UI_StyleNode *next; - b32 pop_when_used; u64 checkpoint; UI_Style style; }; @@ -212,13 +213,15 @@ void UI_PopCheckpoint(void); //////////////////////////////////////////////////////////// //~ Style helpers -UI_StyleNode *UI_PushStyleNode(UI_StyleKind kind, b32 pop_when_used, UI_Style desc); +UI_StyleNode *UI_PushStyleNode(UI_Style desc); UI_Style UI_PopStyleNode(UI_StyleKind kind); UI_StyleNode *UI_PeekTopStyleNode(UI_StyleKind kind); UI_Style UI_StyleFromTopNode(UI_StyleKind kind, b32 use); -#define UI_SetNext(name, v) UI_PushStyleNode(UI_StyleKind_##name, 1, (UI_Style) { .name = v }) -#define UI_Push(name, v) UI_PushStyleNode(UI_StyleKind_##name, 0, (UI_Style) { .name = v }) +#define UI_SetNext(name, v) UI_PushStyleNode((UI_Style) { .kind = UI_StyleKind_##name, .name = v, .pop_when_used = 1 }) +#define UI_Push(name, v) UI_PushStyleNode((UI_Style) { .kind = UI_StyleKind_##name, .name = v }) +#define UI_ForceNext(name, v) UI_PushStyleNode((UI_Style) { .kind = UI_StyleKind_##name, .name = v, .pop_when_used = 1, .forced = 1 }) +#define UI_ForcePush(name, v) UI_PushStyleNode((UI_Style) { .kind = UI_StyleKind_##name, .name = v, .forced = 1 }) #define UI_Pop(name, v) UI_PopStyleNode(UI_StyleKind_##name).name #define UI_UseTop(name) UI_StyleFromTopNode(UI_StyleKind_##name, 1).name #define UI_PeekTop(name) UI_StyleFromTopNode(UI_StyleKind_##name, 0).name @@ -239,7 +242,6 @@ UI_Style UI_StyleFromTopNode(UI_StyleKind kind, b32 use); UI_Box *UI_BuildBox(UI_BoxFlag flags, UI_Key key); -void UI_SetDisplayText(UI_Box *box, String str); void UI_SetBackgroundTexture(UI_Box *box, GPU_Resource *texture, Vec2 uv0, Vec2 uv1); //////////////////////////////////////////////////////////// diff --git a/src/ui/ui_draw.gpu b/src/ui/ui_draw.gpu index a445e593..afce9199 100644 --- a/src/ui/ui_draw.gpu +++ b/src/ui/ui_draw.gpu @@ -119,6 +119,12 @@ UI_RectPS_Output PSDef(UI_RectPS, UI_RectPS_Input input) /* Tint */ result *= input.tint_lin; + /* Debug */ + if (sig.debug_srgb != 0) + { + result = LinearFromSrgbU32(sig.debug_srgb); + } + UI_RectPS_Output output; output.sv_target0 = result; return output; diff --git a/src/ui/ui_draw.h b/src/ui/ui_draw.h index ba378276..32eed4f7 100644 --- a/src/ui/ui_draw.h +++ b/src/ui/ui_draw.h @@ -8,8 +8,13 @@ Struct(UI_RectSig) StructuredBufferRid rects; /* 01 consts */ SamplerStateRid sampler; /* 01 consts */ /* ----------------------------------------------------- */ + u32 debug_srgb; /* 01 consts */ + u32 _pad0; /* 01 consts (padding) */ + u32 _pad1; /* 01 consts (padding) */ + u32 _pad2; /* 01 consts (padding) */ + /* ----------------------------------------------------- */ }; -AssertRootConst(UI_RectSig, 4); +AssertRootConst(UI_RectSig, 8); Enum(UI_RectFlag) {