last minute stufffff
authorhgn <hgodden00@gmail.com>
Tue, 17 Jun 2025 18:36:56 +0000 (19:36 +0100)
committerhgn <hgodden00@gmail.com>
Tue, 17 Jun 2025 18:36:56 +0000 (19:36 +0100)
laptop_gpu.c [new file with mode: 0644]
vg_async2.c
vg_async2.h
vg_build.h
vg_db.c
vg_db.h
vg_engine.c
vg_tex.c

diff --git a/laptop_gpu.c b/laptop_gpu.c
new file mode 100644 (file)
index 0000000..9aeea68
--- /dev/null
@@ -0,0 +1,9 @@
+
+#ifdef _WIN32
+
+__declspec( dllexport ) DWORD NvOptimusEnablement = 0x00000001;
+__declspec( dllexport ) int AmdPowerXpressRequestHighPerformance = 1;
+#else
+__attribute__((used)) unsigned int NvOptimusEnablement = 0x00000001;
+__attribute__((used)) int AmdPowerXpressRequestHighPerformance = 1;
+#endif
index 57e76ae55e87ceb577e92356ac76d93c208882b0..fedaf33fc2008a0abdc5e050a56dd5dab959b86f 100644 (file)
@@ -34,10 +34,16 @@ void vg_free_async_queue( vg_async_queue *queue )
    VG_SEMAPHORE_FREE( queue->blocking_signal );
 }
 
+bool vg_async_checksize( vg_async_queue *queue, u32 bytes )
+{
+   u32 total_size = sizeof(vg_async_task) + bytes;
+   return total_size <= queue->queue.size;
+}
+
 vg_async_task *_vg_allocate_async_task( vg_async_queue *queue, u32 bytes, bool blocking, const char *debug_info )
 {
-   VG_ASSERT( bytes <= queue->queue.size );
    u32 total_size = sizeof(vg_async_task) + bytes;
+   VG_ASSERT( total_size <= queue->queue.size );
    VG_MUTEX_LOCK( queue->data_lock );
    if( queue->allocating_task )
    {
index 80c2c532b63f61b2a78a714794c4bd70b3594862..8cf2d2dffaf3e63a8f9d8f4f89baa5c864c5b182 100644 (file)
@@ -79,3 +79,4 @@ void vg_async_queue_end( vg_async_queue *queue, enum async_quit quit );
 bool vg_async_has_work( vg_async_queue *queue );
 bool vg_async_process_next_task( vg_async_queue *queue );
 void vg_async_call( vg_async_queue *queue, void(*fn)(void *userdata), void *userdata );
+bool vg_async_checksize( vg_async_queue *queue, u32 bytes );
index 2bd12543e6412d8d213fb53a0254b6e11adfc90d..40266908c921f4721dd75a258c2779c2503d1217 100644 (file)
@@ -79,6 +79,7 @@ struct vg_compiler_conf
           library,
           link,
           defines;
+   bool no_lto;
 };
 
 enum obj_type 
@@ -275,8 +276,7 @@ vg_compiler_run( struct vg_project *project,
                        "-fstack-protector-strong " );
    }
 
