texture load waitable

This commit is contained in:
jacob 2025-07-11 19:39:24 -05:00
parent e02858fd21
commit 9fc74f4838
11 changed files with 120 additions and 123 deletions

View File

@ -279,6 +279,8 @@ void sys_app_entry(struct string args_str)
#endif #endif
/* Startup systems */ /* Startup systems */
resource_startup();
gp_startup();
struct sock_startup_receipt sock_sr = sock_startup(); struct sock_startup_receipt sock_sr = sock_startup();
struct host_startup_receipt host_sr = host_startup(&sock_sr); struct host_startup_receipt host_sr = host_startup(&sock_sr);
struct asset_cache_startup_receipt asset_cache_sr = asset_cache_startup(); struct asset_cache_startup_receipt asset_cache_sr = asset_cache_startup();

View File

@ -42,7 +42,7 @@
#define SIM_TILES_PER_UNIT_SQRT (4) #define SIM_TILES_PER_UNIT_SQRT (4)
#define SIM_TILES_PER_CHUNK_SQRT (16) #define SIM_TILES_PER_CHUNK_SQRT (16)
#define SIM_TICKS_PER_SECOND 50 #define SIM_TICKS_PER_SECOND 100
//#define SIM_TIMESCALE 1 //#define SIM_TIMESCALE 1
/* Like USER_INTERP_RATIO, but applies to snapshots received by the local sim from the /* Like USER_INTERP_RATIO, but applies to snapshots received by the local sim from the
* master sim (how far back in time should the client render the server's state) */ * master sim (how far back in time should the client render the server's state) */

View File

@ -17,7 +17,11 @@ struct draw_startup_receipt draw_startup(struct font_startup_receipt *font_sr)
{ {
(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); {
struct snc_counter counter = ZI;
G.solid_white_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(1, 1), &pixel_white, &counter);
snc_counter_wait(&counter);
}
return (struct draw_startup_receipt) { 0 }; return (struct draw_startup_receipt) { 0 };
} }

View File

@ -110,7 +110,12 @@ INTERNAL SYS_JOB_DEF(font_load_asset_job, job)
resource_close(&res); resource_close(&res);
/* Send texture to GPU */ /* Send texture to GPU */
struct gp_resource *texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(result.image_data.width, result.image_data.height), result.image_data.pixels); struct gp_resource *texture = 0;
{
struct snc_counter counter = ZI;
texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(result.image_data.width, result.image_data.height), result.image_data.pixels, &counter);
snc_counter_wait(&counter);
}
/* Allocate store memory */ /* Allocate store memory */
struct font *font = 0; struct font *font = 0;

View File

@ -2,6 +2,7 @@
#define GP_H #define GP_H
struct sys_window; struct sys_window;
struct snc_counter;
/* ========================== * /* ========================== *
* Startup * Startup
@ -38,7 +39,7 @@ enum gp_texture_flag {
GP_TEXTURE_FLAG_TARGETABLE = (1 << 0) GP_TEXTURE_FLAG_TARGETABLE = (1 << 0)
}; };
struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, struct v2i32 size, void *initial_data); struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, struct v2i32 size, void *initial_data, struct snc_counter *counter);
struct v2i32 gp_texture_get_size(struct gp_resource *texture); struct v2i32 gp_texture_get_size(struct gp_resource *texture);

View File

@ -2194,7 +2194,26 @@ INTERNAL D3D12_INDEX_BUFFER_VIEW ibv_from_command_buffer(struct command_buffer *
* Texture * Texture
* ========================== */ * ========================== */
struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, struct v2i32 size, void *initial_data) struct dx12_wait_fence_job_sig {
ID3D12Fence *fence;
u64 target;
};
INTERNAL SYS_JOB_DEF(dx12_wait_fence_job, job)
{
__prof;
struct dx12_wait_fence_job_sig *sig = job.sig;
ID3D12Fence *fence = sig->fence;
u64 target = sig->target;
if (ID3D12Fence_GetCompletedValue(fence) < target) {
HANDLE event = CreateEvent(0, 0, 0, 0);
ID3D12Fence_SetEventOnCompletion(sig->fence, sig->target, event);
WaitForSingleObject(event, INFINITE);
CloseHandle(event);
}
}
struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, struct v2i32 size, void *initial_data, struct snc_counter *counter)
{ {
__prof; __prof;
struct dxgi_format_info { DXGI_FORMAT format; u32 size; }; struct dxgi_format_info { DXGI_FORMAT format; u32 size; };
@ -2336,14 +2355,12 @@ struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, s
} }
u64 fence_target = command_list_close(cl); u64 fence_target = command_list_close(cl);
/* Wait */ /* Submit wait job */
/* TODO: Return async waitable to caller */ if (counter && ID3D12Fence_GetCompletedValue(cq->submit_fence) < fence_target) {
{ struct dx12_wait_fence_job_sig sig = ZI;
__profn("Wait for upload"); sig.fence = cq->submit_fence;
HANDLE event = CreateEvent(0, 0, 0, 0); sig.target = fence_target;
ID3D12Fence_SetEventOnCompletion(cq->submit_fence, fence_target, event); sys_run(1, dx12_wait_fence_job, &sig, SYS_POOL_FLOATING, SYS_PRIORITY_LOW, counter);
WaitForSingleObject(event, INFINITE);
CloseHandle(event);
} }
} }

