ditch jobs in prototype

This commit is contained in:
jacob 2025-12-06 04:46:30 -06:00
parent a8d79cee4c
commit 97237b5ed9
13 changed files with 124 additions and 175 deletions

View File

@ -249,7 +249,7 @@ void SignalExit(i32 code)
{ {
W32_SharedState *g = &W32_shared_state; W32_SharedState *g = &W32_shared_state;
Atomic32Set(&g->exit_code, code); Atomic32Set(&g->exit_code, code);
SetEvent(g->exit_begin_event); SetEvent(g->exit_event);
} }
void ExitNow(i32 code) void ExitNow(i32 code)
@ -278,7 +278,7 @@ i32 W32_Main(void)
/* Setup events */ /* Setup events */
g->panic_event = CreateEventW(0, 1, 0, 0); g->panic_event = CreateEventW(0, 1, 0, 0);
g->exit_begin_event = CreateEventW(0, 1, 0, 0); g->exit_event = CreateEventW(0, 1, 0, 0);
g->main_thread_id = GetCurrentThreadId(); g->main_thread_id = GetCurrentThreadId();
SetThreadDescription(GetCurrentThread(), L"Main thread"); SetThreadDescription(GetCurrentThread(), L"Main thread");
@ -330,20 +330,11 @@ i32 W32_Main(void)
StartupLayers(); StartupLayers();
} }
/* Wait for panic */
if (!Atomic32Fetch(&g->panicking))
{
HANDLE handles[] = {
g->panic_event,
};
WaitForMultipleObjects(countof(handles), handles, 0, INFINITE);
}
/* Wait for exit start or panic */ /* Wait for exit start or panic */
if (!Atomic32Fetch(&g->panicking)) if (!Atomic32Fetch(&g->panicking))
{ {
HANDLE handles[] = { HANDLE handles[] = {
g->exit_begin_event, g->exit_event,
g->panic_event, g->panic_event,
}; };
DWORD wake = WaitForMultipleObjects(countof(handles), handles, 0, INFINITE); DWORD wake = WaitForMultipleObjects(countof(handles), handles, 0, INFINITE);
@ -362,25 +353,6 @@ i32 W32_Main(void)
} }
} }
/* Wait for exit end or panic */
if (!Atomic32Fetch(&g->panicking))
{
HANDLE handles[] = {
g->panic_event
};
WaitForMultipleObjects(countof(handles), handles, 0, INFINITE);
}
/* Signal swap finish */
if (!Atomic32Fetch(&g->panicking) && IsSwappingOut())
{
HANDLE swap_end_event = OpenEventW(EVENT_MODIFY_STATE, 0, L"Local\\pp_swap_end");
if (swap_end_event != 0)
{
SetEvent(swap_end_event);
}
}
/* Exit */ /* Exit */
if (Atomic32Fetch(&g->panicking)) if (Atomic32Fetch(&g->panicking))
{ {

View File

@ -74,7 +74,7 @@ Struct(W32_SharedState)
Atomic32 panicking; Atomic32 panicking;
wchar_t panic_wstr[4096]; wchar_t panic_wstr[4096];
HANDLE panic_event; HANDLE panic_event;
HANDLE exit_begin_event; HANDLE exit_event;
//- Exit funcs //- Exit funcs
Atomic32 num_exit_funcs; Atomic32 num_exit_funcs;

View File

@ -69,14 +69,8 @@
#define FLOOD_DEBUG 0 #define FLOOD_DEBUG 0
#define GPU_DEBUG 1 #define GPU_DEBUG 0
#define GPU_DEBUG_VALIDATION 1 #define GPU_DEBUG_VALIDATION 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
* since the debugger won't be confused by fiber context switching. */
#define VIRTUAL_FIBERS 0
/* If enabled, bitbuffs will insert/verify magic numbers & length for each read & write */ /* If enabled, bitbuffs will insert/verify magic numbers & length for each read & write */
#define BITBUFF_DEBUG 0 #define BITBUFF_DEBUG 0

View File

@ -1,4 +1,5 @@
GPU_SharedUtilState GPU_shared_util_state = ZI; GPU_SharedUtilState GPU_shared_util_state = ZI;
ThreadLocal GPU_ArenaHandle GPU_t_perm_arena = ZI;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Startup //~ Startup
@ -93,12 +94,11 @@ void GPU_StartupCommon(void)
GPU_ArenaHandle GPU_PermArena(void) GPU_ArenaHandle GPU_PermArena(void)
{ {
i16 fiber_id = FiberId(); GPU_ArenaHandle perm = GPU_t_perm_arena;
GPU_ArenaHandle perm = GPU_shared_util_state.perm_arenas[fiber_id];
if (GPU_IsArenaNil(perm)) if (GPU_IsArenaNil(perm))
{ {
GPU_shared_util_state.perm_arenas[fiber_id] = GPU_AcquireArena(); GPU_t_perm_arena = GPU_AcquireArena();
perm = GPU_shared_util_state.perm_arenas[fiber_id]; perm = GPU_t_perm_arena;
} }
return perm; return perm;
} }

View File

@ -7,10 +7,10 @@ Struct(GPU_SharedUtilState)
SamplerStateHandle pt_sampler; SamplerStateHandle pt_sampler;
GPU_IndexBufferDesc quad_indices; GPU_IndexBufferDesc quad_indices;
Texture3DHandle noise_tex; Texture3DHandle noise_tex;
GPU_ArenaHandle perm_arenas[MaxFibers];
} extern GPU_shared_util_state; } extern GPU_shared_util_state;
extern ThreadLocal GPU_ArenaHandle GPU_t_perm_arena;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Startup //~ Startup