-   /* always want this */
-   vg_strcat( &cmd, " -flto \\\n" );
+   vg_strcat( &cmd, conf->no_lto? " -fno-lto \\\n": " -flto \\\n" );
 
    /* want a lot of warnings but not useless ones */
    vg_strcat( &cmd, "  -Wall -ferror-limit=10\\\n"
@@ -363,7 +363,6 @@ vg_compiler_run( struct vg_project *project,
       vg_strcat( &cmd, architecture_names[env->arch] );
       vg_strcat( &cmd, "-" );
       vg_strcat( &cmd, platform_names[env->platform] );
-      vg_strcat( &cmd, " -fno-sanitize=undefined " );
 
       if( env->platform == k_platform_linux )
       {
@@ -382,6 +381,9 @@ vg_compiler_run( struct vg_project *project,
             vg_strcat( &cmd, " /SUBSYSTEM:windows" );
          }
       }
+
+      vg_strcat( &cmd, " -fno-sanitize=undefined " );
+      vg_strcat( &cmd, " -fkeep-static-consts -fkeep-persistent-storage-variables " );
    }
 
    vg_syscall( cmd.buffer );
@@ -462,21 +464,18 @@ vg_make_app( struct vg_project *proj,
    //denv.optimization = 3;
 
    /* external dependencies */
-   struct compile_result depencies = 
-      vg_compiler_run( &vg_proj, &denv, conf, "vg/vg_depencies.c",
-                        "vg_deps", k_obj_type_obj );
+   struct compile_result depencies = vg_compiler_run( &vg_proj, &denv, conf, "vg/vg_depencies.c",
+                                                      "vg_deps", k_obj_type_obj );
    vg_strcatf( &components, "%s ", depencies.path );
 
    /* glad */
-   struct compile_result glad = 
-      vg_compiler_run( &vg_proj, &denv, conf, "vg/dep/glad/glad.c",
-                        "vg_glad", k_obj_type_obj );
+   struct compile_result glad = vg_compiler_run( &vg_proj, &denv, conf, "vg/dep/glad/glad.c",
+                                                 "vg_glad", k_obj_type_obj );
    vg_strcatf( &components, "%s ", glad.path );
 
    /* core engine */
-   struct compile_result vg = 
-      vg_compiler_run( &vg_proj, &denv, conf, "vg/vg_engine.c",
-                        "vg_engine_core", k_obj_type_obj );
+   struct compile_result vg = vg_compiler_run( &vg_proj, &denv, conf, "vg/vg_engine.c",
+                                               "vg_engine_core", k_obj_type_obj );
    vg_strcatf( &components, "%s ", vg.path );
 
    /* steamworks */
diff --git a/vg_db.c b/vg_db.c
index 3f3acca8128a807fe2620652aa2646291768cf28..2656bf5bf063859bce6fc48cb47e82a48feab26c 100644 (file)
--- a/vg_db.c
+++ b/vg_db.c
@@ -2,6 +2,8 @@
 #include <stddef.h>
 #include <stdarg.h>
 
+static void vg_db_touch( vg_db *db, u16 cache_id );
+
 /* util
  * ------------------------------------------------------------------------------------------------------------------ */
 
@@ -40,6 +42,7 @@ static void vg_db_commit( vg_db *db, FILE *fwal )
 
    if( fseek( fwal, 0, SEEK_SET ) )
    {
+      free( temp_page );
       vg_warn( "WAL file was empty (assuming db is atomic)\n" );
       return;
    }
@@ -47,6 +50,7 @@ static void vg_db_commit( vg_db *db, FILE *fwal )
    vg_db_wal log;
    if( !fread( &log, sizeof(log), 1, fwal ) )
    {
+      free( temp_page );
       vg_warn( "No checkpoints in WAL file (assuming db is atomic)\n" );
       return;
    }
@@ -162,11 +166,34 @@ void vg_db_open( vg_db *db, const char *path, const char *wal_path )
       db->fp = fopen( path, "wb+" );
       if( !db->fp )
          vg_db_abort( db, "fopen(wb+) failed for '%s'\n", path );
-      vg_db_allocate_physical_page( db ); // Allocate header as 0
-      vg_db_write( db, offsetof(vg_db_header,ident), &k_ident, 4 );
+
+      vg_db_header init = {0};
+      init.ident = k_ident;
+      init._end = k_ident;
+      init.physical_size = VG_PAGE_SIZE;
+      if( !fwrite( &init, sizeof(init), 1, db->fp ) )
+         vg_db_abort( db, "fwrite header failed'\n" );
+
+      /* Sit it into the cache */
+      u16 cache_id = ++db->cache_count;
+      vg_db_page *page = &db->page_cache[ cache_id-1 ];
+      memset( page, 0, sizeof(vg_db_page) );
+      u64 page_base = 0;
+      u32 hash = vg_dbhash( (void *)(&page_base), sizeof(page_base) ) & (VG_PAGE_CACHE_HASH_WIDTH-1u);
+      db->hash_table[ hash ] = cache_id;
+      vg_db_touch( db, cache_id );
+      page->virtual_id = page_base;
+      page->physical_offset = page_base;
+      page->unwritten = 0;
+      memcpy( db->page_data, &init, sizeof(init) );
+
       db->userdata_address = vg_db_virtual_allocate( db, VG_1GB );
+
+      db->unprotect0 ++;
       vg_db_write( db, offsetof(vg_db_header,userdata_address), &db->userdata_address, 8 );
       vg_db_tree_init( db, offsetof(vg_db_header,address_tree) );
+      db->unprotect0 --;
+
       vg_db_checkpoint( db );
    }
 }
