From c5520b49912b1cfbf34166fbce90ce825dae40c2 Mon Sep 17 00:00:00 2001 From: John Jackson Date: Wed, 19 Jun 2024 07:14:46 -0500 Subject: [PATCH] * Sched updates * Persistent buffer mapping --- gs.h | 58 ++++++++++++++++--- impl/gs_graphics_impl.h | 122 ++++++++++++++++++++++++++++++++++++++-- util/gs_idraw.h | 4 +- 3 files changed, 170 insertions(+), 14 deletions(-) diff --git a/gs.h b/gs.h index ab3bb8e..40e9943 100644 --- a/gs.h +++ b/gs.h @@ -4586,10 +4586,10 @@ typedef struct gs_mt_rand_t } gs_mt_rand_t; GS_API_DECL gs_mt_rand_t gs_rand_seed(uint64_t seed); -GS_API_DECL uint64_t gs_rand_gen_long(gs_mt_rand_t* rand); +GS_API_DECL int64_t gs_rand_gen_long(gs_mt_rand_t* rand); GS_API_DECL double gs_rand_gen(gs_mt_rand_t* rand); GS_API_DECL double gs_rand_gen_range(gs_mt_rand_t* rand, double min, double max); -GS_API_DECL uint64_t gs_rand_gen_range_long(gs_mt_rand_t* rand, int32_t min, int32_t max); +GS_API_DECL int64_t gs_rand_gen_range_long(gs_mt_rand_t* rand, int32_t min, int32_t max); GS_API_DECL gs_color_t gs_rand_gen_color(gs_mt_rand_t* rand); #ifndef GS_NO_SHORT_NAME @@ -4648,6 +4648,7 @@ typedef mco_result gs_coro_result; #include "external/sched/sched.h" #define GS_SCHED_DEFAULT SCHED_DEFAULT +#define gs_sched_fp_t sched_run #define gs_sched_task_t struct sched_task #define gs_sched_task_partition_t struct sched_task_partition #define gs_scheduler_t struct scheduler @@ -4658,6 +4659,7 @@ typedef mco_result gs_coro_result; #define gs_scheduler_join scheduler_join #define gs_scheduler_wait scheduler_wait #define gs_scheduler_stop scheduler_stop +#define gs_sched_task_done sched_task_done #define gs_atomic_int_t int32_t GS_API_DECL uint32_t @@ -4893,6 +4895,7 @@ typedef struct gs_lexer_t bool32 skip_white_space; size_t size; // Optional size_t contents_size; // Optional + uint32_t line; // Line number } gs_lexer_t; GS_API_DECL void gs_lexer_set_contents(gs_lexer_t* lex, const char* contents); @@ -5949,6 +5952,11 @@ gs_enum_decl(gs_graphics_access_type, GS_GRAPHICS_ACCESS_READ_WRITE ); +gs_enum_decl(gs_graphics_buffer_flags, + GS_GRAPHICS_BUFFER_FLAG_MAP_PERSISTENT, + GS_GRAPHICS_BUFFER_FLAG_MAP_COHERENT +); + //=== Texture ===// typedef enum { @@ -6171,11 +6179,13 @@ typedef struct gs_graphics_uniform_buffer_desc_t typedef struct gs_graphics_storage_buffer_desc_t { void* data; + void* map; size_t size; char name[64]; gs_graphics_buffer_usage_type usage; gs_graphics_access_type access; - gs_graphics_buffer_update_desc_t update; + gs_graphics_buffer_flags flags; + gs_graphics_buffer_update_desc_t update; } gs_graphics_storage_buffer_desc_t; typedef struct gs_graphics_framebuffer_desc_t @@ -6440,6 +6450,11 @@ typedef struct gs_graphics_t void (* texture_update)(gs_handle(gs_graphics_texture_t) hndl, gs_graphics_texture_desc_t* desc); void (* texture_read)(gs_handle(gs_graphics_texture_t) hndl, gs_graphics_texture_desc_t* desc); + // Util + void* (* storage_buffer_map_get)(gs_handle(gs_graphics_storage_buffer_t) hndl); + void* (* storage_buffer_lock)(gs_handle(gs_graphics_storage_buffer_t) hndl); + void (* storage_buffer_unlock)(gs_handle(gs_graphics_storage_buffer_t) hndl); + // Submission (Main Thread) void (* command_buffer_submit)(gs_command_buffer_t* cb); @@ -6498,6 +6513,11 @@ GS_API_DECL void gs_graphics_pipeline_desc_query(gs_handle(gs_graphics_pipeline_ GS_API_DECL void gs_graphics_texture_desc_query(gs_handle(gs_graphics_texture_t) hndl, gs_graphics_texture_desc_t* out); GS_API_DECL size_t gs_graphics_uniform_size_query(gs_handle(gs_graphics_uniform_t) hndl); +// Util +GS_API_DECL void* gs_graphics_storage_buffer_map_get(gs_handle(gs_graphics_storage_buffer_t) hndl); +GS_API_DECL void* gs_graphics_storage_buffer_lock(gs_handle(gs_graphics_storage_buffer_t) hndl); +GS_API_DECL void gs_graphics_storage_buffer_unlock(gs_handle(gs_graphics_storage_buffer_t) hndl); + // Resource In-Flight Update GS_API_DECL void gs_graphics_texture_request_update(gs_command_buffer_t* cb, gs_handle(gs_graphics_texture_t) hndl, gs_graphics_texture_desc_t* desc); GS_API_DECL void gs_graphics_vertex_buffer_request_update(gs_command_buffer_t* cb, gs_handle(gs_graphics_vertex_buffer_t) hndl, gs_graphics_vertex_buffer_desc_t* desc); @@ -6971,6 +6991,24 @@ gs_graphics_texture_read(gs_handle(gs_graphics_texture_t) hndl, gs_graphics_text return gs_graphics()->api.texture_read(hndl, desc); } +GS_API_DECL void* +gs_graphics_storage_buffer_map_get(gs_handle(gs_graphics_storage_buffer_t) hndl) +{ + return gs_graphics()->api.storage_buffer_map_get(hndl); +} + +GS_API_DECL void +gs_grapics_storage_buffer_unlock(gs_handle(gs_graphics_storage_buffer_t) hndl) +{ + return gs_graphics()->api.storage_buffer_unlock(hndl); +} + +GS_API_DECL void* +gs_grapics_storage_buffer_lock(gs_handle(gs_graphics_storage_buffer_t) hndl) +{ + return gs_graphics()->api.storage_buffer_lock(hndl); +} + /*============================= // GS_AUDIO =============================*/ @@ -7783,7 +7821,7 @@ gs_rand_seed(uint64_t seed) return rand; } -GS_API_DECL uint64_t +GS_API_DECL int64_t gs_rand_gen_long(gs_mt_rand_t* rand) { uint64_t y; @@ -7820,10 +7858,10 @@ gs_rand_gen(gs_mt_rand_t* rand) return((double)gs_rand_gen_long(rand) / (uint64_t)0xffffffff); } -GS_API_DECL uint64_t +GS_API_DECL int64_t gs_rand_gen_range_long(gs_mt_rand_t* rand, int32_t min, int32_t max) { - return (uint64_t)(floorf(gs_rand_gen_range(rand, (double)min, (double)max))); + return (int64_t)(floorf(gs_rand_gen_range(rand, (double)min, (double)max))); } GS_API_DECL double @@ -8956,9 +8994,10 @@ GS_API_DECL void gs_lexer_c_eat_white_space(gs_lexer_t* lex) { for (;;) { - if (gs_char_is_white_space(*lex->at)) + if (gs_char_is_white_space(*lex->at)) { - lex->at++; + if (gs_char_is_end_of_line(*lex->at)) {lex->line++;} + lex->at++; } // Single line comment @@ -8977,6 +9016,7 @@ GS_API_DECL void gs_lexer_c_eat_white_space(gs_lexer_t* lex) lex->at += 2; while (lex->at[0] && lex->at[1] && !(lex->at[0] == '*' && lex->at[1] == '/')) { + // if (gs_char_is_end_of_line(*lex->at)) {lex->line++;} lex->at++; } if (lex->at[0] == '*') @@ -9088,6 +9128,7 @@ gs_lexer_c_next_token(gs_lexer_t* lex) lex->at += 2; while (lex->can_lex(lex)) { + // if (gs_char_is_end_of_line(*lex->at)) {lex->line++;} if (lex->at[0] == '*' && lex->at[1] == '/') { lex->at += 2; @@ -9113,6 +9154,7 @@ gs_lexer_c_next_token(gs_lexer_t* lex) while (lex->at && *lex->at != '"') { + // if (gs_char_is_end_of_line(*lex->at)) {lex->line++;} if (lex->at[0] == '\\' && lex->at[1]) { lex->at++; diff --git a/impl/gs_graphics_impl.h b/impl/gs_graphics_impl.h index 8fa167d..300c91b 100644 --- a/impl/gs_graphics_impl.h +++ b/impl/gs_graphics_impl.h @@ -76,6 +76,8 @@ typedef struct gsgl_storage_buffer_t { size_t size; uint32_t block_idx; uint32_t location; + void* map; + GLsync sync; // Not sure about this being here... } gsgl_storage_buffer_t; /* Pipeline */ @@ -203,6 +205,17 @@ void gsgl_pipeline_state() ) } +void GLAPIENTRY +gsgl_message_cb(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, + const GLchar* message, void* user_param) +{ + return; + if (type == GL_DEBUG_TYPE_ERROR) { + gs_println("GL [DEBUG]: %s type = 0x%x, severity = 0x%x, message = %s", + type == GL_DEBUG_TYPE_ERROR ? "GL ERROR" : "", type, severity, message); + } +} + /* GS/OGL Utilities */ int32_t gsgl_buffer_usage_to_gl_enum(gs_graphics_buffer_usage_type type) { @@ -931,12 +944,43 @@ gs_graphics_storage_buffer_create_impl(const gs_graphics_storage_buffer_desc_t* glGenBuffers(1, &sbo.buffer); - CHECK_GL_CORE( + // CHECK_GL_CORE( glBindBuffer(GL_SHADER_STORAGE_BUFFER, sbo.buffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, desc->size, desc->data, gsgl_buffer_usage_to_gl_enum(desc->usage)); + + // Check for desc flags to map buffer + GLbitfield flags = 0x00; + if (desc->flags & GS_GRAPHICS_BUFFER_FLAG_MAP_PERSISTENT) {flags |= GL_MAP_PERSISTENT_BIT;} + if (desc->flags & GS_GRAPHICS_BUFFER_FLAG_MAP_COHERENT) {flags |= GL_MAP_PERSISTENT_BIT; flags |= GL_MAP_COHERENT_BIT;} + if (desc->access & GS_GRAPHICS_ACCESS_READ_ONLY) {flags |= GL_MAP_READ_BIT;} + else if (desc->access & GS_GRAPHICS_ACCESS_WRITE_ONLY) {flags |= GL_MAP_WRITE_BIT;} + else if (desc->access & GS_GRAPHICS_ACCESS_READ_WRITE) {flags |= (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);} + + GLbitfield store_flags = flags; + if (desc->usage == GS_GRAPHICS_BUFFER_USAGE_DYNAMIC) { + store_flags |= GL_DYNAMIC_STORAGE_BIT; + } + + // For now, just do read/write access + // flags |= GL_MAP_READ_BIT; flags |= GL_MAP_WRITE_BIT; + glBufferStorage(GL_SHADER_STORAGE_BUFFER, desc->size, desc->data, store_flags); + // glBufferData(GL_SHADER_STORAGE_BUFFER, desc->size, desc->data, gsgl_buffer_usage_to_gl_enum(desc->usage)); glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + + // Store mapping + if (flags & GL_MAP_PERSISTENT_BIT) { + sbo.map = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, desc->size, flags); + // while ((err = glGetError()) != GL_NO_ERROR) { + // gs_println("GL ERROR: 0x%x: %s", err, glGetString(err)); + // } + } + + GLenum err = glGetError(); + if (err) { + gs_println("GL ERROR: 0x%x: %s", err, glGetString(err)); + } + glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); - ); + // ); memcpy(sbo.name, desc->name, 64); sbo.access = desc->access; @@ -1436,6 +1480,67 @@ gs_graphics_texture_read_impl(gs_handle(gs_graphics_texture_t) hndl, gs_graphics glBindTexture(target, 0x00); } +GS_API_DECL void* +gs_graphics_storage_buffer_map_get_impl(gs_handle(gs_graphics_storage_buffer_t) hndl) +{ + gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data; + if (!gs_slot_array_handle_valid(ogl->storage_buffers, hndl.id)) { + gs_log_warning("Storage buffer handle invalid: %zu", hndl.id); + return NULL; + } + gsgl_storage_buffer_t* sbo = gs_slot_array_getp(ogl->storage_buffers, hndl.id); + return sbo->map; +} + +GS_API_DECL void +gs_grapics_storage_buffer_unlock_impl(gs_handle(gs_graphics_storage_buffer_t) hndl) +{ + // Unlock and return mapped pointer + gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data; + if (!gs_slot_array_handle_valid(ogl->storage_buffers, hndl.id)) { + gs_log_warning("Storage buffer handle invalid: %zu", hndl.id); + return NULL; + } + gsgl_storage_buffer_t* sbo = gs_slot_array_getp(ogl->storage_buffers, hndl.id); + + // Already unlocked? + if (sbo->sync) { + while (1) { + GLenum wait = glClientWaitSync(sbo->sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1); + if (wait == GL_ALREADY_SIGNALED || wait == GL_CONDITION_SATISFIED) { + break; + } + } + } +} + +GS_API_DECL void* +gs_grapics_storage_buffer_lock_impl(gs_handle(gs_graphics_storage_buffer_t) hndl) +{ + // Lock + gsgl_data_t* ogl = (gsgl_data_t*)gs_subsystem(graphics)->user_data; + if (!gs_slot_array_handle_valid(ogl->storage_buffers, hndl.id)) { + gs_log_warning("Storage buffer handle invalid: %zu", hndl.id); + return NULL; + } + gsgl_storage_buffer_t* sbo = gs_slot_array_getp(ogl->storage_buffers, hndl.id); + + // Already locked? + if (sbo->sync) { + glDeleteSync(sbo->sync); + } + sbo->sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + if (sbo->sync) { + while (1) { + GLenum wait = glClientWaitSync(sbo->sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1); + if (wait == GL_ALREADY_SIGNALED || wait == GL_CONDITION_SATISFIED) { + break; + } + } + } + return sbo->map; +} + #define __ogl_push_command(CB, OP_CODE, ...)\ do {\ gsgl_data_t* DATA = (gsgl_data_t*)gs_subsystem(graphics)->user_data;\ @@ -2801,8 +2906,17 @@ gs_graphics_init(gs_graphics_t* graphics) graphics->api.texture_update = gs_graphics_texture_update_impl; graphics->api.texture_read = gs_graphics_texture_read_impl; + // Util + graphics->api.storage_buffer_map_get = gs_graphics_storage_buffer_map_get_impl; + graphics->api.storage_buffer_lock = gs_grapics_storage_buffer_lock_impl; + graphics->api.storage_buffer_unlock = gs_grapics_storage_buffer_unlock_impl; + // Submission (Main Thread) - graphics->api.command_buffer_submit = gs_graphics_command_buffer_submit_impl; + graphics->api.command_buffer_submit = gs_graphics_command_buffer_submit_impl; + + // Enable debug output + glEnable(GL_DEBUG_OUTPUT); + glDebugMessageCallback(gsgl_message_cb, 0); } diff --git a/util/gs_idraw.h b/util/gs_idraw.h index 73d8df9..a1eb906 100644 --- a/util/gs_idraw.h +++ b/util/gs_idraw.h @@ -1619,8 +1619,8 @@ void gsi_box(gs_immediate_draw_t* gsi, float x, float y, float z, float hx, floa void gsi_sphere(gs_immediate_draw_t* gsi, float cx, float cy, float cz, float radius, uint8_t r, uint8_t g, uint8_t b, uint8_t a, gs_graphics_primitive_type type) { // Modified from: http://www.songho.ca/opengl/gl_sphere.html - const uint32_t stacks = 16; - const uint32_t sectors = 32; + const uint32_t stacks = 32; + const uint32_t sectors = 64; float sector_step = 2.f * (float)GS_PI / (float)sectors; float stack_step = (float)GS_PI / (float)stacks; struct {