View File

@ -400,12 +400,49 @@ D3D12_BARRIER_LAYOUT GPU_D12_BarrierLayoutFromLayout(GPU_Layout layout)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Pipeline //~ Pipeline
JobImpl(GPU_D12_LoadPipeline, sig, _) GPU_D12_Pipeline *GPU_D12_PipelineFromDesc(GPU_D12_PipelineDesc desc)
{ {
GPU_D12_SharedState *g = &GPU_D12_shared_state; GPU_D12_SharedState *g = &GPU_D12_shared_state;
GPU_D12_Pipeline *pipeline = sig->pipeline; u64 hash = RandU64FromSeed(HashFnv64(Fnv64Basis, StringFromStruct(&desc)));
GPU_D12_PipelineDesc desc = pipeline->desc;
/* Fetch pipeline from cache */
GPU_D12_Pipeline *pipeline = 0;
b32 is_pipeline_new = 0;
GPU_D12_PipelineBin *bin = &g->pipeline_bins[hash % countof(g->pipeline_bins)];
{
{
Lock lock = LockS(&bin->mutex);
for (pipeline = bin->first; pipeline; pipeline = pipeline->next_in_bin)
{
if (pipeline->hash == hash) break;
}
Unlock(&lock);
}
if (!pipeline)
{
Lock lock = LockE(&bin->mutex);
for (pipeline = bin->first; pipeline; pipeline = pipeline->next_in_bin)
{
if (pipeline->hash == hash) break;
}
if (!pipeline)
{
Arena *perm = PermArena();
PushAlign(perm, CachelineSize);
pipeline = PushStruct(perm, GPU_D12_Pipeline);
pipeline->desc = desc;
pipeline->hash = hash;
is_pipeline_new = 1;
PushAlign(perm, CachelineSize);
SllStackPushN(bin->first, pipeline, next_in_bin);
}
Unlock(&lock);
}
}
/* Create pipeline */
if (is_pipeline_new)
{
HRESULT hr = 0; HRESULT hr = 0;
b32 ok = 1; b32 ok = 1;
String error_str = ZI; String error_str = ZI;
@ -507,51 +544,6 @@ JobImpl(GPU_D12_LoadPipeline, sig, _)
pipeline->ok = ok; pipeline->ok = ok;
} }
GPU_D12_Pipeline *GPU_D12_PipelineFromDesc(GPU_D12_PipelineDesc desc)
{
GPU_D12_SharedState *g = &GPU_D12_shared_state;
u64 hash = RandU64FromSeed(HashFnv64(Fnv64Basis, StringFromStruct(&desc)));
GPU_D12_Pipeline *pipeline = 0;
b32 is_pipeline_new = 0;
GPU_D12_PipelineBin *bin = &g->pipeline_bins[hash % countof(g->pipeline_bins)];
{
{
Lock lock = LockS(&bin->mutex);
for (pipeline = bin->first; pipeline; pipeline = pipeline->next_in_bin)
{
if (pipeline->hash == hash) break;
}
Unlock(&lock);
}
if (!pipeline)
{
Lock lock = LockE(&bin->mutex);
for (pipeline = bin->first; pipeline; pipeline = pipeline->next_in_bin)
{
if (pipeline->hash == hash) break;
}
if (!pipeline)
{
Arena *perm = PermArena();
PushAlign(perm, CachelineSize);
pipeline = PushStruct(perm, GPU_D12_Pipeline);
pipeline->desc = desc;
pipeline->hash = hash;
is_pipeline_new = 1;
PushAlign(perm, CachelineSize);
SllStackPushN(bin->first, pipeline, next_in_bin);
}
Unlock(&lock);
}
}
if (is_pipeline_new)
{
RunJob(GPU_D12_LoadPipeline, .fence = &pipeline->ready_fence, .sig.pipeline = pipeline);
}
YieldOnFence(&pipeline->ready_fence, 1);
return pipeline; return pipeline;
} }

View File

