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)
{
AsyncTickCtx tick = Zi;
tick.arena = AcquireArena(Gibi(64));
AsyncFrameLaneCtx frame = Zi;
frame.arena = AcquireArena(Gibi(64));
// Tick forever
for (;;)
@ -64,7 +64,7 @@ void AsyncWorkerEntryPoint(WaveLaneCtx *lane)
Lock lock = LockE(&Base.async.mutex);
{
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;
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)
{
AsyncTickCallback *callback = &w->callbacks[callback_idx];
callback->func(lane, &tick);
callback->func(lane, &frame);
}
//////////////////////////////
@ -92,11 +92,11 @@ void AsyncWorkerEntryPoint(WaveLaneCtx *lane)
WaveSync(lane);
ResetArena(tick.arena);
ResetArena(frame.arena);
{
Arena *tick_arena = tick.arena;
ZeroStruct(&tick);
tick.arena = tick_arena;
Arena *old_frame_arena = frame.arena;
ZeroStruct(&frame);
frame.arena = old_frame_arena;
}
}
}

View File

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

View File

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

View File

@ -1,13 +1,12 @@
D_SharedState D_shared_state = ZI;
D_Ctx D = Zi;
////////////////////////////////////////////////////////////
//~ Bootstrap
void D_Bootstrap(void)
{
D_SharedState *g = &D_shared_state;
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)
{
#if 0
D_SharedState *g = &D_shared_state;
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
// Placeholder
Quad quad = QuadFromLine(start, end, thickness);

View File

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

View File

@ -222,7 +222,7 @@ GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size
////////////////////////////////////////////////////////////
//~ Async
void GC_TickAsync(WaveLaneCtx *lane, AsyncTickCtx *tick)
void GC_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *frame)
{
GC_AsyncCtx *async = &GC.async_ctx;
@ -239,7 +239,7 @@ void GC_TickAsync(WaveLaneCtx *lane, AsyncTickCtx *tick)
{
// Pop cmds from submission queue
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;
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;
ResourceKey resource = glyph->desc.font.r;
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_ascent = ttf_result.font_ascent;
glyph->font_descent = ttf_result.font_descent;

View File

@ -108,7 +108,7 @@ Struct(GC_CmdNode)
};
////////////////////////////////////////////////////////////
//~ Context types
//~ State types
Struct(GC_AsyncCtx)
{
@ -160,4 +160,4 @@ GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size
////////////////////////////////////////////////////////////
//~ 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;
ThreadLocal G_ArenaHandle G_t_perm_arena = Zi;
G_Ctx G = Zi;
ThreadLocal G_ThreadLocalCtx G_tl = Zi;
////////////////////////////////////////////////////////////
//~ Bootstrap
void G_BootstrapCommon(void)
{
G_SharedUtilState *g = &G_shared_util_state;
G_ArenaHandle gpu_perm = G_PermArena();
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 };
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->quad_indices = G_IdxBuff16(quad_indices);
G.quad_indices = G_IdxBuff16(quad_indices);
}
// Init point sampler
{
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
@ -49,7 +47,7 @@ void G_BootstrapCommon(void)
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 perm = G_t_perm_arena;
if (G_IsArenaNil(perm))
if (G_IsArenaNil(G_tl.gpu_perm))
{
G_t_perm_arena = G_AcquireArena();
perm = G_t_perm_arena;
G_tl.gpu_perm = G_AcquireArena();
}
return perm;
return G_tl.gpu_perm;
}
//- Cpu -> Gpu upload
@ -107,15 +103,15 @@ Rng2 G_ScissorFromTexture(G_ResourceHandle texture)
G_IndexBufferDesc G_QuadIndices(void)
{
return G_shared_util_state.quad_indices;
return G.quad_indices;
}
G_SamplerStateRef G_BasicSampler(void)
{
return G_shared_util_state.basic_sampler;
return G.basic_sampler;
}
G_Texture3DRef G_BasicNoiseTexture(void)
{
return G_shared_util_state.basic_noise;
return G.basic_noise;
}

View File

@ -1,15 +1,21 @@
////////////////////////////////////////////////////////////
//~ State types
Struct(G_SharedUtilState)
Struct(G_Ctx)
{
// Common shared resources
G_IndexBufferDesc quad_indices;
G_SamplerStateRef basic_sampler;
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

View File

@ -1,12 +1,11 @@
G_D12_SharedState G_D12_shared_state = Zi;
ThreadLocal G_D12_ThreadLocalState G_D12_tl = Zi;
G_D12_Ctx G_D12 = Zi;
ThreadLocal G_D12_ThreadLocalCtx G_D12_tl = Zi;
////////////////////////////////////////////////////////////
//~ @hookimpl Bootstrap
void G_Bootstrap(void)
{
G_D12_SharedState *g = &G_D12_shared_state;
TempArena scratch = BeginScratchNoConflict();
Arena *perm = PermArena();
@ -48,7 +47,7 @@ void G_Bootstrap(void)
// 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))
{
Panic(Lit("Failed to initialize DXGI factory"));
@ -66,7 +65,7 @@ void G_Bootstrap(void)
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))
{
@ -111,8 +110,8 @@ void G_Bootstrap(void)
}
Panic(error);
}
g->adapter = adapter;
g->device = device;
G_D12.adapter = adapter;
G_D12.device = device;
}
// Enable debug layer breaks
@ -121,7 +120,7 @@ void G_Bootstrap(void)
// Enable D3D12 Debug break
{
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))
{
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_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];
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;
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))
{
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))
{
@ -197,13 +196,13 @@ void G_Bootstrap(void)
for (G_D12_DescriptorHeapKind kind = 0; kind < countof(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->kind = kind;
heap->type = desc.type;
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;
d3d_desc.Type = desc.type;
@ -214,7 +213,7 @@ void G_Bootstrap(void)
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))
@ -272,9 +271,9 @@ void G_Bootstrap(void)
ID3D12RootSignature *rootsig = 0;
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)
{
@ -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_SharedState *g = &G_D12_shared_state;
u64 hash = RandU64FromSeed(HashFnv64(Fnv64Basis, StringFromStruct(&desc)));
// Fetch pipeline from cache
G_D12_Pipeline *pipeline = 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);
@ -542,7 +540,7 @@ G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
String ps = DataFromResource(desc.ps.resource);
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.BytecodeLength = vs.len;
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))
{
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);
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.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))
{
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_SharedState *g = &G_D12_shared_state;
return &g->queues[kind];
return &G_D12.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_SharedState *g = &G_D12_shared_state;
G_D12_Queue *queue = G_D12_QueueFromKind(queue_kind);
// 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))
{
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))
{
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))
@ -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)
{
// TODO
for (u64 heap_idx = 0; heap_idx < countof(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
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_D12_SharedState *g = &G_D12_shared_state;
G_D12_Arena *gpu_arena = G_D12_ArenaFromHandle(arena_handle);
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
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_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;
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;
{
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_align = alloc_info.Alignment;
}
@ -957,7 +948,7 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
}
hr = ID3D12Device10_CreatePlacedResource2(
g->device,
G_D12.device,
heap->d3d_heap,
0,
&d3d_desc,
@ -1035,7 +1026,7 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
u64 size_in_heap = 0;
{
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;
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"));
}
hr = ID3D12Device10_CreatePlacedResource2(
g->device,
G_D12.device,
heap->d3d_heap,
pos_in_heap,
&d3d_desc,
@ -1120,7 +1111,7 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
resource->pos_in_heap = pos_in_heap;
resource->size_in_heap = size_in_heap;
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;
if (is_buffer)
{
@ -1148,7 +1139,7 @@ G_ResourceHandle G_PushResource(G_ArenaHandle arena_handle, G_CommandListHandle
if (is_sampler)
{
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;
}
@ -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_SharedState *g = &G_D12_shared_state;
G_D12_DescriptorHeap *heap = &g->descriptor_heaps[heap_kind];
G_D12_DescriptorHeap *heap = &G_D12.descriptor_heaps[heap_kind];
G_D12_Descriptor *descriptors = ArenaFirst(heap->descriptors_arena, G_D12_Descriptor);
return &descriptors[index];
}
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->descriptor_heaps[heap_kind];
G_D12_DescriptorHeap *heap = &G_D12.descriptor_heaps[heap_kind];
G_D12_Descriptor *descriptor = 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)
{
G_D12_SharedState *g = &G_D12_shared_state;
G_D12_Arena *gpu_arena = G_D12_ArenaFromHandle(arena_handle);
G_D12_Resource *resource = G_D12_ResourceFromHandle(resource_handle);
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.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
{
@ -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.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);
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
{
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)
@ -1365,7 +1353,7 @@ u32 G_PushRef(G_ArenaHandle arena_handle, G_ResourceHandle resource_handle, G_Re
{
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;
@ -1429,7 +1417,6 @@ void *G_HostPointerFromResource(G_ResourceHandle resource_handle)
G_D12_Cmd *G_D12_PushCmd(G_D12_CmdList *cl)
{
G_D12_SharedState *g = &G_D12_shared_state;
// Grab 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)
{
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)
{
g->first_free_cmd_chunk = chunk->next;
G_D12.first_free_cmd_chunk = chunk->next;
}
}
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));
G_D12_SharedState *g = &G_D12_shared_state;
G_QueueKind queue_kind = cl->queue_kind;
G_D12_Queue *queue = G_D12_QueueFromKind(queue_kind);
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_D12_SharedState *g = &G_D12_shared_state;
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)
{
g->first_free_cmd_list = cl->next;
G_D12.first_free_cmd_list = cl->next;
ZeroStruct(cl);
}
else
@ -1710,7 +1695,6 @@ G_CommandListHandle G_PrepareCommandList(G_QueueKind queue)
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_QueueKind queue_kind = cl->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
{
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;
while (chunk)
{
G_D12_CmdChunk *next = chunk->next;
g->first_free_cmd_chunk = chunk;
G_D12.first_free_cmd_chunk = chunk;
chunk = next;
}
}
@ -2049,8 +2033,8 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
if (!descriptor_heaps_set)
{
ID3D12DescriptorHeap *heaps[] = {
g->descriptor_heaps[G_D12_DescriptorHeapKind_CbvSrvUav].d3d_heap,
g->descriptor_heaps[G_D12_DescriptorHeapKind_Sampler].d3d_heap,
G_D12.descriptor_heaps[G_D12_DescriptorHeapKind_CbvSrvUav].d3d_heap,
G_D12.descriptor_heaps[G_D12_DescriptorHeapKind_Sampler].d3d_heap,
};
ID3D12GraphicsCommandList_SetDescriptorHeaps(d3d_cl, countof(heaps), heaps);
descriptor_heaps_set = 1;
@ -2059,7 +2043,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
// Bind rootsig
if (!compute_rootsig_set)
{
ID3D12GraphicsCommandList_SetComputeRootSignature(d3d_cl, g->bindless_rootsig);
ID3D12GraphicsCommandList_SetComputeRootSignature(d3d_cl, G_D12.bindless_rootsig);
compute_rootsig_set = 1;
}
@ -2163,8 +2147,8 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
if (!descriptor_heaps_set)
{
ID3D12DescriptorHeap *heaps[] = {
g->descriptor_heaps[G_D12_DescriptorHeapKind_CbvSrvUav].d3d_heap,
g->descriptor_heaps[G_D12_DescriptorHeapKind_Sampler].d3d_heap,
G_D12.descriptor_heaps[G_D12_DescriptorHeapKind_CbvSrvUav].d3d_heap,
G_D12.descriptor_heaps[G_D12_DescriptorHeapKind_Sampler].d3d_heap,
};
ID3D12GraphicsCommandList_SetDescriptorHeaps(d3d_cl, countof(heaps), heaps);
descriptor_heaps_set = 1;
@ -2173,7 +2157,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
// Bind rootsig
if (!graphics_rootsig_set)
{
ID3D12GraphicsCommandList_SetGraphicsRootSignature(d3d_cl, g->bindless_rootsig);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(d3d_cl, G_D12.bindless_rootsig);
graphics_rootsig_set = 1;
}
@ -2269,7 +2253,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
if (bound_render_target_uids[i] != rt->uid)
{
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;
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;
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;
}
ID3D12GraphicsCommandList_ClearRenderTargetView(d3d_cl, rtv_handle, clear_color, 0, 0);
@ -2379,10 +2363,10 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle)
// 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;
g->first_free_cmd_list = cl;
cl->next = G_D12.first_free_cmd_list;
G_D12.first_free_cmd_list = cl;
}
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)
{
G_D12_SharedState *g = &G_D12_shared_state;
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
G_D12_Resource *dst = G_D12_ResourceFromHandle(dst_handle);
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.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;
}
@ -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)
{
G_D12_SharedState *g = &G_D12_shared_state;
G_D12_CmdList *cl = G_D12_CmdListFromHandle(cl_handle);
G_D12_Resource *src = G_D12_ResourceFromHandle(src_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.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;
}
@ -2562,7 +2544,6 @@ void G_CopyTextureToTexture(G_CommandListHandle cl_handle, G_ResourceHandle dst_
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_Resource *src = G_D12_ResourceFromHandle(src_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)
{
G_D12_SharedState *g = &G_D12_shared_state;
u64 fences_count = 0;
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);
}
ID3D12Device1_SetEventOnMultipleFenceCompletion(
g->device,
G_D12.device,
fences,
(u64 *)fence_targets,
fences_count,
@ -2793,22 +2773,21 @@ void G_SyncEx(G_QueueBarrierDesc desc)
G_Stats G_QueryStats(void)
{
G_D12_SharedState *g = &G_D12_shared_state;
G_Stats result = 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_budget = info.Budget;
}
{
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_committed = info.CurrentUsage;
}
result.driver_resources_allocated = Atomic64Fetch(&g->driver_resources_allocated);
result.driver_descriptors_allocated = Atomic64Fetch(&g->driver_descriptors_allocated);
result.driver_resources_allocated = Atomic64Fetch(&G_D12.driver_resources_allocated);
result.driver_descriptors_allocated = Atomic64Fetch(&G_D12.driver_descriptors_allocated);
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_D12_SharedState *g = &G_D12_shared_state;
G_D12_Swapchain *swapchain = G_D12_SwapchainFromHandle(swapchain_handle);
size = VEC2I32(MaxI32(size.x, 1), MaxI32(size.y, 1));
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.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
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
@ -2898,14 +2876,14 @@ G_ResourceHandle G_PrepareBackbuffer(G_SwapchainHandle swapchain_handle, G_Forma
if (SUCCEEDED(hr))
{
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_event = present_event;
}
// 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))
{
@ -2960,7 +2938,7 @@ G_ResourceHandle G_PrepareBackbuffer(G_SwapchainHandle swapchain_handle, G_Forma
}
ZeroStruct(backbuffer);
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->is_texture = 1;

View File

@ -409,7 +409,7 @@ Struct(G_D12_Swapchain)
////////////////////////////////////////////////////////////
//~ State types
Struct(G_D12_SharedState)
Struct(G_D12_Ctx)
{
Atomic64Padded resource_creation_gen;
@ -445,12 +445,15 @@ Struct(G_D12_SharedState)
IDXGIFactory6 *factory;
IDXGIAdapter3 *adapter;
ID3D12Device10 *device;
} extern G_D12_shared_state;
};
Struct(G_D12_ThreadLocalState)
Struct(G_D12_ThreadLocalCtx)
{
HANDLE sync_event;
} extern ThreadLocal G_D12_tl;
};
extern G_D12_Ctx G_D12;
extern ThreadLocal G_D12_ThreadLocalCtx G_D12_tl;
////////////////////////////////////////////////////////////
//~ 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 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
void MIX_Bootstrap(void)
{
MIX_SharedState *g = &M_shared_state;
g->track_arena = AcquireArena(Gibi(64));
g->listener_pos = VEC2(0, 0);
g->listener_dir = VEC2(0, -1);
MIX.track_arena = AcquireArena(Gibi(64));
MIX.listener_pos = VEC2(0, 0);
MIX.listener_dir = VEC2(0, -1);
}
////////////////////////////////////////////////////////////
@ -31,7 +30,7 @@ void MIX_Bootstrap(void)
MIX_Handle MIX_HandleFromTrack(MIX_Track *track)
{
MIX_Handle result = ZI;
MIX_Handle result = Zi;
result.gen = track->gen;
result.data = track;
return result;
@ -52,16 +51,15 @@ MIX_Track *MIX_TrackFromHandle(MIX_Handle handle)
MIX_Track *MIX_AcquireTrackLocked(Lock *lock, SND_Sound *sound)
{
MIX_SharedState *g = &M_shared_state;
AssertLockedE(lock, &g->mutex);
AssertLockedE(lock, &MIX.mutex);
MIX_Track *track = 0;
if (g->track_first_free)
if (MIX.track_first_free)
{
// Take from free list
track = g->track_first_free;
track = MIX.track_first_free;
MIX_Track *next_free = track->next;
g->track_first_free = next_free;
MIX.track_first_free = next_free;
if (next_free)
{
next_free->prev = 0;
@ -71,7 +69,7 @@ MIX_Track *MIX_AcquireTrackLocked(Lock *lock, SND_Sound *sound)
else
{
// Acquire new
track = PushStruct(g->track_arena, MIX_Track);
track = PushStruct(MIX.track_arena, MIX_Track);
track->gen = 1;
}
@ -80,26 +78,25 @@ MIX_Track *MIX_AcquireTrackLocked(Lock *lock, SND_Sound *sound)
track->mix.track_handle = MIX_HandleFromTrack(track);
// Append to playing list
MIX_Track *prev = g->track_last_playing;
MIX_Track *prev = MIX.track_last_playing;
if (prev)
{
prev->next = track;
}
else
{
g->track_first_playing = track;
MIX.track_first_playing = track;
}
g->track_last_playing = track;
MIX.track_last_playing = track;
track->prev = prev;
++g->track_playing_count;
++MIX.track_playing_count;
return track;
}
void MIX_ReleaseTrackLocked(Lock *lock, MIX_Track *track)
{
MIX_SharedState *g = &M_shared_state;
AssertLockedE(lock, &g->mutex);
AssertLockedE(lock, &MIX.mutex);
// Remove from playing list
MIX_Track *prev = track->prev;
@ -111,7 +108,7 @@ void MIX_ReleaseTrackLocked(Lock *lock, MIX_Track *track)
else
{
// Track was first in list
g->track_first_playing = next;
MIX.track_first_playing = next;
}
if (next)
{
@ -120,34 +117,33 @@ void MIX_ReleaseTrackLocked(Lock *lock, MIX_Track *track)
else
{
// 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;
// Add to free list
track->prev = 0;
track->next = g->track_first_free;
if (g->track_first_free)
track->next = MIX.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.
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_SharedState *g = &M_shared_state;
MIX_Track *track;
{
Lock lock = LockE(&g->mutex);
Lock lock = LockE(&MIX.mutex);
{
track = MIX_AcquireTrackLocked(&lock, sound);
track->desc = desc;
@ -160,14 +156,13 @@ MIX_Handle MIX_PlaySoundEx(SND_Sound *sound, MIX_TrackDesc desc)
// NOTE: This is quite inefficient.
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);
if (track)
{
// 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
track = MIX_TrackFromHandle(handle);
@ -185,12 +180,11 @@ MIX_TrackDesc MIX_TrackDescFromHandle(MIX_Handle handle)
// NOTE: This is quite inefficient.
void MIX_UpdateTrack(MIX_Handle handle, MIX_TrackDesc desc)
{
MIX_SharedState *g = &M_shared_state;
MIX_Track *track = MIX_TrackFromHandle(handle);
if (track)
{
// 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
track = MIX_TrackFromHandle(handle);
@ -205,11 +199,10 @@ void MIX_UpdateTrack(MIX_Handle handle, MIX_TrackDesc desc)
void MIX_UpdateListener(Vec2 pos, Vec2 dir)
{
MIX_SharedState *g = &M_shared_state;
Lock lock = LockE(&g->mutex);
Lock lock = LockE(&MIX.mutex);
{
g->listener_pos = pos;
g->listener_dir = NormVec2(dir);
MIX.listener_pos = pos;
MIX.listener_dir = NormVec2(dir);
}
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)
{
TempArena scratch = BeginScratch(arena);
MIX_SharedState *g = &M_shared_state;
MIX_PcmF32 result = ZI;
MIX_PcmF32 result = Zi;
result.count = frame_count * 2;
result.samples = PushStructs(arena, f32, result.count);
@ -251,15 +243,15 @@ MIX_PcmF32 MIX_MixAllTracks(Arena *arena, u64 frame_count)
MIX_MixData **mixes = 0;
u64 mixes_count = 0;
{
Lock lock = LockE(&g->mutex);
Lock lock = LockE(&MIX.mutex);
// Read listener info
listener_pos = g->listener_pos;
listener_dir = g->listener_dir;
listener_pos = MIX.listener_pos;
listener_dir = MIX.listener_dir;
// Update & read mixes
mixes = PushStructsNoZero(scratch.arena, MIX_MixData *, g->track_playing_count);
for (MIX_Track *track = g->track_first_playing; track; track = track->next)
mixes = PushStructsNoZero(scratch.arena, MIX_MixData *, MIX.track_playing_count);
for (MIX_Track *track = MIX.track_first_playing; track; track = track->next)
{
MIX_MixData *mix = &track->mix;
mix->desc = track->desc;
@ -445,7 +437,7 @@ MIX_PcmF32 MIX_MixAllTracks(Arena *arena, u64 frame_count)
//- Update track effect data
{
Lock lock = LockE(&g->mutex);
Lock lock = LockE(&MIX.mutex);
for (u64 i = 0; i < mixes_count; ++i)
{
MIX_MixData *mix = mixes[i];

View File

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

View File

@ -1,18 +1,16 @@
P_W32_SharedState P_W32_shared_state = Zi;
P_W32_Ctx P_W32 = Zi;
////////////////////////////////////////////////////////////
//~ @hookimpl Bootstrap
void P_Bootstrap(void)
{
P_W32_SharedState *g = &P_W32_shared_state;
//- Init watches pool
g->watches_arena = AcquireArena(Gibi(64));
P_W32.watches_arena = AcquireArena(Gibi(64));
// Init winsock
WSAStartup(MAKEWORD(2, 2), &g->wsa_data);
g->socks_arena = AcquireArena(Gibi(64));
WSAStartup(MAKEWORD(2, 2), &P_W32.wsa_data);
P_W32.socks_arena = AcquireArena(Gibi(64));
// Init timer
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 result = {
.len = 0,
.text = ArenaNext(arena, u8)
};
String result = Zi;
result.text = ArenaNext(arena, u8);
while (*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;
src += decoded.advance16;
}
return result;
}
@ -159,7 +153,6 @@ P_Address P_W32_PlatformAddressFromWin32Address(P_W32_Address ws_addr)
void P_W32_SyncTimerForever(WaveLaneCtx *lane)
{
P_W32_SharedState *g = &P_W32_shared_state;
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
// Create high resolution timer
@ -208,11 +201,11 @@ void P_W32_SyncTimerForever(WaveLaneCtx *lane)
periods_sum_ns += (f64)periods[i];
}
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
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;
GetFileSizeEx((HANDLE)file.handle, (PLARGE_INTEGER)&size);
String s = {
.len = size,
.text = 0
};
String result;
result.len = size;
if (size > 0)
{
// ReadFile returns non-zero on success
// TODO: error checking
PushAlign(arena, CachelineSize);
s.text = PushStructsNoZero(arena, u8, size);
result.text = PushStructsNoZero(arena, u8, size);
ReadFile(
(HANDLE)file.handle,
s.text,
(DWORD)s.len,
result.text,
(DWORD)result.len,
0,
0
);
}
return s;
return result;
}
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_W32_SharedState *g = &P_W32_shared_state;
P_W32_Sock *ws = 0;
{
Lock lock = LockE(&g->socks_mutex);
if (g->first_free_sock)
Lock lock = LockE(&P_W32.socks_mutex);
if (P_W32.first_free_sock)
{
ws = g->first_free_sock;
g->first_free_sock = ws->next_free;
ws = P_W32.first_free_sock;
P_W32.first_free_sock = ws->next_free;
}
else
{
ws = PushStructNoZero(g->socks_arena, P_W32_Sock);
ws = PushStructNoZero(P_W32.socks_arena, P_W32_Sock);
}
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)
{
P_W32_SharedState *g = &P_W32_shared_state;
P_W32_Sock *ws = (P_W32_Sock *)sock;
closesocket(ws->sock);
Lock lock = LockE(&g->socks_mutex);
Lock lock = LockE(&P_W32.socks_mutex);
{
ws->next_free = g->first_free_sock;
g->first_free_sock = ws;
ws->next_free = P_W32.first_free_sock;
P_W32.first_free_sock = ws;
}
Unlock(&lock);
}
@ -965,14 +952,12 @@ String P_GetClipboardText(Arena *arena)
Fence *P_GetTimerFence(void)
{
P_W32_SharedState *g = &P_W32_shared_state;
return &g->timer_fence;
return &P_W32.timer_fence;
}
i64 P_GetCurrentTimerPeriodNs(void)
{
P_W32_SharedState *g = &P_W32_shared_state;
return Atomic64Fetch(&g->average_timer_period_ns.v);
return Atomic64Fetch(&P_W32.average_timer_period_ns.v);
}
////////////////////////////////////////////////////////////

View File

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

View File

@ -3,18 +3,17 @@
// Based on mmozeiko's WASAPI examples
// 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
void PB_Bootstrap(void)
{
PB_WSP_SharedState *g = &PB_WSP_shared_state;
PB_WSP_InitializeWasapi();
// Start playback job
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);
}
@ -23,14 +22,12 @@ void PB_Bootstrap(void)
ExitFuncDef(PB_WSP_Shutdown)
{
PB_WSP_SharedState *g = &PB_WSP_shared_state;
Atomic32Set(&g->shutdown, 1);
YieldOnFence(&g->shutdown_jobs_fence, g->shutdown_jobs_count);
Atomic32Set(&PB_WSP.shutdown, 1);
YieldOnFence(&PB_WSP.shutdown_jobs_fence, PB_WSP.shutdown_jobs_count);
}
void PB_WSP_InitializeWasapi(void)
{
PB_WSP_SharedState *g = &PB_WSP_shared_state;
u64 sample_rate = PB_SampleRate;
u64 channel_count = 2;
u32 channel_mask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
@ -45,7 +42,7 @@ void PB_WSP_InitializeWasapi(void)
IMMDeviceEnumerator_Release(enumerator);
// 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);
WAVEFORMATEXTENSIBLE format_ex = {
@ -67,7 +64,7 @@ void PB_WSP_InitializeWasapi(void)
#if 0
b32 client_initialized = 0;
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)
// 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)
REFERENCE_TIME duration;
IAudioClient_GetDevicePeriod(g->client, &duration, 0);
IAudioClient_GetDevicePeriod(PB_WSP.client, &duration, 0);
// Initialize audio playback
//
@ -100,23 +97,23 @@ void PB_WSP_InitializeWasapi(void)
// always convert to native mixing format. This may introduce latency
// but allows for any input format.
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
g->event = CreateEventW(0, 0, 0, 0);
IAudioClient_SetEventHandle(g->client, g->event);
PB_WSP.event = CreateEventW(0, 0, 0, 0);
IAudioClient_SetEventHandle(PB_WSP.client, PB_WSP.event);
// 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
IAudioClient_Start(g->client);
IAudioClient_Start(PB_WSP.client);
// 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_SharedState *g = &PB_WSP_shared_state;
PB_WSP_Buff wspbuf = ZI;
// Get padding frames
u32 padding_frames;
IAudioClient_GetCurrentPadding(g->client, &padding_frames);
IAudioClient_GetCurrentPadding(PB_WSP.client, &padding_frames);
// Get output buffer from WASAPI
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;
}
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_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)
{
// 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;
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
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)
{
PB_WSP_SharedState *g = &PB_WSP_shared_state;
//
// FIXME: If playback fails at any point and mixer stops advancing, we
// 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
//
while (!Atomic32Fetch(&g->shutdown))
while (!Atomic32Fetch(&PB_WSP.shutdown))
{
TempArena scratch = BeginScratchNoConflict();
{
WaitForSingleObject(g->event, INFINITE);
WaitForSingleObject(PB_WSP.event, INFINITE);
}
{
PB_WSP_Buff wspbuf = PB_WSP_BeginUpdate();

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
Readonly SPR_Texture SPR_NilTexture = ZI;
Readonly SPR_Sheet SPR_NilSheet = ZI;
SPR_SharedState SPR_shared_state = ZI;
Readonly SPR_Texture SPR_NilTexture = Zi;
Readonly SPR_Sheet SPR_NilSheet = Zi;
SPR_Ctx SPR = Zi;
////////////////////////////////////////////////////////////
//~ Load jobs
@ -240,10 +240,9 @@ JobImpl(SPR_LoadSheet, sig, _)
// TODO: Per-thread L1 cache
SPR_Entry *SPR_FetchEntry(ResourceKey resource, JobPoolId pool, SPR_FetchFlag flags)
{
SPR_SharedState *g = &SPR_shared_state;
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
entry = bin->first;
{
@ -345,14 +344,14 @@ SPR_Sheet *SPR_SheetFromResourceAsync(ResourceKey resource)
SPR_SpanKey SPR_SpanKeyFromName(String name)
{
SPR_SpanKey result = ZI;
SPR_SpanKey result = Zi;
result.hash = HashFnv64(Fnv64Basis, name);
return result;
}
SPR_SliceKey SPR_SliceKeyFromName(String name)
{
SPR_SliceKey result = ZI;
SPR_SliceKey result = Zi;
result.hash = HashFnv64(Fnv64Basis, name);
return result;
}
@ -362,7 +361,7 @@ SPR_SliceKey SPR_SliceKeyFromName(String name)
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;
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 result = ZI;
SPR_Frame result = Zi;
if (sheet->frames_count > 0)
{
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 result = ZI;
SPR_Slice result = Zi;
b32 match = 0;
u32 bins_count = sheet->slice_group_bins_count;

View File

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

View File

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

View File

@ -320,7 +320,7 @@ Struct(UI_BoxIterResult)
};
////////////////////////////////////////////////////////////
//~ Context types
//~ State types
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
void WND_Bootstrap(void)
{
WND_W32_SharedState *g = &WND_W32_shared_state;
//////////////////////////////
//- 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)
{
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)
{
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)
{
g->vk_to_button[i] = (Button)j;
WND_W32.vk_to_button[i] = (Button)j;
}
g->vk_to_button[VK_ESCAPE] = Button_Escape;
g->vk_to_button[VK_OEM_3] = Button_GraveAccent;
g->vk_to_button[VK_OEM_MINUS] = Button_Minus;
g->vk_to_button[VK_OEM_PLUS] = Button_Equal;
g->vk_to_button[VK_BACK] = Button_Backspace;
g->vk_to_button[VK_TAB] = Button_Tab;
g->vk_to_button[VK_SPACE] = Button_Space;
g->vk_to_button[VK_RETURN] = Button_Enter;
g->vk_to_button[VK_CONTROL] = Button_Ctrl;
g->vk_to_button[VK_SHIFT] = Button_Shift;
g->vk_to_button[VK_MENU] = Button_Alt;
g->vk_to_button[VK_UP] = Button_Up;
g->vk_to_button[VK_LEFT] = Button_Left;
g->vk_to_button[VK_DOWN] = Button_Down;
g->vk_to_button[VK_RIGHT] = Button_Right;
g->vk_to_button[VK_DELETE] = Button_Delete;
g->vk_to_button[VK_PRIOR] = Button_PageUp;
g->vk_to_button[VK_NEXT] = Button_PageDown;
g->vk_to_button[VK_HOME] = Button_Home;
g->vk_to_button[VK_END] = Button_End;
g->vk_to_button[VK_OEM_2] = Button_ForwardSlash;
g->vk_to_button[VK_OEM_PERIOD] = Button_Period;
g->vk_to_button[VK_OEM_COMMA] = Button_Comma;
g->vk_to_button[VK_OEM_7] = Button_Quote;
g->vk_to_button[VK_OEM_4] = Button_LeftBracket;
g->vk_to_button[VK_OEM_6] = Button_RightBracket;
g->vk_to_button[VK_INSERT] = Button_Insert;
g->vk_to_button[VK_OEM_1] = Button_Semicolon;
WND_W32.vk_to_button[VK_ESCAPE] = Button_Escape;
WND_W32.vk_to_button[VK_OEM_3] = Button_GraveAccent;
WND_W32.vk_to_button[VK_OEM_MINUS] = Button_Minus;
WND_W32.vk_to_button[VK_OEM_PLUS] = Button_Equal;
WND_W32.vk_to_button[VK_BACK] = Button_Backspace;
WND_W32.vk_to_button[VK_TAB] = Button_Tab;
WND_W32.vk_to_button[VK_SPACE] = Button_Space;
WND_W32.vk_to_button[VK_RETURN] = Button_Enter;
WND_W32.vk_to_button[VK_CONTROL] = Button_Ctrl;
WND_W32.vk_to_button[VK_SHIFT] = Button_Shift;
WND_W32.vk_to_button[VK_MENU] = Button_Alt;
WND_W32.vk_to_button[VK_UP] = Button_Up;
WND_W32.vk_to_button[VK_LEFT] = Button_Left;
WND_W32.vk_to_button[VK_DOWN] = Button_Down;
WND_W32.vk_to_button[VK_RIGHT] = Button_Right;
WND_W32.vk_to_button[VK_DELETE] = Button_Delete;
WND_W32.vk_to_button[VK_PRIOR] = Button_PageUp;
WND_W32.vk_to_button[VK_NEXT] = Button_PageDown;
WND_W32.vk_to_button[VK_HOME] = Button_Home;
WND_W32.vk_to_button[VK_END] = Button_End;
WND_W32.vk_to_button[VK_OEM_2] = Button_ForwardSlash;
WND_W32.vk_to_button[VK_OEM_PERIOD] = Button_Period;
WND_W32.vk_to_button[VK_OEM_COMMA] = Button_Comma;
WND_W32.vk_to_button[VK_OEM_7] = Button_Quote;
WND_W32.vk_to_button[VK_OEM_4] = Button_LeftBracket;
WND_W32.vk_to_button[VK_OEM_6] = Button_RightBracket;
WND_W32.vk_to_button[VK_INSERT] = Button_Insert;
WND_W32.vk_to_button[VK_OEM_1] = Button_Semicolon;
}
//////////////////////////////
@ -59,18 +57,18 @@ void WND_Bootstrap(void)
{
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);
g->cursors[WND_CursorKind_No] = LoadCursor(0, IDC_NO);
g->cursors[WND_CursorKind_Hand] = LoadCursor(0, IDC_HAND);
g->cursors[WND_CursorKind_Move] = LoadCursor(0, IDC_SIZEALL);
g->cursors[WND_CursorKind_HorizontalResize] = LoadCursor(0, IDC_SIZEWE);
g->cursors[WND_CursorKind_VerticalResize] = LoadCursor(0, IDC_SIZENS);
g->cursors[WND_CursorKind_TlBrResize] = LoadCursor(0, IDC_SIZENWSE);
g->cursors[WND_CursorKind_TrBlResize] = LoadCursor(0, IDC_SIZENESW);
WND_W32.cursors[WND_CursorKind_Text] = LoadCursor(0, IDC_IBEAM);
WND_W32.cursors[WND_CursorKind_No] = LoadCursor(0, IDC_NO);
WND_W32.cursors[WND_CursorKind_Hand] = LoadCursor(0, IDC_HAND);
WND_W32.cursors[WND_CursorKind_Move] = LoadCursor(0, IDC_SIZEALL);
WND_W32.cursors[WND_CursorKind_HorizontalResize] = LoadCursor(0, IDC_SIZEWE);
WND_W32.cursors[WND_CursorKind_VerticalResize] = LoadCursor(0, IDC_SIZENS);
WND_W32.cursors[WND_CursorKind_TlBrResize] = LoadCursor(0, IDC_SIZENWSE);
WND_W32.cursors[WND_CursorKind_TrBlResize] = LoadCursor(0, IDC_SIZENESW);
}
//////////////////////////////
@ -80,7 +78,7 @@ void WND_Bootstrap(void)
HMODULE instance = GetModuleHandle(0);
// Register the window class
WNDCLASSEXW *wc = &g->window_class;
WNDCLASSEXW *wc = &WND_W32.window_class;
wc->cbSize = sizeof(WNDCLASSEX);
wc->lpszClassName = WND_W32_WindowClassName;
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
void WND_W32_ProcessMessagesForever(WaveLaneCtx *lane)
{
WND_W32_SharedState *g = &WND_W32_shared_state;
WND_W32_Window *window = &g->window;
WND_W32_Window *window = &WND_W32.window;
window->w2u_events_arena = AcquireArena(Gibi(64));
//- Initialize hwnd
@ -150,7 +147,7 @@ void WND_W32_ProcessMessagesForever(WaveLaneCtx *lane)
// TODO: Check for hwnd success
window->hwnd = CreateWindowExW(
exstyle,
g->window_class.lpszClassName,
WND_W32.window_class.lpszClassName,
L"",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
@ -159,7 +156,7 @@ void WND_W32_ProcessMessagesForever(WaveLaneCtx *lane)
CW_USEDEFAULT,
0,
0,
g->window_class.hInstance,
WND_W32.window_class.hInstance,
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)
{
WND_W32_SharedState *g = &WND_W32_shared_state;
WND_W32_Window *window = &g->window;
WND_W32_Window *window = &WND_W32.window;
LRESULT result = 0;
{
@ -267,9 +263,9 @@ LRESULT CALLBACK WND_W32_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
{
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);
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_W32_SharedState *g = &WND_W32_shared_state;
WND_W32_Window *window = &g->window;
WND_W32_Window *window = &WND_W32.window;
WND_Frame result = Zi;
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)
{
TempArena scratch = BeginScratchNoConflict();
WND_W32_SharedState *g = &WND_W32_shared_state;
WND_W32_Window *window = WND_W32_WindowFromHandle(frame.window);
HWND hwnd = window->hwnd;
@ -658,7 +652,7 @@ void WND_EndFrame(WND_Frame frame, i32 vsync)
//- Cursor
case WND_CmdKind_SetCursor:
{
desired_cursor = g->cursors[cmd.cursor];
desired_cursor = WND_W32.cursors[cmd.cursor];
} break;
//- Restore

View File

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