From fb18be564badf538fd203058d70457e059bae494 Mon Sep 17 00:00:00 2001 From: hgn Date: Thu, 30 Oct 2025 03:05:30 +0000 Subject: [PATCH] fixup async task queue quiting, shader source paths correct, recompiling --- source/async/sdl_async.c | 12 +++++- source/async/vg_async.c | 13 ++++-- source/async/vg_async.h | 1 + source/engine/engine.kv | 12 +++--- source/engine/vg_engine.c | 8 ++-- source/engine/vg_shader.c | 74 +++++++++++++++++++++++++++------ source/foundation/foundation.kv | 5 +++ source/foundation/stream.c | 13 +++--- source/terminal_main.c | 1 + source/tools/metacompiler.c | 6 ++- 10 files changed, 112 insertions(+), 33 deletions(-) diff --git a/source/async/sdl_async.c b/source/async/sdl_async.c index c1aa445..c85fcef 100644 --- a/source/async/sdl_async.c +++ b/source/async/sdl_async.c @@ -249,6 +249,15 @@ void task_send( struct task *task, void (*fn)( struct task *task ) ) SDL_SignalCondition( queue->work_signal ); } +void _task_queue_stop_normal( enum thread_id thread ) +{ + struct task_queue *queue = _get_thread_task_queue( thread ); + SDL_LockMutex( queue->lock ); + queue->count ++; + SDL_UnlockMutex( queue->lock ); + SDL_SignalCondition( queue->work_signal ); +} + b8 _task_queue_process( b8 blocking ) { struct task_queue *queue = _get_thread_task_queue( _get_thread_id() ); @@ -290,6 +299,5 @@ b8 _task_queue_process( b8 blocking ) SDL_SignalCondition( queue->blocking_signal ); return 1; } - else - return 0; + else return 0; } diff --git a/source/async/vg_async.c b/source/async/vg_async.c index c52183b..64181c3 100644 --- a/source/async/vg_async.c +++ b/source/async/vg_async.c @@ -246,6 +246,15 @@ void task_send( struct task *task, void (*fn)( struct task *task ) ) ASSERT_CRITICAL( cnd_signal( &queue->work_signal ) == thrd_success ); } +void _task_queue_stop_normal( enum thread_id thread ) +{ + struct task_queue *queue = _get_thread_task_queue( thread ); + ASSERT_CRITICAL( mtx_lock( &queue->lock ) == thrd_success ); + queue->count ++; + ASSERT_CRITICAL( mtx_unlock( &queue->lock ) == thrd_success ); + ASSERT_CRITICAL( cnd_signal( &queue->work_signal ) == thrd_success ); +} + bool _task_queue_process( bool blocking ) { struct task_queue *queue = _get_thread_task_queue( _get_thread_id() ); @@ -284,10 +293,8 @@ bool _task_queue_process( bool blocking ) queue_pop( &queue->queue ); queue->count --; ASSERT_CRITICAL( mtx_unlock( &queue->lock ) == thrd_success ); - ASSERT_CRITICAL( cnd_signal( &queue->blocking_signal ) == thrd_success ); return 1; } - else - return 0; + else return 1; } diff --git a/source/async/vg_async.h b/source/async/vg_async.h index fd3a412..6b9f006 100644 --- a/source/async/vg_async.h +++ b/source/async/vg_async.h @@ -27,6 +27,7 @@ b8 _thread_has_flags( enum thread_id id, u32 flags ); struct task *_task_new( enum thread_id thread, u32 buffer_size, u32 async_flags, const c8 *debug_info ); void task_send( struct task *task, void (*fn)( struct task *task ) ); +void _task_queue_stop_normal( enum thread_id thread ); void *task_buffer( struct task *task ); u32 task_buffer_size( struct task *task ); diff --git a/source/engine/engine.kv b/source/engine/engine.kv index 93bebf3..4a3b361 100644 --- a/source/engine/engine.kv +++ b/source/engine/engine.kv @@ -321,11 +321,14 @@ shader hook { event START - function "_shaders_compile" + function "_shader_init" +} +ccmd +{ + name reload_shaders + function _shader_recompile_ccmd + description "Recompile shaders (DEVELOPER ONLY!)" } - - - @@ -391,7 +394,6 @@ hook function _dsp_init } - add model.c add metascene.c add array_file.c diff --git a/source/engine/vg_engine.c b/source/engine/vg_engine.c index 3fa992f..6f3788a 100644 --- a/source/engine/vg_engine.c +++ b/source/engine/vg_engine.c @@ -47,7 +47,7 @@ void _engine_options(void) } -i32 async_thread( void *_ ) +i32 _async_thread( void *_ ) { _set_thread_id( k_thread_async ); while( _task_queue_process( 1 ) ) {} @@ -208,8 +208,7 @@ i32 main( i32 argc, const c8 *argv[] ) mt_random_seed( &_engine.random, 887765 ); EVENT_CALL( START ); - SDL_CreateThread( async_thread, "ASync thread", NULL ); - ASSERT_CRITICAL( async_thread ); + SDL_Thread *async_thread = SDL_CreateThread( _async_thread, "ASync thread", NULL ); L_new_frame:; f64 now = (f64)SDL_GetTicksNS() / 1000000000.0; @@ -282,6 +281,9 @@ L_new_frame:; if( e.type == SDL_EVENT_QUIT ) { SDL_DestroyWindow( _engine.window_handle ); + EVENT_CALL( END ); + _task_queue_stop_normal( k_thread_async ); + SDL_WaitThread( async_thread, NULL ); SDL_Quit(); _normal_exit(); } diff --git a/source/engine/vg_shader.c b/source/engine/vg_shader.c index 81b9adf..226af60 100644 --- a/source/engine/vg_shader.c +++ b/source/engine/vg_shader.c @@ -1,6 +1,7 @@ #include "foundation.h" #include "vg_opengl.h" #include "vg_shader.h" +#include "console_system.h" GLuint compile_opengl_subshader( GLint type, const c8 *sources[], u32 source_count, b8 critical, const c8 *name ) { @@ -98,7 +99,7 @@ struct shader #include "generated/shaders.c" -void _shaders_compile(void) +static void _shaders_compile( b8 recompile ) { for( u32 i=0; isource_uniforms; - sources[ source_count ++ ] = subshader->source_static; + + u32 temp_frame = _start_temporary_frame(); + if( recompile ) + { + for( u32 k=0; ksource_count; k ++ ) + { + struct stream file; + if( stream_open_file( &file, subshader->source_list[k], k_stream_read ) ) + { + u32 length; + sources[ source_count ++ ] = stream_read_all( &file, _temporary_stack_allocator(), 4, &length ); + stream_close( &file ); + } + else + { + _end_temporary_frame( temp_frame ); + goto fail_shader; + } + } + } + else + sources[ source_count ++ ] = subshader->source_static; ASSERT_CRITICAL( subshader->type != k_subshader_geometry ); sub_programs[j] = compile_opengl_subshader( (subshader->type == k_subshader_vertex? GL_VERTEX_SHADER: GL_FRAGMENT_SHADER), - sources, source_count, 1, shader->name ); - glAttachShader( new_program, sub_programs[j] ); - } + sources, source_count, recompile==0, shader->name ); + _end_temporary_frame( temp_frame ); - link_opengl_program( new_program, 1 ); - _shader_programs[i] = new_program; - - for( u32 j=0; jsubshader_count; j ++ ) - glDeleteShader( sub_programs[j] ); + if( sub_programs[j] ) + glAttachShader( new_program, sub_programs[j] ); + else + goto fail_shader; + } - for( u32 j=0; juniform_count; j ++ ) + if( link_opengl_program( new_program, recompile==0 ) ) { - u32 index = shader->uniform_start+j; - _uniform_locations[ index ] = glGetUniformLocation( new_program, _uniform_aliases[ index ] ); + if( recompile ) + glDeleteProgram( _shader_programs[i] ); + _shader_programs[i] = new_program; + for( u32 j=0; juniform_count; j ++ ) + { + u32 index = shader->uniform_start+j; + _uniform_locations[ index ] = glGetUniformLocation( new_program, _uniform_aliases[ index ] ); + } + $log( $ok, {"Shader complete: "}, {shader->name} ); + goto cleanup; } + +fail_shader: + $log( $error, {"Shader failed: "}, {shader->name} ); + glDeleteProgram( new_program ); +cleanup: + for( u32 j=0; jsubshader_count; j ++ ) + if( sub_programs[j] ) + glDeleteShader( sub_programs[j] ); } } +void _shader_init(void) +{ + _shaders_compile(0); +} + void _shader_bind( enum shader_id id ) { glUseProgram( _shader_programs[ id ] ); } + +i32 _shader_recompile_ccmd( struct console_arguments *args ) +{ + _shaders_compile(1); + return 0; +} diff --git a/source/foundation/foundation.kv b/source/foundation/foundation.kv index a4fb6e6..6145269 100644 --- a/source/foundation/foundation.kv +++ b/source/foundation/foundation.kv @@ -10,6 +10,11 @@ event name START prototype "void" } +event +{ + name END + prototype "void" +} add options.c add logging.c diff --git a/source/foundation/stream.c b/source/foundation/stream.c index cc4eeed..950fd7d 100644 --- a/source/foundation/stream.c +++ b/source/foundation/stream.c @@ -145,12 +145,15 @@ u32 stream_read( struct stream *stream, void *buffer, u32 length ) void *stream_read_all( struct stream *stream, struct stack_allocator *stack, u32 alignment, u32 *length ) { - stack_allocate( stack, 0, alignment, "Alignment" ); - i32 space = ((i32)stack->capacity - (i32)alignment) - (i32)stack->offset; - void *buffer = stack_allocate( stack, space, alignment, "Remaining buffer" ); - u32 l = stream_read( stream, buffer, space ); - stack_extend_last( stack, buffer, -(i32)( space - l ) ); + void *buffer = stack_allocate( stack, 1, alignment, "Stream data" ); + u32 l = 0; + while( stream_read( stream, buffer+l, 1 ) ) + { + stack_extend_last( stack, buffer, 1 ); + l ++; + } + ((u8 *)buffer)[l] = 0x00; *length = l; return buffer; } diff --git a/source/terminal_main.c b/source/terminal_main.c index 1ef17a0..1cd4132 100644 --- a/source/terminal_main.c +++ b/source/terminal_main.c @@ -4,4 +4,5 @@ i32 main( i32 argc, const c8 *argv[] ) { VG_PRE_MAIN; EVENT_CALL( START ); + _normal_exit(); } diff --git a/source/tools/metacompiler.c b/source/tools/metacompiler.c index 9646057..d2e4943 100644 --- a/source/tools/metacompiler.c +++ b/source/tools/metacompiler.c @@ -408,9 +408,11 @@ void _codegen_shaders(void) { ASSERT_CRITICAL( source_count < ARRAY_COUNT( sources ) ); - /* FIXME: EXPAND PATH TO FULL PATH LIKE SOURCE ADDS */ const c8 *path = keyvalues_value( &_assembly, source_it, NULL ); - $v_string( &C, {" \""}, {path}, {"\",\n"} ); + u32 context_block = _assembly_kv_file_context( source_it ); + $v_string( &C, {" \""}, {keyvalues_read_string( &_assembly, context_block, "folder", NULL )}, + {"/"}, {path}, {"\",\n"} ); + sources[ source_count ++ ] = source_it; } -- 2.25.1