fixup async task queue quiting, shader source paths correct, recompiling
authorhgn <hgodden00@gmail.com>
Thu, 30 Oct 2025 03:05:30 +0000 (03:05 +0000)
committerhgn <hgodden00@gmail.com>
Thu, 30 Oct 2025 03:05:30 +0000 (03:05 +0000)
source/async/sdl_async.c
source/async/vg_async.c
source/async/vg_async.h
source/engine/engine.kv
source/engine/vg_engine.c
source/engine/vg_shader.c
source/foundation/foundation.kv
source/foundation/stream.c
source/terminal_main.c
source/tools/metacompiler.c

index c1aa4451d5fc2e9aa483bb73bc23047391c26a21..c85fcef833576fc9f9b8533c8ee93b639a2ed171 100644 (file)
@@ -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;
 }
index c52183b679d773b08912ffe79f3d9fd9ed2e0391..64181c3532980586ec58bb7f08c1875f6b6327c3 100644 (file)
@@ -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;
 }
index fd3a4129aff6a64fdaff86e62dd2715897b9c78b..6b9f006efe1106a3bc7c0f1d320af91bec2afb7a 100644 (file)
@@ -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 );
index 93bebf34ff5f79597392d07e62dff7b1b344e767..4a3b3613506e85565ccd5488d2120625a0ae5a63 100644 (file)
@@ -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
index 3fa992f330ee2b8c755c0c4ade52d276c47425f7..6f3788ad6f6a1e4262c6f11f431e6874bfa82f7d 100644 (file)
@@ -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();
       }
index 81b9adf03b32ceb45a496af08ea215ad31e70142..226af6015c872df4cf8c040385dfb912e454c718 100644 (file)
@@ -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; i<k_shader_count; i ++ )
    {
@@ -113,30 +114,77 @@ void _shaders_compile(void)
          const c8 *sources[32] = { "#version 330 core\n", NULL };
          u32 source_count = 1;
          sources[ source_count ++ ] = subshader->source_uniforms;
-         sources[ source_count ++ ] = subshader->source_static;
+
+         u32 temp_frame = _start_temporary_frame();
+         if( recompile )
+         {
+            for( u32 k=0; k<subshader->source_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; j<shader->subshader_count; j ++ )
-         glDeleteShader( sub_programs[j] );
+         if( sub_programs[j] )
+            glAttachShader( new_program, sub_programs[j] );
+         else
+            goto fail_shader;
+      }
 
-      for( u32 j=0; j<shader->uniform_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; j<shader->uniform_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; j<shader->subshader_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;
+}
index a4fb6e67555a43e85af7f4080857636f9988ebf8..614526950a800ec7a71f5f51dd67a92bfdebfb9e 100644 (file)
@@ -10,6 +10,11 @@ event
    name START
    prototype "void"
 }
+event
+{
+   name END
+   prototype "void"
+}
 
 add options.c
 add logging.c
index cc4eeeddb27db83ac18fbe06cbccc0ddb22e41e3..950fd7d6f2361c3e22f0dae03e09ff6a8e9ad86c 100644 (file)
@@ -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;
 }
index 1ef17a0e1463e58fc0ed57559a584bfbd67db7d8..1cd413285f96346d38e5487627f95cc5a8c0c59d 100644 (file)
@@ -4,4 +4,5 @@ i32 main( i32 argc, const c8 *argv[] )
 {
    VG_PRE_MAIN;
    EVENT_CALL( START );
+   _normal_exit();
 }
index 964605748128a3b9cef3a1ba04e5449296ccd86b..d2e49437b9da3b3c0b55480ab4cea11d3537c462 100644 (file)
@@ -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;
          }