@ -45,7 +45,6 @@ Struct(GPU_D12_Pipeline)
GPU_D12_PipelineDesc desc; GPU_D12_PipelineDesc desc;
ID3D12PipelineState *pso; ID3D12PipelineState *pso;
Fence ready_fence;
b32 ok; b32 ok;
String error; String error;
}; };
@ -350,9 +349,6 @@ Struct(GPU_D12_SharedState)
{ {
Atomic64Padded resource_creation_gen; Atomic64Padded resource_creation_gen;
/* Per-fiber permanent arenas */
GPU_ArenaHandle perm_arenas[MaxFibers];
/* Stats */ /* Stats */
Atomic64 driver_resources_allocated; Atomic64 driver_resources_allocated;
Atomic64 driver_descriptors_allocated; Atomic64 driver_descriptors_allocated;
@ -405,7 +401,6 @@ D3D12_BARRIER_LAYOUT GPU_D12_BarrierLayoutFromLayout(GPU_Layout layout);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Pipeline //~ Pipeline
JobDecl(GPU_D12_LoadPipeline, { GPU_D12_Pipeline *pipeline; });
GPU_D12_Pipeline *GPU_D12_PipelineFromDesc(GPU_D12_PipelineDesc desc); GPU_D12_Pipeline *GPU_D12_PipelineFromDesc(GPU_D12_PipelineDesc desc);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -15,8 +15,7 @@ void P_Startup(void)
g->socks_arena = AcquireArena(Gibi(64)); g->socks_arena = AcquireArena(Gibi(64));
//- Init timer //- Init timer
JobPoolId timer_pool = InitJobPool(1, Lit("Timer sync"), JobPoolPriority_Critical); DispatchWave(Lit("Win32 timer sync"), 1, P_W32_SyncTimerForever, 0);
RunJob(P_W32_StartTimerSync, .pool = timer_pool);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -158,7 +157,7 @@ P_Address P_W32_PlatformAddressFromWin32Address(P_W32_Address ws_addr)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Timer job //~ Timer job
JobImpl(P_W32_StartTimerSync, _, __) void P_W32_SyncTimerForever(WaveLaneCtx *lane, void *udata)
{ {
P_W32_SharedState *g = &P_W32_shared_state; P_W32_SharedState *g = &P_W32_shared_state;
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);

View File

@ -103,4 +103,4 @@ P_Address P_W32_PlatformAddressFromWin32Address(P_W32_Address ws_addr);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Timer job //~ Timer job
JobDecl(P_W32_StartTimerSync, EmptySig); void P_W32_SyncTimerForever(WaveLaneCtx *lane, void *udata);

View File

@ -1,5 +1,4 @@
JobDecl(PT_RunForever, EmptySig); void PT_RunForever(WaveLaneCtx *lane, void *udata)
JobImpl(PT_RunForever, _sig, _id)
{ {
GPU_ArenaHandle gpu_frame_arena = GPU_AcquireArena(); GPU_ArenaHandle gpu_frame_arena = GPU_AcquireArena();
@ -89,8 +88,7 @@ JobImpl(PT_RunForever, _sig, _id)
} }
} }
void PT_Startup(void);
void PT_Startup(void) void PT_Startup(void)
{ {
RunJob(PT_RunForever); DispatchWave(Lit("Proto"), 1, PT_RunForever, 0);
} }

View File

@ -233,7 +233,7 @@ JobImpl(SPR_LoadSheet, sig, _)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Cache //~ Cache
/* TODO: Per-fiber L1 cache */ /* TODO: Per-thread L1 cache */
SPR_Entry *SPR_FetchEntry(ResourceKey resource, JobPoolId pool, SPR_FetchFlag flags) SPR_Entry *SPR_FetchEntry(ResourceKey resource, JobPoolId pool, SPR_FetchFlag flags)
{ {
SPR_SharedState *g = &SPR_shared_state; SPR_SharedState *g = &SPR_shared_state;

View File

@ -85,9 +85,8 @@ void WND_Startup(void)
RegisterRawInputDevices(&rid, 1, sizeof(rid)); RegisterRawInputDevices(&rid, 1, sizeof(rid));
} }
//- Start message processing job //- Dispatch message processor
JobPoolId message_job_pool = InitJobPool(1, Lit("Win32 message loop"), JobPoolPriority_Graphics); DispatchWave(Lit("Win32 msg loop"), 1, WND_W32_ProcessMessagesForever, 0);
RunJob(WND_W32_ProcessMessagesForever, .pool = message_job_pool);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -102,7 +101,7 @@ WND_W32_Window *WND_W32_WindowFromHandle(WND_Handle handle)
//~ Initialization //~ Initialization
/* Win32 limitation: Window must be initialized on same thread that processes events */ /* Win32 limitation: Window must be initialized on same thread that processes events */
JobImpl(WND_W32_ProcessMessagesForever, sig, id) void WND_W32_ProcessMessagesForever(WaveLaneCtx *lane, void *udata)
{ {
WND_W32_SharedState *g = &WND_W32_shared_state; WND_W32_SharedState *g = &WND_W32_shared_state;
WND_W32_Window *window = &g->window; WND_W32_Window *window = &g->window;

View File

@ -77,7 +77,7 @@ WND_W32_Window *WND_W32_WindowFromHandle(WND_Handle handle);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Initialization //~ Initialization
JobDecl(WND_W32_ProcessMessagesForever, EmptySig); void WND_W32_ProcessMessagesForever(WaveLaneCtx *lane, void *udata);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Message processing //~ Message processing