View File

@ -221,12 +221,6 @@ INTERNAL void wasapi_update_end(struct wasapi_buffer *wspbuf, struct mixed_pcm_f
* Playback thread entry * Playback thread entry
* ========================== */ * ========================== */
INTERNAL SYS_JOB_DEF(playback_wait_job, _)
{
__prof;
WaitForSingleObject(G.event, INFINITE);
}
INTERNAL SYS_JOB_DEF(playback_job, _) INTERNAL SYS_JOB_DEF(playback_job, _)
{ {
__prof; __prof;
@ -239,9 +233,7 @@ INTERNAL SYS_JOB_DEF(playback_job, _)
struct arena_temp scratch = scratch_begin_no_conflict(); struct arena_temp scratch = scratch_begin_no_conflict();
{ {
__profn("Wasapi wait"); __profn("Wasapi wait");
struct snc_counter counter = ZI; WaitForSingleObject(G.event, INFINITE);
sys_run(1, playback_wait_job, 0, SYS_POOL_FLOATING, SYS_PRIORITY_INHERIT, &counter);
snc_counter_wait(&counter);
} }
{ {
__profn("Fill sample buffer"); __profn("Fill sample buffer");

View File

@ -221,7 +221,11 @@ struct sprite_startup_receipt sprite_startup(void)
{ {
struct arena_temp scratch = scratch_begin_no_conflict(); struct arena_temp scratch = scratch_begin_no_conflict();
struct image_rgba purple_black_image = generate_purple_black_image(scratch.arena, 64, 64); struct image_rgba purple_black_image = generate_purple_black_image(scratch.arena, 64, 64);
G.nil_texture->gp_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(purple_black_image.width, purple_black_image.height), purple_black_image.pixels); {
struct snc_counter counter = ZI;
G.nil_texture->gp_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(purple_black_image.width, purple_black_image.height), purple_black_image.pixels, &counter);
snc_counter_wait(&counter);
}
scratch_end(scratch); scratch_end(scratch);
} }
@ -366,9 +370,13 @@ INTERNAL void cache_entry_load_texture(struct cache_ref ref, struct sprite_tag t
e->texture = arena_push(e->arena, struct sprite_texture); e->texture = arena_push(e->arena, struct sprite_texture);
e->texture->width = decoded.image.width; e->texture->width = decoded.image.width;
e->texture->height = decoded.image.height; e->texture->height = decoded.image.height;
e->texture->gp_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB, 0, V2I32(decoded.image.width, decoded.image.height), decoded.image.pixels);
e->texture->valid = 1; e->texture->valid = 1;
e->texture->loaded = 1; e->texture->loaded = 1;
{
struct snc_counter counter = ZI;
e->texture->gp_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB, 0, V2I32(decoded.image.width, decoded.image.height), decoded.image.pixels, &counter);
snc_counter_wait(&counter);
}
/* TODO: Query gpu for more accurate texture size in VRAM */ /* TODO: Query gpu for more accurate texture size in VRAM */
memory_size += (decoded.image.width * decoded.image.height) * sizeof(*decoded.image.pixels); memory_size += (decoded.image.width * decoded.image.height) * sizeof(*decoded.image.pixels);
success = 1; success = 1;
@ -1208,7 +1216,6 @@ INTERNAL SORT_COMPARE_FUNC_DEF(evict_sort, arg_a, arg_b, udata)
return (b_cycle > a_cycle) - (a_cycle > b_cycle); return (b_cycle > a_cycle) - (a_cycle > b_cycle);
} }
/* NOTE: /* NOTE:
* A cache node is safe from eviction as long as: * A cache node is safe from eviction as long as:
* - Its bin mutex is locked * - Its bin mutex is locked

View File

@ -457,14 +457,11 @@ struct sys_window_settings {
i32 floating_height; i32 floating_height;
}; };
struct sys_window_present_job_sig { struct sys_window *sys_window_alloc(void);
struct sys_window *window;
struct sys_event_array events;
};
struct sys_window *sys_window_alloc(sys_job_func *present_job);
void sys_window_release(struct sys_window *sys_window); void sys_window_release(struct sys_window *sys_window);
struct sys_event_array sys_window_pop_events(struct arena *arena, struct sys_window *sys_window);
void sys_window_update_settings(struct sys_window *sys_window, struct sys_window_settings *settings); void sys_window_update_settings(struct sys_window *sys_window, struct sys_window_settings *settings);
struct sys_window_settings sys_window_get_settings(struct sys_window *sys_window); struct sys_window_settings sys_window_get_settings(struct sys_window *sys_window);
@ -482,8 +479,6 @@ void sys_window_cursor_hide(struct sys_window *sys_window);
void sys_window_cursor_enable_clip(struct sys_window *sys_window, struct rect bounds); void sys_window_cursor_enable_clip(struct sys_window *sys_window, struct rect bounds);
void sys_window_cursor_disable_clip(struct sys_window *sys_window); void sys_window_cursor_disable_clip(struct sys_window *sys_window);
struct gp_swapchain *sys_window_get_swapchain(struct sys_window *window);
/* ========================== * /* ========================== *
* Threads * Threads
* ========================== */ * ========================== */

