ui progress

This commit is contained in:
jacob 2025-11-02 14:14:34 -06:00
parent 5d87cc2a0e
commit 04d8039f5c
12 changed files with 194 additions and 162 deletions

View File

@ -72,6 +72,8 @@
#define GPU_DEBUG 1 #define GPU_DEBUG 1
#define GPU_DEBUG_VALIDATION 0 #define GPU_DEBUG_VALIDATION 0
#define UI_DEBUG 0
/* If virtual fibers are enabled, each fiber will get its own OS thread, /* If virtual fibers are enabled, each fiber will get its own OS thread,
* and fiber suspend/resume will be emulated using OS thread primitives. * and fiber suspend/resume will be emulated using OS thread primitives.
* This is slow but allows for easier debugging in tricky cases * This is slow but allows for easier debugging in tricky cases

View File

@ -248,6 +248,12 @@ F_Run F_RunFromString(Arena *arena, F_Font *font, String str)
for (CodepointIter it = InitCodepointIter(str); NextCodepoint(&it);) for (CodepointIter it = InitCodepointIter(str); NextCodepoint(&it);)
{ {
u32 codepoint = it.codepoint; u32 codepoint = it.codepoint;
if (codepoint < 0 || font->glyphs_count <= codepoint)
{
codepoint = '?';
}
if (0 <= codepoint && codepoint < font->glyphs_count)
{
u16 index = font->lookup[codepoint]; u16 index = font->lookup[codepoint];
F_Glyph glyph = font->glyphs[index]; F_Glyph glyph = font->glyphs[index];
F_RunRect *rect = PushStruct(arena, F_RunRect); F_RunRect *rect = PushStruct(arena, F_RunRect);
@ -267,6 +273,7 @@ F_Run F_RunFromString(Arena *arena, F_Font *font, String str)
result.baseline_length += glyph.advance; result.baseline_length += glyph.advance;
} }
}
return result; return result;
} }

View File

@ -327,7 +327,9 @@ Enum(GPU_RasterizeMode)
GPU_RasterizeMode_LineList, GPU_RasterizeMode_LineList,
GPU_RasterizeMode_LineStrip, GPU_RasterizeMode_LineStrip,
GPU_RasterizeMode_TriangleList, GPU_RasterizeMode_TriangleList,
GPU_RasterizeMode_WireTriangleList,
GPU_RasterizeMode_TriangleStrip, GPU_RasterizeMode_TriangleStrip,
GPU_RasterizeMode_WireTriangleStrip,
}; };
Struct(GPU_Viewport) Struct(GPU_Viewport)

View File

@ -403,7 +403,14 @@ JobDef(GPU_D12_LoadPipeline, sig, _)
if (ok && (!IsResourceNil(desc.vs.resource) != 0 || !IsResourceNil(desc.ps.resource))) if (ok && (!IsResourceNil(desc.vs.resource) != 0 || !IsResourceNil(desc.ps.resource)))
{ {
D3D12_RASTERIZER_DESC raster_desc = ZI; D3D12_RASTERIZER_DESC raster_desc = ZI;
if (desc.is_wireframe)
{
raster_desc.FillMode = D3D12_FILL_MODE_WIREFRAME;
}
else
{
raster_desc.FillMode = D3D12_FILL_MODE_SOLID; raster_desc.FillMode = D3D12_FILL_MODE_SOLID;
}
raster_desc.CullMode = D3D12_CULL_MODE_NONE; raster_desc.CullMode = D3D12_CULL_MODE_NONE;
raster_desc.FrontCounterClockwise = 0; raster_desc.FrontCounterClockwise = 0;
raster_desc.DepthBias = D3D12_DEFAULT_DEPTH_BIAS; 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.Count = 1;
d3d_desc.SampleDesc.Quality = 0; 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_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); 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); Atomic64FetchAdd(&g->driver_resources_allocated, 1);
if (FAILED(hr)) if (FAILED(hr))
@ -924,7 +931,7 @@ GPU_Resource *GPU_AcquireResource(GPU_ResourceDesc desc)
d3d_desc.SampleDesc.Quality = 0; 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_UNORDERED_ACCESS * !!(desc.flags & GPU_ResourceFlag_Writable);
d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET * !!(desc.flags & GPU_ResourceFlag_Renderable); 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 } }; D3D12_CLEAR_VALUE clear_value = { .Format = d3d_desc.Format, .Color = { 0 } };
clear_value.Color[0] = desc.clear_color.x; clear_value.Color[0] = desc.clear_color.x;
clear_value.Color[1] = desc.clear_color.y; clear_value.Color[1] = desc.clear_color.y;
@ -1280,12 +1287,23 @@ i64 GPU_EndCommandList(GPU_CommandList *gpu_cl)
} }
b32 skip = 0; 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) 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; 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 transitions into existing state */
skip = 1; skip = 1;
@ -1375,6 +1393,9 @@ i64 GPU_EndCommandList(GPU_CommandList *gpu_cl)
if (cpy_len > 0) if (cpy_len > 0)
{ {
ID3D12GraphicsCommandList_CopyBufferRegion(rcl, dst->d3d_resource, 0, src->d3d_resource, 0, cpy_len); 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) 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; src_loc.PlacedFootprint = dst_placed_footprint;
ID3D12GraphicsCommandList_CopyTextureRegion(rcl, &dst_loc, 0, 0, 0, &src_loc, 0); 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) else if (dst_desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
{ /* Copy texture -> buffer */ { /* Copy texture -> buffer */
@ -1425,9 +1449,15 @@ i64 GPU_EndCommandList(GPU_CommandList *gpu_cl)
case GPU_RasterizeMode_LineList: pipeline_desc.topology_type = D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE; 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_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_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_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) for (u32 i = 0; i < cmd->rasterize.rts_count; ++i)
{ {
GPU_D12_Resource *r = slotted_render_targets[i]; GPU_D12_Resource *r = slotted_render_targets[i];
@ -1508,7 +1538,9 @@ i64 GPU_EndCommandList(GPU_CommandList *gpu_cl)
case GPU_RasterizeMode_LineList: topology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; break; case GPU_RasterizeMode_LineList: topology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; break;
case GPU_RasterizeMode_LineStrip: topology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; break; case GPU_RasterizeMode_LineStrip: topology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; break;
case GPU_RasterizeMode_TriangleList: topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; 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_TriangleStrip: topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; break;
case GPU_RasterizeMode_WireTriangleStrip: topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; break;
} }
ID3D12GraphicsCommandList_IASetPrimitiveTopology(rcl, topology); ID3D12GraphicsCommandList_IASetPrimitiveTopology(rcl, topology);
} }

