unlock fiber wake while wait list locked
This commit is contained in:
parent
c3f94380c2
commit
66586f9cf5
@ -36,9 +36,9 @@ GLOBAL struct {
|
|||||||
|
|
||||||
struct asset_cache_startup_receipt asset_cache_startup(void)
|
struct asset_cache_startup_receipt asset_cache_startup(void)
|
||||||
{
|
{
|
||||||
|
__prof;
|
||||||
/* Init store */
|
/* Init store */
|
||||||
G.store_arena = arena_alloc(GIBI(64));
|
G.store_arena = arena_alloc(GIBI(64));
|
||||||
|
|
||||||
return (struct asset_cache_startup_receipt) { 0 };
|
return (struct asset_cache_startup_receipt) { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,7 @@ GLOBAL struct {
|
|||||||
|
|
||||||
struct draw_startup_receipt draw_startup(struct font_startup_receipt *font_sr)
|
struct draw_startup_receipt draw_startup(struct font_startup_receipt *font_sr)
|
||||||
{
|
{
|
||||||
|
__prof;
|
||||||
(UNUSED)font_sr;
|
(UNUSED)font_sr;
|
||||||
u32 pixel_white = 0xFFFFFFFF;
|
u32 pixel_white = 0xFFFFFFFF;
|
||||||
G.solid_white_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(1, 1), &pixel_white);
|
G.solid_white_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(1, 1), &pixel_white);
|
||||||
|
|||||||
@ -42,11 +42,10 @@ GLOBAL struct {
|
|||||||
struct font_startup_receipt font_startup(struct asset_cache_startup_receipt *asset_cache_sr,
|
struct font_startup_receipt font_startup(struct asset_cache_startup_receipt *asset_cache_sr,
|
||||||
struct ttf_startup_receipt *ttf_sr)
|
struct ttf_startup_receipt *ttf_sr)
|
||||||
{
|
{
|
||||||
|
__prof;
|
||||||
(UNUSED)asset_cache_sr;
|
(UNUSED)asset_cache_sr;
|
||||||
(UNUSED)ttf_sr;
|
(UNUSED)ttf_sr;
|
||||||
|
|
||||||
G.params.arena = arena_alloc(GIBI(64));
|
G.params.arena = arena_alloc(GIBI(64));
|
||||||
|
|
||||||
return (struct font_startup_receipt) { 0 };
|
return (struct font_startup_receipt) { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
151
src/gp_dx12.c
151
src/gp_dx12.c
@ -123,8 +123,14 @@ struct pipeline_scope {
|
|||||||
struct pipeline_scope *next_free;
|
struct pipeline_scope *next_free;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct command_queue_desc {
|
||||||
|
enum D3D12_COMMAND_LIST_TYPE type;
|
||||||
|
enum D3D12_COMMAND_QUEUE_PRIORITY priority;
|
||||||
|
struct string dbg_name;
|
||||||
|
};
|
||||||
|
|
||||||
struct command_queue {
|
struct command_queue {
|
||||||
D3D12_COMMAND_LIST_TYPE type;
|
struct command_queue_desc desc;
|
||||||
ID3D12CommandQueue *cq;
|
ID3D12CommandQueue *cq;
|
||||||
struct arena *arena;
|
struct arena *arena;
|
||||||
|
|
||||||
@ -343,11 +349,16 @@ INTERNAL void dx12_init_device(void);
|
|||||||
INTERNAL void dx12_init_objects(void);
|
INTERNAL void dx12_init_objects(void);
|
||||||
INTERNAL void dx12_init_pipelines(void);
|
INTERNAL void dx12_init_pipelines(void);
|
||||||
INTERNAL struct cpu_descriptor_heap *cpu_descriptor_heap_alloc(enum D3D12_DESCRIPTOR_HEAP_TYPE type);
|
INTERNAL struct cpu_descriptor_heap *cpu_descriptor_heap_alloc(enum D3D12_DESCRIPTOR_HEAP_TYPE type);
|
||||||
INTERNAL struct command_queue *command_queue_alloc(enum D3D12_COMMAND_LIST_TYPE type, enum D3D12_COMMAND_QUEUE_PRIORITY priority, struct string dbg_name);
|
|
||||||
INTERNAL void command_queue_release(struct command_queue *cq);
|
INTERNAL void command_queue_release(struct command_queue *cq);
|
||||||
INTERNAL SYS_JOB_DEF(dx12_evictor_job, _);
|
INTERNAL SYS_JOB_DEF(dx12_evictor_job, _);
|
||||||
INTERNAL void fenced_release(void *data, enum fenced_release_kind kind);
|
INTERNAL void fenced_release(void *data, enum fenced_release_kind kind);
|
||||||
|
|
||||||
|
struct command_queue_alloc_job_sig { struct command_queue_desc *descs_in; struct command_queue **cqs_out; };
|
||||||
|
INTERNAL SYS_JOB_DEF(command_queue_alloc_job, job);
|
||||||
|
|
||||||
|
struct pipeline_alloc_job_sig { struct pipeline_desc *descs_in; struct pipeline **pipelines_out; };
|
||||||
|
INTERNAL SYS_JOB_DEF(pipeline_alloc_job, job);
|
||||||
|
|
||||||
#if RESOURCE_RELOADING
|
#if RESOURCE_RELOADING
|
||||||
INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(pipeline_resource_watch_callback, name);
|
INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(pipeline_resource_watch_callback, name);
|
||||||
#endif
|
#endif
|
||||||
@ -591,6 +602,8 @@ INTERNAL void dx12_init_device(void)
|
|||||||
|
|
||||||
INTERNAL void dx12_init_objects(void)
|
INTERNAL void dx12_init_objects(void)
|
||||||
{
|
{
|
||||||
|
__prof;
|
||||||
|
|
||||||
/* Initialize desc sizes */
|
/* Initialize desc sizes */
|
||||||
G.desc_sizes[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] = ID3D12Device_GetDescriptorHandleIncrementSize(G.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
G.desc_sizes[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] = ID3D12Device_GetDescriptorHandleIncrementSize(G.device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||||
G.desc_sizes[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER] = ID3D12Device_GetDescriptorHandleIncrementSize(G.device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
|
G.desc_sizes[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER] = ID3D12Device_GetDescriptorHandleIncrementSize(G.device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
|
||||||
@ -606,16 +619,34 @@ INTERNAL void dx12_init_objects(void)
|
|||||||
G.rtv_heap = cpu_descriptor_heap_alloc(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
G.rtv_heap = cpu_descriptor_heap_alloc(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||||
|
|
||||||
/* Create command queues */
|
/* Create command queues */
|
||||||
for (u32 i = 0; i < DX12_NUM_QUEUES; ++i) {
|
{
|
||||||
if (i == DX12_QUEUE_DIRECT) {
|
__profn("Allocate command queues");
|
||||||
G.command_queues[i] = command_queue_alloc(D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, LIT("Direct queue"));
|
struct command_queue_desc params[] = {
|
||||||
} else if (i == DX12_QUEUE_COMPUTE) {
|
{ .type = D3D12_COMMAND_LIST_TYPE_DIRECT, .priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, .dbg_name = LIT("Direct queue") },
|
||||||
G.command_queues[i] = command_queue_alloc(D3D12_COMMAND_LIST_TYPE_COMPUTE, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, LIT("Compute queue"));
|
{ .type = D3D12_COMMAND_LIST_TYPE_COMPUTE, .priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, .dbg_name = LIT("Compute queue") },
|
||||||
} else if (i == DX12_QUEUE_COPY) {
|
{ .type = D3D12_COMMAND_LIST_TYPE_COPY, .priority = D3D12_COMMAND_QUEUE_PRIORITY_HIGH, .dbg_name = LIT("Copy queue") },
|
||||||
G.command_queues[i] = command_queue_alloc(D3D12_COMMAND_LIST_TYPE_COPY, D3D12_COMMAND_QUEUE_PRIORITY_HIGH, LIT("Copy queue"));
|
{ .type = D3D12_COMMAND_LIST_TYPE_COPY, .priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, .dbg_name = LIT("Background copy queue") }
|
||||||
} else if (i == DX12_QUEUE_COPY_BACKGROUND) {
|
};
|
||||||
G.command_queues[i] = command_queue_alloc(D3D12_COMMAND_LIST_TYPE_COPY, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, LIT("Background copy queue"));
|
struct command_queue_alloc_job_sig sig = ZI;
|
||||||
|
sig.descs_in = params;
|
||||||
|
sig.cqs_out = G.command_queues;
|
||||||
|
{
|
||||||
|
struct snc_counter counter = ZI;
|
||||||
|
sys_run(DX12_NUM_QUEUES, command_queue_alloc_job, &sig, SYS_POOL_INHERIT, SYS_PRIORITY_INHERIT, &counter);
|
||||||
|
snc_counter_wait(&counter);
|
||||||
}
|
}
|
||||||
|
#if PROFILING
|
||||||
|
{
|
||||||
|
/* Initialize serially for consistent order in profiler */
|
||||||
|
__profn("Initialize command queue profiling contexts");
|
||||||
|
for (i32 i = 0; i < DX12_NUM_QUEUES; ++i) {
|
||||||
|
struct command_queue *cq = G.command_queues[i];
|
||||||
|
struct string dbg_name = params[i].dbg_name;
|
||||||
|
__prof_dx12_ctx_alloc(cq->prof, G.device, cq->cq, dbg_name.text, dbg_name.len);
|
||||||
|
(UNUSED)dbg_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -623,7 +654,6 @@ INTERNAL void dx12_init_objects(void)
|
|||||||
* Dx12 pipeline initialization
|
* Dx12 pipeline initialization
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
INTERNAL void pipeline_alloc(u64 num_pipelines, struct pipeline_desc *descs_in, struct pipeline **pipelines_out);
|
|
||||||
INTERNAL void pipeline_register(u64 num_pipelines, struct pipeline **pipelines);
|
INTERNAL void pipeline_register(u64 num_pipelines, struct pipeline **pipelines);
|
||||||
|
|
||||||
INTERNAL void dx12_init_pipelines(void)
|
INTERNAL void dx12_init_pipelines(void)
|
||||||
@ -676,7 +706,15 @@ INTERNAL void dx12_init_pipelines(void)
|
|||||||
++num_pipelines;
|
++num_pipelines;
|
||||||
}
|
}
|
||||||
struct pipeline **pipelines = arena_push_array(scratch.arena, struct pipeline *, num_pipelines);
|
struct pipeline **pipelines = arena_push_array(scratch.arena, struct pipeline *, num_pipelines);
|
||||||
pipeline_alloc(num_pipelines, descs, pipelines);
|
{
|
||||||
|
__profn("Allocate pipelines");
|
||||||
|
struct pipeline_alloc_job_sig sig = ZI;
|
||||||
|
sig.descs_in = descs;
|
||||||
|
sig.pipelines_out = pipelines;
|
||||||
|
struct snc_counter counter = ZI;
|
||||||
|
sys_run(num_pipelines, pipeline_alloc_job, &sig, SYS_POOL_INHERIT, SYS_PRIORITY_INHERIT, &counter);
|
||||||
|
snc_counter_wait(&counter);
|
||||||
|
}
|
||||||
for (u32 i = 0; i < num_pipelines; ++i) {
|
for (u32 i = 0; i < num_pipelines; ++i) {
|
||||||
struct pipeline *pipeline = pipelines[i];
|
struct pipeline *pipeline = pipelines[i];
|
||||||
if (!pipeline->success) {
|
if (!pipeline->success) {
|
||||||
@ -826,6 +864,7 @@ INTERNAL SYS_JOB_DEF(shader_compile_job, job)
|
|||||||
|
|
||||||
/* Compile shader */
|
/* Compile shader */
|
||||||
{
|
{
|
||||||
|
__profn("Compile shader");
|
||||||
struct string shader_src = resource_get_data(shader_res);
|
struct string shader_src = resource_get_data(shader_res);
|
||||||
logf_info("Compiling shader \"%F:%F\"", FMT_STR(shader_desc.file), FMT_STR(shader_desc.func));
|
logf_info("Compiling shader \"%F:%F\"", FMT_STR(shader_desc.file), FMT_STR(shader_desc.func));
|
||||||
/* Compile shader */
|
/* Compile shader */
|
||||||
@ -872,15 +911,10 @@ INTERNAL SYS_JOB_DEF(shader_compile_job, job)
|
|||||||
* Pipeline
|
* Pipeline
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
struct pipeline_init_job_sig {
|
INTERNAL SYS_JOB_DEF(pipeline_alloc_job, job)
|
||||||
struct pipeline_desc *descs_in;
|
|
||||||
struct pipeline **pipelines_out;
|
|
||||||
};
|
|
||||||
|
|
||||||
INTERNAL SYS_JOB_DEF(pipeline_init_job, job)
|
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct pipeline_init_job_sig *sig = job.sig;
|
struct pipeline_alloc_job_sig *sig = job.sig;
|
||||||
struct pipeline_desc *desc = &sig->descs_in[job.id];
|
struct pipeline_desc *desc = &sig->descs_in[job.id];
|
||||||
struct pipeline **pipelines_out = sig->pipelines_out;
|
struct pipeline **pipelines_out = sig->pipelines_out;
|
||||||
|
|
||||||
@ -1131,15 +1165,6 @@ INTERNAL SYS_JOB_DEF(pipeline_init_job, job)
|
|||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL void pipeline_alloc(u64 num_pipelines, struct pipeline_desc *descs_in, struct pipeline **pipelines_out)
|
|
||||||
{
|
|
||||||
__prof;
|
|
||||||
struct pipeline_init_job_sig sig = { .descs_in = descs_in, .pipelines_out = pipelines_out };
|
|
||||||
struct snc_counter counter = ZI;
|
|
||||||
sys_run(num_pipelines, pipeline_init_job, &sig, SYS_POOL_INHERIT, SYS_PRIORITY_INHERIT, &counter);
|
|
||||||
snc_counter_wait(&counter);
|
|
||||||
}
|
|
||||||
|
|
||||||
INTERNAL void pipeline_release_now(struct pipeline *pipeline)
|
INTERNAL void pipeline_release_now(struct pipeline *pipeline)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
@ -1279,8 +1304,16 @@ INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(pipeline_resource_watch_callback, name
|
|||||||
|
|
||||||
/* Recompile dirty pipelines */
|
/* Recompile dirty pipelines */
|
||||||
if (num_pipelines > 0) {
|
if (num_pipelines > 0) {
|
||||||
|
__profn("Compile dirty pipelines");
|
||||||
struct pipeline **pipelines = arena_push_array(scratch.arena, struct pipeline *, num_pipelines);
|
struct pipeline **pipelines = arena_push_array(scratch.arena, struct pipeline *, num_pipelines);
|
||||||
pipeline_alloc(num_pipelines, pipeline_descs, pipelines);
|
{
|
||||||
|
struct pipeline_alloc_job_sig sig = ZI;
|
||||||
|
sig.descs_in = pipeline_descs;
|
||||||
|
sig.pipelines_out = pipelines;
|
||||||
|
struct snc_counter counter = ZI;
|
||||||
|
sys_run(num_pipelines, pipeline_alloc_job, &sig, SYS_POOL_INHERIT, SYS_PRIORITY_INHERIT, &counter);
|
||||||
|
snc_counter_wait(&counter);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
struct snc_lock lock = snc_lock_s(&G.pipelines_mutex);
|
struct snc_lock lock = snc_lock_s(&G.pipelines_mutex);
|
||||||
for (u32 i = 0; i < num_pipelines; ++i) {
|
for (u32 i = 0; i < num_pipelines; ++i) {
|
||||||
@ -1711,36 +1744,38 @@ void gp_resource_release(struct gp_resource *resource)
|
|||||||
|
|
||||||
INTERNAL struct command_list_pool *command_list_pool_alloc(struct command_queue *cq);
|
INTERNAL struct command_list_pool *command_list_pool_alloc(struct command_queue *cq);
|
||||||
|
|
||||||
INTERNAL struct command_queue *command_queue_alloc(enum D3D12_COMMAND_LIST_TYPE type, enum D3D12_COMMAND_QUEUE_PRIORITY priority, struct string dbg_name)
|
INTERNAL SYS_JOB_DEF(command_queue_alloc_job, job)
|
||||||
{
|
{
|
||||||
__prof;
|
__prof;
|
||||||
struct command_queue *cq = 0;
|
struct command_queue_alloc_job_sig *sig = job.sig;
|
||||||
|
struct command_queue_desc *desc = &sig->descs_in[job.id];
|
||||||
{
|
{
|
||||||
struct arena *arena = arena_alloc(GIBI(64));
|
struct command_queue *cq = 0;
|
||||||
cq = arena_push(arena, struct command_queue);
|
{
|
||||||
cq->arena = arena;
|
struct arena *arena = arena_alloc(GIBI(64));
|
||||||
|
cq = arena_push(arena, struct command_queue);
|
||||||
|
cq->arena = arena;
|
||||||
|
}
|
||||||
|
cq->desc = *desc;
|
||||||
|
|
||||||
|
D3D12_COMMAND_QUEUE_DESC dx12_desc = ZI;
|
||||||
|
dx12_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||||
|
dx12_desc.Type = desc->type;
|
||||||
|
dx12_desc.Priority = desc->priority;
|
||||||
|
HRESULT hr = ID3D12Device_CreateCommandQueue(G.device, &dx12_desc, &IID_ID3D12CommandQueue, (void **)&cq->cq);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
sys_panic(LIT("Failed to create command queue"));
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = ID3D12Device_CreateFence(G.device, 0, 0, &IID_ID3D12Fence, (void **)&cq->submit_fence);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
sys_panic(LIT("Failed to create command queue fence"));
|
||||||
|
}
|
||||||
|
|
||||||
|
cq->cl_pool = command_list_pool_alloc(cq);
|
||||||
|
|
||||||
|
sig->cqs_out[job.id] = cq;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D12_COMMAND_QUEUE_DESC desc = ZI;
|
|
||||||
desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
|
||||||
desc.Type = type;
|
|
||||||
desc.Priority = priority;
|
|
||||||
HRESULT hr = ID3D12Device_CreateCommandQueue(G.device, &desc, &IID_ID3D12CommandQueue, (void **)&cq->cq);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
sys_panic(LIT("Failed to create command queue"));
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = ID3D12Device_CreateFence(G.device, 0, 0, &IID_ID3D12Fence, (void **)&cq->submit_fence);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
sys_panic(LIT("Failed to create command queue fence"));
|
|
||||||
}
|
|
||||||
|
|
||||||
__prof_dx12_ctx_alloc(cq->prof, G.device, cq->cq, dbg_name.text, dbg_name.len);
|
|
||||||
(UNUSED)dbg_name;
|
|
||||||
|
|
||||||
cq->type = type;
|
|
||||||
cq->cl_pool = command_list_pool_alloc(cq);
|
|
||||||
return cq;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL void command_queue_release(struct command_queue *cq)
|
INTERNAL void command_queue_release(struct command_queue *cq)
|
||||||
@ -1816,12 +1851,12 @@ INTERNAL struct command_list *command_list_open(struct command_list_pool *pool)
|
|||||||
cl->cl = old_cl;
|
cl->cl = old_cl;
|
||||||
cl->ca = old_ca;
|
cl->ca = old_ca;
|
||||||
} else {
|
} else {
|
||||||
hr = ID3D12Device_CreateCommandAllocator(G.device, cq->type, &IID_ID3D12CommandAllocator, (void **)&cl->ca);
|
hr = ID3D12Device_CreateCommandAllocator(G.device, cq->desc.type, &IID_ID3D12CommandAllocator, (void **)&cl->ca);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
sys_panic(LIT("Failed to create command allocator"));
|
sys_panic(LIT("Failed to create command allocator"));
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = ID3D12Device_CreateCommandList(G.device, 0, cq->type, cl->ca, 0, &IID_ID3D12GraphicsCommandList, (void **)&cl->cl);
|
hr = ID3D12Device_CreateCommandList(G.device, 0, cq->desc.type, cl->ca, 0, &IID_ID3D12GraphicsCommandList, (void **)&cl->cl);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
sys_panic(LIT("Failed to create command list"));
|
sys_panic(LIT("Failed to create command list"));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -165,8 +165,8 @@ INTERNAL void host_msg_assembler_release(struct host_msg_assembler *ma);
|
|||||||
|
|
||||||
struct host_startup_receipt host_startup(struct sock_startup_receipt *sock_sr)
|
struct host_startup_receipt host_startup(struct sock_startup_receipt *sock_sr)
|
||||||
{
|
{
|
||||||
|
__prof;
|
||||||
(UNUSED)sock_sr;
|
(UNUSED)sock_sr;
|
||||||
|
|
||||||
return (struct host_startup_receipt) { 0 };
|
return (struct host_startup_receipt) { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -64,6 +64,7 @@ GLOBAL READONLY struct log_level_settings g_log_level_settings[LOG_LEVEL_COUNT]
|
|||||||
|
|
||||||
void log_startup(struct string logfile_path)
|
void log_startup(struct string logfile_path)
|
||||||
{
|
{
|
||||||
|
__prof;
|
||||||
G.callbacks_arena = arena_alloc(MEBI(8));
|
G.callbacks_arena = arena_alloc(MEBI(8));
|
||||||
if (logfile_path.len > 0) {
|
if (logfile_path.len > 0) {
|
||||||
/* Create / wipe log file */
|
/* Create / wipe log file */
|
||||||
|
|||||||
@ -72,10 +72,10 @@ GLOBAL struct {
|
|||||||
|
|
||||||
struct mixer_startup_receipt mixer_startup(void)
|
struct mixer_startup_receipt mixer_startup(void)
|
||||||
{
|
{
|
||||||
|
__prof;
|
||||||
G.track_arena = arena_alloc(GIBI(64));
|
G.track_arena = arena_alloc(GIBI(64));
|
||||||
G.listener_pos = V2(0, 0);
|
G.listener_pos = V2(0, 0);
|
||||||
G.listener_dir = V2(0, -1);
|
G.listener_dir = V2(0, -1);
|
||||||
|
|
||||||
return (struct mixer_startup_receipt) { 0 };
|
return (struct mixer_startup_receipt) { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -54,8 +54,8 @@ INTERNAL SYS_JOB_DEF(playback_job, _);
|
|||||||
|
|
||||||
struct playback_startup_receipt playback_startup(struct mixer_startup_receipt *mixer_sr)
|
struct playback_startup_receipt playback_startup(struct mixer_startup_receipt *mixer_sr)
|
||||||
{
|
{
|
||||||
|
__prof;
|
||||||
(UNUSED)mixer_sr;
|
(UNUSED)mixer_sr;
|
||||||
|
|
||||||
wasapi_initialize();
|
wasapi_initialize();
|
||||||
/* Start playback job */
|
/* Start playback job */
|
||||||
sys_run(1, playback_job, 0, SYS_POOL_AUDIO, SYS_PRIORITY_HIGH, &G.playback_job_counter);
|
sys_run(1, playback_job, 0, SYS_POOL_AUDIO, SYS_PRIORITY_HIGH, &G.playback_job_counter);
|
||||||
|
|||||||
@ -52,6 +52,7 @@ INTERNAL SYS_EXIT_FUNC(resource_shutdown);
|
|||||||
|
|
||||||
struct resource_startup_receipt resource_startup(void)
|
struct resource_startup_receipt resource_startup(void)
|
||||||
{
|
{
|
||||||
|
__prof;
|
||||||
G.arena = arena_alloc(GIBI(64));
|
G.arena = arena_alloc(GIBI(64));
|
||||||
|
|
||||||
#if RESOURCES_EMBEDDED
|
#if RESOURCES_EMBEDDED
|
||||||
|
|||||||
@ -62,6 +62,7 @@ READONLY struct sim_ent **_g_sim_ent_nil = &G.nil_ent;
|
|||||||
|
|
||||||
struct sim_startup_receipt sim_startup(void)
|
struct sim_startup_receipt sim_startup(void)
|
||||||
{
|
{
|
||||||
|
__prof;
|
||||||
G.nil_arena = arena_alloc(GIBI(1));
|
G.nil_arena = arena_alloc(GIBI(1));
|
||||||
|
|
||||||
/* Nil client store */
|
/* Nil client store */
|
||||||
|
|||||||
@ -51,6 +51,7 @@ GLOBAL struct {
|
|||||||
|
|
||||||
struct sock_startup_receipt sock_startup(void)
|
struct sock_startup_receipt sock_startup(void)
|
||||||
{
|
{
|
||||||
|
__prof;
|
||||||
/* Startup winsock */
|
/* Startup winsock */
|
||||||
WSAStartup(MAKEWORD(2, 2), &G.wsa_data);
|
WSAStartup(MAKEWORD(2, 2), &G.wsa_data);
|
||||||
G.win32_socks_arena = arena_alloc(GIBI(64));
|
G.win32_socks_arena = arena_alloc(GIBI(64));
|
||||||
|
|||||||
@ -35,10 +35,9 @@ GLOBAL struct {
|
|||||||
|
|
||||||
struct sound_startup_receipt sound_startup(struct asset_cache_startup_receipt *asset_cache_sr)
|
struct sound_startup_receipt sound_startup(struct asset_cache_startup_receipt *asset_cache_sr)
|
||||||
{
|
{
|
||||||
|
__prof;
|
||||||
(UNUSED)asset_cache_sr;
|
(UNUSED)asset_cache_sr;
|
||||||
|
|
||||||
G.params.arena = arena_alloc(GIBI(64));
|
G.params.arena = arena_alloc(GIBI(64));
|
||||||
|
|
||||||
return (struct sound_startup_receipt) { 0 };
|
return (struct sound_startup_receipt) { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -210,6 +210,7 @@ INTERNAL RESOURCE_WATCH_CALLBACK_FUNC_DEF(sprite_resource_watch_callback, info);
|
|||||||
|
|
||||||
struct sprite_startup_receipt sprite_startup(void)
|
struct sprite_startup_receipt sprite_startup(void)
|
||||||
{
|
{
|
||||||
|
__prof;
|
||||||
G.perm_arena = arena_alloc(MEBI(1));
|
G.perm_arena = arena_alloc(MEBI(1));
|
||||||
{
|
{
|
||||||
/* Init loading texture */
|
/* Init loading texture */
|
||||||
|
|||||||
@ -49,13 +49,6 @@ void sys_wake(void *addr, i32 count);
|
|||||||
|
|
||||||
i16 sys_current_fiber_id(void);
|
i16 sys_current_fiber_id(void);
|
||||||
|
|
||||||
/* When a job reaches a 'sys_wait' statement, by default the fiber will yield to the job pool and potentially resume on a different thread.
|
|
||||||
* Call this function to disable this behavior for the remainder of the job, and instead force a blocking wait on the current thread.
|
|
||||||
*
|
|
||||||
* For example, a job that processes audio and runs until the end of the program can set thread priority and then call this function to
|
|
||||||
* ensure it will never switch off of the worker thread that it set thread priority for. */
|
|
||||||
void sys_make_current_job_unyielding(void);
|
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Job
|
* Job
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|||||||
@ -159,10 +159,9 @@ struct alignas(64) fiber {
|
|||||||
/* ==================================================== */
|
/* ==================================================== */
|
||||||
char *name_cstr; /* 08 bytes */
|
char *name_cstr; /* 08 bytes */
|
||||||
/* ==================================================== */
|
/* ==================================================== */
|
||||||
struct atomic16 wake_lock; /* 02 bytes (4 byte alignment) */
|
struct atomic32 wake_lock; /* 04 bytes (4 byte alignment) */
|
||||||
i16 id; /* 02 bytes */
|
i16 id; /* 02 bytes */
|
||||||
i16 parent_id; /* 02 bytes */
|
i16 parent_id; /* 02 bytes */
|
||||||
i16 unyielding; /* 02 bytes */
|
|
||||||
/* ==================================================== */
|
/* ==================================================== */
|
||||||
u64 wait_addr; /* 08 bytes */
|
u64 wait_addr; /* 08 bytes */
|
||||||
/* ==================================================== */
|
/* ==================================================== */
|
||||||
@ -173,10 +172,10 @@ struct alignas(64) fiber {
|
|||||||
i16 next_time_waiter; /* 02 bytes */
|
i16 next_time_waiter; /* 02 bytes */
|
||||||
i16 prev_time_waiter; /* 02 bytes */
|
i16 prev_time_waiter; /* 02 bytes */
|
||||||
/* ==================================================== */
|
/* ==================================================== */
|
||||||
u8 _pad0[8]; /* 08 bytes (padding) */
|
|
||||||
/* ==================================================== */
|
|
||||||
u8 _pad1[8]; /* 08 bytes (padding) */
|
u8 _pad1[8]; /* 08 bytes (padding) */
|
||||||
/* ==================================================== */
|
/* ==================================================== */
|
||||||
|
u8 _pad2[8]; /* 08 bytes (padding) */
|
||||||
|
/* ==================================================== */
|
||||||
/* ==================== Cache line ==================== */
|
/* ==================== Cache line ==================== */
|
||||||
/* ==================================================== */
|
/* ==================================================== */
|
||||||
struct sys_scratch_ctx scratch_ctx; /* 16 bytes */
|
struct sys_scratch_ctx scratch_ctx; /* 16 bytes */
|
||||||
@ -193,7 +192,7 @@ struct alignas(64) fiber {
|
|||||||
/* ==================================================== */
|
/* ==================================================== */
|
||||||
struct yield_param *yield_param; /* 08 bytes */
|
struct yield_param *yield_param; /* 08 bytes */
|
||||||
/* ==================================================== */
|
/* ==================================================== */
|
||||||
u8 _pad2[8]; /* 08 bytes (padding) */
|
u8 _pad3[8]; /* 08 bytes (padding) */
|
||||||
|
|
||||||
};
|
};
|
||||||
STATIC_ASSERT(sizeof(struct fiber) == 128); /* Padding validation (increase if necessary) */
|
STATIC_ASSERT(sizeof(struct fiber) == 128); /* Padding validation (increase if necessary) */
|
||||||
@ -442,7 +441,7 @@ void sys_wait(void *addr, void *cmp, u32 size, i64 timeout_ns)
|
|||||||
{
|
{
|
||||||
struct fiber *fiber = fiber_from_id(sys_current_fiber_id());
|
struct fiber *fiber = fiber_from_id(sys_current_fiber_id());
|
||||||
i16 parent_id = fiber->parent_id;
|
i16 parent_id = fiber->parent_id;
|
||||||
if (parent_id != 0 && !fiber->unyielding) {
|
if (parent_id != 0) {
|
||||||
*fiber->yield_param = (struct yield_param) {
|
*fiber->yield_param = (struct yield_param) {
|
||||||
.kind = YIELD_KIND_WAIT,
|
.kind = YIELD_KIND_WAIT,
|
||||||
.wait = {
|
.wait = {
|
||||||
@ -575,6 +574,8 @@ INTERNAL void wake_fibers_locked(i32 num_fibers, struct fiber **fibers)
|
|||||||
fiber->prev_time_waiter = 0;
|
fiber->prev_time_waiter = 0;
|
||||||
fiber->next_time_waiter = 0;
|
fiber->next_time_waiter = 0;
|
||||||
}
|
}
|
||||||
|
/* Unlock fiber */
|
||||||
|
atomic32_fetch_set(&fiber->wake_lock, 0);
|
||||||
}
|
}
|
||||||
/* Unlock wait bins */
|
/* Unlock wait bins */
|
||||||
if (wait_time_bin != 0) tm_unlock(&wait_time_bin->lock);
|
if (wait_time_bin != 0) tm_unlock(&wait_time_bin->lock);
|
||||||
@ -612,7 +613,6 @@ INTERNAL void wake_fibers_locked(i32 num_fibers, struct fiber **fibers)
|
|||||||
queue->first = info;
|
queue->first = info;
|
||||||
}
|
}
|
||||||
queue->last = info;
|
queue->last = info;
|
||||||
atomic16_fetch_set(&fiber->wake_lock, 0);
|
|
||||||
}
|
}
|
||||||
tm_unlock(&queue->lock);
|
tm_unlock(&queue->lock);
|
||||||
}
|
}
|
||||||
@ -659,7 +659,7 @@ INTERNAL void wake_address(void *addr, i32 count)
|
|||||||
if (wait_addr_list) {
|
if (wait_addr_list) {
|
||||||
fibers = arena_push_array_no_zero(scratch.arena, struct fiber *, wait_addr_list->num_waiters);
|
fibers = arena_push_array_no_zero(scratch.arena, struct fiber *, wait_addr_list->num_waiters);
|
||||||
for (struct fiber *fiber = fiber_from_id(wait_addr_list->first_waiter); fiber && num_fibers < count; fiber = fiber_from_id(fiber->next_addr_waiter)) {
|
for (struct fiber *fiber = fiber_from_id(wait_addr_list->first_waiter); fiber && num_fibers < count; fiber = fiber_from_id(fiber->next_addr_waiter)) {
|
||||||
if (atomic16_fetch_test_set(&fiber->wake_lock, 0, 1) == 0) {
|
if (atomic32_fetch_test_set(&fiber->wake_lock, 0, 1) == 0) {
|
||||||
fibers[num_fibers] = fiber;
|
fibers[num_fibers] = fiber;
|
||||||
++num_fibers;
|
++num_fibers;
|
||||||
}
|
}
|
||||||
@ -710,7 +710,7 @@ INTERNAL void wake_time(u64 time)
|
|||||||
/* Set waiter wake status & build fibers list */
|
/* Set waiter wake status & build fibers list */
|
||||||
fibers = arena_push_array_no_zero(scratch.arena, struct fiber *, wait_time_list->num_waiters);
|
fibers = arena_push_array_no_zero(scratch.arena, struct fiber *, wait_time_list->num_waiters);
|
||||||
for (struct fiber *fiber = fiber_from_id(wait_time_list->first_waiter); fiber; fiber = fiber_from_id(fiber->next_time_waiter)) {
|
for (struct fiber *fiber = fiber_from_id(wait_time_list->first_waiter); fiber; fiber = fiber_from_id(fiber->next_time_waiter)) {
|
||||||
if (atomic16_fetch_test_set(&fiber->wake_lock, 0, 1) == 0) {
|
if (atomic32_fetch_test_set(&fiber->wake_lock, 0, 1) == 0) {
|
||||||
fibers[num_fibers] = fiber;
|
fibers[num_fibers] = fiber;
|
||||||
++num_fibers;
|
++num_fibers;
|
||||||
}
|
}
|
||||||
@ -812,7 +812,6 @@ INTERNAL struct fiber *fiber_alloc(struct job_pool *pool)
|
|||||||
fiber->addr = ConvertThreadToFiber((void *)(i64)fiber_id);
|
fiber->addr = ConvertThreadToFiber((void *)(i64)fiber_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MEMZERO_STRUCT(&fiber->wake_lock);
|
|
||||||
fiber->wait_addr = 0;
|
fiber->wait_addr = 0;
|
||||||
fiber->wait_time = 0;
|
fiber->wait_time = 0;
|
||||||
fiber->prev_addr_waiter = 0;
|
fiber->prev_addr_waiter = 0;
|
||||||
@ -827,7 +826,6 @@ INTERNAL struct fiber *fiber_alloc(struct job_pool *pool)
|
|||||||
fiber->job_counter = 0;
|
fiber->job_counter = 0;
|
||||||
fiber->yield_param = 0;
|
fiber->yield_param = 0;
|
||||||
fiber->parent_id = 0;
|
fiber->parent_id = 0;
|
||||||
fiber->unyielding = 0;
|
|
||||||
return fiber;
|
return fiber;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -860,11 +858,6 @@ i16 sys_current_fiber_id(void)
|
|||||||
return (i16)(i64)GetFiberData();
|
return (i16)(i64)GetFiberData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sys_make_current_job_unyielding(void)
|
|
||||||
{
|
|
||||||
fiber_from_id(sys_current_fiber_id())->unyielding = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sys_run(i32 count, sys_job_func *func, void *sig, enum sys_pool pool_kind, enum sys_priority priority, struct snc_counter *counter)
|
void sys_run(i32 count, sys_job_func *func, void *sig, enum sys_pool pool_kind, enum sys_priority priority, struct snc_counter *counter)
|
||||||
{
|
{
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
@ -926,7 +919,7 @@ INTERNAL void job_fiber_yield(struct fiber *fiber, struct fiber *parent_fiber)
|
|||||||
MemoryBarrier();
|
MemoryBarrier();
|
||||||
SwitchToFiber(parent_fiber->addr);
|
SwitchToFiber(parent_fiber->addr);
|
||||||
MemoryBarrier();
|
MemoryBarrier();
|
||||||
__prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS - MEBI(fiber->job_pool) + fiber->id + 1);
|
__prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS - MEBI(fiber->job_pool) + KIBI(1) + fiber->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -945,7 +938,7 @@ INTERNAL void job_fiber_entry(void *id_ptr)
|
|||||||
{
|
{
|
||||||
i16 id = (i32)(i64)id_ptr;
|
i16 id = (i32)(i64)id_ptr;
|
||||||
struct fiber *fiber = fiber_from_id(id);
|
struct fiber *fiber = fiber_from_id(id);
|
||||||
__prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS - MEBI(fiber->job_pool) + fiber->id + 1);
|
__prof_fiber_enter(fiber->name_cstr, PROF_THREAD_GROUP_FIBERS - MEBI(fiber->job_pool) + KIBI(1) + fiber->id);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* Run job */
|
/* Run job */
|
||||||
{
|
{
|
||||||
@ -1086,12 +1079,10 @@ INTERNAL SYS_THREAD_DEF(job_worker_entry, worker_ctx_arg)
|
|||||||
}
|
}
|
||||||
job_fiber_id = job_fiber->id;
|
job_fiber_id = job_fiber->id;
|
||||||
{
|
{
|
||||||
//__profnc("Run fiber", RGB32_F(0.25, 0.75, 0));
|
|
||||||
__profnc("Run fiber", RGB32_F(1, 1, 1));
|
__profnc("Run fiber", RGB32_F(1, 1, 1));
|
||||||
__profvalue(job_fiber->id);
|
__profvalue(job_fiber->id);
|
||||||
struct yield_param yield = ZI;
|
struct yield_param yield = ZI;
|
||||||
job_fiber->parent_id = worker_fiber_id;
|
job_fiber->parent_id = worker_fiber_id;
|
||||||
job_fiber->unyielding = 0;
|
|
||||||
job_fiber->job_func = job_func;
|
job_fiber->job_func = job_func;
|
||||||
job_fiber->job_sig = job_sig;
|
job_fiber->job_sig = job_sig;
|
||||||
job_fiber->job_id = job_id;
|
job_fiber->job_id = job_id;
|
||||||
@ -1365,7 +1356,7 @@ INTERNAL SYS_THREAD_DEF(test_entry, _)
|
|||||||
case SYS_POOL_SIM:
|
case SYS_POOL_SIM:
|
||||||
{
|
{
|
||||||
name_fmt = LIT("Sim worker #%F");
|
name_fmt = LIT("Sim worker #%F");
|
||||||
pool->thread_affinity_mask = 0x000000000000000Full;
|
//pool->thread_affinity_mask = 0x000000000000000Full;
|
||||||
pool->thread_priority = THREAD_PRIORITY_TIME_CRITICAL;
|
pool->thread_priority = THREAD_PRIORITY_TIME_CRITICAL;
|
||||||
pool->num_worker_threads = 4;
|
pool->num_worker_threads = 4;
|
||||||
} break;
|
} break;
|
||||||
@ -1373,7 +1364,7 @@ INTERNAL SYS_THREAD_DEF(test_entry, _)
|
|||||||
case SYS_POOL_USER:
|
case SYS_POOL_USER:
|
||||||
{
|
{
|
||||||
name_fmt = LIT("User worker #%F");
|
name_fmt = LIT("User worker #%F");
|
||||||
pool->thread_affinity_mask = 0x00000000000000F0ull;
|
//pool->thread_affinity_mask = 0x00000000000000F0ull;
|
||||||
pool->thread_priority = THREAD_PRIORITY_TIME_CRITICAL;
|
pool->thread_priority = THREAD_PRIORITY_TIME_CRITICAL;
|
||||||
pool->num_worker_threads = 4;
|
pool->num_worker_threads = 4;
|
||||||
} break;
|
} break;
|
||||||
@ -1381,7 +1372,7 @@ INTERNAL SYS_THREAD_DEF(test_entry, _)
|
|||||||
case SYS_POOL_AUDIO:
|
case SYS_POOL_AUDIO:
|
||||||
{
|
{
|
||||||
name_fmt = LIT("Audio worker #%F");
|
name_fmt = LIT("Audio worker #%F");
|
||||||
pool->thread_affinity_mask = 0x0000000000000300ull;
|
//pool->thread_affinity_mask = 0x0000000000000300ull;
|
||||||
pool->thread_priority = THREAD_PRIORITY_TIME_CRITICAL;
|
pool->thread_priority = THREAD_PRIORITY_TIME_CRITICAL;
|
||||||
pool->thread_mm_characteristics = "Pro Audio";
|
pool->thread_mm_characteristics = "Pro Audio";
|
||||||
pool->num_worker_threads = 2;
|
pool->num_worker_threads = 2;
|
||||||
@ -1390,14 +1381,14 @@ INTERNAL SYS_THREAD_DEF(test_entry, _)
|
|||||||
case SYS_POOL_BACKGROUND:
|
case SYS_POOL_BACKGROUND:
|
||||||
{
|
{
|
||||||
name_fmt = LIT("Background worker #%F");
|
name_fmt = LIT("Background worker #%F");
|
||||||
pool->thread_affinity_mask = 0x0000000000000C00ull;
|
//pool->thread_affinity_mask = 0x0000000000000C00ull;
|
||||||
pool->num_worker_threads = 2;
|
pool->num_worker_threads = 2;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case SYS_POOL_FLOATING:
|
case SYS_POOL_FLOATING:
|
||||||
{
|
{
|
||||||
name_fmt = LIT("Floating worker #%F");
|
name_fmt = LIT("Floating worker #%F");
|
||||||
pool->thread_affinity_mask = 0x0000000000000FFFull;
|
//pool->thread_affinity_mask = 0x0000000000000FFFull;
|
||||||
pool->thread_priority = 0;
|
pool->thread_priority = 0;
|
||||||
pool->num_worker_threads = 8;
|
pool->num_worker_threads = 8;
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
@ -49,6 +49,7 @@ INTERNAL i32 round_up(f32 x)
|
|||||||
/* Call this during font system startup */
|
/* Call this during font system startup */
|
||||||
struct ttf_startup_receipt ttf_startup(void)
|
struct ttf_startup_receipt ttf_startup(void)
|
||||||
{
|
{
|
||||||
|
__prof;
|
||||||
ASSERT(!G.factory);
|
ASSERT(!G.factory);
|
||||||
/* FIXME: I think IDWriteFactory5 only exists on later updates of windows
|
/* FIXME: I think IDWriteFactory5 only exists on later updates of windows
|
||||||
* 10? Need to verify. Maybe should just use a custom loader. (We're only
|
* 10? Need to verify. Maybe should just use a custom loader. (We're only
|
||||||
|
|||||||
@ -206,6 +206,7 @@ struct user_startup_receipt user_startup(struct font_startup_receipt *font_sr,
|
|||||||
struct sim_startup_receipt *sim_sr,
|
struct sim_startup_receipt *sim_sr,
|
||||||
struct string connect_address_str)
|
struct string connect_address_str)
|
||||||
{
|
{
|
||||||
|
__prof;
|
||||||
(UNUSED)font_sr;
|
(UNUSED)font_sr;
|
||||||
(UNUSED)sprite_sr;
|
(UNUSED)sprite_sr;
|
||||||
(UNUSED)draw_sr;
|
(UNUSED)draw_sr;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user