match global system state variable names to corresponding namespace

This commit is contained in:
jacob 2025-12-28 13:07:07 -06:00
parent 4ffb9a8d73
commit 75bedaecbb
25 changed files with 297 additions and 347 deletions

View File

@ -36,8 +36,8 @@ void SignalAsyncTick(void)
void AsyncWorkerEntryPoint(WaveLaneCtx *lane) void AsyncWorkerEntryPoint(WaveLaneCtx *lane)
{ {
AsyncTickCtx tick = Zi; AsyncFrameLaneCtx frame = Zi;
tick.arena = AcquireArena(Gibi(64)); frame.arena = AcquireArena(Gibi(64));
// Tick forever // Tick forever
for (;;) for (;;)
@ -64,7 +64,7 @@ void AsyncWorkerEntryPoint(WaveLaneCtx *lane)
Lock lock = LockE(&Base.async.mutex); Lock lock = LockE(&Base.async.mutex);
{ {
w->callbacks_count = Base.async.callback_nodes_count; w->callbacks_count = Base.async.callback_nodes_count;
w->callbacks = PushStructsNoZero(tick.arena, AsyncTickCallback, w->callbacks_count); w->callbacks = PushStructsNoZero(frame.arena, AsyncTickCallback, w->callbacks_count);
u64 callback_idx = 0; u64 callback_idx = 0;
for (AsyncTickCallbackNode *n = Base.async.first_callback_node; n; n = n->next) for (AsyncTickCallbackNode *n = Base.async.first_callback_node; n; n = n->next)
{ {
@ -84,7 +84,7 @@ void AsyncWorkerEntryPoint(WaveLaneCtx *lane)
for (u64 callback_idx = 0; callback_idx < w->callbacks_count; ++callback_idx) for (u64 callback_idx = 0; callback_idx < w->callbacks_count; ++callback_idx)
{ {
AsyncTickCallback *callback = &w->callbacks[callback_idx]; AsyncTickCallback *callback = &w->callbacks[callback_idx];
callback->func(lane, &tick); callback->func(lane, &frame);
} }
////////////////////////////// //////////////////////////////
@ -92,11 +92,11 @@ void AsyncWorkerEntryPoint(WaveLaneCtx *lane)
WaveSync(lane); WaveSync(lane);
ResetArena(tick.arena); ResetArena(frame.arena);
{ {
Arena *tick_arena = tick.arena; Arena *old_frame_arena = frame.arena;
ZeroStruct(&tick); ZeroStruct(&frame);
tick.arena = tick_arena; frame.arena = old_frame_arena;
} }
} }
} }

View File

@ -1,8 +1,8 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Async types //~ Async types
Struct(AsyncTickCtx); Struct(AsyncFrameLaneCtx);
typedef void AsyncTickCallbackFunc(WaveLaneCtx *lane, AsyncTickCtx *tick); typedef void AsyncTickCallbackFunc(WaveLaneCtx *lane, AsyncFrameLaneCtx *frame);
Struct(AsyncTickCallback) Struct(AsyncTickCallback)
{ {
@ -15,7 +15,7 @@ Struct(AsyncTickCallbackNode)
AsyncTickCallback callback; AsyncTickCallback callback;
}; };
Struct(AsyncTickCtx) Struct(AsyncFrameLaneCtx)
{ {
Arena *arena; Arena *arena;
}; };

View File

@ -54,7 +54,7 @@ Struct(W32_FindEmbeddedDataCtx)
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Context types //~ State types
Struct(W32_Ctx) Struct(W32_Ctx)
{ {

View File

@ -1,13 +1,12 @@
D_SharedState D_shared_state = ZI; D_Ctx D = Zi;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Bootstrap //~ Bootstrap
void D_Bootstrap(void) void D_Bootstrap(void)
{ {
D_SharedState *g = &D_shared_state;
u32 pixel_white = 0xFFFFFFFF; u32 pixel_white = 0xFFFFFFFF;
g->solid_white_texture = GPU_AcquireTexture(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, VEC2I32(1, 1), &pixel_white); D.solid_white_texture = GPU_AcquireTexture(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, VEC2I32(1, 1), &pixel_white);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -108,9 +107,8 @@ void D_DrawQuad(GPU_RenderSig *sig, Quad quad, u32 color)
void D_DrawLineGradient(GPU_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, u32 start_color, u32 end_color) void D_DrawLineGradient(GPU_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, u32 start_color, u32 end_color)
{ {
#if 0 #if 0
D_SharedState *g = &D_shared_state;
Quad quad = QuadFromLine(start, end, thickness); Quad quad = QuadFromLine(start, end, thickness);
D_DrawMaterial(sig, D_MATERIALPARAMS(.texture = g->solid_white_texture, .tint0 = start_color, .tint1 = end_color, .quad = quad)); D_DrawMaterial(sig, D_MATERIALPARAMS(.texture = D.solid_white_texture, .tint0 = start_color, .tint1 = end_color, .quad = quad));
#else #else
// Placeholder // Placeholder
Quad quad = QuadFromLine(start, end, thickness); Quad quad = QuadFromLine(start, end, thickness);

View File

@ -101,10 +101,12 @@ Struct(D_TextParams)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ State types //~ State types
Struct(D_SharedState) Struct(D_Ctx)
{ {
GPU_Resource *solid_white_texture; GPU_Resource *solid_white_texture;
} extern D_shared_state; };
extern D_Ctx D;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Bootstrap //~ Bootstrap

View File

@ -222,7 +222,7 @@ GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Async //~ Async
void GC_TickAsync(WaveLaneCtx *lane, AsyncTickCtx *tick) void GC_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *frame)
{ {
GC_AsyncCtx *async = &GC.async_ctx; GC_AsyncCtx *async = &GC.async_ctx;
@ -239,7 +239,7 @@ void GC_TickAsync(WaveLaneCtx *lane, AsyncTickCtx *tick)
{ {
// Pop cmds from submission queue // Pop cmds from submission queue
async->cmds.count = GC.submit.count; async->cmds.count = GC.submit.count;
async->cmds.v = PushStructsNoZero(tick->arena, GC_Cmd, GC.submit.count); async->cmds.v = PushStructsNoZero(frame->arena, GC_Cmd, GC.submit.count);
u64 cmd_idx = 0; u64 cmd_idx = 0;
for (GC_CmdNode *n = GC.submit.first; n; n = n->next) for (GC_CmdNode *n = GC.submit.first; n; n = n->next)
{ {
@ -272,7 +272,7 @@ void GC_TickAsync(WaveLaneCtx *lane, AsyncTickCtx *tick)
GC_Glyph *glyph = cmd->glyph; GC_Glyph *glyph = cmd->glyph;
ResourceKey resource = glyph->desc.font.r; ResourceKey resource = glyph->desc.font.r;
GC_GlyphDesc desc = glyph->desc; GC_GlyphDesc desc = glyph->desc;
TTF_GlyphResult ttf_result = TTF_RasterizeGlyphFromCodepoint(tick->arena, desc.codepoint, resource, desc.font_size);; TTF_GlyphResult ttf_result = TTF_RasterizeGlyphFromCodepoint(frame->arena, desc.codepoint, resource, desc.font_size);;
glyph->font_size = desc.font_size; glyph->font_size = desc.font_size;
glyph->font_ascent = ttf_result.font_ascent; glyph->font_ascent = ttf_result.font_ascent;
glyph->font_descent = ttf_result.font_descent; glyph->font_descent = ttf_result.font_descent;

View File

@ -108,7 +108,7 @@ Struct(GC_CmdNode)
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Context types //~ State types
Struct(GC_AsyncCtx) Struct(GC_AsyncCtx)
{ {
@ -160,4 +160,4 @@ GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Async //~ Async
void GC_TickAsync(WaveLaneCtx *lane, AsyncTickCtx *ctx); void GC_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *frame);

View File

@ -1,13 +1,11 @@
G_SharedUtilState G_shared_util_state = Zi; G_Ctx G = Zi;
ThreadLocal G_ArenaHandle G_t_perm_arena = Zi; ThreadLocal G_ThreadLocalCtx G_tl = Zi;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Bootstrap //~ Bootstrap
void G_BootstrapCommon(void) void G_BootstrapCommon(void)
{ {
G_SharedUtilState *g = &G_shared_util_state;
G_ArenaHandle gpu_perm = G_PermArena(); G_ArenaHandle gpu_perm = G_PermArena();
G_CommandListHandle cl = G_PrepareCommandList(G_QueueKind_Direct); G_CommandListHandle cl = G_PrepareCommandList(G_QueueKind_Direct);
@ -18,13 +16,13 @@ void G_BootstrapCommon(void)
u16 quad_data[6] = { 0, 1, 2, 0, 2, 3 }; u16 quad_data[6] = { 0, 1, 2, 0, 2, 3 };
quad_indices = G_PushBuffer(gpu_perm, cl, u16, countof(quad_data)); quad_indices = G_PushBuffer(gpu_perm, cl, u16, countof(quad_data));
G_CopyCpuToBuffer(cl, quad_indices, 0, quad_data, RNGU64(0, sizeof(quad_data))); G_CopyCpuToBuffer(cl, quad_indices, 0, quad_data, RNGU64(0, sizeof(quad_data)));
g->quad_indices = G_IdxBuff16(quad_indices); G.quad_indices = G_IdxBuff16(quad_indices);
} }
// Init point sampler // Init point sampler
{ {
G_ResourceHandle pt_sampler = G_PushSampler(gpu_perm, cl, .filter = G_Filter_MinMagMipPoint); G_ResourceHandle pt_sampler = G_PushSampler(gpu_perm, cl, .filter = G_Filter_MinMagMipPoint);
g->basic_sampler = G_PushSamplerStateRef(gpu_perm, pt_sampler); G.basic_sampler = G_PushSamplerStateRef(gpu_perm, pt_sampler);
} }
// Init noise texture // Init noise texture
@ -49,7 +47,7 @@ void G_BootstrapCommon(void)
RNG3I32(VEC3I32(0, 0, 0), noise_dims) RNG3I32(VEC3I32(0, 0, 0), noise_dims)
); );
g->basic_noise = G_PushTexture3DRef(gpu_perm, noise_tex); G.basic_noise = G_PushTexture3DRef(gpu_perm, noise_tex);
} }
} }
@ -66,13 +64,11 @@ void G_BootstrapCommon(void)
G_ArenaHandle G_PermArena(void) G_ArenaHandle G_PermArena(void)
{ {
G_ArenaHandle perm = G_t_perm_arena; if (G_IsArenaNil(G_tl.gpu_perm))
if (G_IsArenaNil(perm))
{ {
G_t_perm_arena = G_AcquireArena(); G_tl.gpu_perm = G_AcquireArena();
perm = G_t_perm_arena;
} }
return perm; return G_tl.gpu_perm;
} }
//- Cpu -> Gpu upload //- Cpu -> Gpu upload
@ -107,15 +103,15 @@ Rng2 G_ScissorFromTexture(G_ResourceHandle texture)
G_IndexBufferDesc G_QuadIndices(void) G_IndexBufferDesc G_QuadIndices(void)
{ {
return G_shared_util_state.quad_indices; return G.quad_indices;
} }
G_SamplerStateRef G_BasicSampler(void) G_SamplerStateRef G_BasicSampler(void)
{ {
return G_shared_util_state.basic_sampler; return G.basic_sampler;
} }
G_Texture3DRef G_BasicNoiseTexture(void) G_Texture3DRef G_BasicNoiseTexture(void)
{ {
return G_shared_util_state.basic_noise; return G.basic_noise;
} }

View File

@ -1,15 +1,21 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ State types //~ State types
Struct(G_SharedUtilState) Struct(G_Ctx)
{ {
// Common shared resources // Common shared resources
G_IndexBufferDesc quad_indices; G_IndexBufferDesc quad_indices;
G_SamplerStateRef basic_sampler; G_SamplerStateRef basic_sampler;
G_Texture3DRef basic_noise; G_Texture3DRef basic_noise;
} extern G_shared_util_state; };
extern ThreadLocal G_ArenaHandle G_t_perm_arena; Struct(G_ThreadLocalCtx)
{
G_ArenaHandle gpu_perm;
};
extern G_Ctx G;
extern ThreadLocal G_ThreadLocalCtx G_tl;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Bootstrap //~ Bootstrap

View File

@ -1,12 +1,11 @@
G_D12_SharedState G_D12_shared_state = Zi; G_D12_Ctx G_D12 = Zi;
ThreadLocal G_D12_ThreadLocalState G_D12_tl = Zi; ThreadLocal G_D12_ThreadLocalCtx G_D12_tl = Zi;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ @hookimpl Bootstrap //~ @hookimpl Bootstrap
void G_Bootstrap(void) void G_Bootstrap(void)
{ {
G_D12_SharedState *g = &G_D12_shared_state;
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
Arena *perm = PermArena(); Arena *perm = PermArena();
@ -48,7 +47,7 @@ void G_Bootstrap(void)
// Create factory // Create factory
{ {
hr = CreateDXGIFactory2(dxgi_factory_flags, &IID_IDXGIFactory6, (void **)&g->factory); hr = CreateDXGIFactory2(dxgi_factory_flags, &IID_IDXGIFactory6, (void **)&G_D12.factory);
if (FAILED(hr)) if (FAILED(hr))
{ {
Panic(Lit("Failed to initialize DXGI factory")); Panic(Lit("Failed to initialize DXGI factory"));
@ -66,7 +65,7 @@ void G_Bootstrap(void)
for (;;) for (;;)
{ {
{ {
hr = IDXGIFactory6_EnumAdapterByGpuPreference(g->factory, adapter_index, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, &IID_IDXGIAdapter3, (void **)&adapter); hr = IDXGIFactory6_EnumAdapterByGpuPreference(G_D12.factory, adapter_index, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, &IID_IDXGIAdapter3, (void **)&adapter);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
@ -111,8 +110,8 @@ void G_Bootstrap(void)
} }
Panic(error); Panic(error);
} }
g->adapter = adapter; G_D12.adapter = adapter;
g->device = device; G_D12.device = device;
} }
// Enable debug layer breaks // Enable debug layer breaks
@ -121,7 +120,7 @@ void G_Bootstrap(void)
// Enable D3D12 Debug break // Enable D3D12 Debug break
{ {
ID3D12InfoQueue *info = 0; ID3D12InfoQueue *info = 0;
hr = ID3D12Device_QueryInterface(g->device, &IID_ID3D12InfoQueue, (void **)&info); hr = ID3D12Device_QueryInterface(G_D12.device, &IID_ID3D12InfoQueue, (void **)&info);
if (FAILED(hr)) if (FAILED(hr))
{ {
Panic(Lit("Failed to query ID3D12Device interface")); Panic(Lit("Failed to query ID3D12Device interface"));
@ -154,16 +153,16 @@ void G_Bootstrap(void)
{ .type = D3D12_COMMAND_LIST_TYPE_COMPUTE, .priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL }, { .type = D3D12_COMMAND_LIST_TYPE_COMPUTE, .priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL },
{ .type = D3D12_COMMAND_LIST_TYPE_COPY, .priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL }, { .type = D3D12_COMMAND_LIST_TYPE_COPY, .priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL },
}; };
for (u32 i = 0; i < MinU32(countof(descs), countof(g->queues)); ++i) for (u32 i = 0; i < MinU32(countof(descs), countof(G_D12.queues)); ++i)
{ {
G_D12_CommandQueueDesc desc = descs[i]; G_D12_CommandQueueDesc desc = descs[i];
D3D12_COMMAND_QUEUE_DESC d3d_desc = { .Type = desc.type, .Priority = desc.priority }; D3D12_COMMAND_QUEUE_DESC d3d_desc = { .Type = desc.type, .Priority = desc.priority };
G_D12_Queue *queue = &g->queues[i]; G_D12_Queue *queue = &G_D12.queues[i];
queue->desc = desc; queue->desc = desc;
HRESULT hr = ID3D12Device_CreateCommandQueue(g->device, &d3d_desc, &IID_ID3D12CommandQueue, (void **)&queue->d3d_queue); HRESULT hr = ID3D12Device_CreateCommandQueue(G_D12.device, &d3d_desc, &IID_ID3D12CommandQueue, (void **)&queue->d3d_queue);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = ID3D12Device_CreateFence(g->device, 0, 0, &IID_ID3D12Fence, (void **)&queue->commit_fence); hr = ID3D12Device_CreateFence(G_D12.device, 0, 0, &IID_ID3D12Fence, (void **)&queue->commit_fence);
} }
if (FAILED(hr)) if (FAILED(hr))
{ {
@ -197,13 +196,13 @@ void G_Bootstrap(void)
for (G_D12_DescriptorHeapKind kind = 0; kind < countof(descs); ++kind) for (G_D12_DescriptorHeapKind kind = 0; kind < countof(descs); ++kind)
{ {
Dx12HeapDesc desc = descs[kind]; Dx12HeapDesc desc = descs[kind];
G_D12_DescriptorHeap *heap = &g->descriptor_heaps[kind]; G_D12_DescriptorHeap *heap = &G_D12.descriptor_heaps[kind];
heap->descriptors_arena = AcquireArena(Gibi(1)); heap->descriptors_arena = AcquireArena(Gibi(1));
heap->kind = kind; heap->kind = kind;
heap->type = desc.type; heap->type = desc.type;
heap->max_count = desc.max; heap->max_count = desc.max;
heap->descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(g->device, desc.type); heap->descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(G_D12.device, desc.type);
D3D12_DESCRIPTOR_HEAP_DESC d3d_desc = Zi; D3D12_DESCRIPTOR_HEAP_DESC d3d_desc = Zi;
d3d_desc.Type = desc.type; d3d_desc.Type = desc.type;
@ -214,7 +213,7 @@ void G_Bootstrap(void)
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = ID3D12Device_CreateDescriptorHeap(g->device, &d3d_desc, &IID_ID3D12DescriptorHeap, (void **)&heap->d3d_heap); hr = ID3D12Device_CreateDescriptorHeap(G_D12.device, &d3d_desc, &IID_ID3D12DescriptorHeap, (void **)&heap->d3d_heap);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -272,9 +271,9 @@ void G_Bootstrap(void)
ID3D12RootSignature *rootsig = 0; ID3D12RootSignature *rootsig = 0;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = ID3D12Device_CreateRootSignature(g->device, 0, ID3D10Blob_GetBufferPointer(blob), ID3D10Blob_GetBufferSize(blob), &IID_ID3D12RootSignature, (void **)&rootsig); hr = ID3D12Device_CreateRootSignature(G_D12.device, 0, ID3D10Blob_GetBufferPointer(blob), ID3D10Blob_GetBufferSize(blob), &IID_ID3D12RootSignature, (void **)&rootsig);
} }
g->bindless_rootsig = rootsig; G_D12.bindless_rootsig = rootsig;
if (blob) if (blob)
{ {
@ -447,13 +446,12 @@ D3D12_BARRIER_LAYOUT G_D12_BarrierLayoutFromLayout(G_Layout layout)
G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc) G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
{ {
G_D12_SharedState *g = &G_D12_shared_state;
u64 hash = RandU64FromSeed(HashFnv64(Fnv64Basis, StringFromStruct(&desc))); u64 hash = RandU64FromSeed(HashFnv64(Fnv64Basis, StringFromStruct(&desc)));
// Fetch pipeline from cache // Fetch pipeline from cache
G_D12_Pipeline *pipeline = 0; G_D12_Pipeline *pipeline = 0;
b32 is_pipeline_new = 0; b32 is_pipeline_new = 0;
G_D12_PipelineBin *bin = &g->pipeline_bins[hash % countof(g->pipeline_bins)]; G_D12_PipelineBin *bin = &G_D12.pipeline_bins[hash % countof(G_D12.pipeline_bins)];
{ {
{ {
Lock lock = LockS(&bin->mutex); Lock lock = LockS(&bin->mutex);
@ -542,7 +540,7 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
String ps = DataFromResource(desc.ps.resource); String ps = DataFromResource(desc.ps.resource);
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc = Zi; D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc = Zi;
{ {
pso_desc.pRootSignature = g->bindless_rootsig; pso_desc.pRootSignature = G_D12.bindless_rootsig;
pso_desc.VS.pShaderBytecode = vs.text; pso_desc.VS.pShaderBytecode = vs.text;
pso_desc.VS.BytecodeLength = vs.len; pso_desc.VS.BytecodeLength = vs.len;
pso_desc.PS.pShaderBytecode = ps.text; pso_desc.PS.pShaderBytecode = ps.text;
@ -568,7 +566,7 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
} }
} }
} }
hr = ID3D12Device_CreateGraphicsPipelineState(g->device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso); hr = ID3D12Device_CreateGraphicsPipelineState(G_D12.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso);
if (FAILED(hr)) if (FAILED(hr))
{ {
error_str = Lit("Failed to create graphics pipeline"); error_str = Lit("Failed to create graphics pipeline");
@ -580,11 +578,11 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
String cs = DataFromResource(desc.cs.resource); String cs = DataFromResource(desc.cs.resource);
D3D12_COMPUTE_PIPELINE_STATE_DESC pso_desc = Zi; D3D12_COMPUTE_PIPELINE_STATE_DESC pso_desc = Zi;
{ {
pso_desc.pRootSignature = g->bindless_rootsig; pso_desc.pRootSignature = G_D12.bindless_rootsig;
pso_desc.CS.pShaderBytecode = cs.text; pso_desc.CS.pShaderBytecode = cs.text;
pso_desc.CS.BytecodeLength = cs.len; pso_desc.CS.BytecodeLength = cs.len;
} }
hr = ID3D12Device_CreateComputePipelineState(g->device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso); hr = ID3D12Device_CreateComputePipelineState(G_D12.device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso);
if (FAILED(hr)) if (FAILED(hr))
{ {
error_str = Lit("Failed to create compute pipeline"); error_str = Lit("Failed to create compute pipeline");
@ -611,8 +609,7 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
G_D12_Queue *G_D12_QueueFromKind(G_QueueKind kind) G_D12_Queue *G_D12_QueueFromKind(G_QueueKind kind)
{ {
G_D12_SharedState *g = &G_D12_shared_state; return &G_D12.queues[kind];
return &g->queues[kind];
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -620,7 +617,6 @@ G_D12_Queue *G_D12_QueueFromKind(G_QueueKind kind)
G_D12_RawCommandList *G_D12_PrepareRawCommandList(G_QueueKind queue_kind) G_D12_RawCommandList *G_D12_PrepareRawCommandList(G_QueueKind queue_kind)
{ {
G_D12_SharedState *g = &G_D12_shared_state;
G_D12_Queue *queue = G_D12_QueueFromKind(queue_kind); G_D12_Queue *queue = G_D12_QueueFromKind(queue_kind);
// Try to pull first completed command list from queue // Try to pull first completed command list from queue
@ -657,12 +653,12 @@ G_D12_RawCommandList *G_D12_PrepareRawCommandList(G_QueueKind queue_kind)
{ {
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = ID3D12Device_CreateCommandAllocator(g->device, queue->desc.type, &IID_ID3D12CommandAllocator, (void **)&cl->d3d_ca); hr = ID3D12Device_CreateCommandAllocator(G_D12.device, queue->desc.type, &IID_ID3D12CommandAllocator, (void **)&cl->d3d_ca);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = ID3D12Device_CreateCommandList(g->device, 0, queue->desc.type, cl->d3d_ca, 0, &IID_ID3D12GraphicsCommandList7, (void **)&cl->d3d_cl); hr = ID3D12Device_CreateCommandList(G_D12.device, 0, queue->desc.type, cl->d3d_ca, 0, &IID_ID3D12GraphicsCommandList7, (void **)&cl->d3d_cl);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -792,8 +788,6 @@ void G_ResetArena(G_CommandListHandle cl_handle, G_ArenaHandle arena_handle)
void G_D12_ResetArena(G_D12_CmdList *cl, G_D12_Arena *gpu_arena) void G_D12_ResetArena(G_D12_CmdList *cl, G_D12_Arena *gpu_arena)
{ {
// TODO
for (u64 heap_idx = 0; heap_idx < countof(gpu_arena->resource_heaps); ++heap_idx) for (u64 heap_idx = 0; heap_idx < countof(gpu_arena->resource_heaps); ++heap_idx)
{ {
G_D12_ResourceHeap *heap = &gpu_arena->resource_heaps[heap_idx]; G_D12_ResourceHeap *heap = &gpu_arena->resource_heaps[heap_idx];
@ -821,8 +815,6 @@ void G_D12_ResetArena(G_D12_CmdList *cl, G_D12_Arena *gpu_arena)
} }
} }
// Push descriptors to cl reset list // Push descriptors to cl reset list
if (gpu_arena->descriptors.first) if (gpu_arena->descriptors.first)
{ {
@ -848,7 +840,6 @@ void G_D12_ResetArena(G_D12_CmdList *cl, G_D12_Arena *gpu_arena)
G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle cl_handle, G_ResourceDesc desc) G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle cl_handle, G_ResourceDesc desc)
{ {
G_D12_SharedState *g = &G_D12_shared_state;
G_D12_Arena *gpu_arena = G_D12_ArenaFromHandle(arena_handle); G_D12_Arena *gpu_arena = G_D12_ArenaFromHandle(arena_handle);
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle); G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
G_D12_Resource *resource = 0; G_D12_Resource *resource = 0;
@ -913,7 +904,7 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
} }
d3d_desc.Flags |= D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; d3d_desc.Flags |= D3D12_HEAP_FLAG_CREATE_NOT_ZEROED;
d3d_desc.Flags |= D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES; // TODO: Remove this and support tier 1 resource heaps d3d_desc.Flags |= D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES; // TODO: Remove this and support tier 1 resource heaps
hr = ID3D12Device_CreateHeap(g->device, &d3d_desc, &IID_ID3D12Heap, (void **)&heap->d3d_heap); hr = ID3D12Device_CreateHeap(G_D12.device, &d3d_desc, &IID_ID3D12Heap, (void **)&heap->d3d_heap);
heap->size = d3d_desc.SizeInBytes; heap->size = d3d_desc.SizeInBytes;
if (d3d_desc.Properties.Type == D3D12_HEAP_TYPE_DEFAULT) if (d3d_desc.Properties.Type == D3D12_HEAP_TYPE_DEFAULT)
{ {
@ -946,7 +937,7 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
u64 alloc_align = 0; u64 alloc_align = 0;
{ {
D3D12_RESOURCE_ALLOCATION_INFO alloc_info = Zi; D3D12_RESOURCE_ALLOCATION_INFO alloc_info = Zi;
ID3D12Device_GetResourceAllocationInfo(g->device, &alloc_info, 0, 1, (D3D12_RESOURCE_DESC *)&d3d_desc); ID3D12Device_GetResourceAllocationInfo(G_D12.device, &alloc_info, 0, 1, (D3D12_RESOURCE_DESC *)&d3d_desc);
alloc_size = alloc_info.SizeInBytes; alloc_size = alloc_info.SizeInBytes;
alloc_align = alloc_info.Alignment; alloc_align = alloc_info.Alignment;
} }
@ -957,7 +948,7 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
} }
hr = ID3D12Device10_CreatePlacedResource2( hr = ID3D12Device10_CreatePlacedResource2(
g->device, G_D12.device,
heap->d3d_heap, heap->d3d_heap,
0, 0,
&d3d_desc, &d3d_desc,
@ -1035,7 +1026,7 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
u64 size_in_heap = 0; u64 size_in_heap = 0;
{ {
D3D12_RESOURCE_ALLOCATION_INFO alloc_info = Zi; D3D12_RESOURCE_ALLOCATION_INFO alloc_info = Zi;
ID3D12Device_GetResourceAllocationInfo(g->device, &alloc_info, 0, 1, (D3D12_RESOURCE_DESC *)&d3d_desc); ID3D12Device_GetResourceAllocationInfo(G_D12.device, &alloc_info, 0, 1, (D3D12_RESOURCE_DESC *)&d3d_desc);
align_in_heap = alloc_info.Alignment; align_in_heap = alloc_info.Alignment;
size_in_heap = alloc_info.SizeInBytes; size_in_heap = alloc_info.SizeInBytes;
} }
@ -1100,7 +1091,7 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
Panic(Lit("Gpu arena overflow")); Panic(Lit("Gpu arena overflow"));
} }
hr = ID3D12Device10_CreatePlacedResource2( hr = ID3D12Device10_CreatePlacedResource2(
g->device, G_D12.device,
heap->d3d_heap, heap->d3d_heap,
pos_in_heap, pos_in_heap,
&d3d_desc, &d3d_desc,
@ -1120,7 +1111,7 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
resource->pos_in_heap = pos_in_heap; resource->pos_in_heap = pos_in_heap;
resource->size_in_heap = size_in_heap; resource->size_in_heap = size_in_heap;
resource->d3d_resource = d3d_resource; resource->d3d_resource = d3d_resource;
resource->uid = Atomic64FetchAdd(&g->resource_creation_gen.v, 1) + 1; resource->uid = Atomic64FetchAdd(&G_D12.resource_creation_gen.v, 1) + 1;
resource->flags = flags; resource->flags = flags;
if (is_buffer) if (is_buffer)
{ {
@ -1148,7 +1139,7 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
if (is_sampler) if (is_sampler)
{ {
resource = PushStruct(gpu_arena->arena, G_D12_Resource); resource = PushStruct(gpu_arena->arena, G_D12_Resource);
resource->uid = Atomic64FetchAdd(&g->resource_creation_gen.v, 1) + 1; resource->uid = Atomic64FetchAdd(&G_D12.resource_creation_gen.v, 1) + 1;
resource->sampler_desc = desc.sampler; resource->sampler_desc = desc.sampler;
} }
@ -1160,16 +1151,14 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
G_D12_Descriptor *G_D12_DescriptorFromIndex(G_D12_DescriptorHeapKind heap_kind, u32 index) G_D12_Descriptor *G_D12_DescriptorFromIndex(G_D12_DescriptorHeapKind heap_kind, u32 index)
{ {
G_D12_SharedState *g = &G_D12_shared_state; G_D12_DescriptorHeap *heap = &G_D12.descriptor_heaps[heap_kind];
G_D12_DescriptorHeap *heap = &g->descriptor_heaps[heap_kind];
G_D12_Descriptor *descriptors = ArenaFirst(heap->descriptors_arena, G_D12_Descriptor); G_D12_Descriptor *descriptors = ArenaFirst(heap->descriptors_arena, G_D12_Descriptor);
return &descriptors[index]; return &descriptors[index];
} }
G_D12_Descriptor *G_D12_PushDescriptor(G_D12_Arena *gpu_arena, G_D12_DescriptorHeapKind heap_kind) G_D12_Descriptor *G_D12_PushDescriptor(G_D12_Arena *gpu_arena, G_D12_DescriptorHeapKind heap_kind)
{ {
G_D12_SharedState *g = &G_D12_shared_state; G_D12_DescriptorHeap *heap = &G_D12.descriptor_heaps[heap_kind];
G_D12_DescriptorHeap *heap = &g->descriptor_heaps[heap_kind];
G_D12_Descriptor *descriptor = 0; G_D12_Descriptor *descriptor = 0;
u32 index = 0; u32 index = 0;
@ -1238,7 +1227,6 @@ G_D12_Descriptor *G_D12_PushDescriptor(G_D12_Arena *gpu_arena, G_D12_DescriptorH
u32 G_PushRef(G_ArenaHandle arena_handle, G_ResourceHandle resource_handle, G_RefDesc ref_desc) u32 G_PushRef(G_ArenaHandle arena_handle, G_ResourceHandle resource_handle, G_RefDesc ref_desc)
{ {
G_D12_SharedState *g = &G_D12_shared_state;
G_D12_Arena *gpu_arena = G_D12_ArenaFromHandle(arena_handle); G_D12_Arena *gpu_arena = G_D12_ArenaFromHandle(arena_handle);
G_D12_Resource *resource = G_D12_ResourceFromHandle(resource_handle); G_D12_Resource *resource = G_D12_ResourceFromHandle(resource_handle);
u32 result = 0; u32 result = 0;
@ -1302,7 +1290,7 @@ u32 G_PushRef(G_ArenaHandle arena_handle, G_ResourceHandle resource_handle, G_Re
desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW; desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW;
desc.Buffer.StructureByteStride = 0; desc.Buffer.StructureByteStride = 0;
} }
ID3D12Device_CreateUnorderedAccessView(g->device, resource->d3d_resource, 0, &desc, descriptor->handle); ID3D12Device_CreateUnorderedAccessView(G_D12.device, resource->d3d_resource, 0, &desc, descriptor->handle);
} }
else else
{ {
@ -1322,7 +1310,7 @@ u32 G_PushRef(G_ArenaHandle arena_handle, G_ResourceHandle resource_handle, G_Re
desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW; desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW;
desc.Buffer.StructureByteStride = 0; desc.Buffer.StructureByteStride = 0;
} }
ID3D12Device_CreateShaderResourceView(g->device, resource->d3d_resource, &desc, descriptor->handle); ID3D12Device_CreateShaderResourceView(G_D12.device, resource->d3d_resource, &desc, descriptor->handle);
} }
} }
} }
@ -1331,11 +1319,11 @@ u32 G_PushRef(G_ArenaHandle arena_handle, G_ResourceHandle resource_handle, G_Re
descriptor = G_D12_PushDescriptor(gpu_arena, G_D12_DescriptorHeapKind_CbvSrvUav); descriptor = G_D12_PushDescriptor(gpu_arena, G_D12_DescriptorHeapKind_CbvSrvUav);
if (is_uav) if (is_uav)
{ {
ID3D12Device_CreateUnorderedAccessView(g->device, resource->d3d_resource, 0, 0, descriptor->handle); ID3D12Device_CreateUnorderedAccessView(G_D12.device, resource->d3d_resource, 0, 0, descriptor->handle);
} }
else else
{ {
ID3D12Device_CreateShaderResourceView(g->device, resource->d3d_resource, 0, descriptor->handle); ID3D12Device_CreateShaderResourceView(G_D12.device, resource->d3d_resource, 0, descriptor->handle);
} }
} }
else if (is_sampler) else if (is_sampler)
@ -1365,7 +1353,7 @@ u32 G_PushRef(G_ArenaHandle arena_handle, G_ResourceHandle resource_handle, G_Re
{ {
d3d_desc.MaxLOD = D3D12_FLOAT32_MAX; d3d_desc.MaxLOD = D3D12_FLOAT32_MAX;
} }
ID3D12Device_CreateSampler(g->device, &d3d_desc, descriptor->handle); ID3D12Device_CreateSampler(G_D12.device, &d3d_desc, descriptor->handle);
} }
return descriptor->index; return descriptor->index;
@ -1429,7 +1417,6 @@ void *G_HostPointerFromResource(G_ResourceHandle resource_handle)
G_D12_Cmd *G_D12_PushCmd(G_D12_CmdList *cl) G_D12_Cmd *G_D12_PushCmd(G_D12_CmdList *cl)
{ {
G_D12_SharedState *g = &G_D12_shared_state;
// Grab chunk // Grab chunk
G_D12_CmdChunk *chunk = cl->last_cmd_chunk; G_D12_CmdChunk *chunk = cl->last_cmd_chunk;
@ -1440,12 +1427,12 @@ G_D12_Cmd *G_D12_PushCmd(G_D12_CmdList *cl)
} }
if (!chunk) if (!chunk)
{ {
Lock lock = LockE(&g->free_cmd_chunks_mutex); Lock lock = LockE(&G_D12.free_cmd_chunks_mutex);
{ {
chunk = g->first_free_cmd_chunk; chunk = G_D12.first_free_cmd_chunk;
if (chunk) if (chunk)
{ {
g->first_free_cmd_chunk = chunk->next; G_D12.first_free_cmd_chunk = chunk->next;
} }
} }
Unlock(&lock); Unlock(&lock);
@ -1488,7 +1475,6 @@ G_D12_StagingRegionNode *G_D12_PushStagingRegion(G_D12_CmdList *cl, u64 size)
{ {
size = AlignU64(size, MaxU64(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT, 512)); size = AlignU64(size, MaxU64(D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT, 512));
G_D12_SharedState *g = &G_D12_shared_state;
G_QueueKind queue_kind = cl->queue_kind; G_QueueKind queue_kind = cl->queue_kind;
G_D12_Queue *queue = G_D12_QueueFromKind(queue_kind); G_D12_Queue *queue = G_D12_QueueFromKind(queue_kind);
G_D12_StagingRegionNode *result = 0; G_D12_StagingRegionNode *result = 0;
@ -1686,14 +1672,13 @@ G_D12_StagingRegionNode *G_D12_PushStagingRegion(G_D12_CmdList *cl, u64 size)
G_CommandListHandle G_PrepareCommandList(G_QueueKind queue) G_CommandListHandle G_PrepareCommandList(G_QueueKind queue)
{ {
G_D12_SharedState *g = &G_D12_shared_state;
G_D12_CmdList *cl = 0; G_D12_CmdList *cl = 0;
Lock lock = LockE(&g->free_cmd_lists_mutex); Lock lock = LockE(&G_D12.free_cmd_lists_mutex);
{ {
cl = g->first_free_cmd_list; cl = G_D12.first_free_cmd_list;
if (cl) if (cl)
{ {
g->first_free_cmd_list = cl->next; G_D12.first_free_cmd_list = cl->next;
ZeroStruct(cl); ZeroStruct(cl);
} }
else else
@ -1710,7 +1695,6 @@ G_CommandListHandle G_PrepareCommandList(G_QueueKind queue)
i64 G_CommitCommandList(G_CommandListHandle cl_handle) i64 G_CommitCommandList(G_CommandListHandle cl_handle)
{ {
G_D12_SharedState *g = &G_D12_shared_state;
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle); G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
G_QueueKind queue_kind = cl->queue_kind; G_QueueKind queue_kind = cl->queue_kind;
G_D12_Queue *queue = G_D12_QueueFromKind(queue_kind); G_D12_Queue *queue = G_D12_QueueFromKind(queue_kind);
@ -1763,13 +1747,13 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
} }
// Free command chunks // Free command chunks
{ {
Lock lock = LockE(&g->free_cmd_chunks_mutex); Lock lock = LockE(&G_D12.free_cmd_chunks_mutex);
{ {
G_D12_CmdChunk *chunk = cl->first_cmd_chunk; G_D12_CmdChunk *chunk = cl->first_cmd_chunk;
while (chunk) while (chunk)
{ {
G_D12_CmdChunk *next = chunk->next; G_D12_CmdChunk *next = chunk->next;
g->first_free_cmd_chunk = chunk; G_D12.first_free_cmd_chunk = chunk;
chunk = next; chunk = next;
} }
} }
@ -2049,8 +2033,8 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
if (!descriptor_heaps_set) if (!descriptor_heaps_set)
{ {
ID3D12DescriptorHeap *heaps[] = { ID3D12DescriptorHeap *heaps[] = {
g->descriptor_heaps[G_D12_DescriptorHeapKind_CbvSrvUav].d3d_heap, G_D12.descriptor_heaps[G_D12_DescriptorHeapKind_CbvSrvUav].d3d_heap,
g->descriptor_heaps[G_D12_DescriptorHeapKind_Sampler].d3d_heap, G_D12.descriptor_heaps[G_D12_DescriptorHeapKind_Sampler].d3d_heap,
}; };
ID3D12GraphicsCommandList_SetDescriptorHeaps(d3d_cl, countof(heaps), heaps); ID3D12GraphicsCommandList_SetDescriptorHeaps(d3d_cl, countof(heaps), heaps);
descriptor_heaps_set = 1; descriptor_heaps_set = 1;
@ -2059,7 +2043,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
// Bind rootsig // Bind rootsig
if (!compute_rootsig_set) if (!compute_rootsig_set)
{ {
ID3D12GraphicsCommandList_SetComputeRootSignature(d3d_cl, g->bindless_rootsig); ID3D12GraphicsCommandList_SetComputeRootSignature(d3d_cl, G_D12.bindless_rootsig);
compute_rootsig_set = 1; compute_rootsig_set = 1;
} }
@ -2163,8 +2147,8 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
if (!descriptor_heaps_set) if (!descriptor_heaps_set)
{ {
ID3D12DescriptorHeap *heaps[] = { ID3D12DescriptorHeap *heaps[] = {
g->descriptor_heaps[G_D12_DescriptorHeapKind_CbvSrvUav].d3d_heap, G_D12.descriptor_heaps[G_D12_DescriptorHeapKind_CbvSrvUav].d3d_heap,
g->descriptor_heaps[G_D12_DescriptorHeapKind_Sampler].d3d_heap, G_D12.descriptor_heaps[G_D12_DescriptorHeapKind_Sampler].d3d_heap,
}; };
ID3D12GraphicsCommandList_SetDescriptorHeaps(d3d_cl, countof(heaps), heaps); ID3D12GraphicsCommandList_SetDescriptorHeaps(d3d_cl, countof(heaps), heaps);
descriptor_heaps_set = 1; descriptor_heaps_set = 1;
@ -2173,7 +2157,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
// Bind rootsig // Bind rootsig
if (!graphics_rootsig_set) if (!graphics_rootsig_set)
{ {
ID3D12GraphicsCommandList_SetGraphicsRootSignature(d3d_cl, g->bindless_rootsig); ID3D12GraphicsCommandList_SetGraphicsRootSignature(d3d_cl, G_D12.bindless_rootsig);
graphics_rootsig_set = 1; graphics_rootsig_set = 1;
} }
@ -2269,7 +2253,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
if (bound_render_target_uids[i] != rt->uid) if (bound_render_target_uids[i] != rt->uid)
{ {
G_D12_Descriptor *rtv_descriptor = rcl->rtv_descriptors[i]; G_D12_Descriptor *rtv_descriptor = rcl->rtv_descriptors[i];
ID3D12Device_CreateRenderTargetView(g->device, rt->d3d_resource, 0, rtv_descriptor->handle); ID3D12Device_CreateRenderTargetView(G_D12.device, rt->d3d_resource, 0, rtv_descriptor->handle);
bound_render_target_uids[i] = rt->uid; bound_render_target_uids[i] = rt->uid;
om_dirty = 1; om_dirty = 1;
} }
@ -2313,7 +2297,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle = rcl->rtv_clear_descriptor->handle; D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle = rcl->rtv_clear_descriptor->handle;
if (bound_render_clear_target_uid != rt->uid) if (bound_render_clear_target_uid != rt->uid)
{ {
ID3D12Device_CreateRenderTargetView(g->device, rt->d3d_resource, 0, rtv_handle); ID3D12Device_CreateRenderTargetView(G_D12.device, rt->d3d_resource, 0, rtv_handle);
bound_render_clear_target_uid = rt->uid; bound_render_clear_target_uid = rt->uid;
} }
ID3D12GraphicsCommandList_ClearRenderTargetView(d3d_cl, rtv_handle, clear_color, 0, 0); ID3D12GraphicsCommandList_ClearRenderTargetView(d3d_cl, rtv_handle, clear_color, 0, 0);
@ -2379,10 +2363,10 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
// Free command list // Free command list
{ {
Lock lock = LockE(&g->free_cmd_lists_mutex); Lock lock = LockE(&G_D12.free_cmd_lists_mutex);
{ {
cl->next = g->first_free_cmd_list; cl->next = G_D12.first_free_cmd_list;
g->first_free_cmd_list = cl; G_D12.first_free_cmd_list = cl;
} }
Unlock(&lock); Unlock(&lock);
} }
@ -2421,7 +2405,6 @@ void G_CopyCpuToTexture(G_CommandListHandle cl_handle, G_ResourceHandle dst_hand
} }
if (staged_dims.x > 0 && staged_dims.y > 0 && staged_dims.z > 0) if (staged_dims.x > 0 && staged_dims.y > 0 && staged_dims.z > 0)
{ {
G_D12_SharedState *g = &G_D12_shared_state;
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle); G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
G_D12_Resource *dst = G_D12_ResourceFromHandle(dst_handle); G_D12_Resource *dst = G_D12_ResourceFromHandle(dst_handle);
Assert(dst->is_texture); Assert(dst->is_texture);
@ -2440,7 +2423,7 @@ void G_CopyCpuToTexture(G_CommandListHandle cl_handle, G_ResourceHandle dst_hand
src_desc.Height = staged_dims.y; src_desc.Height = staged_dims.y;
src_desc.DepthOrArraySize = staged_dims.z; src_desc.DepthOrArraySize = staged_dims.z;
} }
ID3D12Device_GetCopyableFootprints(g->device, &src_desc, 0, 1, 0, &staging_footprint, (u32 *)&staging_footprint_rows_count, &staging_footprint_row_size, &staging_footprint_size); ID3D12Device_GetCopyableFootprints(G_D12.device, &src_desc, 0, 1, 0, &staging_footprint, (u32 *)&staging_footprint_rows_count, &staging_footprint_row_size, &staging_footprint_size);
staging_footprint_row_pitch = staging_footprint.Footprint.RowPitch; staging_footprint_row_pitch = staging_footprint.Footprint.RowPitch;
} }
@ -2510,7 +2493,6 @@ void G_CopyBufferToTexture(G_CommandListHandle cl_handle, G_ResourceHandle dst_h
} }
if (src_dims.x > 0 && src_dims.y > 0 && src_dims.z > 0) if (src_dims.x > 0 && src_dims.y > 0 && src_dims.z > 0)
{ {
G_D12_SharedState *g = &G_D12_shared_state;
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle); G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
G_D12_Resource *src = G_D12_ResourceFromHandle(src_handle); G_D12_Resource *src = G_D12_ResourceFromHandle(src_handle);
G_D12_Resource *dst = G_D12_ResourceFromHandle(dst_handle); G_D12_Resource *dst = G_D12_ResourceFromHandle(dst_handle);
@ -2527,7 +2509,7 @@ void G_CopyBufferToTexture(G_CommandListHandle cl_handle, G_ResourceHandle dst_h
src_desc.Height = src_dims.y; src_desc.Height = src_dims.y;
src_desc.DepthOrArraySize = src_dims.z; src_desc.DepthOrArraySize = src_dims.z;
} }
ID3D12Device_GetCopyableFootprints(g->device, &src_desc, 0, 1, 0, &src_footprint, 0, 0, 0); ID3D12Device_GetCopyableFootprints(G_D12.device, &src_desc, 0, 1, 0, &src_footprint, 0, 0, 0);
src_footprint.Offset = src_offset; src_footprint.Offset = src_offset;
} }
@ -2562,7 +2544,6 @@ void G_CopyTextureToTexture(G_CommandListHandle cl_handle, G_ResourceHandle dst_
src_copy_range.p1.z > src_copy_range.p0.z src_copy_range.p1.z > src_copy_range.p0.z
) )
{ {
G_D12_SharedState *g = &G_D12_shared_state;
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle); G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
G_D12_Resource *src = G_D12_ResourceFromHandle(src_handle); G_D12_Resource *src = G_D12_ResourceFromHandle(src_handle);
G_D12_Resource *dst = G_D12_ResourceFromHandle(dst_handle); G_D12_Resource *dst = G_D12_ResourceFromHandle(dst_handle);
@ -2728,7 +2709,6 @@ G_QueueCompletions G_CompletionTargetsFromQueues(G_QueueMask queue_mask)
void G_SyncEx(G_QueueBarrierDesc desc) void G_SyncEx(G_QueueBarrierDesc desc)
{ {
G_D12_SharedState *g = &G_D12_shared_state;
u64 fences_count = 0; u64 fences_count = 0;
ID3D12Fence *fences[G_NumQueues] = Zi; ID3D12Fence *fences[G_NumQueues] = Zi;
@ -2777,7 +2757,7 @@ void G_SyncEx(G_QueueBarrierDesc desc)
G_D12_tl.sync_event = CreateEvent(0, 0, 0, 0); G_D12_tl.sync_event = CreateEvent(0, 0, 0, 0);
} }
ID3D12Device1_SetEventOnMultipleFenceCompletion( ID3D12Device1_SetEventOnMultipleFenceCompletion(
g->device, G_D12.device,
fences, fences,
(u64 *)fence_targets, (u64 *)fence_targets,
fences_count, fences_count,
@ -2793,22 +2773,21 @@ void G_SyncEx(G_QueueBarrierDesc desc)
G_Stats G_QueryStats(void) G_Stats G_QueryStats(void)
{ {
G_D12_SharedState *g = &G_D12_shared_state;
G_Stats result = Zi; G_Stats result = Zi;
{ {
DXGI_QUERY_VIDEO_MEMORY_INFO info = Zi; DXGI_QUERY_VIDEO_MEMORY_INFO info = Zi;
IDXGIAdapter3_QueryVideoMemoryInfo(g->adapter, 0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &info); IDXGIAdapter3_QueryVideoMemoryInfo(G_D12.adapter, 0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &info);
result.local_committed = info.CurrentUsage; result.local_committed = info.CurrentUsage;
result.local_budget = info.Budget; result.local_budget = info.Budget;
} }
{ {
DXGI_QUERY_VIDEO_MEMORY_INFO info = Zi; DXGI_QUERY_VIDEO_MEMORY_INFO info = Zi;
IDXGIAdapter3_QueryVideoMemoryInfo(g->adapter, 0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &info); IDXGIAdapter3_QueryVideoMemoryInfo(G_D12.adapter, 0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &info);
result.non_local_budget = info.Budget; result.non_local_budget = info.Budget;
result.non_local_committed = info.CurrentUsage; result.non_local_committed = info.CurrentUsage;
} }
result.driver_resources_allocated = Atomic64Fetch(&g->driver_resources_allocated); result.driver_resources_allocated = Atomic64Fetch(&G_D12.driver_resources_allocated);
result.driver_descriptors_allocated = Atomic64Fetch(&g->driver_descriptors_allocated); result.driver_descriptors_allocated = Atomic64Fetch(&G_D12.driver_descriptors_allocated);
return result; return result;
} }
@ -2833,7 +2812,6 @@ void G_ReleaseSwapchain(G_SwapchainHandle swapchain_handle)
G_ResourceHandle G_PrepareBackbuffer(G_SwapchainHandle swapchain_handle, G_Format format, Vec2I32 size) G_ResourceHandle G_PrepareBackbuffer(G_SwapchainHandle swapchain_handle, G_Format format, Vec2I32 size)
{ {
G_D12_SharedState *g = &G_D12_shared_state;
G_D12_Swapchain *swapchain = G_D12_SwapchainFromHandle(swapchain_handle); G_D12_Swapchain *swapchain = G_D12_SwapchainFromHandle(swapchain_handle);
size = VEC2I32(MaxI32(size.x, 1), MaxI32(size.y, 1)); size = VEC2I32(MaxI32(size.x, 1), MaxI32(size.y, 1));
G_D12_Queue *direct_queue = G_D12_QueueFromKind(G_QueueKind_Direct); G_D12_Queue *direct_queue = G_D12_QueueFromKind(G_QueueKind_Direct);
@ -2863,7 +2841,7 @@ G_ResourceHandle G_PrepareBackbuffer(G_SwapchainHandle swapchain_handle, G_Forma
desc.Flags = G_D12_SwapchainFlags; desc.Flags = G_D12_SwapchainFlags;
desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
hr = IDXGIFactory2_CreateSwapChainForHwnd(g->factory, (IUnknown *)direct_queue->d3d_queue, swapchain->window_hwnd, &desc, 0, 0, &swapchain1); hr = IDXGIFactory2_CreateSwapChainForHwnd(G_D12.factory, (IUnknown *)direct_queue->d3d_queue, swapchain->window_hwnd, &desc, 0, 0, &swapchain1);
} }
// Upgrade to swapchain3 // Upgrade to swapchain3
@ -2898,14 +2876,14 @@ G_ResourceHandle G_PrepareBackbuffer(G_SwapchainHandle swapchain_handle, G_Forma
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
present_event = CreateEvent(0, 0, 0, 0); present_event = CreateEvent(0, 0, 0, 0);
hr = ID3D12Device_CreateFence(g->device, 0, 0, &IID_ID3D12Fence, (void **)&present_fence); hr = ID3D12Device_CreateFence(G_D12.device, 0, 0, &IID_ID3D12Fence, (void **)&present_fence);
} }
swapchain->present_fence = present_fence; swapchain->present_fence = present_fence;
swapchain->present_event = present_event; swapchain->present_event = present_event;
} }
// Disable Alt+Enter // Disable Alt+Enter
IDXGIFactory_MakeWindowAssociation(g->factory, swapchain->window_hwnd, DXGI_MWA_NO_ALT_ENTER); IDXGIFactory_MakeWindowAssociation(G_D12.factory, swapchain->window_hwnd, DXGI_MWA_NO_ALT_ENTER);
if (FAILED(hr)) if (FAILED(hr))
{ {
@ -2960,7 +2938,7 @@ G_ResourceHandle G_PrepareBackbuffer(G_SwapchainHandle swapchain_handle, G_Forma
} }
ZeroStruct(backbuffer); ZeroStruct(backbuffer);
backbuffer->d3d_resource = d3d_resource; backbuffer->d3d_resource = d3d_resource;
backbuffer->uid = Atomic64FetchAdd(&g->resource_creation_gen.v, 1) + 1; backbuffer->uid = Atomic64FetchAdd(&G_D12.resource_creation_gen.v, 1) + 1;
backbuffer->flags = G_ResourceFlag_AllowRenderTarget; backbuffer->flags = G_ResourceFlag_AllowRenderTarget;
backbuffer->is_texture = 1; backbuffer->is_texture = 1;

View File

@ -409,7 +409,7 @@ Struct(G_D12_Swapchain)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ State types //~ State types
Struct(G_D12_SharedState) Struct(G_D12_Ctx)
{ {
Atomic64Padded resource_creation_gen; Atomic64Padded resource_creation_gen;
@ -445,12 +445,15 @@ Struct(G_D12_SharedState)
IDXGIFactory6 *factory; IDXGIFactory6 *factory;
IDXGIAdapter3 *adapter; IDXGIAdapter3 *adapter;
ID3D12Device10 *device; ID3D12Device10 *device;
} extern G_D12_shared_state; };
Struct(G_D12_ThreadLocalState) Struct(G_D12_ThreadLocalCtx)
{ {
HANDLE sync_event; HANDLE sync_event;
} extern ThreadLocal G_D12_tl; };
extern G_D12_Ctx G_D12;
extern ThreadLocal G_D12_ThreadLocalCtx G_D12_tl;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Helpers //~ Helpers

View File

@ -13,17 +13,16 @@
// - 2 16 bit integer samples output by audio file decoder representing two sound samples, one sample for each audio channel // - 2 16 bit integer samples output by audio file decoder representing two sound samples, one sample for each audio channel
// - 2 32 bit float samples output by mixer and consumed by playback API, one sample for each audio channel // - 2 32 bit float samples output by mixer and consumed by playback API, one sample for each audio channel
MIX_SharedState M_shared_state = ZI; MIX_Ctx M = Zi;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Bootstrap //~ Bootstrap
void MIX_Bootstrap(void) void MIX_Bootstrap(void)
{ {
MIX_SharedState *g = &M_shared_state; MIX.track_arena = AcquireArena(Gibi(64));
g->track_arena = AcquireArena(Gibi(64)); MIX.listener_pos = VEC2(0, 0);
g->listener_pos = VEC2(0, 0); MIX.listener_dir = VEC2(0, -1);
g->listener_dir = VEC2(0, -1);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -31,7 +30,7 @@ void MIX_Bootstrap(void)
MIX_Handle MIX_HandleFromTrack(MIX_Track *track) MIX_Handle MIX_HandleFromTrack(MIX_Track *track)
{ {
MIX_Handle result = ZI; MIX_Handle result = Zi;
result.gen = track->gen; result.gen = track->gen;
result.data = track; result.data = track;
return result; return result;
@ -52,16 +51,15 @@ MIX_Track *MIX_TrackFromHandle(MIX_Handle handle)
MIX_Track *MIX_AcquireTrackLocked(Lock *lock, SND_Sound *sound) MIX_Track *MIX_AcquireTrackLocked(Lock *lock, SND_Sound *sound)
{ {
MIX_SharedState *g = &M_shared_state; AssertLockedE(lock, &MIX.mutex);
AssertLockedE(lock, &g->mutex);
MIX_Track *track = 0; MIX_Track *track = 0;
if (g->track_first_free) if (MIX.track_first_free)
{ {
// Take from free list // Take from free list
track = g->track_first_free; track = MIX.track_first_free;
MIX_Track *next_free = track->next; MIX_Track *next_free = track->next;
g->track_first_free = next_free; MIX.track_first_free = next_free;
if (next_free) if (next_free)
{ {
next_free->prev = 0; next_free->prev = 0;
@ -71,7 +69,7 @@ MIX_Track *MIX_AcquireTrackLocked(Lock *lock, SND_Sound *sound)
else else
{ {
// Acquire new // Acquire new
track = PushStruct(g->track_arena, MIX_Track); track = PushStruct(MIX.track_arena, MIX_Track);
track->gen = 1; track->gen = 1;
} }
@ -80,26 +78,25 @@ MIX_Track *MIX_AcquireTrackLocked(Lock *lock, SND_Sound *sound)
track->mix.track_handle = MIX_HandleFromTrack(track); track->mix.track_handle = MIX_HandleFromTrack(track);
// Append to playing list // Append to playing list
MIX_Track *prev = g->track_last_playing; MIX_Track *prev = MIX.track_last_playing;
if (prev) if (prev)
{ {
prev->next = track; prev->next = track;
} }
else else
{ {
g->track_first_playing = track; MIX.track_first_playing = track;
} }
g->track_last_playing = track; MIX.track_last_playing = track;
track->prev = prev; track->prev = prev;
++g->track_playing_count; ++MIX.track_playing_count;
return track; return track;
} }
void MIX_ReleaseTrackLocked(Lock *lock, MIX_Track *track) void MIX_ReleaseTrackLocked(Lock *lock, MIX_Track *track)
{ {
MIX_SharedState *g = &M_shared_state; AssertLockedE(lock, &MIX.mutex);
AssertLockedE(lock, &g->mutex);
// Remove from playing list // Remove from playing list
MIX_Track *prev = track->prev; MIX_Track *prev = track->prev;
@ -111,7 +108,7 @@ void MIX_ReleaseTrackLocked(Lock *lock, MIX_Track *track)
else else
{ {
// Track was first in list // Track was first in list
g->track_first_playing = next; MIX.track_first_playing = next;
} }
if (next) if (next)
{ {
@ -120,34 +117,33 @@ void MIX_ReleaseTrackLocked(Lock *lock, MIX_Track *track)
else else
{ {
// Track was last in list // Track was last in list
g->track_last_playing = prev; MIX.track_last_playing = prev;
} }
--g->track_playing_count; --MIX.track_playing_count;
++track->gen; ++track->gen;
// Add to free list // Add to free list
track->prev = 0; track->prev = 0;
track->next = g->track_first_free; track->next = MIX.track_first_free;
if (g->track_first_free) if (MIX.track_first_free)
{ {
g->track_first_free->prev = track; MIX.track_first_free->prev = track;
} }
g->track_first_free = track; MIX.track_first_free = track;
} }
// TODO: Rework interface to be command based instead of directly modifying tracks. // TODO: Rework interface to be command based instead of directly modifying tracks.
MIX_Handle MIX_PlaySound(SND_Sound *sound) MIX_Handle MIX_PlaySound(SND_Sound *sound)
{ {
return MIX_PlaySoundEx(sound, M_TRACKDESC()); return MIX_PlaySoundEx(sound, MIX_TRACKDESC());
} }
MIX_Handle MIX_PlaySoundEx(SND_Sound *sound, MIX_TrackDesc desc) MIX_Handle MIX_PlaySoundEx(SND_Sound *sound, MIX_TrackDesc desc)
{ {
MIX_SharedState *g = &M_shared_state;
MIX_Track *track; MIX_Track *track;
{ {
Lock lock = LockE(&g->mutex); Lock lock = LockE(&MIX.mutex);
{ {
track = MIX_AcquireTrackLocked(&lock, sound); track = MIX_AcquireTrackLocked(&lock, sound);
track->desc = desc; track->desc = desc;
@ -160,14 +156,13 @@ MIX_Handle MIX_PlaySoundEx(SND_Sound *sound, MIX_TrackDesc desc)
// NOTE: This is quite inefficient. // NOTE: This is quite inefficient.
MIX_TrackDesc MIX_TrackDescFromHandle(MIX_Handle handle) MIX_TrackDesc MIX_TrackDescFromHandle(MIX_Handle handle)
{ {
MIX_SharedState *g = &M_shared_state; MIX_TrackDesc result = Zi;
MIX_TrackDesc result = ZI;
MIX_Track *track = MIX_TrackFromHandle(handle); MIX_Track *track = MIX_TrackFromHandle(handle);
if (track) if (track)
{ {
// TODO: Only lock mutex on track itself or something // TODO: Only lock mutex on track itself or something
Lock lock = LockE(&g->mutex); Lock lock = LockE(&MIX.mutex);
{ {
// Confirm handle is still valid now that we're locked // Confirm handle is still valid now that we're locked
track = MIX_TrackFromHandle(handle); track = MIX_TrackFromHandle(handle);
@ -185,12 +180,11 @@ MIX_TrackDesc MIX_TrackDescFromHandle(MIX_Handle handle)
// NOTE: This is quite inefficient. // NOTE: This is quite inefficient.
void MIX_UpdateTrack(MIX_Handle handle, MIX_TrackDesc desc) void MIX_UpdateTrack(MIX_Handle handle, MIX_TrackDesc desc)
{ {
MIX_SharedState *g = &M_shared_state;
MIX_Track *track = MIX_TrackFromHandle(handle); MIX_Track *track = MIX_TrackFromHandle(handle);
if (track) if (track)
{ {
// TODO: Only lock mutex on track itself or something // TODO: Only lock mutex on track itself or something
Lock lock = LockE(&g->mutex); Lock lock = LockE(&MIX.mutex);
{ {
// Confirm handle is still valid now that we're locked // Confirm handle is still valid now that we're locked
track = MIX_TrackFromHandle(handle); track = MIX_TrackFromHandle(handle);
@ -205,11 +199,10 @@ void MIX_UpdateTrack(MIX_Handle handle, MIX_TrackDesc desc)
void MIX_UpdateListener(Vec2 pos, Vec2 dir) void MIX_UpdateListener(Vec2 pos, Vec2 dir)
{ {
MIX_SharedState *g = &M_shared_state; Lock lock = LockE(&MIX.mutex);
Lock lock = LockE(&g->mutex);
{ {
g->listener_pos = pos; MIX.listener_pos = pos;
g->listener_dir = NormVec2(dir); MIX.listener_dir = NormVec2(dir);
} }
Unlock(&lock); Unlock(&lock);
} }
@ -237,9 +230,8 @@ i16 MIX_SampleSound(SND_Sound *sound, u64 sample_pos, b32 wrap)
MIX_PcmF32 MIX_MixAllTracks(Arena *arena, u64 frame_count) MIX_PcmF32 MIX_MixAllTracks(Arena *arena, u64 frame_count)
{ {
TempArena scratch = BeginScratch(arena); TempArena scratch = BeginScratch(arena);
MIX_SharedState *g = &M_shared_state;
MIX_PcmF32 result = ZI; MIX_PcmF32 result = Zi;
result.count = frame_count * 2; result.count = frame_count * 2;
result.samples = PushStructs(arena, f32, result.count); result.samples = PushStructs(arena, f32, result.count);
@ -251,15 +243,15 @@ MIX_PcmF32 MIX_MixAllTracks(Arena *arena, u64 frame_count)
MIX_MixData **mixes = 0; MIX_MixData **mixes = 0;
u64 mixes_count = 0; u64 mixes_count = 0;
{ {
Lock lock = LockE(&g->mutex); Lock lock = LockE(&MIX.mutex);
// Read listener info // Read listener info
listener_pos = g->listener_pos; listener_pos = MIX.listener_pos;
listener_dir = g->listener_dir; listener_dir = MIX.listener_dir;
// Update & read mixes // Update & read mixes
mixes = PushStructsNoZero(scratch.arena, MIX_MixData *, g->track_playing_count); mixes = PushStructsNoZero(scratch.arena, MIX_MixData *, MIX.track_playing_count);
for (MIX_Track *track = g->track_first_playing; track; track = track->next) for (MIX_Track *track = MIX.track_first_playing; track; track = track->next)
{ {
MIX_MixData *mix = &track->mix; MIX_MixData *mix = &track->mix;
mix->desc = track->desc; mix->desc = track->desc;
@ -445,7 +437,7 @@ MIX_PcmF32 MIX_MixAllTracks(Arena *arena, u64 frame_count)
//- Update track effect data //- Update track effect data
{ {
Lock lock = LockE(&g->mutex); Lock lock = LockE(&MIX.mutex);
for (u64 i = 0; i < mixes_count; ++i) for (u64 i = 0; i < mixes_count; ++i)
{ {
MIX_MixData *mix = mixes[i]; MIX_MixData *mix = mixes[i];

View File

@ -22,13 +22,13 @@ Struct(MIX_TrackDesc)
Vec2 pos; Vec2 pos;
}; };
#define M_TRACKDESC(...) ((MIX_TrackDesc) { \ #define MIX_TRACKDESC(...) ((MIX_TrackDesc) { \
.flags = 0, \ .flags = 0, \
.volume = 1.0, \ .volume = 1.0, \
.speed = 1.0, \ .speed = 1.0, \
.looping = 0, \ .looping = 0, \
.pos = VEC2(0, 0), \ .pos = VEC2(0, 0), \
__VA_ARGS__ \ __VA_ARGS__ \
}) })
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -76,7 +76,7 @@ Struct(MIX_Track){
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ State types //~ State types
Struct(MIX_SharedState) Struct(MIX_Ctx)
{ {
Mutex mutex; Mutex mutex;
@ -90,7 +90,9 @@ Struct(MIX_SharedState)
MIX_Track *track_last_playing; MIX_Track *track_last_playing;
u64 track_playing_count; u64 track_playing_count;
MIX_Track *track_first_free; MIX_Track *track_first_free;
} extern M_shared_state; };
extern MIX_Ctx MIX;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Bootstrap //~ Bootstrap

View File

@ -1,18 +1,16 @@
P_W32_SharedState P_W32_shared_state = Zi; P_W32_Ctx P_W32 = Zi;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ @hookimpl Bootstrap //~ @hookimpl Bootstrap
void P_Bootstrap(void) void P_Bootstrap(void)
{ {
P_W32_SharedState *g = &P_W32_shared_state;
//- Init watches pool //- Init watches pool
g->watches_arena = AcquireArena(Gibi(64)); P_W32.watches_arena = AcquireArena(Gibi(64));
// Init winsock // Init winsock
WSAStartup(MAKEWORD(2, 2), &g->wsa_data); WSAStartup(MAKEWORD(2, 2), &P_W32.wsa_data);
g->socks_arena = AcquireArena(Gibi(64)); P_W32.socks_arena = AcquireArena(Gibi(64));
// Init timer // Init timer
DispatchWave(Lit("Win32 timer sync"), 1, P_W32_SyncTimerForever, 0); DispatchWave(Lit("Win32 timer sync"), 1, P_W32_SyncTimerForever, 0);
@ -41,11 +39,8 @@ DateTime P_W32_DateTimeFromWin32SystemTime(SYSTEMTIME st)
String P_W32_StringFromWin32Path(Arena *arena, wchar_t *src) String P_W32_StringFromWin32Path(Arena *arena, wchar_t *src)
{ {
String result = { String result = Zi;
.len = 0, result.text = ArenaNext(arena, u8);
.text = ArenaNext(arena, u8)
};
while (*src) while (*src)
{ {
String16 decode_str = { .len = *(src + 1) ? 2 : 1, .text = src }; String16 decode_str = { .len = *(src + 1) ? 2 : 1, .text = src };
@ -64,7 +59,6 @@ String P_W32_StringFromWin32Path(Arena *arena, wchar_t *src)
result.len += encoded.count8; result.len += encoded.count8;
src += decoded.advance16; src += decoded.advance16;
} }
return result; return result;
} }
@ -159,7 +153,6 @@ P_Address P_W32_PlatformAddressFromWin32Address(P_W32_Address ws_addr)
void P_W32_SyncTimerForever(WaveLaneCtx *lane) void P_W32_SyncTimerForever(WaveLaneCtx *lane)
{ {
P_W32_SharedState *g = &P_W32_shared_state;
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
// Create high resolution timer // Create high resolution timer
@ -208,11 +201,11 @@ void P_W32_SyncTimerForever(WaveLaneCtx *lane)
periods_sum_ns += (f64)periods[i]; periods_sum_ns += (f64)periods[i];
} }
f64 mean_ns = periods_sum_ns / (f64)countof(periods); f64 mean_ns = periods_sum_ns / (f64)countof(periods);
Atomic64Set(&g->average_timer_period_ns.v, RoundF64ToI64(mean_ns)); Atomic64Set(&P_W32.average_timer_period_ns.v, RoundF64ToI64(mean_ns));
} }
// Update fence // Update fence
SetFence(&g->timer_fence, now_ns); SetFence(&P_W32.timer_fence, now_ns);
} }
} }
@ -408,27 +401,23 @@ String P_ReadFile(Arena *arena, P_File file)
i64 size = 0; i64 size = 0;
GetFileSizeEx((HANDLE)file.handle, (PLARGE_INTEGER)&size); GetFileSizeEx((HANDLE)file.handle, (PLARGE_INTEGER)&size);
String s = { String result;
.len = size, result.len = size;
.text = 0
};
if (size > 0) if (size > 0)
{ {
// ReadFile returns non-zero on success // ReadFile returns non-zero on success
// TODO: error checking // TODO: error checking
PushAlign(arena, CachelineSize); PushAlign(arena, CachelineSize);
s.text = PushStructsNoZero(arena, u8, size); result.text = PushStructsNoZero(arena, u8, size);
ReadFile( ReadFile(
(HANDLE)file.handle, (HANDLE)file.handle,
s.text, result.text,
(DWORD)s.len, (DWORD)result.len,
0, 0,
0 0
); );
} }
return result;
return s;
} }
void P_WriteFile(P_File file, String data) void P_WriteFile(P_File file, String data)
@ -770,18 +759,17 @@ b32 P_MatchAddress(P_Address a, P_Address b)
P_Sock *P_AcquireSock(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size) P_Sock *P_AcquireSock(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size)
{ {
P_W32_SharedState *g = &P_W32_shared_state;
P_W32_Sock *ws = 0; P_W32_Sock *ws = 0;
{ {
Lock lock = LockE(&g->socks_mutex); Lock lock = LockE(&P_W32.socks_mutex);
if (g->first_free_sock) if (P_W32.first_free_sock)
{ {
ws = g->first_free_sock; ws = P_W32.first_free_sock;
g->first_free_sock = ws->next_free; P_W32.first_free_sock = ws->next_free;
} }
else else
{ {
ws = PushStructNoZero(g->socks_arena, P_W32_Sock); ws = PushStructNoZero(P_W32.socks_arena, P_W32_Sock);
} }
Unlock(&lock); Unlock(&lock);
} }
@ -805,13 +793,12 @@ P_Sock *P_AcquireSock(u16 listen_port, u64 sndbuf_size, u64 rcvbuf_size)
void P_ReleaseSock(P_Sock *sock) void P_ReleaseSock(P_Sock *sock)
{ {
P_W32_SharedState *g = &P_W32_shared_state;
P_W32_Sock *ws = (P_W32_Sock *)sock; P_W32_Sock *ws = (P_W32_Sock *)sock;
closesocket(ws->sock); closesocket(ws->sock);
Lock lock = LockE(&g->socks_mutex); Lock lock = LockE(&P_W32.socks_mutex);
{ {
ws->next_free = g->first_free_sock; ws->next_free = P_W32.first_free_sock;
g->first_free_sock = ws; P_W32.first_free_sock = ws;
} }
Unlock(&lock); Unlock(&lock);
} }
@ -965,14 +952,12 @@ String P_GetClipboardText(Arena *arena)
Fence *P_GetTimerFence(void) Fence *P_GetTimerFence(void)
{ {
P_W32_SharedState *g = &P_W32_shared_state; return &P_W32.timer_fence;
return &g->timer_fence;
} }
i64 P_GetCurrentTimerPeriodNs(void) i64 P_GetCurrentTimerPeriodNs(void)
{ {
P_W32_SharedState *g = &P_W32_shared_state; return Atomic64Fetch(&P_W32.average_timer_period_ns.v);
return Atomic64Fetch(&g->average_timer_period_ns.v);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -40,7 +40,7 @@ Struct(P_W32_Sock)
#define P_W32_NumRollingTimerPeriods 500 #define P_W32_NumRollingTimerPeriods 500
#define P_W32_DefaultTimerPeriodNs 50000000 #define P_W32_DefaultTimerPeriodNs 50000000
Struct(P_W32_SharedState) Struct(P_W32_Ctx)
{ {
//- Watches pool //- Watches pool
Mutex watches_mutex; Mutex watches_mutex;
@ -56,7 +56,9 @@ Struct(P_W32_SharedState)
//- Timer //- Timer
Fence timer_fence; Fence timer_fence;
Atomic64Padded average_timer_period_ns; Atomic64Padded average_timer_period_ns;
} extern P_W32_shared_state; };
extern P_W32_Ctx P_W32;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Time //~ Time

View File

@ -3,18 +3,17 @@
// Based on mmozeiko's WASAPI examples // Based on mmozeiko's WASAPI examples
// https://gist.github.com/mmozeiko/5a5b168e61aff4c1eaec0381da62808f#file-win32_wasapi-h // https://gist.github.com/mmozeiko/5a5b168e61aff4c1eaec0381da62808f#file-win32_wasapi-h
PB_WSP_SharedState PB_WSP_shared_state = ZI; PB_WSP_Ctx PB_WSP = Zi;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ @hookimpl Bootstrap //~ @hookimpl Bootstrap
void PB_Bootstrap(void) void PB_Bootstrap(void)
{ {
PB_WSP_SharedState *g = &PB_WSP_shared_state;
PB_WSP_InitializeWasapi(); PB_WSP_InitializeWasapi();
// Start playback job // Start playback job
JobPoolId playback_pool = InitJobPool(1, Lit("Playback"), JobPoolPriority_Audio); JobPoolId playback_pool = InitJobPool(1, Lit("Playback"), JobPoolPriority_Audio);
g->shutdown_jobs_count += RunJob(PB_WSP_Playback, .pool = playback_pool, .fence = &g->shutdown_jobs_fence); PB_WSP.shutdown_jobs_count += RunJob(PB_WSP_Playback, .pool = playback_pool, .fence = &PB_WSP.shutdown_jobs_fence);
OnExit(&PB_WSP_Shutdown); OnExit(&PB_WSP_Shutdown);
} }
@ -23,14 +22,12 @@ void PB_Bootstrap(void)
ExitFuncDef(PB_WSP_Shutdown) ExitFuncDef(PB_WSP_Shutdown)
{ {
PB_WSP_SharedState *g = &PB_WSP_shared_state; Atomic32Set(&PB_WSP.shutdown, 1);
Atomic32Set(&g->shutdown, 1); YieldOnFence(&PB_WSP.shutdown_jobs_fence, PB_WSP.shutdown_jobs_count);
YieldOnFence(&g->shutdown_jobs_fence, g->shutdown_jobs_count);
} }
void PB_WSP_InitializeWasapi(void) void PB_WSP_InitializeWasapi(void)
{ {
PB_WSP_SharedState *g = &PB_WSP_shared_state;
u64 sample_rate = PB_SampleRate; u64 sample_rate = PB_SampleRate;
u64 channel_count = 2; u64 channel_count = 2;
u32 channel_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; u32 channel_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
@ -45,7 +42,7 @@ void PB_WSP_InitializeWasapi(void)
IMMDeviceEnumerator_Release(enumerator); IMMDeviceEnumerator_Release(enumerator);
// Create audio client for device // Create audio client for device
IMMDevice_Activate(device, &IID_IAudioClient, CLSCTX_ALL, 0, (LPVOID *)&g->client); IMMDevice_Activate(device, &IID_IAudioClient, CLSCTX_ALL, 0, (LPVOID *)&PB_WSP.client);
IMMDevice_Release(device); IMMDevice_Release(device);
WAVEFORMATEXTENSIBLE format_ex = { WAVEFORMATEXTENSIBLE format_ex = {
@ -67,7 +64,7 @@ void PB_WSP_InitializeWasapi(void)
#if 0 #if 0
b32 client_initialized = 0; b32 client_initialized = 0;
IAudioClient3 *client3; IAudioClient3 *client3;
if (SUCCEEDED(IAudioClient_QueryInterface(g->client, &IID_IAudioClient3, (LPVOID *)&client3))) if (SUCCEEDED(IAudioClient_QueryInterface(PB_WSP.client, &IID_IAudioClient3, (LPVOID *)&client3)))
{ {
// From Martins: Minimum buffer size will typically be 480 samples (10msec @ 48khz) // From Martins: Minimum buffer size will typically be 480 samples (10msec @ 48khz)
// but it can be 128 samples (2.66 msec @ 48khz) if driver is properly installed // but it can be 128 samples (2.66 msec @ 48khz) if driver is properly installed
@ -91,7 +88,7 @@ void PB_WSP_InitializeWasapi(void)
{ {
// Get duration for shared-mode streams, this will typically be 480 samples (10msec @ 48khz) // Get duration for shared-mode streams, this will typically be 480 samples (10msec @ 48khz)
REFERENCE_TIME duration; REFERENCE_TIME duration;
IAudioClient_GetDevicePeriod(g->client, &duration, 0); IAudioClient_GetDevicePeriod(PB_WSP.client, &duration, 0);
// Initialize audio playback // Initialize audio playback
// //
@ -100,23 +97,23 @@ void PB_WSP_InitializeWasapi(void)
// always convert to native mixing format. This may introduce latency // always convert to native mixing format. This may introduce latency
// but allows for any input format. // but allows for any input format.
const DWORD flags = AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY; const DWORD flags = AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY;
IAudioClient_Initialize(g->client, AUDCLNT_SHAREMODE_SHARED, flags, duration, 0, wfx, 0); IAudioClient_Initialize(PB_WSP.client, AUDCLNT_SHAREMODE_SHARED, flags, duration, 0, wfx, 0);
} }
IAudioClient_GetMixFormat(g->client, &g->buffer_format); IAudioClient_GetMixFormat(PB_WSP.client, &PB_WSP.buffer_format);
// Set up event handler to wait on // Set up event handler to wait on
g->event = CreateEventW(0, 0, 0, 0); PB_WSP.event = CreateEventW(0, 0, 0, 0);
IAudioClient_SetEventHandle(g->client, g->event); IAudioClient_SetEventHandle(PB_WSP.client, PB_WSP.event);
// Get playback client // Get playback client
IAudioClient_GetService(g->client, &IID_IAudioRenderClient, (LPVOID *)&g->playback); IAudioClient_GetService(PB_WSP.client, &IID_IAudioRenderClient, (LPVOID *)&PB_WSP.playback);
// Start the playback // Start the playback
IAudioClient_Start(g->client); IAudioClient_Start(PB_WSP.client);
// Get audio buffer size in samples // Get audio buffer size in samples
IAudioClient_GetBufferSize(g->client, &g->buffer_frames); IAudioClient_GetBufferSize(PB_WSP.client, &PB_WSP.buffer_frames);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -124,27 +121,25 @@ void PB_WSP_InitializeWasapi(void)
PB_WSP_Buff PB_WSP_BeginUpdate(void) PB_WSP_Buff PB_WSP_BeginUpdate(void)
{ {
PB_WSP_SharedState *g = &PB_WSP_shared_state;
PB_WSP_Buff wspbuf = ZI; PB_WSP_Buff wspbuf = ZI;
// Get padding frames // Get padding frames
u32 padding_frames; u32 padding_frames;
IAudioClient_GetCurrentPadding(g->client, &padding_frames); IAudioClient_GetCurrentPadding(PB_WSP.client, &padding_frames);
// Get output buffer from WASAPI // Get output buffer from WASAPI
wspbuf.frames_count = 0; wspbuf.frames_count = 0;
if (padding_frames <= g->buffer_frames) if (padding_frames <= PB_WSP.buffer_frames)
{ {
wspbuf.frames_count = g->buffer_frames - padding_frames; wspbuf.frames_count = PB_WSP.buffer_frames - padding_frames;
} }
IAudioRenderClient_GetBuffer(g->playback, wspbuf.frames_count, &wspbuf.frames); IAudioRenderClient_GetBuffer(PB_WSP.playback, wspbuf.frames_count, &wspbuf.frames);
return wspbuf; return wspbuf;
} }
void PB_WSP_EndUpdate(PB_WSP_Buff *wspbuf, MIX_PcmF32 src) void PB_WSP_EndUpdate(PB_WSP_Buff *wspbuf, MIX_PcmF32 src)
{ {
PB_WSP_SharedState *g = &PB_WSP_shared_state;
u32 frames_in_source = src.count / 2; u32 frames_in_source = src.count / 2;
u32 frames_in_output = wspbuf->frames_count; u32 frames_in_output = wspbuf->frames_count;
@ -152,7 +147,7 @@ void PB_WSP_EndUpdate(PB_WSP_Buff *wspbuf, MIX_PcmF32 src)
if (frames_in_source == frames_in_output) if (frames_in_source == frames_in_output)
{ {
// Copy bytes to output // Copy bytes to output
u32 bytes_per_sample = g->buffer_format->nBlockAlign / g->buffer_format->nChannels; u32 bytes_per_sample = PB_WSP.buffer_format->nBlockAlign / PB_WSP.buffer_format->nChannels;
u32 write_size = frames_in_source * 2 * bytes_per_sample; u32 write_size = frames_in_source * 2 * bytes_per_sample;
CopyBytes(wspbuf->frames, src.samples, write_size); CopyBytes(wspbuf->frames, src.samples, write_size);
} }
@ -172,7 +167,7 @@ void PB_WSP_EndUpdate(PB_WSP_Buff *wspbuf, MIX_PcmF32 src)
} }
// Submit output buffer to WASAPI // Submit output buffer to WASAPI
IAudioRenderClient_ReleaseBuffer(g->playback, frames_in_source, flags); IAudioRenderClient_ReleaseBuffer(PB_WSP.playback, frames_in_source, flags);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -180,19 +175,17 @@ void PB_WSP_EndUpdate(PB_WSP_Buff *wspbuf, MIX_PcmF32 src)
JobImpl(PB_WSP_Playback, sig, id) JobImpl(PB_WSP_Playback, sig, id)
{ {
PB_WSP_SharedState *g = &PB_WSP_shared_state;
// //
// FIXME: If playback fails at any point and mixer stops advancing, we // FIXME: If playback fails at any point and mixer stops advancing, we
// need to halt mixer to prevent memory leak when sounds are played. // need to halt mixer to prevent memory leak when sounds are played.
// //
// TODO: Signal counter that running job wiats on, rather than scheduling job manually // TODO: Signal counter that running job wiats on, rather than scheduling job manually
// //
while (!Atomic32Fetch(&g->shutdown)) while (!Atomic32Fetch(&PB_WSP.shutdown))
{ {
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
{ {
WaitForSingleObject(g->event, INFINITE); WaitForSingleObject(PB_WSP.event, INFINITE);
} }
{ {
PB_WSP_Buff wspbuf = PB_WSP_BeginUpdate(); PB_WSP_Buff wspbuf = PB_WSP_BeginUpdate();

View File

@ -24,7 +24,7 @@ Struct(PB_WSP_Buff)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ State types //~ State types
Struct(PB_WSP_SharedState) Struct(PB_WSP_Ctx)
{ {
Atomic32 shutdown; Atomic32 shutdown;
IAudioClient *client; IAudioClient *client;
@ -34,7 +34,9 @@ Struct(PB_WSP_SharedState)
u32 buffer_frames; u32 buffer_frames;
Fence shutdown_jobs_fence; Fence shutdown_jobs_fence;
u32 shutdown_jobs_count; u32 shutdown_jobs_count;
} extern PB_WSP_shared_state; };
extern PB_WSP_Ctx PB_WSP;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Wasapi startup //~ Wasapi startup

View File

@ -170,10 +170,7 @@ Struct(S_CmdNode)
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Context types //~ State types
#define S_InputStatesCount 2
#define S_OutputStatesCount 2
Struct(S_InputState) Struct(S_InputState)
{ {
@ -200,13 +197,12 @@ Struct(S_Ctx)
//- Sim input //- Sim input
TicketMutex input_back_tm; TicketMutex input_back_tm;
i32 input_back_idx; i32 input_back_idx;
S_InputState input_states[S_InputStatesCount]; S_InputState input_states[2];
//- Sim output //- Sim output
TicketMutex output_back_tm; TicketMutex output_back_tm;
i32 output_back_idx; i32 output_back_idx;
S_OutputState output_states[S_OutputStatesCount]; S_OutputState output_states[2];
}; };
Struct(S_ReadonlyCtx) Struct(S_ReadonlyCtx)

View File

@ -186,7 +186,7 @@ Struct(V_Window)
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Context types //~ State types
Enum(V_EditMode) Enum(V_EditMode)
{ {

View File

@ -1,6 +1,6 @@
Readonly SPR_Texture SPR_NilTexture = ZI; Readonly SPR_Texture SPR_NilTexture = Zi;
Readonly SPR_Sheet SPR_NilSheet = ZI; Readonly SPR_Sheet SPR_NilSheet = Zi;
SPR_SharedState SPR_shared_state = ZI; SPR_Ctx SPR = Zi;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Load jobs //~ Load jobs
@ -240,10 +240,9 @@ JobImpl(SPR_LoadSheet, sig, _)
// TODO: Per-thread 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_Entry *entry = 0; SPR_Entry *entry = 0;
{ {
SPR_EntryBin *bin = &g->entry_bins[resource.hash % SPR_EntryBinsCount]; SPR_EntryBin *bin = &SPR.entry_bins[resource.hash % countof(SPR.entry_bins)];
// Search for entry // Search for entry
entry = bin->first; entry = bin->first;
{ {
@ -345,14 +344,14 @@ SPR_Sheet *SPR_SheetFromResourceAsync(ResourceKey resource)
SPR_SpanKey SPR_SpanKeyFromName(String name) SPR_SpanKey SPR_SpanKeyFromName(String name)
{ {
SPR_SpanKey result = ZI; SPR_SpanKey result = Zi;
result.hash = HashFnv64(Fnv64Basis, name); result.hash = HashFnv64(Fnv64Basis, name);
return result; return result;
} }
SPR_SliceKey SPR_SliceKeyFromName(String name) SPR_SliceKey SPR_SliceKeyFromName(String name)
{ {
SPR_SliceKey result = ZI; SPR_SliceKey result = Zi;
result.hash = HashFnv64(Fnv64Basis, name); result.hash = HashFnv64(Fnv64Basis, name);
return result; return result;
} }
@ -362,7 +361,7 @@ SPR_SliceKey SPR_SliceKeyFromName(String name)
SPR_Span SPR_SpanFromKey(SPR_Sheet *sheet, SPR_SpanKey key) SPR_Span SPR_SpanFromKey(SPR_Sheet *sheet, SPR_SpanKey key)
{ {
SPR_Span result = ZI; SPR_Span result = Zi;
u32 bins_count = sheet->span_bins_count; u32 bins_count = sheet->span_bins_count;
if (bins_count > 0) if (bins_count > 0)
{ {
@ -383,7 +382,7 @@ SPR_Span SPR_SpanFromKey(SPR_Sheet *sheet, SPR_SpanKey key)
SPR_Frame SPR_FrameFromIndex(SPR_Sheet *sheet, u64 index) SPR_Frame SPR_FrameFromIndex(SPR_Sheet *sheet, u64 index)
{ {
SPR_Frame result = ZI; SPR_Frame result = Zi;
if (sheet->frames_count > 0) if (sheet->frames_count > 0)
{ {
result = sheet->frames[index % sheet->frames_count]; result = sheet->frames[index % sheet->frames_count];
@ -393,7 +392,7 @@ SPR_Frame SPR_FrameFromIndex(SPR_Sheet *sheet, u64 index)
SPR_Slice SPR_SliceFromKey(SPR_Sheet *sheet, SPR_SliceKey key, u64 frame_index) SPR_Slice SPR_SliceFromKey(SPR_Sheet *sheet, SPR_SliceKey key, u64 frame_index)
{ {
SPR_Slice result = ZI; SPR_Slice result = Zi;
b32 match = 0; b32 match = 0;
u32 bins_count = sheet->slice_group_bins_count; u32 bins_count = sheet->slice_group_bins_count;

View File

@ -141,12 +141,12 @@ Struct(SPR_EntryBin)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ State types //~ State types
#define SPR_EntryBinsCount 1024 Struct(SPR_Ctx)
Struct(SPR_SharedState)
{ {
SPR_EntryBin entry_bins[SPR_EntryBinsCount]; SPR_EntryBin entry_bins[1024];
} extern SPR_shared_state; };
extern SPR_Ctx SPR;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Load jobs //~ Load jobs

View File

@ -186,7 +186,7 @@ Struct(TTF_DW_RenderTarget)
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Context types //~ State types
// TODO: Determine font dpi dynamically // TODO: Determine font dpi dynamically
#define TTF_DW_Dpi (96.0f) #define TTF_DW_Dpi (96.0f)

View File

@ -320,7 +320,7 @@ Struct(UI_BoxIterResult)
}; };
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Context types //~ State types
Enum(UI_FrameFlag) Enum(UI_FrameFlag)
{ {

View File

@ -1,57 +1,55 @@
WND_W32_SharedState WND_W32_shared_state = Zi; WND_W32_Ctx WND_W32 = Zi;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ @hookimpl Bootstrap //~ @hookimpl Bootstrap
void WND_Bootstrap(void) void WND_Bootstrap(void)
{ {
WND_W32_SharedState *g = &WND_W32_shared_state;
////////////////////////////// //////////////////////////////
//- Init btn table //- Init btn table
{ {
ZeroFixedArray(g->vk_to_button); ZeroFixedArray(WND_W32.vk_to_button);
for (u32 i = 'A', j = Button_A; i <= 'Z'; ++i, ++j) for (u32 i = 'A', j = Button_A; i <= 'Z'; ++i, ++j)
{ {
g->vk_to_button[i] = (Button)j; WND_W32.vk_to_button[i] = (Button)j;
} }
for (u32 i = '0', j = Button_0; i <= '9'; ++i, ++j) for (u32 i = '0', j = Button_0; i <= '9'; ++i, ++j)
{ {
g->vk_to_button[i] = (Button)j; WND_W32.vk_to_button[i] = (Button)j;
} }
for (u32 i = VK_F1, j = Button_F1; i <= VK_F24; ++i, ++j) for (u32 i = VK_F1, j = Button_F1; i <= VK_F24; ++i, ++j)
{ {
g->vk_to_button[i] = (Button)j; WND_W32.vk_to_button[i] = (Button)j;
} }
g->vk_to_button[VK_ESCAPE] = Button_Escape; WND_W32.vk_to_button[VK_ESCAPE] = Button_Escape;
g->vk_to_button[VK_OEM_3] = Button_GraveAccent; WND_W32.vk_to_button[VK_OEM_3] = Button_GraveAccent;
g->vk_to_button[VK_OEM_MINUS] = Button_Minus; WND_W32.vk_to_button[VK_OEM_MINUS] = Button_Minus;
g->vk_to_button[VK_OEM_PLUS] = Button_Equal; WND_W32.vk_to_button[VK_OEM_PLUS] = Button_Equal;
g->vk_to_button[VK_BACK] = Button_Backspace; WND_W32.vk_to_button[VK_BACK] = Button_Backspace;
g->vk_to_button[VK_TAB] = Button_Tab; WND_W32.vk_to_button[VK_TAB] = Button_Tab;
g->vk_to_button[VK_SPACE] = Button_Space; WND_W32.vk_to_button[VK_SPACE] = Button_Space;
g->vk_to_button[VK_RETURN] = Button_Enter; WND_W32.vk_to_button[VK_RETURN] = Button_Enter;
g->vk_to_button[VK_CONTROL] = Button_Ctrl; WND_W32.vk_to_button[VK_CONTROL] = Button_Ctrl;
g->vk_to_button[VK_SHIFT] = Button_Shift; WND_W32.vk_to_button[VK_SHIFT] = Button_Shift;
g->vk_to_button[VK_MENU] = Button_Alt; WND_W32.vk_to_button[VK_MENU] = Button_Alt;
g->vk_to_button[VK_UP] = Button_Up; WND_W32.vk_to_button[VK_UP] = Button_Up;
g->vk_to_button[VK_LEFT] = Button_Left; WND_W32.vk_to_button[VK_LEFT] = Button_Left;
g->vk_to_button[VK_DOWN] = Button_Down; WND_W32.vk_to_button[VK_DOWN] = Button_Down;
g->vk_to_button[VK_RIGHT] = Button_Right; WND_W32.vk_to_button[VK_RIGHT] = Button_Right;
g->vk_to_button[VK_DELETE] = Button_Delete; WND_W32.vk_to_button[VK_DELETE] = Button_Delete;
g->vk_to_button[VK_PRIOR] = Button_PageUp; WND_W32.vk_to_button[VK_PRIOR] = Button_PageUp;
g->vk_to_button[VK_NEXT] = Button_PageDown; WND_W32.vk_to_button[VK_NEXT] = Button_PageDown;
g->vk_to_button[VK_HOME] = Button_Home; WND_W32.vk_to_button[VK_HOME] = Button_Home;
g->vk_to_button[VK_END] = Button_End; WND_W32.vk_to_button[VK_END] = Button_End;
g->vk_to_button[VK_OEM_2] = Button_ForwardSlash; WND_W32.vk_to_button[VK_OEM_2] = Button_ForwardSlash;
g->vk_to_button[VK_OEM_PERIOD] = Button_Period; WND_W32.vk_to_button[VK_OEM_PERIOD] = Button_Period;
g->vk_to_button[VK_OEM_COMMA] = Button_Comma; WND_W32.vk_to_button[VK_OEM_COMMA] = Button_Comma;
g->vk_to_button[VK_OEM_7] = Button_Quote; WND_W32.vk_to_button[VK_OEM_7] = Button_Quote;
g->vk_to_button[VK_OEM_4] = Button_LeftBracket; WND_W32.vk_to_button[VK_OEM_4] = Button_LeftBracket;
g->vk_to_button[VK_OEM_6] = Button_RightBracket; WND_W32.vk_to_button[VK_OEM_6] = Button_RightBracket;
g->vk_to_button[VK_INSERT] = Button_Insert; WND_W32.vk_to_button[VK_INSERT] = Button_Insert;
g->vk_to_button[VK_OEM_1] = Button_Semicolon; WND_W32.vk_to_button[VK_OEM_1] = Button_Semicolon;
} }
////////////////////////////// //////////////////////////////
@ -59,18 +57,18 @@ void WND_Bootstrap(void)
{ {
HCURSOR arrow = LoadCursor(0, IDC_ARROW); HCURSOR arrow = LoadCursor(0, IDC_ARROW);
for (u64 cursor_idx = 0; cursor_idx < countof(g->cursors); ++cursor_idx) for (u64 cursor_idx = 0; cursor_idx < countof(WND_W32.cursors); ++cursor_idx)
{ {
g->cursors[cursor_idx] = arrow; WND_W32.cursors[cursor_idx] = arrow;
} }
g->cursors[WND_CursorKind_Text] = LoadCursor(0, IDC_IBEAM); WND_W32.cursors[WND_CursorKind_Text] = LoadCursor(0, IDC_IBEAM);
g->cursors[WND_CursorKind_No] = LoadCursor(0, IDC_NO); WND_W32.cursors[WND_CursorKind_No] = LoadCursor(0, IDC_NO);
g->cursors[WND_CursorKind_Hand] = LoadCursor(0, IDC_HAND); WND_W32.cursors[WND_CursorKind_Hand] = LoadCursor(0, IDC_HAND);
g->cursors[WND_CursorKind_Move] = LoadCursor(0, IDC_SIZEALL); WND_W32.cursors[WND_CursorKind_Move] = LoadCursor(0, IDC_SIZEALL);
g->cursors[WND_CursorKind_HorizontalResize] = LoadCursor(0, IDC_SIZEWE); WND_W32.cursors[WND_CursorKind_HorizontalResize] = LoadCursor(0, IDC_SIZEWE);
g->cursors[WND_CursorKind_VerticalResize] = LoadCursor(0, IDC_SIZENS); WND_W32.cursors[WND_CursorKind_VerticalResize] = LoadCursor(0, IDC_SIZENS);
g->cursors[WND_CursorKind_TlBrResize] = LoadCursor(0, IDC_SIZENWSE); WND_W32.cursors[WND_CursorKind_TlBrResize] = LoadCursor(0, IDC_SIZENWSE);
g->cursors[WND_CursorKind_TrBlResize] = LoadCursor(0, IDC_SIZENESW); WND_W32.cursors[WND_CursorKind_TrBlResize] = LoadCursor(0, IDC_SIZENESW);
} }
////////////////////////////// //////////////////////////////
@ -80,7 +78,7 @@ void WND_Bootstrap(void)
HMODULE instance = GetModuleHandle(0); HMODULE instance = GetModuleHandle(0);
// Register the window class // Register the window class
WNDCLASSEXW *wc = &g->window_class; WNDCLASSEXW *wc = &WND_W32.window_class;
wc->cbSize = sizeof(WNDCLASSEX); wc->cbSize = sizeof(WNDCLASSEX);
wc->lpszClassName = WND_W32_WindowClassName; wc->lpszClassName = WND_W32_WindowClassName;
wc->hCursor = LoadCursor(0, IDC_ARROW); wc->hCursor = LoadCursor(0, IDC_ARROW);
@ -130,8 +128,7 @@ WND_W32_Window *WND_W32_WindowFromHandle(WND_Handle handle)
// Win32 limitation: Window must be initialized on same thread that processes events // Win32 limitation: Window must be initialized on same thread that processes events
void WND_W32_ProcessMessagesForever(WaveLaneCtx *lane) void WND_W32_ProcessMessagesForever(WaveLaneCtx *lane)
{ {
WND_W32_SharedState *g = &WND_W32_shared_state; WND_W32_Window *window = &WND_W32.window;
WND_W32_Window *window = &g->window;
window->w2u_events_arena = AcquireArena(Gibi(64)); window->w2u_events_arena = AcquireArena(Gibi(64));
//- Initialize hwnd //- Initialize hwnd
@ -150,7 +147,7 @@ void WND_W32_ProcessMessagesForever(WaveLaneCtx *lane)
// TODO: Check for hwnd success // TODO: Check for hwnd success
window->hwnd = CreateWindowExW( window->hwnd = CreateWindowExW(
exstyle, exstyle,
g->window_class.lpszClassName, WND_W32.window_class.lpszClassName,
L"", L"",
WS_OVERLAPPEDWINDOW, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
@ -159,7 +156,7 @@ void WND_W32_ProcessMessagesForever(WaveLaneCtx *lane)
CW_USEDEFAULT, CW_USEDEFAULT,
0, 0,
0, 0,
g->window_class.hInstance, WND_W32.window_class.hInstance,
0 0
); );
@ -208,8 +205,7 @@ void WND_W32_PushEvent(WND_W32_Window *window, ControllerEvent event)
LRESULT CALLBACK WND_W32_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) LRESULT CALLBACK WND_W32_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{ {
WND_W32_SharedState *g = &WND_W32_shared_state; WND_W32_Window *window = &WND_W32.window;
WND_W32_Window *window = &g->window;
LRESULT result = 0; LRESULT result = 0;
{ {
@ -267,9 +263,9 @@ LRESULT CALLBACK WND_W32_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
{ {
event.kind = ControllerEventKind_ButtonUp; event.kind = ControllerEventKind_ButtonUp;
} }
if (vk_code < countof(g->vk_to_button)) if (vk_code < countof(WND_W32.vk_to_button))
{ {
event.button = g->vk_to_button[vk_code]; event.button = WND_W32.vk_to_button[vk_code];
} }
WND_W32_PushEvent(window, event); WND_W32_PushEvent(window, event);
if (msg == WM_SYSKEYUP || msg == WM_SYSKEYDOWN) if (msg == WM_SYSKEYUP || msg == WM_SYSKEYDOWN)
@ -455,8 +451,7 @@ void WND_PushCmd_(WND_Frame frame, WND_Cmd desc)
WND_Frame WND_BeginFrame(G_Format backbuffer_format, WND_BackbufferSizeMode backbuffer_size_mode) WND_Frame WND_BeginFrame(G_Format backbuffer_format, WND_BackbufferSizeMode backbuffer_size_mode)
{ {
WND_W32_SharedState *g = &WND_W32_shared_state; WND_W32_Window *window = &WND_W32.window;
WND_W32_Window *window = &g->window;
WND_Frame result = Zi; WND_Frame result = Zi;
while (!Atomic32Fetch(&window->is_ready)) while (!Atomic32Fetch(&window->is_ready))
@ -579,7 +574,6 @@ WND_Frame WND_BeginFrame(G_Format backbuffer_format, WND_BackbufferSizeMode back
void WND_EndFrame(WND_Frame frame, i32 vsync) void WND_EndFrame(WND_Frame frame, i32 vsync)
{ {
TempArena scratch = BeginScratchNoConflict(); TempArena scratch = BeginScratchNoConflict();
WND_W32_SharedState *g = &WND_W32_shared_state;
WND_W32_Window *window = WND_W32_WindowFromHandle(frame.window); WND_W32_Window *window = WND_W32_WindowFromHandle(frame.window);
HWND hwnd = window->hwnd; HWND hwnd = window->hwnd;
@ -658,7 +652,7 @@ void WND_EndFrame(WND_Frame frame, i32 vsync)
//- Cursor //- Cursor
case WND_CmdKind_SetCursor: case WND_CmdKind_SetCursor:
{ {
desired_cursor = g->cursors[cmd.cursor]; desired_cursor = WND_W32.cursors[cmd.cursor];
} break; } break;
//- Restore //- Restore

View File

@ -67,7 +67,7 @@ Struct(WND_W32_CmdNode)
#define WND_W32_WindowClassName L"pp_window_class" #define WND_W32_WindowClassName L"pp_window_class"
Struct(WND_W32_SharedState) Struct(WND_W32_Ctx)
{ {
Button vk_to_button[256]; Button vk_to_button[256];
@ -76,7 +76,9 @@ Struct(WND_W32_SharedState)
WNDCLASSEXW window_class; WNDCLASSEXW window_class;
WND_W32_Window window; // Single-window for now WND_W32_Window window; // Single-window for now
} extern WND_W32_shared_state; };
extern WND_W32_Ctx WND_W32;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Window helpers //~ Window helpers