begin reworking format utils to take argument arrays instead of only va_list
This commit is contained in:
parent
bc76a511e6
commit
4fe18195d1
@ -531,13 +531,14 @@ String TrimWhitespace(String s)
|
||||
*
|
||||
* FmtEnd (internal): Denote the end of the va_list
|
||||
*/
|
||||
String FormatStringV(Arena *arena, String fmt, va_list args)
|
||||
String FormatString(Arena *arena, String fmt, FmtArgArray args)
|
||||
{
|
||||
u64 final_len = 0;
|
||||
u8 *final_text = ArenaNext(arena, u8);
|
||||
String result = ZI;
|
||||
result.text = ArenaNext(arena, u8);
|
||||
|
||||
u8 *end = fmt.text + fmt.len;
|
||||
b32 no_more_args = 0;
|
||||
u64 arg_idx = 0;
|
||||
for (u8 *c = fmt.text; c < end; ++c)
|
||||
{
|
||||
u8 *next = ((c + 1) < end) ? (c + 1) : (u8 *)"\0";
|
||||
@ -546,80 +547,92 @@ String FormatStringV(Arena *arena, String fmt, va_list args)
|
||||
b32 escape = !no_more_args && *c == '%' && *next == '%';
|
||||
if (escape)
|
||||
{
|
||||
/* Skip the escape '%' char from parsing */
|
||||
/* Skip the escaped '%' char from parsing */
|
||||
++c;
|
||||
}
|
||||
|
||||
if (!no_more_args && !escape && *c == '%' && *next == 'F')
|
||||
{
|
||||
String parsed_str = ZI;
|
||||
/* Detect arg type and parse to string */
|
||||
FmtArg arg = va_arg(args, FmtArg);
|
||||
String parsed_arg = ZI;
|
||||
|
||||
FmtArg arg = ZI;
|
||||
if (arg_idx < args.count)
|
||||
{
|
||||
arg = args.args[arg_idx];
|
||||
++arg_idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
no_more_args = 1;
|
||||
}
|
||||
|
||||
switch (arg.kind)
|
||||
{
|
||||
default:
|
||||
{
|
||||
/* Unknown format type */
|
||||
Assert(0);
|
||||
parsed_str = PushString(arena, Lit("<?>"));
|
||||
parsed_arg = PushString(arena, Lit("<?>"));
|
||||
no_more_args = 1;
|
||||
} break;
|
||||
|
||||
case FmtArgKind_Char:
|
||||
{
|
||||
parsed_str = StringFromChar(arena, arg.value.c);
|
||||
parsed_arg = StringFromChar(arena, arg.value.c);
|
||||
} break;
|
||||
|
||||
case FmtArgKind_String:
|
||||
{
|
||||
parsed_str = PushString(arena, arg.value.string);
|
||||
parsed_arg = PushString(arena, arg.value.string);
|
||||
} break;
|
||||
|
||||
case FmtArgKind_Uint:
|
||||
{
|
||||
parsed_str = StringFromU64(arena, arg.value.uint, 10, arg.z);
|
||||
parsed_arg = StringFromU64(arena, arg.value.uint, 10, arg.z);
|
||||
} break;
|
||||
|
||||
case FmtArgKind_Sint:
|
||||
{
|
||||
parsed_str = StringFromI64(arena, arg.value.sint, 10, arg.z);
|
||||
parsed_arg = StringFromI64(arena, arg.value.sint, 10, arg.z);
|
||||
} break;
|
||||
|
||||
case FmtArgKind_Hex:
|
||||
{
|
||||
parsed_str = StringFromU64(arena, arg.value.sint, 16, arg.z);
|
||||
parsed_arg = StringFromU64(arena, arg.value.sint, 16, arg.z);
|
||||
} break;
|
||||
|
||||
case FmtArgKind_Ptr:
|
||||
{
|
||||
parsed_str = StringFromPtr(arena, arg.value.ptr);
|
||||
parsed_arg = StringFromPtr(arena, arg.value.ptr);
|
||||
} break;
|
||||
|
||||
case FmtArgKind_Float:
|
||||
{
|
||||
parsed_str = StringFromF64(arena, arg.value.f, arg.p);
|
||||
parsed_arg = StringFromF64(arena, arg.value.f, arg.p);
|
||||
} break;
|
||||
|
||||
case FmtArgKind_Handle:
|
||||
{
|
||||
parsed_str = StringFromhandle(arena, arg.value.handle.h64[0], arg.value.handle.h64[1]);
|
||||
parsed_arg = StringFromhandle(arena, arg.value.handle.h64[0], arg.value.handle.h64[1]);
|
||||
} break;
|
||||
|
||||
case FmtArgKind_Uid:
|
||||
{
|
||||
parsed_str = StringFromUid(arena, arg.value.uid);
|
||||
parsed_arg = StringFromUid(arena, arg.value.uid);
|
||||
} break;
|
||||
|
||||
case FmtArgKind_End:
|
||||
{
|
||||
/* Unexpected end. Not enough FMT args passed to function. */
|
||||
Assert(0);
|
||||
parsed_str = PushString(arena, Lit("<?>"));
|
||||
parsed_arg = PushString(arena, Lit("<?>"));
|
||||
no_more_args = 1;
|
||||
} break;
|
||||
}
|
||||
|
||||
/* Update final string len / start */
|
||||
final_len += parsed_str.len;
|
||||
final_len += parsed_arg.len;
|
||||
|
||||
/* Skip 'F' from parsing */
|
||||
++c;
|
||||
}
|
||||
@ -634,26 +647,63 @@ String FormatStringV(Arena *arena, String fmt, va_list args)
|
||||
#if IsRtcEnabled
|
||||
if (!no_more_args)
|
||||
{
|
||||
FmtArg last_arg = va_arg(args, FmtArg);
|
||||
/* End arg not reached. Too many FMT values passed to function. */
|
||||
FmtArg last_arg = ZI;
|
||||
if (arg_idx < args.count)
|
||||
{
|
||||
last_arg = args.args[arg_idx];
|
||||
}
|
||||
/* End arg not reached. Too many args supplied. */
|
||||
Assert(last_arg.kind == FmtArgKind_End);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (String)
|
||||
{
|
||||
.len = final_len,
|
||||
.text = final_text
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
String FormatString_(Arena *arena, String fmt, ...)
|
||||
String FormatStringV_(Arena *arena, String fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
String new_str = FormatStringV(arena, fmt, args);
|
||||
String result = FormatStringVL(arena, fmt, args);
|
||||
va_end(args);
|
||||
return new_str;
|
||||
return result;
|
||||
}
|
||||
|
||||
FmtArgArray FmtArgsFromVaList(Arena *arena, va_list args)
|
||||
{
|
||||
FmtArgArray result = ZI;
|
||||
result.args = ArenaNext(arena, FmtArg);
|
||||
{
|
||||
b32 done = 0;
|
||||
while (!done)
|
||||
{
|
||||
FmtArg arg = va_arg(args, FmtArg);
|
||||
*PushStructNoZero(arena, FmtArg) = arg;
|
||||
++result.count;
|
||||
switch (arg.kind)
|
||||
{
|
||||
default:
|
||||
{
|
||||
/* Last arg reached */
|
||||
done = 1;
|
||||
} break;
|
||||
|
||||
case FmtArgKind_Char:
|
||||
case FmtArgKind_String:
|
||||
case FmtArgKind_Uint:
|
||||
case FmtArgKind_Sint:
|
||||
case FmtArgKind_Hex:
|
||||
case FmtArgKind_Ptr:
|
||||
case FmtArgKind_Float:
|
||||
case FmtArgKind_Uid:
|
||||
case FmtArgKind_Handle:
|
||||
{
|
||||
/* Continue */
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
@ -43,6 +43,12 @@ Struct(FmtArg)
|
||||
} value;
|
||||
};
|
||||
|
||||
Struct(FmtArgArray)
|
||||
{
|
||||
u64 count;
|
||||
FmtArg *args;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Unicode types
|
||||
|
||||
@ -111,10 +117,23 @@ String StringFromList(Arena *arena, StringList l, String separator);
|
||||
#define FmtUid(v, ...) FMTARG(FmtArgKind_Uid, .value.uid = (v), __VA_ARGS__)
|
||||
#define FmtEnd FMTARG(FmtArgKind_End) /* Denotes end of VA list */
|
||||
|
||||
#define StringF(arena, lit, ...) FormatString_((arena), Lit(lit), __VA_ARGS__, FmtEnd)
|
||||
#define FormatString(arena, fmt, ...) FormatString_((arena), (fmt), __VA_ARGS__, FmtEnd)
|
||||
String FormatString_(Arena *arena, String fmt, ...);
|
||||
String FormatStringV(Arena *arena, String fmt, va_list args);
|
||||
// #define StringF(arena, lit, ...) FormatString_((arena), Lit(lit), __VA_ARGS__, FmtEnd)
|
||||
// #define FormatString(arena, fmt, ...) FormatString_((arena), (fmt), __VA_ARGS__, FmtEnd)
|
||||
// String FormatString_(Arena *arena, String fmt, ...);
|
||||
// String FormatStringV(Arena *arena, String fmt, va_list args);
|
||||
|
||||
String FormatString(Arena *arena, String fmt, FmtArgArray args);
|
||||
String StringF_(Arena *arena, String fmt, ...);
|
||||
#define StringF(arena, lit, ...) StringF_((arena), Lit(lit), __VA_ARGS__, FmtEnd)
|
||||
|
||||
FmtArgArray FmtArgsFromVaList(Arena *arena, va_list vl);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Unicode
|
||||
|
||||
@ -137,7 +137,7 @@ void G_Bootstrap(void)
|
||||
hr = DXGIGetDebugInterface1(0, &IID_IDXGIInfoQueue, (void **)&dxgi_info);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Panic(Lit("Failed to get DXGI debug interface"));
|
||||
Panic(Lit("Failed to retrieve DXGI debug interface"));
|
||||
}
|
||||
IDXGIInfoQueue_SetBreakOnSeverity(dxgi_info, DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, 1);
|
||||
IDXGIInfoQueue_SetBreakOnSeverity(dxgi_info, DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, 1);
|
||||
@ -487,6 +487,7 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
|
||||
if (ok && (!IsResourceNil(desc.vs.resource) || !IsResourceNil(desc.ps.resource)))
|
||||
{
|
||||
D3D12_RASTERIZER_DESC raster_desc = ZI;
|
||||
{
|
||||
if (desc.is_wireframe)
|
||||
{
|
||||
raster_desc.FillMode = D3D12_FILL_MODE_WIREFRAME;
|
||||
@ -505,8 +506,10 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
|
||||
raster_desc.AntialiasedLineEnable = 0;
|
||||
raster_desc.ForcedSampleCount = 0;
|
||||
raster_desc.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
|
||||
}
|
||||
|
||||
D3D12_BLEND_DESC blend_desc = ZI;
|
||||
{
|
||||
blend_desc.AlphaToCoverageEnable = 0;
|
||||
blend_desc.IndependentBlendEnable = 0;
|
||||
blend_desc.RenderTarget[0].BlendEnable = 1;
|
||||
@ -517,15 +520,18 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
|
||||
blend_desc.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA;
|
||||
blend_desc.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
|
||||
blend_desc.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
|
||||
}
|
||||
|
||||
D3D12_DEPTH_STENCIL_DESC ds_desc = ZI;
|
||||
{
|
||||
ds_desc.DepthEnable = 0;
|
||||
ds_desc.StencilEnable = 0;
|
||||
}
|
||||
|
||||
String vs = DataFromResource(desc.vs.resource);
|
||||
String ps = DataFromResource(desc.ps.resource);
|
||||
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc = ZI;
|
||||
{
|
||||
pso_desc.pRootSignature = g->bindless_rootsig;
|
||||
pso_desc.VS.pShaderBytecode = vs.text;
|
||||
pso_desc.VS.BytecodeLength = vs.len;
|
||||
@ -551,6 +557,7 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
hr = ID3D12Device_CreateGraphicsPipelineState(g->device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
@ -561,11 +568,12 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
|
||||
else if (ok)
|
||||
{
|
||||
String cs = DataFromResource(desc.cs.resource);
|
||||
|
||||
D3D12_COMPUTE_PIPELINE_STATE_DESC pso_desc = ZI;
|
||||
{
|
||||
pso_desc.pRootSignature = g->bindless_rootsig;
|
||||
pso_desc.CS.pShaderBytecode = cs.text;
|
||||
pso_desc.CS.BytecodeLength = cs.len;
|
||||
}
|
||||
hr = ID3D12Device_CreateComputePipelineState(g->device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
@ -2748,7 +2756,7 @@ G_ResourceHandle G_PrepareBackbuffer(G_SwapchainHandle swapchain_handle, G_Forma
|
||||
if (FAILED(hr))
|
||||
{
|
||||
/* TODO: Don't panic */
|
||||
Panic(Lit("Failed to get swapchain buffer"));
|
||||
Panic(Lit("Failed to retrieve swapchain buffer"));
|
||||
}
|
||||
ZeroStruct(backbuffer);
|
||||
backbuffer->d3d_resource = d3d_resource;
|
||||
@ -2825,6 +2833,8 @@ void G_CommitBackbuffer(G_ResourceHandle backbuffer_handle, i32 vsync)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Collection worker
|
||||
|
||||
/* TODO: Move this to common */
|
||||
|
||||
void G_D12_CollectionWorkerEntry(WaveLaneCtx *lane)
|
||||
{
|
||||
G_QueueKind queue_kind = G_QueueKind_Direct;
|
||||
@ -2861,6 +2871,7 @@ void G_D12_CollectionWorkerEntry(WaveLaneCtx *lane)
|
||||
G_CommitCommandList(cl);
|
||||
|
||||
G_SyncCpu(G_MaskFromQueue(queue_kind));
|
||||
|
||||
u32 attempted_print_bytes_count = *(G_StructFromResource(readback_buff, u32) + 0);
|
||||
u32 prints_count = *(G_StructFromResource(readback_buff, u32) + 1);
|
||||
u32 overflows_count = *(G_StructFromResource(readback_buff, u32) + 2);
|
||||
@ -2891,49 +2902,44 @@ void G_D12_CollectionWorkerEntry(WaveLaneCtx *lane)
|
||||
at += chars_count;
|
||||
}
|
||||
|
||||
FmtArg *args = 0;
|
||||
FmtArgArray args = ZI;
|
||||
args.count = args_count;
|
||||
{
|
||||
if (args_count > 0)
|
||||
{
|
||||
args = PushStructs(scratch.arena, FmtArg, args_count);
|
||||
args.args = PushStructs(scratch.arena, FmtArg, args_count);
|
||||
for (u32 arg_idx = 0; arg_idx <= args_count; ++arg_idx)
|
||||
{
|
||||
G_FmtArgKind gpu_kind = (G_FmtArgKind)(*at);
|
||||
at += 1;
|
||||
u32 gpu_data = *(u32 *)at;
|
||||
|
||||
u32 gpu_value = *(u32 *)at;
|
||||
at += 4;
|
||||
|
||||
FmtArg *dst = &args[arg_idx];
|
||||
FmtArg *dst = &args.args[arg_idx];
|
||||
switch (gpu_kind)
|
||||
{
|
||||
case G_FmtArgKind_U32:
|
||||
{
|
||||
dst->kind = FmtArgKind_Uint;
|
||||
dst->value.uint = gpu_data;
|
||||
dst->value.uint = gpu_value;
|
||||
} break;
|
||||
case G_FmtArgKind_I32:
|
||||
{
|
||||
dst->kind = FmtArgKind_Sint;
|
||||
dst->value.sint = (i32)gpu_data;
|
||||
dst->value.sint = (i32)gpu_value;
|
||||
} break;
|
||||
case G_FmtArgKind_F32:
|
||||
{
|
||||
dst->kind = FmtArgKind_Float;
|
||||
dst->value.f = *(f32 *)&gpu_data;
|
||||
dst->value.f = *(f32 *)&gpu_value;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// String final_str = ZI;
|
||||
// if (args_count > 0)
|
||||
// {
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// final_str = PushString(scratch.arena, fmt);
|
||||
// }
|
||||
String final_str = FormatString(scratch.arena, fmt, args);
|
||||
|
||||
at = (u8 *)AlignU64((u64)at, 4);
|
||||
}
|
||||
|
||||
@ -163,8 +163,9 @@ Struct(G_FmtArg)
|
||||
alloc_size += 4; /* Header */
|
||||
alloc_size += chunks_count * 4; /* Chunks */
|
||||
|
||||
/* Atomic fetch + add to base counter */
|
||||
u32 base;
|
||||
rw.InterlockedAdd(0, alloc_size, base); /* Write to base counter */
|
||||
rw.InterlockedAdd(0, alloc_size, base);
|
||||
|
||||
u32 pos = base;
|
||||
pos += 4; /* Offset for base counter */
|
||||
@ -176,7 +177,7 @@ Struct(G_FmtArg)
|
||||
/* Increment success counter */
|
||||
rw.InterlockedAdd(4, 1);
|
||||
|
||||
/* Store header */
|
||||
/* Write header */
|
||||
{
|
||||
u32 header = 0;
|
||||
header |= (buff.fmt_size << 0) & 0x0000FFFF;
|
||||
@ -184,7 +185,8 @@ Struct(G_FmtArg)
|
||||
rw.Store(base + pos, header);
|
||||
pos += 4;
|
||||
}
|
||||
/* Store chunks */
|
||||
|
||||
/* Write chunks */
|
||||
for (u32 chunk_idx = 0; chunk_idx < chunks_count; ++chunk_idx)
|
||||
{
|
||||
u32 chunk = buff.char_chunks[chunk_idx];
|
||||
|
||||
Loading…
Reference in New Issue
Block a user