@@ -197,13 +224,14 @@ void vg_db_close( vg_db *db )
 
 static u64 vg_db_allocate_physical_page( vg_db *db )
 {
-   if( fseek( db->fp, 0, SEEK_END ) )
-      vg_db_abort( db, "SEEK_END(0) failed\n" );
-   u64 zero = 0;
-   for( u64 i=0; i<VG_PAGE_SIZE/8; i ++ )
-      if( !fwrite( &zero, 8, 1, db->fp ) )
-         vg_db_abort( db, "fwrite failed\n" );
-   return ftell( db->fp ) - VG_PAGE_SIZE;
+   u64 physical_size, address;
+   vg_db_read( db, 0x0lu + offsetof(vg_db_header,physical_size), &physical_size, sizeof(physical_size) );
+   address = physical_size;
+   physical_size += VG_PAGE_SIZE;
+   db->unprotect0 ++;
+   vg_db_write( db, 0x0lu + offsetof(vg_db_header,physical_size), &physical_size, sizeof(physical_size) );
+   db->unprotect0 --;
+   return address;
 }
 
 static void vg_db_sync_page( vg_db *db, u16 cache_id )
@@ -277,7 +305,9 @@ static void *vg_db_devirtualize( vg_db *db, u64 address, bool write, u64 *out_ph
       if( translated_page_base == 0 )
       {
          u64 new_page = vg_db_allocate_physical_page( db );
+         db->unprotect0 ++;
          vg_db_tree_map( db, tree_address, page_base, new_page );
+         db->unprotect0 --;
          translated_page_base = new_page;
       }
    }
@@ -314,11 +344,30 @@ static void *vg_db_devirtualize( vg_db *db, u64 address, bool write, u64 *out_ph
    page->unwritten = write;
 
    /* read entire page into memory */
-   void *page_data = db->page_data + (u64)(cache_id-1)*VG_PAGE_SIZE;
+   u8 *page_data = (u8 *)(db->page_data + (u64)(cache_id-1)*VG_PAGE_SIZE);
    if( fseek( db->fp, translated_page_base, SEEK_SET ) )
       vg_db_abort( db, "SEEK_SET (%lx) failed\n", translated_page_base );
-   if( !fread( page_data, VG_PAGE_SIZE, 1, db->fp ) )
-      vg_db_abort( db, "fread page failed\n" );
+
+   bool eof = 0;
+   for( u32 i=0; i<VG_PAGE_SIZE; i ++ )
+   {
+      if( !eof )
+      {
+         if( !fread( page_data+i, 1, 1, db->fp ) )
+         {
+            if( ferror( db->fp ) )
+               vg_db_abort( db, "fread page failed\n" );
+            else if( feof( db->fp ) )
+               eof = 1;
+            else
+               vg_db_abort( db, "Invalid read condition\n" );
+         }
+      }
+
+      if( eof )
+         page_data[i] = 0;
+   }
+
    *out_physical_address = translated_page_base + inner_offset;
    return page_data + inner_offset;
 }