View File

@ -30,6 +30,7 @@ Struct(GPU_D12_PipelineDesc)
VertexShader vs; VertexShader vs;
PixelShader ps; PixelShader ps;
ComputeShader cs; ComputeShader cs;
b32 is_wireframe;
D3D12_PRIMITIVE_TOPOLOGY_TYPE topology_type; D3D12_PRIMITIVE_TOPOLOGY_TYPE topology_type;
GPU_Format render_target_formats[GPU_MaxRenderTargets]; GPU_Format render_target_formats[GPU_MaxRenderTargets];
}; };

View File

@ -359,13 +359,13 @@ void DrawDebugConsole(b32 minimized)
i64 now_ns = TimeNs(); i64 now_ns = TimeNs();
UI_PushCheckpoint(); UI_PushCheckpoint();
{ {
UI_Box *console_box = 0;
{ {
UI_SetNext(LayoutAxis, Axis_Y); UI_SetNext(LayoutAxis, Axis_Y);
// UI_SetNext(Tint, 0); // UI_SetNext(Tint, 0);
// UI_SetNext(BorderColor, Rgba32F(1, 1, 1, 0.25)); // UI_SetNext(BorderColor, Rgba32F(1, 1, 1, 0.25));
UI_SetNext(Border, 0); UI_SetNext(Border, 0);
// UI_SetNext(Width, UI_FIT(1)); // UI_SetNext(Width, UI_FIT(1));
// UI_ForceNext(BackgroundColor, Color_Purple);
if (minimized) if (minimized)
{ {
UI_SetNext(BackgroundColor, 0); UI_SetNext(BackgroundColor, 0);
@ -376,21 +376,17 @@ void DrawDebugConsole(b32 minimized)
{ {
UI_SetNext(BackgroundColor, Rgba32F(1, 1, 1, 0.02)); UI_SetNext(BackgroundColor, Rgba32F(1, 1, 1, 0.02));
UI_SetNext(Width, UI_FILL(1, 0)); 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); UI_Push(Parent, console_box);
if (!minimized)
{
UI_BuildSpacer(UI_FILL(1, 0));
}
} }
// UI_Push(Width, UI_TXT(0)); // UI_Push(Width, UI_TXT(0));
UI_Push(Width, UI_FIT(1)); // UI_Push(Width, UI_FIT(1));
UI_Push(Height, UI_FIT(1)); // UI_Push(Height, UI_FIT(1));
UI_Push(BorderColor, Rgba32F(0.25, 0.25, 0.25, 1)); // UI_Push(BorderColor, Rgba32F(0.25, 0.25, 0.25, 1));
UI_Push(Rounding, 0); // UI_Push(Rounding, 0);
UI_Push(TextPadding, 6);
Lock lock = LockE(&g->console_logs_mutex); Lock lock = LockE(&g->console_logs_mutex);
{ {
/* Gather display logs */ /* Gather display logs */
@ -440,30 +436,30 @@ void DrawDebugConsole(b32 minimized)
FmtUintZ(datetime.milliseconds, 3), FmtUintZ(datetime.milliseconds, 3),
FmtString(text)); 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_PushCheckpoint();
{ {
UI_Push(Parent, log_box); UI_Push(Tint, Alpha32F(0xFFFFFFFF, opacity));
UI_Push(BackgroundColor, 0);
UI_Push(Border, 0);
f32 spacer = 50;
{ {
// 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(Width, UI_FILL(1, 1));
UI_SetNext(Height, UI_TXT(1)); UI_SetNext(Height, UI_TXT(1));
UI_Box *log_textbox = UI_BuildBox(UI_BoxFlag_DrawText, UI_NilKey); 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(); UI_PopCheckpoint();
} }
@ -2122,6 +2118,7 @@ void UpdateUser(void)
UI_SetNext(BorderColor, 0); UI_SetNext(BorderColor, 0);
UI_SetNext(Width, UI_FIT(1)); UI_SetNext(Width, UI_FIT(1));
UI_SetNext(Height, UI_FIT(1)); UI_SetNext(Height, UI_FIT(1));
UI_SetNext(Tint, 0);
UI_Box *dbg_box = UI_BuildBox(0, UI_NilKey); UI_Box *dbg_box = UI_BuildBox(0, UI_NilKey);
UI_PushCheckpoint(); UI_PushCheckpoint();
{ {

View File

@ -203,7 +203,6 @@ Struct(SharedUserState)
ConsoleLog *first_console_log; ConsoleLog *first_console_log;
ConsoleLog *last_console_log; ConsoleLog *last_console_log;
i32 console_log_color_indices[P_LogLevel_Count]; i32 console_log_color_indices[P_LogLevel_Count];
b32 debug_console;
//- Window -> user //- Window -> user
Mutex sys_window_events_mutex; Mutex sys_window_events_mutex;
@ -258,6 +257,9 @@ Struct(SharedUserState)
Vec2 debug_camera_pan_start; Vec2 debug_camera_pan_start;
b32 debug_draw; b32 debug_draw;
//- Debug console
b32 debug_console;
//- Per frame //- Per frame
Vec2I32 screen_size; Vec2I32 screen_size;

View File

@ -6,8 +6,8 @@ UI_Box *UI_BuildLabel(String text)
UI_Key key = UI_KeyFromString(0, text); UI_Key key = UI_KeyFromString(0, text);
UI_SetNext(Width, UI_TXT(0)); UI_SetNext(Width, UI_TXT(0));
UI_SetNext(Height, UI_TXT(0)); UI_SetNext(Height, UI_TXT(0));
UI_SetNext(Text, text);
UI_Box *box = UI_BuildBox(UI_BoxFlag_DrawText, UI_NilKey); UI_Box *box = UI_BuildBox(UI_BoxFlag_DrawText, UI_NilKey);
UI_SetDisplayText(box, text);
return box; return box;
} }
@ -35,11 +35,9 @@ UI_Box *UI_BuildSpacer(UI_Size size)
if (UI_PeekTop(Parent)->layout_axis == Axis_X) if (UI_PeekTop(Parent)->layout_axis == Axis_X)
{ {
UI_SetNext(Width, size); UI_SetNext(Width, size);
UI_SetNext(Height, UI_FILL(1, 0));
} }
else else
{ {
UI_SetNext(Width, UI_FILL(1, 0));
UI_SetNext(Height, size); UI_SetNext(Height, size);
} }
UI_Box *box = UI_BuildBox(0, UI_NilKey); UI_Box *box = UI_BuildBox(0, UI_NilKey);

View File

@ -94,10 +94,19 @@ void UI_PopCheckpoint(void)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Style stack helpers //~ 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_SharedState *g = &UI_shared_state;
UI_StyleNode *n = g->first_free_style_node; UI_StyleNode *n = g->style_tops[desc.kind];
if (!n->style.forced)
{
if (n->style.pop_when_used)
{
ZeroStruct(n);
}
else
{
n = g->first_free_style_node;
if (n) if (n)
{ {
g->first_free_style_node = n->next; g->first_free_style_node = n->next;
@ -107,11 +116,21 @@ UI_StyleNode *UI_PushStyleNode(UI_StyleKind kind, b32 pop_when_used, UI_Style de
{ {
n = PushStruct(g->build_arena, UI_StyleNode); n = PushStruct(g->build_arena, UI_StyleNode);
} }
n->pop_when_used = pop_when_used; n->next = g->style_tops[desc.kind];
}
n->style = desc; n->style = desc;
n->next = g->style_tops[kind];
n->checkpoint = g->top_checkpoint->v; n->checkpoint = g->top_checkpoint->v;
g->style_tops[kind] = n; switch (desc.kind)
{
default: break;
case UI_StyleKind_Text:
{
n->style.Text = PushString(g->build_arena, desc.Text);
} break;
}
}
g->style_tops[desc.kind] = n;
return n; return n;
} }
@ -138,7 +157,7 @@ UI_Style UI_StyleFromTopNode(UI_StyleKind kind, b32 use)
UI_SharedState *g = &UI_shared_state; UI_SharedState *g = &UI_shared_state;
UI_StyleNode *n = g->style_tops[kind]; UI_StyleNode *n = g->style_tops[kind];
UI_Style style = n->style; UI_Style style = n->style;
if (use && n->pop_when_used) if (use && n->style.pop_when_used)
{ {
g->style_tops[kind] = n->next; g->style_tops[kind] = n->next;
n->next = g->first_free_style_node; 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->layout_axis = UI_UseTop(LayoutAxis);
box->background_color = UI_UseTop(BackgroundColor); box->background_color = UI_UseTop(BackgroundColor);
box->border_color = UI_UseTop(BorderColor); box->border_color = UI_UseTop(BorderColor);
box->text_color = UI_UseTop(TextColor);
box->tint = UI_UseTop(Tint); box->tint = UI_UseTop(Tint);
box->border = UI_UseTop(Border); box->border = UI_UseTop(Border);
box->font_resource = UI_UseTop(Font); box->font_resource = UI_UseTop(Font);
box->font_size = UI_UseTop(FontSize); box->font_size = UI_UseTop(FontSize);
box->text_padding = UI_UseTop(TextPadding); box->text_padding = UI_UseTop(TextPadding);
box->rounding = UI_UseTop(Rounding); box->rounding = UI_UseTop(Rounding);
box->display_text = UI_UseTop(Text);
/* Prefetch font */ /* Prefetch font */
if (box->flags & UI_BoxFlag_DrawText) if (box->display_text.len > 0)
{ {
box->font = F_LoadFontAsync(box->font_resource, box->font_size); 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; 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) void UI_SetBackgroundTexture(UI_Box *box, GPU_Resource *texture, Vec2 uv0, Vec2 uv1)
{ {
box->background_texture = texture; box->background_texture = texture;
@ -422,9 +434,8 @@ i64 UI_EndBuild(GPU_Resource *render_target)
UI_Size pref_size = box->pref_size[axis]; UI_Size pref_size = box->pref_size[axis];
if (pref_size.kind == UI_SizeKind_Fill) if (pref_size.kind == UI_SizeKind_Fill)
{ {
UI_Box *ancestor = box->parent;
f32 ancestor_size = 0; 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]; UI_Size tmp = ancestor->pref_size[axis];
if (tmp.kind == UI_SizeKind_Pixel || tmp.kind == UI_SizeKind_TextContents) 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 */ /* Solve violations */
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index) 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->tint & 0xFF000000) != 0);
is_visible = is_visible && (box->p1.x > box->p0.x); is_visible = is_visible && (box->p1.x > box->p0.x);
is_visible = is_visible && (box->p1.y > box->p0.y); is_visible = is_visible && (box->p1.y > box->p0.y);
if (is_visible) if (is_visible || UI_DEBUG)
{ {
/* Push box rect */ /* Push box rect */
{ {
@ -685,6 +641,8 @@ i64 UI_EndBuild(GPU_Resource *render_target)
GPU_Viewport viewport = GPU_ViewportFromRect(render_viewport); GPU_Viewport viewport = GPU_ViewportFromRect(render_viewport);
GPU_Scissor scissor = GPU_ScissorFromRect(render_viewport); GPU_Scissor scissor = GPU_ScissorFromRect(render_viewport);
/* Render rects */
{
UI_RectSig sig = ZI; UI_RectSig sig = ZI;
sig.viewport_size = RoundVec2ToVec2I32(render_viewport.size); sig.viewport_size = RoundVec2ToVec2I32(render_viewport.size);
sig.sampler = GPU_SamplerStateRidFromResource(GPU_GetCommonPointSampler()); sig.sampler = GPU_SamplerStateRidFromResource(GPU_GetCommonPointSampler());
@ -700,6 +658,26 @@ i64 UI_EndBuild(GPU_Resource *render_target)
GPU_RasterizeMode_TriangleList); 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 //- Prep post pass
{ {
GPU_TransitionToWritable(cl, render_target); GPU_TransitionToWritable(cl, render_target);

View File

@ -39,11 +39,11 @@ Struct(UI_Size)
x(Size, UI_Size) \ x(Size, UI_Size) \
x(BackgroundColor, u32) \ x(BackgroundColor, u32) \
x(BorderColor, u32) \ x(BorderColor, u32) \
x(TextColor, u32) \
x(Tint, u32) \ x(Tint, u32) \
x(Border, f32) \ x(Border, f32) \
x(Font, ResourceKey) \ x(Font, ResourceKey) \
x(FontSize, u32) \ x(FontSize, u32) \
x(Text, String) \
x(TextPadding, f32) \ x(TextPadding, f32) \
x(Rounding, f32) \ x(Rounding, f32) \
/* ------------------------------------------- */ /* ------------------------------------------- */
@ -60,6 +60,8 @@ Enum(UI_StyleKind)
Struct(UI_Style) Struct(UI_Style)
{ {
UI_StyleKind kind; UI_StyleKind kind;
b32 pop_when_used;
b32 forced;
/* Union of all style fields */ /* Union of all style fields */
union union
{ {
@ -72,7 +74,6 @@ Struct(UI_Style)
Struct(UI_StyleNode) Struct(UI_StyleNode)
{ {
UI_StyleNode *next; UI_StyleNode *next;
b32 pop_when_used;
u64 checkpoint; u64 checkpoint;
UI_Style style; UI_Style style;
}; };
@ -212,13 +213,15 @@ void UI_PopCheckpoint(void);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Style helpers //~ 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_Style UI_PopStyleNode(UI_StyleKind kind);
UI_StyleNode *UI_PeekTopStyleNode(UI_StyleKind kind); UI_StyleNode *UI_PeekTopStyleNode(UI_StyleKind kind);
UI_Style UI_StyleFromTopNode(UI_StyleKind kind, b32 use); 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_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_StyleKind_##name, 0, (UI_Style) { .name = v }) #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_Pop(name, v) UI_PopStyleNode(UI_StyleKind_##name).name
#define UI_UseTop(name) UI_StyleFromTopNode(UI_StyleKind_##name, 1).name #define UI_UseTop(name) UI_StyleFromTopNode(UI_StyleKind_##name, 1).name
#define UI_PeekTop(name) UI_StyleFromTopNode(UI_StyleKind_##name, 0).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); 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); void UI_SetBackgroundTexture(UI_Box *box, GPU_Resource *texture, Vec2 uv0, Vec2 uv1);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -119,6 +119,12 @@ UI_RectPS_Output PSDef(UI_RectPS, UI_RectPS_Input input)
/* Tint */ /* Tint */
result *= input.tint_lin; result *= input.tint_lin;
/* Debug */
if (sig.debug_srgb != 0)
{
result = LinearFromSrgbU32(sig.debug_srgb);
}
UI_RectPS_Output output; UI_RectPS_Output output;
output.sv_target0 = result; output.sv_target0 = result;
return output; return output;

View File

@ -8,8 +8,13 @@ Struct(UI_RectSig)
StructuredBufferRid rects; /* 01 consts */ StructuredBufferRid rects; /* 01 consts */
SamplerStateRid sampler; /* 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) Enum(UI_RectFlag)
{ {