View File

@ -8,7 +8,6 @@
#include "math.h" #include "math.h"
#include "util.h" #include "util.h"
#include "uni.h" #include "uni.h"
#include "gp.h"
#include "resource.h" #include "resource.h"
#pragma warning(push, 0) #pragma warning(push, 0)
@ -105,16 +104,11 @@ struct win32_window {
struct v2 cursor_set_position; struct v2 cursor_set_position;
struct rect cursor_clip_bounds; struct rect cursor_clip_bounds;
struct gp_swapchain *swapchain;
struct snc_mutex event_arena_swp_mutex; struct snc_mutex event_arena_swp_mutex;
i32 current_event_arena_index; i32 current_event_arena_index;
struct arena *event_arenas[2]; struct arena *event_arenas[2];
sys_job_func *present_job;
struct sys_thread *event_thread; struct sys_thread *event_thread;
struct sys_thread *present_thread;
struct atomic32 shutdown; struct atomic32 shutdown;
struct win32_window *next_free; struct win32_window *next_free;
@ -426,6 +420,7 @@ void sys_wait(void *addr, void *cmp, u32 size, i64 timeout_ns)
/* REQUIRED: Caller must have acquired `wake_lock` for each fiber in array */ /* REQUIRED: Caller must have acquired `wake_lock` for each fiber in array */
INTERNAL void wake_fibers_locked(i32 num_fibers, struct fiber **fibers) INTERNAL void wake_fibers_locked(i32 num_fibers, struct fiber **fibers)
{ {
__prof;
/* Update wait lists */ /* Update wait lists */
for (i32 i = 0; i < num_fibers; ++i) { for (i32 i = 0; i < num_fibers; ++i) {
struct fiber *fiber = fibers[i]; struct fiber *fiber = fibers[i];
@ -1303,7 +1298,7 @@ INTERNAL SYS_THREAD_DEF(test_entry, _)
struct sys_thread *scheduler_thread = sys_thread_alloc(job_scheduler_entry, 0, LIT("Scheduler thread"), PROF_THREAD_GROUP_SCHEDULER); struct sys_thread *scheduler_thread = sys_thread_alloc(job_scheduler_entry, 0, LIT("Scheduler thread"), PROF_THREAD_GROUP_SCHEDULER);
/* Start workers */ /* Start workers */
/* TODO: Heuristic worker count & priorities */ /* TODO: Heuristic worker counts & affinities */
for (enum sys_pool pool_kind = 0; pool_kind < (i32)countof(G.job_pools); ++pool_kind) { for (enum sys_pool pool_kind = 0; pool_kind < (i32)countof(G.job_pools); ++pool_kind) {
struct job_pool *pool = &G.job_pools[pool_kind]; struct job_pool *pool = &G.job_pools[pool_kind];
struct string name_fmt = ZI; struct string name_fmt = ZI;
@ -1348,7 +1343,7 @@ INTERNAL SYS_THREAD_DEF(test_entry, _)
name_fmt = LIT("Floating worker #%F"); name_fmt = LIT("Floating worker #%F");
pool->thread_affinity_mask = 0xFFFFFFFFFFFFFFFFull; pool->thread_affinity_mask = 0xFFFFFFFFFFFFFFFFull;
pool->thread_priority = 0; pool->thread_priority = 0;
pool->num_worker_threads = 32; pool->num_worker_threads = 8;
} break; } break;
} }
pool->worker_threads_arena = arena_alloc(GIBI(64)); pool->worker_threads_arena = arena_alloc(GIBI(64));
@ -1371,6 +1366,7 @@ INTERNAL SYS_THREAD_DEF(test_entry, _)
sys_thread_wait_release(worker_thread); sys_thread_wait_release(worker_thread);
} }
} }
/* Wait on scheduler */ /* Wait on scheduler */
sys_thread_wait_release(scheduler_thread); sys_thread_wait_release(scheduler_thread);
@ -2164,14 +2160,12 @@ INTERNAL void win32_window_wake(struct win32_window *window);
INTERNAL void win32_window_process_event(struct win32_window *window, struct sys_event event) INTERNAL void win32_window_process_event(struct win32_window *window, struct sys_event event)
{ {
__prof; __prof;
if (window->present_job) {
struct snc_lock lock = snc_lock_e(&window->event_arena_swp_mutex); struct snc_lock lock = snc_lock_e(&window->event_arena_swp_mutex);
{ {
*arena_push(window->event_arenas[window->current_event_arena_index], struct sys_event) = event; *arena_push(window->event_arenas[window->current_event_arena_index], struct sys_event) = event;
} }
snc_unlock(&lock); snc_unlock(&lock);
} }
}
INTERNAL HWND win32_create_window(struct win32_window *window) INTERNAL HWND win32_create_window(struct win32_window *window)
{ {
@ -2296,44 +2290,7 @@ INTERNAL SYS_THREAD_DEF(window_event_thread_entry_point, arg)
DestroyWindow(window->hwnd); DestroyWindow(window->hwnd);
} }
INTERNAL SYS_THREAD_DEF(window_present_thread_entry_point, arg) INTERNAL struct win32_window *win32_window_alloc(void)
{
struct win32_window *window = (struct win32_window *)arg;
/* Show window */
sys_window_show((struct sys_window *)window);
while (!atomic32_fetch(&window->shutdown)) {
{
__profn("Swapchain wait");
gp_swapchain_wait(window->swapchain);
}
{
i32 event_arena_index = 0;
{
struct snc_lock lock = snc_lock_e(&window->event_arena_swp_mutex);
event_arena_index = window->current_event_arena_index;
window->current_event_arena_index = 1 - window->current_event_arena_index;
snc_unlock(&lock);
}
struct arena *events_arena = window->event_arenas[event_arena_index];
struct sys_event_array events = ZI;
events.count = events_arena->pos / sizeof(struct sys_event);
events.events = (struct sys_event *)arena_base(events_arena);
{
struct snc_counter counter = ZI;
struct sys_window_present_job_sig sig = ZI;
sig.window = (struct sys_window *)window;
sig.events = events;
sys_run(1, window->present_job, &sig, SYS_POOL_USER, SYS_PRIORITY_HIGH, &counter);
snc_counter_wait(&counter);
}
arena_reset(events_arena);
}
}
}
INTERNAL struct win32_window *win32_window_alloc(sys_job_func *present_job)
{ {
struct win32_window *window = 0; struct win32_window *window = 0;
{ {
@ -2347,12 +2304,9 @@ INTERNAL struct win32_window *win32_window_alloc(sys_job_func *present_job)
snc_unlock(&lock); snc_unlock(&lock);
} }
MEMZERO_STRUCT(window); MEMZERO_STRUCT(window);
window->present_job = present_job;
if (present_job) {
window->event_arenas[0] = arena_alloc(GIBI(64)); window->event_arenas[0] = arena_alloc(GIBI(64));
window->event_arenas[1] = arena_alloc(GIBI(64)); window->event_arenas[1] = arena_alloc(GIBI(64));
}
/* Start window event thread */ /* Start window event thread */
/* NOTE: This thread must finish building for the window to actually be /* NOTE: This thread must finish building for the window to actually be
@ -2362,12 +2316,6 @@ INTERNAL struct win32_window *win32_window_alloc(sys_job_func *present_job)
window->event_thread = sys_thread_alloc(&window_event_thread_entry_point, window, LIT("Window event thread"), PROF_THREAD_GROUP_WINDOW); window->event_thread = sys_thread_alloc(&window_event_thread_entry_point, window, LIT("Window event thread"), PROF_THREAD_GROUP_WINDOW);
snc_counter_wait(&window->ready_fence); snc_counter_wait(&window->ready_fence);
/* Start window present thread */
if (present_job) {
window->swapchain = gp_swapchain_alloc((struct sys_window *)window, V2I32(100, 100));
window->present_thread = sys_thread_alloc(&window_present_thread_entry_point, window, LIT("Window present thread"), PROF_THREAD_GROUP_WINDOW);
}
return window; return window;
} }
@ -2376,12 +2324,8 @@ INTERNAL void win32_window_release(struct win32_window *window)
/* Stop window threads */ /* Stop window threads */
atomic32_fetch_set(&window->shutdown, 1); atomic32_fetch_set(&window->shutdown, 1);
win32_window_wake(window); win32_window_wake(window);
sys_thread_wait_release(window->present_thread);
sys_thread_wait_release(window->event_thread); sys_thread_wait_release(window->event_thread);
/* Release swapchain */
gp_swapchain_release(window->swapchain);
struct snc_lock lock = snc_lock_e(&G.windows_mutex); struct snc_lock lock = snc_lock_e(&G.windows_mutex);
{ {
window->next_free = G.first_free_window; window->next_free = G.first_free_window;
@ -2390,6 +2334,26 @@ INTERNAL void win32_window_release(struct win32_window *window)
snc_unlock(&lock); snc_unlock(&lock);
} }
struct sys_event_array sys_window_pop_events(struct arena *arena, struct sys_window *sys_window)
{
__prof;
struct win32_window *window = (struct win32_window *)sys_window;
i32 event_arena_index = 0;
{
struct snc_lock lock = snc_lock_e(&window->event_arena_swp_mutex);
event_arena_index = window->current_event_arena_index;
window->current_event_arena_index = 1 - window->current_event_arena_index;
snc_unlock(&lock);
}
struct arena *events_arena = window->event_arenas[event_arena_index];
struct sys_event_array events = ZI;
events.count = events_arena->pos / sizeof(struct sys_event);
events.events = arena_push_array_no_zero(arena, struct sys_event, events.count);
MEMCPY(events.events, arena_base(events_arena), events_arena->pos);
arena_reset(events_arena);
return events;
}
INTERNAL void win32_update_window_from_system(struct win32_window *window) INTERNAL void win32_update_window_from_system(struct win32_window *window)
{ {
HWND hwnd = window->hwnd; HWND hwnd = window->hwnd;
@ -2750,10 +2714,10 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam,
return result; return result;
} }
struct sys_window *sys_window_alloc(sys_job_func *present_job) struct sys_window *sys_window_alloc(void)
{ {
__prof; __prof;
return (struct sys_window *)win32_window_alloc(present_job); return (struct sys_window *)win32_window_alloc();
} }
void sys_window_release(struct sys_window *sys_window) void sys_window_release(struct sys_window *sys_window)
@ -2857,12 +2821,6 @@ void sys_window_cursor_disable_clip(struct sys_window *sys_window)
win32_window_wake(window); win32_window_wake(window);
} }
/* TODO: Remove this */
struct gp_swapchain *sys_window_get_swapchain(struct sys_window *window)
{
return ((struct win32_window *)window)->swapchain;
}
/* ========================== * /* ========================== *
* Threads * Threads
* ========================== */ * ========================== */
@ -3348,10 +3306,6 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
/* Start test thread */ /* Start test thread */
struct sys_thread *test_thread = sys_thread_alloc(test_entry, 0, LIT("Test thread"), PROF_THREAD_GROUP_APP); struct sys_thread *test_thread = sys_thread_alloc(test_entry, 0, LIT("Test thread"), PROF_THREAD_GROUP_APP);
/* Startup systems */
resource_startup();
gp_startup();
/* ========================== * /* ========================== *
* App thread setup * App thread setup
* ========================== */ * ========================== */

