From 806f059123982507c00d2763a2ac32fd8d993a85 Mon Sep 17 00:00:00 2001 From: hgn Date: Tue, 17 Jun 2025 19:36:56 +0100 Subject: [PATCH] last minute stufffff --- laptop_gpu.c | 9 ++++++ vg_async2.c | 8 ++++- vg_async2.h | 1 + vg_build.h | 23 +++++++------- vg_db.c | 84 ++++++++++++++++++++++++++++++++++++++++++++-------- vg_db.h | 3 ++ vg_engine.c | 7 +---- vg_tex.c | 9 +++++- 8 files changed, 112 insertions(+), 32 deletions(-) create mode 100644 laptop_gpu.c diff --git a/laptop_gpu.c b/laptop_gpu.c new file mode 100644 index 0000000..9aeea68 --- /dev/null +++ b/laptop_gpu.c @@ -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 diff --git a/vg_async2.c b/vg_async2.c index 57e76ae..fedaf33 100644 --- a/vg_async2.c +++ b/vg_async2.c @@ -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 ) { diff --git a/vg_async2.h b/vg_async2.h index 80c2c53..8cf2d2d 100644 --- a/vg_async2.h +++ b/vg_async2.h @@ -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 ); diff --git a/vg_build.h b/vg_build.h index 2bd1254..4026690 100644 --- a/vg_build.h +++ b/vg_build.h @@ -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 3f3acca..2656bf5 100644 --- a/vg_db.c +++ b/vg_db.c @@ -2,6 +2,8 @@ #include #include +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; ifp ) ) - 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; ifp ) ) + { + 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 b7fe29c..5505610 100644 --- 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 diff --git a/vg_engine.c b/vg_engine.c index 131f592..a95b60c 100644 --- a/vg_engine.c +++ b/vg_engine.c @@ -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" diff --git a/vg_tex.c b/vg_tex.c index e82fa31..3462db6 100644 --- 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; -- 2.25.1