ensure createprocess children don't share pipes

This commit is contained in:
jacob 2025-09-09 00:41:59 -05:00
parent 43a82bd540
commit 84f5c503df
14 changed files with 250 additions and 137 deletions

View File

@ -207,7 +207,7 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
#endif
//- Static
#define LocalPersist static
#define PERSIST static
#define Global static
/* TODO: Remove this */
#define internal static

View File

@ -164,7 +164,7 @@ i64 SignF64(f64 f)
/* Taken from https://gist.github.com/orlp/3551590 */
u64 PowU64(u64 base, u8 exp)
{
LocalPersist const u8 highest_bit_set[] = {
PERSIST const u8 highest_bit_set[] = {
0, 1, 2, 2, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5,
@ -281,8 +281,8 @@ u64 AlignU64Pow2(u64 x)
* https://github.com/freebsd/freebsd-src/blob/main/lib/msun/src/e_logf.c */
f32 LnF32(f32 x)
{
LocalPersist const f32 ln2_hi = 6.9313812256e-01f;
LocalPersist const f32 ln2_lo = 9.0580006145e-06f;
PERSIST const f32 ln2_hi = 6.9313812256e-01f;
PERSIST const f32 ln2_lo = 9.0580006145e-06f;
i32 x_int = *(i32 *)&x;
@ -376,14 +376,14 @@ f32 LnF32(f32 x)
* https://github.com/freebsd/freebsd-src/blob/main/lib/msun/src/e_expf.c */
f32 ExpF32(f32 x)
{
LocalPersist const f32 half[2] = { 0.5, -0.5 };
LocalPersist const f32 o_threshold = 8.8721679688e+01f;
LocalPersist const f32 u_threshold = -1.0397208405e+02f;
LocalPersist const f32 ln2_hi[2] = { 6.9314575195e-01f, -6.9314575195e-01f };
LocalPersist const f32 ln2_lo[2] = { 1.4286067653e-06f, -1.4286067653e-06f };
LocalPersist const f32 inv_ln2 = 1.4426950216e+00f;
LocalPersist const f32 huge = 1.0e+30f;
LocalPersist const f32 two_m100 = 7.8886090522e-31f;
PERSIST const f32 half[2] = { 0.5, -0.5 };
PERSIST const f32 o_threshold = 8.8721679688e+01f;
PERSIST const f32 u_threshold = -1.0397208405e+02f;
PERSIST const f32 ln2_hi[2] = { 6.9314575195e-01f, -6.9314575195e-01f };
PERSIST const f32 ln2_lo[2] = { 1.4286067653e-06f, -1.4286067653e-06f };
PERSIST const f32 inv_ln2 = 1.4426950216e+00f;
PERSIST const f32 huge = 1.0e+30f;
PERSIST const f32 two_m100 = 7.8886090522e-31f;
u32 x_uint = *(u32 *)&x;
i32 x_sign_bit = (i32)((x_uint >> 31) & 1);

View File

@ -5,7 +5,7 @@
Utf8DecodeResult DecodeUtf8(String str)
{
LocalPersist const u8 lengths[32] = {
const u8 lengths[32] = {
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,2,2,2,2,3,3,4,5
};

View File

@ -358,6 +358,20 @@ void W32_WaitReleaseThread(W32_Thread *thread)
////////////////////////////////
//~ Win32 wait list
W32_WaitBin *W32_WaitBinFromAddr(u64 addr)
{
W32_SharedJobCtx *g = &W32_shared_job_ctx;
u64 mixed = RandU64FromSeed(addr);
return &g->wait_addr_bins[mixed % W32_NumWaitAddrBins];
}
W32_WaitBin *W32_WaitBinFromTime(u64 time)
{
W32_SharedJobCtx *g = &W32_shared_job_ctx;
u64 mixed = RandU64FromSeed(time);
return &g->wait_addr_bins[mixed % W32_NumWaitTimeBins];
}
/* REQUIRED: Caller must have acquired `wake_lock` for each fiber in array */
void W32_WakeLockedFibers(i32 num_fibers, W32_Fiber **fibers)
{
@ -378,7 +392,7 @@ void W32_WakeLockedFibers(i32 num_fibers, W32_Fiber **fibers)
W32_WaitList *wait_time_list = 0;
if (wait_addr != 0)
{
wait_addr_bin = &g->wait_addr_bins[wait_addr % W32_NumWaitAddrBins];
wait_addr_bin = W32_WaitBinFromAddr(wait_addr);
LockTicketMutex(&wait_addr_bin->lock);
for (W32_WaitList *tmp = wait_addr_bin->first_wait_list; tmp && !wait_addr_list; tmp = tmp->next_in_bin)
{
@ -390,7 +404,7 @@ void W32_WakeLockedFibers(i32 num_fibers, W32_Fiber **fibers)
}
if (wait_time != 0)
{
wait_time_bin = &g->wait_time_bins[wait_time % W32_NumWaitTimeBins];
wait_time_bin = W32_WaitBinFromTime(wait_time);
LockTicketMutex(&wait_time_bin->lock);
for (W32_WaitList *tmp = wait_time_bin->first_wait_list; tmp && !wait_time_list; tmp = tmp->next_in_bin)
{
@ -586,10 +600,8 @@ void W32_WakeLockedFibers(i32 num_fibers, W32_Fiber **fibers)
void W32_WakeByAddress(void *addr, i32 count)
{
TempArena scratch = BeginScratchNoConflict();
W32_SharedJobCtx *g = &W32_shared_job_ctx;
u64 wait_addr_bin_index = (u64)addr % W32_NumWaitAddrBins;
W32_WaitBin *wait_addr_bin = &g->wait_addr_bins[wait_addr_bin_index];
W32_WaitBin *wait_addr_bin = W32_WaitBinFromAddr((u64)addr);
W32_WaitList *wait_addr_list = 0;
/* Get list of waiting fibers */
@ -648,10 +660,8 @@ void W32_WakeByAddress(void *addr, i32 count)
void W32_WakeByTime(u64 time)
{
TempArena scratch = BeginScratchNoConflict();
W32_SharedJobCtx *g = &W32_shared_job_ctx;
u64 wait_time_bin_index = (u64)time % W32_NumWaitTimeBins;
W32_WaitBin *wait_time_bin = &g->wait_time_bins[wait_time_bin_index];
W32_WaitBin *wait_time_bin = W32_WaitBinFromTime(time);
W32_WaitList *wait_time_list = 0;
/* Build list of waiters to resume */
@ -914,7 +924,7 @@ W32_ThreadDef(W32_JobWorkerEntryFunc, worker_ctx_arg)
/* TODO: Pin non-worker threads to other cores */
HANDLE thread_handle = GetCurrentThread();
if (pool->thread_priority)
if (pool->thread_priority != 0)
{
__profn("Set priority");
b32 success = SetThreadPriority(thread_handle, pool->thread_priority) != 0;
@ -1083,10 +1093,8 @@ W32_ThreadDef(W32_JobWorkerEntryFunc, worker_ctx_arg)
wait_time = current_scheduler_cycle + MaxI64((i64)((f64)wait_timeout_ns / (f64)current_scheduler_cycle_period_ns), 1);
}
u64 wait_addr_bin_index = (u64)wait_addr % W32_NumWaitAddrBins;
u64 wait_time_bin_index = (u64)wait_time % W32_NumWaitTimeBins;
W32_WaitBin *wait_addr_bin = &g->wait_addr_bins[wait_addr_bin_index];
W32_WaitBin *wait_time_bin = &g->wait_time_bins[wait_time_bin_index];
W32_WaitBin *wait_addr_bin = W32_WaitBinFromAddr((u64)wait_addr);
W32_WaitBin *wait_time_bin = W32_WaitBinFromTime((u64)wait_time);
if (wait_addr != 0) LockTicketMutex(&wait_addr_bin->lock);
{

View File

@ -275,6 +275,9 @@ void W32_WaitReleaseThread(W32_Thread *thread);
////////////////////////////////
//~ Wait list operations
W32_WaitBin *W32_WaitBinFromAddr(u64 addr);
W32_WaitBin *W32_WaitBinFromTime(u64 time);
void W32_WakeLockedFibers(i32 num_fibers, W32_Fiber **fibers);
void W32_WakeByAddress(void *addr, i32 count);
void W32_WakeByTime(u64 time);

View File

@ -94,7 +94,7 @@ void D_DrawCircle(GPU_RenderSig *sig, Vec2 pos, f32 radius, u32 color, u32 detai
void D_DrawQuad(GPU_RenderSig *sig, Quad quad, u32 color)
{
LocalPersist u32 indices_array[6] = {
PERSIST const u32 indices_array[6] = {
0, 1, 2,
0, 2, 3
};

View File

@ -6,7 +6,7 @@ JobDef(F_LoadJob, sig, _)
__prof;
TempArena scratch = BeginScratchNoConflict();
Readonly LocalPersist u32 font_codes[] = {
PERSIST Readonly u32 font_codes[] = {
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,
0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,
0x3C,0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,

View File

@ -5,7 +5,7 @@ GPU_D12_SharedState GPU_D12_shared_state = ZI;
GPU_D12_FiberState *GPU_D12_FiberStateFromId(i16 fiber_id)
{
LocalPersist GPU_D12_FiberState *fiber_states[MaxFibers] = ZI;
PERSIST GPU_D12_FiberState *fiber_states[MaxFibers] = ZI;
GPU_D12_FiberState *result = fiber_states[fiber_id];
if (!result)
{
@ -16,6 +16,12 @@ GPU_D12_FiberState *GPU_D12_FiberStateFromId(i16 fiber_id)
return result;
}
GPU_D12_SharedState *GPU_D12_GetSharedState(void)
{
PERSIST GPU_D12_SharedState g = ZI;
return &g;
}
////////////////////////////////
//~ Helpers
@ -69,6 +75,7 @@ void GPU_D12_EndRawCommandList(GPU_D12_RawCommandList *cl)
void GPU_Startup(void)
{
GPU_D12_SharedState *g = GPU_D12_GetSharedState();
}
////////////////////////////////

View File

@ -158,12 +158,11 @@ Struct(GPU_D12_SharedState)
i32 _;
};
extern GPU_D12_SharedState GPU_D12_shared_state;
////////////////////////////////
//~ State operations
GPU_D12_FiberState *GPU_D12_FiberStateFromId(i16 fiber_id);
GPU_D12_SharedState *GPU_D12_GetSharedState(void);
////////////////////////////////
//~ Helpers

View File

@ -65,21 +65,13 @@
/* TODO: Move this to OS layer */
void Echo(String msg)
{
HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
if (console_handle != INVALID_HANDLE_VALUE)
{
WriteFile(console_handle, msg.text, msg.len, 0, 0);
}
OS_Echo(msg);
}
void EchoLine(String msg)
{
HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
if (console_handle != INVALID_HANDLE_VALUE)
{
WriteFile(console_handle, msg.text, msg.len, 0, 0);
WriteFile(console_handle, "\n", 1, 0, 0);
}
OS_Echo(msg);
OS_Echo(Lit("\n"));
}
Struct(LineCol)
@ -113,13 +105,21 @@ LineCol LineColFromPos(String data, i64 pos)
////////////////////////////////
//~ OS command job
JobDecl(RunCommandJob, { String *cmds; OS_CommandResult *results; });
Struct(RunCommandResult)
{
OS_CommandResult cmd_result;
i64 elapsed_ns;
};
JobDecl(RunCommandJob, { String *cmds; RunCommandResult *results; });
JobDef(RunCommandJob, sig, id)
{
i64 start_ns = TimeNs();
Arena *arena = PermArena();
String cmd = sig->cmds[id];
OS_CommandResult *result = &sig->results[id];
*result = OS_RunCommand(arena, cmd);
RunCommandResult *result = &sig->results[id];
result->cmd_result = OS_RunCommand(arena, cmd);
result->elapsed_ns = TimeNs() - start_ns;
}
////////////////////////////////
@ -514,7 +514,7 @@ JobDef(StepJob, sig, id)
//- Compile shaders
String *compile_cmds = PushStructs(arena, String, shader_entries_count);
OS_CommandResult *compile_results = PushStructs(arena, OS_CommandResult, shader_entries_count);
RunCommandResult *compile_results = PushStructs(arena, RunCommandResult, shader_entries_count);
{
i32 i = 0;
for (ShaderEntry *e = first_shader_entry; e; e = e->next)
@ -525,7 +525,7 @@ JobDef(StepJob, sig, id)
: Lit("vs_6_6");
String *compile_cmd = &compile_cmds[i];
*compile_cmd = StringF(arena,
"dxc.exe -T %F -E %F -Fo %F/%F %F %F",
"cmd /c dxc.exe -T %F -E %F -Fo %F/%F %F %F",
FmtString(target),
FmtString(e->name),
FmtString(shaders_out_dir),
@ -544,15 +544,16 @@ JobDef(StepJob, sig, id)
i32 i = 0;
for (ShaderEntry *e = first_shader_entry; e; e = e->next)
{
OS_CommandResult compile_result = compile_results[i];
RunCommandResult compile_result = compile_results[i];
OS_CommandResult cmd_result = compile_result.cmd_result;
if (result->return_code == 0)
{
PushStringToList(arena, output, StringF(arena, "%F:%F", FmtString(F_GetFileName(gpu_out_file)), FmtString(e->name)));
if (compile_result.output.len > 0)
PushStringToList(arena, output, StringF(arena, "%F:%F %Fs", FmtString(F_GetFileName(gpu_out_file)), FmtString(e->name), FmtFloat(SecondsFromNs(compile_result.elapsed_ns))));
if (cmd_result.output.len > 0)
{
PushStringToList(arena, output, compile_result.output);
PushStringToList(arena, output, cmd_result.output);
}
result->return_code = compile_result.code;
result->return_code = cmd_result.code;
}
++i;
}
@ -989,8 +990,6 @@ void StartupMeta(void)
Counter step_counter = ZI;
RunJob(countof(params_array), StepJob, JobPool_Hyper, JobPriority_Normal, &step_counter, .params = params_array, .results = results_array);
EchoLine(Lit("[Compiling]"));
YieldOnCounter(&step_counter);
////////////////////////////////
@ -1011,13 +1010,13 @@ void StartupMeta(void)
String shader_output = StringFromList(arena, shader_result->output_lines, Lit("\n"));
String resource_output = StringFromList(arena, resource_result->output_lines, Lit("\n"));
EchoLine(StringF(arena, "----- Built C in %Fs", FmtFloat(SecondsFromNs(program_result->elapsed_ns))));
EchoLine(StringF(arena, ">>>>> Built C in %Fs", FmtFloat(SecondsFromNs(program_result->elapsed_ns))));
if (program_output.len > 0) EchoLine(program_output);
EchoLine(StringF(arena, "----- Built shaders in %Fs", FmtFloat(SecondsFromNs(shader_result->elapsed_ns))));
EchoLine(StringF(arena, ">>>>> Built shaders in %Fs", FmtFloat(SecondsFromNs(shader_result->elapsed_ns))));
if (shader_output.len > 0) EchoLine(shader_output);
EchoLine(StringF(arena, "----- Built resources in %Fs", FmtFloat(SecondsFromNs(resource_result->elapsed_ns))));
EchoLine(StringF(arena, ">>>>> Built resources in %Fs", FmtFloat(SecondsFromNs(resource_result->elapsed_ns))));
if (resource_output.len > 0) EchoLine(resource_output);
}
@ -1033,7 +1032,6 @@ void StartupMeta(void)
String shader_obj_files_str = StringFromList(arena, shader_result->obj_files, Lit(" "));
String resource_obj_files_str = StringFromList(arena, resource_result->obj_files, Lit(" "));
EchoLine(Lit("[Linking]"));
String cmd = StringF(arena,
"cmd /c link.exe %F %F %F /OUT:%F %F %F",
FmtString(program_obj_files_str),

View File

@ -53,4 +53,5 @@ void OS_Rm(String path);
////////////////////////////////
//~ @hookdecl Shell operations
void OS_Echo(String msg);
OS_CommandResult OS_RunCommand(Arena *arena, String cmd);

View File

@ -1,3 +1,30 @@
////////////////////////////////
//~ Win32 helpers
String W32_StringFromError(Arena *arena, DWORD err)
{
String result = ZI;
char *msg_cstr = 0;
i64 len = FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
0,
err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&msg_cstr,
0,
0);
if (len > 0)
{
result = PushString(arena, TrimWhitespace(StringFromCstr(msg_cstr, len)));
LocalFree(msg_cstr);
}
else
{
result = StringF(arena, "Unknown win32 error - %F", FmtHex(err));
}
return result;
}
////////////////////////////////
//~ @hookdef Startup hook
@ -181,93 +208,158 @@ void OS_Rm(String path)
////////////////////////////////
//~ @hookdef Shell hooks
void OS_Echo(String msg)
{
HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
if (console_handle != INVALID_HANDLE_VALUE)
{
WriteFile(console_handle, msg.text, msg.len, 0, 0);
}
}
OS_CommandResult OS_RunCommand(Arena *arena, String cmd)
{
TempArena scratch = BeginScratch(arena);
OS_CommandResult result = ZI;
b32 ok = 1;
wchar_t *cmd_wstr = WstrFromString(scratch.arena, cmd);
SECURITY_ATTRIBUTES sa = ZI;
sa.nLength = sizeof(sa);
sa.bInheritHandle = 1;
sa.bInheritHandle = 0;
HANDLE pipe_read, pipe_write;
if (CreatePipe(&pipe_read, &pipe_write, &sa, 0))
/* Create pipe */
HANDLE pipe_read = 0;
HANDLE pipe_write = 0;
if (ok)
{
SetHandleInformation(pipe_read, HANDLE_FLAG_INHERIT, 0);
STARTUPINFO si = ZI;
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
si.hStdOutput = pipe_write;
si.hStdError = pipe_write;
PROCESS_INFORMATION pi = ZI;
result.output.text = PushDry(arena, u8);
if (!CreateProcessW(0, cmd_wstr, 0, 0, 1, 0, 0, 0, &si, &pi))
ok = CreatePipe(&pipe_read, &pipe_write, &sa, 0) != 0;
if (!ok)
{
DWORD err = GetLastError();
char *msg_cstr = 0;
i64 len = FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
0,
err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&msg_cstr,
0,
0);
if (len > 0)
{
result.output = PushString(arena, StringFromCstr(msg_cstr, len));
LocalFree(msg_cstr);
}
else
{
result.output = Lit("Failed to create process");
}
result.code = -1;
} else {
CloseHandle(pipe_write);
b32 exit_code_valid = 0;
i32 exit_code = 0;
b32 stdout_finished = 0;
while (!stdout_finished)
{
u8 buff[4096] = ZI;
DWORD bytes_read = 0;
if (!ReadFile(pipe_read, buff, countof(buff), &bytes_read, 0))
{
if (GetLastError() == ERROR_BROKEN_PIPE)
{
GetExitCodeProcess(pi.hProcess, &exit_code);
exit_code_valid = 1;
}
stdout_finished = 1;
}
PushStructsNoZero(arena, u8, bytes_read);
CopyBytes(result.output.text + result.output.len, buff, bytes_read);
result.output.len += bytes_read;
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
if (exit_code_valid)
{
result.code = exit_code;
} else {
result.code = -1;
}
result.output = Lit("Failed to create pipe");
pipe_read = 0;
pipe_write = 0;
}
CloseHandle(pipe_read);
}
else
/* Duplicate pipe for child process */
HANDLE child_pipe_write = 0;
if (ok)
{
ok = DuplicateHandle(GetCurrentProcess(), pipe_write, GetCurrentProcess(), &child_pipe_write, 0, 1, DUPLICATE_SAME_ACCESS) != 0;
if (!ok)
{
result.output = Lit("Failed to create child pipe");
child_pipe_write = 0;
}
}
/* Initialize attrs list */
LPPROC_THREAD_ATTRIBUTE_LIST attrs = ZI;
if (ok)
{
u64 attrs_size = 0;
InitializeProcThreadAttributeList(0, 1, 0, &attrs_size);
ok = attrs_size > 0;
if (ok)
{
attrs = PushBytes(scratch.arena, attrs_size, 64);
ok = InitializeProcThreadAttributeList(attrs, 1, 0, &attrs_size) != 0;
}
if (!ok)
{
result.output = Lit("Failed to initialize attrs list");
}
}
/* Build the handle inheritance whitelist */
if (ok) {
HANDLE inherit_list[] = { child_pipe_write };
ok = UpdateProcThreadAttribute(attrs, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, inherit_list, sizeof(inherit_list), 0, 0) != 0;
if (!ok)
{
result.output = Lit("Failed to update attributes");
}
}
/* Create process */
/* TODO: Allow caller to set child process's thread affinity by job pool */
HANDLE process = 0;
HANDLE process_thread = 0;
if (ok)
{
PROCESS_INFORMATION pi = ZI;
STARTUPINFOEXW si = ZI;
si.StartupInfo.cb = sizeof(si);
si.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
si.StartupInfo.hStdOutput = child_pipe_write;
si.StartupInfo.hStdError = child_pipe_write;
si.lpAttributeList = attrs;
ok = CreateProcessW(0, cmd_wstr, 0, 0, 1, EXTENDED_STARTUPINFO_PRESENT, 0, 0, &si.StartupInfo, &pi) != 0;
if (ok)
{
process = pi.hProcess;
process_thread = pi.hThread;
}
else
{
result.output = W32_StringFromError(arena, GetLastError());
}
/* Close write pipe handles */
{
CloseHandle(child_pipe_write);
CloseHandle(pipe_write);
child_pipe_write = 0;
pipe_write = 0;
}
}
/* Read process output */
if (ok)
{
result.output.text = PushDry(arena, u8);
b32 exit_code_valid = 0;
i32 exit_code = 0;
b32 stdout_finished = 0;
while (!stdout_finished)
{
u8 buff[4096] = ZI;
DWORD bytes_read = 0;
if (!ReadFile(pipe_read, buff, countof(buff), &bytes_read, 0))
{
DWORD err = GetLastError();
if (err == ERROR_BROKEN_PIPE)
{
GetExitCodeProcess(process, &exit_code);
exit_code_valid = 1;
}
else
{
result.output.len += W32_StringFromError(arena, err).len;
}
stdout_finished = 1;
}
PushStructsNoZero(arena, u8, bytes_read);
CopyBytes(result.output.text + result.output.len, buff, bytes_read);
result.output.len += bytes_read;
}
if (exit_code_valid)
{
result.code = exit_code;
}
}
/* Close handles */
if (attrs) DeleteProcThreadAttributeList(attrs);
if (process_thread) CloseHandle(process_thread);
if (process) CloseHandle(process);
if (child_pipe_write) CloseHandle(child_pipe_write);
if (pipe_read) CloseHandle(pipe_read);
if (pipe_write) CloseHandle(pipe_write);
if (!ok && result.code == 0)
{
result.output = Lit("Failed to create pipe");
result.code = -1;
}

View File

@ -3,3 +3,8 @@
#pragma comment(lib, "kernel32")
#pragma comment(lib, "user32")
////////////////////////////////
//~ Win32 helpers
String W32_StringFromError(Arena *arena, DWORD err);

View File

@ -288,7 +288,7 @@ void DrawDebugConsole(i32 level, b32 minimized)
f32 spacing = 0;
f32 bg_margin = 5;
LocalPersist u32 colors[P_LogLevel_Count][2] = ZI;
u32 colors[P_LogLevel_Count][2] = ZI;
SetBytes(colors, 0xFF, sizeof(colors));
#if 1
colors[P_LogLevel_Debug][0] = Rgb32F(0.4, 0.1, 0.4); colors[P_LogLevel_Debug][1] = Rgb32F(0.5, 0.2, 0.5);
@ -2149,12 +2149,12 @@ void UpdateUser(P_Window *window)
if (g->shade_target && !EqVec2I32(g->render_size, GPU_GetTextureSize(g->shade_target)))
{
__profn("Release render resources");
GPU_ReleaseResource(g->albedo, g->render_fence, GPU_ReleaseFlag_None);
GPU_ReleaseResource(g->emittance, g->render_fence, GPU_ReleaseFlag_None);
GPU_ReleaseResource(g->emittance_flood_read, g->render_fence, GPU_ReleaseFlag_None);
GPU_ReleaseResource(g->albedo, g->render_fence, GPU_ReleaseFlag_None);
GPU_ReleaseResource(g->emittance, g->render_fence, GPU_ReleaseFlag_None);
GPU_ReleaseResource(g->emittance_flood_read, g->render_fence, GPU_ReleaseFlag_None);
GPU_ReleaseResource(g->emittance_flood_target, g->render_fence, GPU_ReleaseFlag_None);
GPU_ReleaseResource(g->shade_read, g->render_fence, GPU_ReleaseFlag_None);
GPU_ReleaseResource(g->shade_target, g->render_fence, GPU_ReleaseFlag_None);
GPU_ReleaseResource(g->shade_read, g->render_fence, GPU_ReleaseFlag_None);
GPU_ReleaseResource(g->shade_target, g->render_fence, GPU_ReleaseFlag_None);
g->shade_target = 0;
}
if (!g->shade_target)
@ -2181,7 +2181,7 @@ void UpdateUser(P_Window *window)
/* Acquire transfer buffers */
/* TODO: Make these static */
LocalPersist u16 quad_indices[6] = { 0, 1, 2, 0, 2, 3 };
u16 quad_indices[6] = { 0, 1, 2, 0, 2, 3 };
GPU_Resource *quad_index_buffer = AcquireTransferBuffer(countof(quad_indices), sizeof(*quad_indices), quad_indices);
GPU_Resource *material_instance_buffer = AcquireTransferBufferFromArena(g->material_instances_count, g->material_instances_arena);
GPU_Resource *ui_rect_instance_buffer = AcquireTransferBufferFromArena(g->ui_rect_instances_count, g->ui_rect_instances_arena);