View File

@ -51,6 +51,7 @@ GLOBAL struct {
struct atomic32 shutdown; struct atomic32 shutdown;
struct snc_counter shutdown_job_counters; struct snc_counter shutdown_job_counters;
struct sys_window *window; struct sys_window *window;
struct gp_swapchain *swapchain;
struct sim_ctx *local_sim_ctx; struct sim_ctx *local_sim_ctx;
@ -242,12 +243,15 @@ struct user_startup_receipt user_startup(struct font_startup_receipt *font_sr,
//log_register_callback(debug_console_log_callback, LOG_LEVEL_SUCCESS); //log_register_callback(debug_console_log_callback, LOG_LEVEL_SUCCESS);
log_register_callback(debug_console_log_callback, LOG_LEVEL_DEBUG); log_register_callback(debug_console_log_callback, LOG_LEVEL_DEBUG);
/* Start sim job */ G.window = sys_window_alloc();
G.swapchain = gp_swapchain_alloc(G.window, V2I32(100, 100));
sys_window_show(G.window);
/* Start jobs */
sys_run(1, user_update_job, 0, SYS_POOL_USER, SYS_PRIORITY_HIGH, &G.shutdown_job_counters);
sys_run(1, local_sim_job, 0, SYS_POOL_SIM, SYS_PRIORITY_HIGH, &G.shutdown_job_counters); sys_run(1, local_sim_job, 0, SYS_POOL_SIM, SYS_PRIORITY_HIGH, &G.shutdown_job_counters);
sys_on_exit(&user_shutdown); sys_on_exit(&user_shutdown);
G.window = sys_window_alloc(user_update_job);
return (struct user_startup_receipt) { 0 }; return (struct user_startup_receipt) { 0 };
} }
@ -561,12 +565,9 @@ INTERNAL SORT_COMPARE_FUNC_DEF(ent_draw_order_cmp, arg_a, arg_b, udata)
* Update * Update
* ========================== */ * ========================== */
SYS_JOB_DEF(user_update_job, job) INTERNAL void user_update(struct sys_window *window)
{ {
__prof; __prof;
struct sys_window_present_job_sig *sig = job.sig;
struct sys_window *window = sig->window;
struct sys_event_array events = sig->events;
struct arena_temp scratch = scratch_begin_no_conflict(); struct arena_temp scratch = scratch_begin_no_conflict();
@ -701,6 +702,8 @@ SYS_JOB_DEF(user_update_job, job)
{ {
__profn("Process sys events"); __profn("Process sys events");
struct sys_event_array events = sys_window_pop_events(scratch.arena, window);
/* Reset bind pressed / released states */ /* Reset bind pressed / released states */
for (u32 i = 0; i < countof(G.bind_states); ++i) { for (u32 i = 0; i < countof(G.bind_states); ++i) {
G.bind_states[i] = (struct bind_state) { G.bind_states[i] = (struct bind_state) {
@ -2023,7 +2026,12 @@ SYS_JOB_DEF(user_update_job, job)
if (G.user_texture) { if (G.user_texture) {
gp_resource_release(G.user_texture); gp_resource_release(G.user_texture);
} }
G.user_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, GP_TEXTURE_FLAG_TARGETABLE, user_resolution, 0); {
/* TODO: Don't wait here */
struct snc_counter counter = ZI;
G.user_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, GP_TEXTURE_FLAG_TARGETABLE, user_resolution, 0, &counter);
snc_counter_wait(&counter);
}
} }
/* Render world to user texture */ /* Render world to user texture */
@ -2047,9 +2055,8 @@ SYS_JOB_DEF(user_update_job, job)
gp_dispatch(params); gp_dispatch(params);
} }
/* Present user texture */ /* Present */
struct gp_swapchain *swapchain = sys_window_get_swapchain(window); gp_present(G.swapchain, backbuffer_resolution, G.user_texture, XFORM_TRS(.t = v2_mul(G.screen_size, 0.5), .s = G.user_size), VSYNC);
gp_present(swapchain, backbuffer_resolution, G.user_texture, XFORM_TRS(.t = v2_mul(G.screen_size, 0.5), .s = G.user_size), VSYNC);
} }
/* ========================== * /* ========================== *
@ -2061,6 +2068,19 @@ SYS_JOB_DEF(user_update_job, job)
scratch_end(scratch); scratch_end(scratch);
} }
INTERNAL SYS_JOB_DEF(user_update_job, _)
{
(UNUSED)_;
while (!atomic32_fetch(&G.shutdown)) {
struct sys_window *window = G.window;
{
__profn("Swapchain wait");
gp_swapchain_wait(G.swapchain);
}
user_update(window);
}
}