@@ -366,9 +415,18 @@ void vg_db_xch( vg_db *db, u64 base_address, void *buf, u32 length, bool write )
            *user_buffer  = buf + (address-base_address);
       if( write ) 
       {
+         if( (physical_address < VG_PAGE_SIZE) && !db->unprotect0 )
+         {
+            vg_db_abort( db, "Tried to write to the 0 page while unprotected!\n"
+                             " base_address: %llu, length: %u\n", base_address, length );
+         }
+
          if( db->fp_wal == NULL )
          {
             db->fp_wal = fopen( db->wal_path, "wb+" );
+            if( !db->fp_wal )
+               vg_db_abort( db, "Failed to open wal file '%s'\n", db->wal_path );
+
             vg_db_wal log = {
                .type = k_wal_log_checkpoint,
                .previous_log_offset = 0,
@@ -411,7 +469,9 @@ u64 vg_db_virtual_allocate( vg_db *db, u64 bytes )
    u64 pages = (bytes + (VG_PAGE_SIZE-1lu)) >> VG_PAGE_BITS,
        addr  = page_count * VG_PAGE_SIZE;
    page_count += pages;
+   db->unprotect0 ++;
    vg_db_write( db,0x0lu + offsetof(vg_db_header,virtual_pages), &page_count, sizeof(page_count) );
+   db->unprotect0 --;
    return VG_VIRTUAL_ADDRESS_BIT | addr;
 }
 
diff --git a/vg_db.h b/vg_db.h
index b7fe29cd09ebf9812fc34a69b6218f76cf9c8053..5505610e1b8088c37d1aa7b3f928c1274f83902f 100644 (file)
--- a/vg_db.h
+++ b/vg_db.h
@@ -59,8 +59,10 @@ struct vg_db_header
 {
    u32 ident, none0, none1, none2;
    u64 virtual_pages;
+   u64 physical_size;
    u64 userdata_address;
    vg_db_address_tree address_tree;
+   u32 _end;
 };
 
 struct vg_db_skip
@@ -96,6 +98,7 @@ struct vg_db
    void *page_data;
    u64 userdata_address;
    vg_rand rand;
+   u16 unprotect0;
 };
 
 enum wal_log_type
index 131f592682ef5531c4bdc35f3301a8a8f3a577e9..a95b60ccf120564f089b4f9c597c88ea5851b643 100644 (file)
@@ -1287,12 +1287,6 @@ static int cmd_vg_settings_toggle( int argc, const char *argv[] )
    return 0;
 }
 
-/*
- * Graphic cards will check these to force it to use the GPU.
- */
-__attribute__((used)) u32 NvOptimusEnablement = 0x00000001;
-__attribute__((used)) int AmdPowerXpressRequestHighPerformance = 1;
-
 #include "vg_async2.c"
 #include "vg_audio.c"
 #include "vg_audio_dsp.c"
@@ -1326,6 +1320,7 @@ __attribute__((used)) int AmdPowerXpressRequestHighPerformance = 1;
 #include "vg_opengl.c"
 #include "vg_mem_view.c"
 #include "vg_tower.c"
+#include "laptop_gpu.c"
 
 #ifdef VG_CUSTOM_SHADERS
  #include "shaders/impl.c"
index e82fa31db0aca0db4fa28c23332ee20d201ce8ff..3462db67f97760d59b07599bb70afaf9e0cbceec 100644 (file)
--- a/vg_tex.c
+++ b/vg_tex.c
@@ -172,7 +172,6 @@ void vg_tex2d_load_qoi_async( const u8 *bytes, u32 size, u32 flags, GLuint *dest
    qoi_rgba_t px;
    int px_len, chunks_len, px_pos;
    int p = 0, run = 0;
-
    u32 channels = 4; /* TODO */
 
    qoi_desc desc;
@@ -217,6 +216,14 @@ void vg_tex2d_load_qoi_async( const u8 *bytes, u32 size, u32 flags, GLuint *dest
    u32 hdr_size = vg_align8(sizeof(struct texture_load_info)),
        tex_size = vg_align8(px_len);
 
+   if( !vg_async_checksize( &vg.main_tasks, hdr_size + tex_size ) )
+   {
+      vg_error( "Texture too large for task buffer! Dimensions: %u x %u x 4 (%u total bytes)\n", 
+                  desc.width, desc.height, tex_size );
+      vg_tex2d_replace_with_error_async( flags, dest );
+      return;
+   }
+
    vg_async_task *task = vg_allocate_async_task( &vg.main_tasks, hdr_size + tex_size, 1 );
    struct texture_load_info *info = (void *)task->data;
    info->dest = dest;