From a460d5d38ca9ec766832b1aa2fa91fe7b97d128b Mon Sep 17 00:00:00 2001 From: EmeraldLoc Date: Sat, 20 Jun 2026 00:13:12 -0500 Subject: [PATCH] Optimize and fix uniforms in opengl --- src/pc/gfx/gfx_opengl.c | 54 +++++++++------ src/pc/gfx/gfx_pc.c | 142 ++++++++++++++++++++-------------------- 2 files changed, 105 insertions(+), 91 deletions(-) diff --git a/src/pc/gfx/gfx_opengl.c b/src/pc/gfx/gfx_opengl.c index 77b896efd..967a88bb0 100644 --- a/src/pc/gfx/gfx_opengl.c +++ b/src/pc/gfx/gfx_opengl.c @@ -112,7 +112,6 @@ static void gfx_opengl_load_shader(struct ShaderProgram *new_prg) { opengl_prg = new_prg; glUseProgram(new_prg->opengl_program_id); gfx_opengl_vertex_array_set_attribs(new_prg); - gfx_opengl_set_shader_uniforms(); gfx_opengl_set_texture_uniforms(new_prg, 0); gfx_opengl_set_texture_uniforms(new_prg, 1); } @@ -136,14 +135,29 @@ static void gfx_opengl_remove_shaders(void) { } } -static void cache_uniform_locations(int shaderProgram, struct Shader *shader) { +static void cache_uniform_locations(GLint shaderProgram, struct Shader *shader) { + int count = 0; + for (int i = 0; i < MAX_SHADER_UNIFORMS; i++) { - if (shader->shaderUniforms[i].size == 0) { continue; } + struct ShaderUniform *shaderUniform = &shader->shaderUniforms[i]; - int loc = glGetUniformLocation(shaderProgram, shader->shaderUniforms[i].name); - if (loc == -1) { continue; } + if (shaderUniform->size == 0) continue; - shader->shaderUniforms[i].location = loc; + GLint loc = glGetUniformLocation(shaderProgram, shaderUniform->name); + if (loc == -1) continue; + + shaderUniform->location = loc; + + if (count != i) { + shader->shaderUniforms[count] = *shaderUniform; + memset(&shader->shaderUniforms[i], 0, sizeof(struct ShaderUniform)); + } + + count++; + } + + for (int i = count; i < MAX_SHADER_UNIFORMS; i++) { + shader->shaderUniforms[i].size = 0; } } @@ -351,8 +365,8 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC glUniform1i(passTexLoc, 10); } - cache_uniform_locations(prg->opengl_program_id, vertexShader); - cache_uniform_locations(prg->opengl_program_id, fragmentShader); + cache_uniform_locations(shader_program, vertexShader); + cache_uniform_locations(shader_program, fragmentShader); prg->vertexShader = vertexShader; prg->fragmentShader = fragmentShader; @@ -485,8 +499,6 @@ static struct ShaderProgram *gfx_opengl_create_or_load_post_process_shader(void) glAttachShader(shader_program, fragment_shader); glLinkProgram(shader_program); - glUseProgram(shader_program); - size_t cnt = 0; size_t num_floats = 0; @@ -505,8 +517,10 @@ static struct ShaderProgram *gfx_opengl_create_or_load_post_process_shader(void) prg->num_floats = num_floats; prg->num_attribs = cnt; - cache_uniform_locations(prg->opengl_program_id, vertexShader); - cache_uniform_locations(prg->opengl_program_id, fragmentShader); + glUseProgram(shader_program); + + cache_uniform_locations(shader_program, vertexShader); + cache_uniform_locations(shader_program, fragmentShader); prg->vertexShader = vertexShader; prg->fragmentShader = fragmentShader; @@ -602,18 +616,18 @@ static void gfx_opengl_reset_framebuffer(void) { static void gfx_opengl_set_uniform_for_shader(struct Shader *shader, const char* name, ShaderUniformType type, const void *data, uint32_t numElements) { if (!shader) { return; } for (int i = 0; i < MAX_SHADER_UNIFORMS; i++) { - if (shader->shaderUniforms[i].size == 0) { break; } + if (shader->shaderUniforms[i].size == 0) { return; } if (strcmp(shader->shaderUniforms[i].name, name) == 0) { GLint loc = shader->shaderUniforms[i].location; switch (type) { - case SHADER_UNIFORM_TYPE_BOOL: glUniform1iv(loc, numElements, (const GLint*)data); break; - case SHADER_UNIFORM_TYPE_INT: glUniform1iv(loc, numElements, (const GLint*)data); break; - case SHADER_UNIFORM_TYPE_FLOAT: glUniform1fv(loc, numElements, (const GLfloat*)data); break; - case SHADER_UNIFORM_TYPE_VEC2: glUniform2fv(loc, numElements, (const GLfloat*)data); break; - case SHADER_UNIFORM_TYPE_VEC3: glUniform3fv(loc, numElements, (const GLfloat*)data); break; - case SHADER_UNIFORM_TYPE_VEC4: glUniform4fv(loc, numElements, (const GLfloat*)data); break; - case SHADER_UNIFORM_TYPE_MAT4: glUniformMatrix4fv(loc, numElements, GL_FALSE, (const GLfloat*)data); break; + case SHADER_UNIFORM_TYPE_BOOL: glUniform1iv(loc, numElements, (const GLint*)data); return; + case SHADER_UNIFORM_TYPE_INT: glUniform1iv(loc, numElements, (const GLint*)data); return; + case SHADER_UNIFORM_TYPE_FLOAT: glUniform1fv(loc, numElements, (const GLfloat*)data); return; + case SHADER_UNIFORM_TYPE_VEC2: glUniform2fv(loc, numElements, (const GLfloat*)data); return; + case SHADER_UNIFORM_TYPE_VEC3: glUniform3fv(loc, numElements, (const GLfloat*)data); return; + case SHADER_UNIFORM_TYPE_VEC4: glUniform4fv(loc, numElements, (const GLfloat*)data); return; + case SHADER_UNIFORM_TYPE_MAT4: glUniformMatrix4fv(loc, numElements, GL_FALSE, (const GLfloat*)data); return; } } } diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index ed443ff6b..580b247cb 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -107,11 +107,11 @@ static struct RenderingState { struct ShaderProgram *shader_program; struct TextureHashmapNode *textures[2]; ALIGNED16 Mat4 mp_matrix; -} rendering_state; +} sRenderingState; struct GfxDimensions gfx_current_dimensions = { 0 }; -static bool dropped_frame = false; +static bool sDroppedFrame = false; static float buf_vbo[VERTEX_STRIDE] = { 0.0f }; static size_t buf_vbo_len = 0; @@ -229,9 +229,9 @@ static void color_combiner_update_hash(struct ColorCombiner* cc) { static struct ShaderProgram *gfx_lookup_or_create_shader_program(struct ColorCombiner* cc) { struct ShaderProgram *prg = gfx_rapi->lookup_shader(cc); if (prg == NULL) { - gfx_rapi->unload_shader(rendering_state.shader_program); + gfx_rapi->unload_shader(sRenderingState.shader_program); prg = gfx_rapi->create_and_load_new_shader(cc); - rendering_state.shader_program = prg; + sRenderingState.shader_program = prg; } return prg; } @@ -578,7 +578,7 @@ static void import_texture_ci8(int tile) { static void import_texture(int tile) { tile = tile % MAX_TILES; extern s32 dynos_tex_import(void **output, void *ptr, s32 tile, void *grapi, void **hashmap, void *pool, s32 *poolpos, s32 poolsize); - if (dynos_tex_import((void **) &rendering_state.textures[tile], (void *) rdp.loaded_texture[tile].addr, tile, gfx_rapi, (void **) gfx_texture_cache.hashmap, (void *) gfx_texture_cache.pool, (int *) &gfx_texture_cache.pool_pos, MAX_CACHED_TEXTURES)) { return; } + if (dynos_tex_import((void **) &sRenderingState.textures[tile], (void *) rdp.loaded_texture[tile].addr, tile, gfx_rapi, (void **) gfx_texture_cache.hashmap, (void *) gfx_texture_cache.pool, (int *) &gfx_texture_cache.pool_pos, MAX_CACHED_TEXTURES)) { return; } uint8_t fmt = rdp.texture_tile[tile].fmt; uint8_t siz = rdp.texture_tile[tile].siz; @@ -592,7 +592,7 @@ static void import_texture(int tile) { return; } - if (gfx_texture_cache_lookup(tile, &rendering_state.textures[tile], rdp.loaded_texture[tile].addr, fmt, siz)) { + if (gfx_texture_cache_lookup(tile, &sRenderingState.textures[tile], rdp.loaded_texture[tile].addr, fmt, siz)) { return; } @@ -989,104 +989,104 @@ static void OPTIMIZE_O3 gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t struct GfxVertex *v_arr[3] = {v1, v2, v3}; int cull_mode = (rsp.geometry_mode & G_CULL_BOTH); - if (cull_mode != rendering_state.cull_mode) { + if (cull_mode != sRenderingState.cull_mode) { gfx_flush(); gfx_rapi->set_cull_mode(cull_mode); - rendering_state.cull_mode = cull_mode; + sRenderingState.cull_mode = cull_mode; } bool depth_test = (rsp.geometry_mode & G_ZBUFFER) == G_ZBUFFER; - if (depth_test != rendering_state.depth_test) { + if (depth_test != sRenderingState.depth_test) { gfx_flush(); gfx_rapi->set_depth_test(depth_test); - rendering_state.depth_test = depth_test; + sRenderingState.depth_test = depth_test; } bool z_upd = (rdp.other_mode_l & Z_UPD) == Z_UPD; - if (z_upd != rendering_state.depth_mask) { + if (z_upd != sRenderingState.depth_mask) { gfx_flush(); gfx_rapi->set_depth_mask(z_upd); - rendering_state.depth_mask = z_upd; + sRenderingState.depth_mask = z_upd; } bool zmode_decal = (rdp.other_mode_l & ZMODE_DEC) == ZMODE_DEC; - if (zmode_decal != rendering_state.decal_mode) { + if (zmode_decal != sRenderingState.decal_mode) { gfx_flush(); gfx_rapi->set_zmode_decal(zmode_decal); - rendering_state.decal_mode = zmode_decal; + sRenderingState.decal_mode = zmode_decal; } bool fog_enabled = (rsp.geometry_mode & G_FOG) == G_FOG; - if (fog_enabled != rendering_state.fog_enabled) { + if (fog_enabled != sRenderingState.fog_enabled) { gfx_flush(); - rendering_state.fog_enabled = fog_enabled; + sRenderingState.fog_enabled = fog_enabled; } - if (sDepthZAdd != rendering_state.depth_z_add) { + if (sDepthZAdd != sRenderingState.depth_z_add) { gfx_flush(); - rendering_state.depth_z_add = sDepthZAdd; + sRenderingState.depth_z_add = sDepthZAdd; } - if (sDepthZMult != rendering_state.depth_z_mult) { + if (sDepthZMult != sRenderingState.depth_z_mult) { gfx_flush(); - rendering_state.depth_z_mult = sDepthZMult; + sRenderingState.depth_z_mult = sDepthZMult; } - if (sDepthZSub != rendering_state.depth_z_sub) { + if (sDepthZSub != sRenderingState.depth_z_sub) { gfx_flush(); - rendering_state.depth_z_sub = sDepthZSub; + sRenderingState.depth_z_sub = sDepthZSub; } - if (rsp.fog_mul != rendering_state.fog_mul) { + if (rsp.fog_mul != sRenderingState.fog_mul) { gfx_flush(); - rendering_state.fog_mul = rsp.fog_mul; + sRenderingState.fog_mul = rsp.fog_mul; } - if (gFogIntensity != rendering_state.fog_intensity) { + if (gFogIntensity != sRenderingState.fog_intensity) { gfx_flush(); - rendering_state.fog_intensity = gFogIntensity; + sRenderingState.fog_intensity = gFogIntensity; } - if (rsp.fog_offset != rendering_state.fog_offset) { + if (rsp.fog_offset != sRenderingState.fog_offset) { gfx_flush(); - rendering_state.fog_offset = rsp.fog_offset; + sRenderingState.fog_offset = rsp.fog_offset; } - if (gFogColor[0] != rendering_state.fog_color_r || - gFogColor[1] != rendering_state.fog_color_g || - gFogColor[2] != rendering_state.fog_color_b || - rdp.fog_color.r != rendering_state.rdp_fog_color_r || - rdp.fog_color.g != rendering_state.rdp_fog_color_g || - rdp.fog_color.b != rendering_state.rdp_fog_color_b) { + if (gFogColor[0] != sRenderingState.fog_color_r || + gFogColor[1] != sRenderingState.fog_color_g || + gFogColor[2] != sRenderingState.fog_color_b || + rdp.fog_color.r != sRenderingState.rdp_fog_color_r || + rdp.fog_color.g != sRenderingState.rdp_fog_color_g || + rdp.fog_color.b != sRenderingState.rdp_fog_color_b) { gfx_flush(); - rendering_state.fog_color_r = gFogColor[0]; - rendering_state.fog_color_g = gFogColor[1]; - rendering_state.fog_color_b = gFogColor[2]; - rendering_state.rdp_fog_color_r = rdp.fog_color.r; - rendering_state.rdp_fog_color_g = rdp.fog_color.g; - rendering_state.rdp_fog_color_b = rdp.fog_color.b; + sRenderingState.fog_color_r = gFogColor[0]; + sRenderingState.fog_color_g = gFogColor[1]; + sRenderingState.fog_color_b = gFogColor[2]; + sRenderingState.rdp_fog_color_r = rdp.fog_color.r; + sRenderingState.rdp_fog_color_g = rdp.fog_color.g; + sRenderingState.rdp_fog_color_b = rdp.fog_color.b; } - if (memcmp(v1->MP_matrix, rendering_state.mp_matrix, sizeof(rendering_state.mp_matrix)) != 0) { + if (memcmp(v1->MP_matrix, sRenderingState.mp_matrix, sizeof(sRenderingState.mp_matrix)) != 0) { gfx_flush(); - mtxf_copy(rendering_state.mp_matrix, v1->MP_matrix); + mtxf_copy(sRenderingState.mp_matrix, v1->MP_matrix); } if (rdp.viewport_or_scissor_changed) { static uint32_t x_adjust_4by3_prev; - if (memcmp(&rdp.viewport, &rendering_state.viewport, sizeof(rdp.viewport)) != 0 + if (memcmp(&rdp.viewport, &sRenderingState.viewport, sizeof(rdp.viewport)) != 0 || x_adjust_4by3_prev != gfx_current_dimensions.x_adjust_4by3) { gfx_flush(); gfx_rapi->set_viewport(rdp.viewport.x + gfx_current_dimensions.x_adjust_4by3, rdp.viewport.y, rdp.viewport.width, rdp.viewport.height); - rendering_state.viewport = rdp.viewport; + sRenderingState.viewport = rdp.viewport; } - if (memcmp(&rdp.scissor, &rendering_state.scissor, sizeof(rdp.scissor)) != 0 + if (memcmp(&rdp.scissor, &sRenderingState.scissor, sizeof(rdp.scissor)) != 0 || x_adjust_4by3_prev != gfx_current_dimensions.x_adjust_4by3) { gfx_flush(); gfx_rapi->set_scissor(rdp.scissor.x + gfx_current_dimensions.x_adjust_4by3, rdp.scissor.y, rdp.scissor.width, rdp.scissor.height); - rendering_state.scissor = rdp.scissor; + sRenderingState.scissor = rdp.scissor; } rdp.viewport_or_scissor_changed = false; x_adjust_4by3_prev = gfx_current_dimensions.x_adjust_4by3; @@ -1118,16 +1118,16 @@ static void OPTIMIZE_O3 gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t cm = &comb->cm; struct ShaderProgram *prg = comb->prg; - if (prg != rendering_state.shader_program) { + if (prg != sRenderingState.shader_program) { gfx_flush(); - gfx_rapi->unload_shader(rendering_state.shader_program); + gfx_rapi->unload_shader(sRenderingState.shader_program); gfx_rapi->load_shader(prg); - rendering_state.shader_program = prg; + sRenderingState.shader_program = prg; } - if (cm->use_alpha != rendering_state.alpha_blend) { + if (cm->use_alpha != sRenderingState.alpha_blend) { gfx_flush(); gfx_rapi->set_use_alpha(cm->use_alpha); - rendering_state.alpha_blend = cm->use_alpha; + sRenderingState.alpha_blend = cm->use_alpha; } uint8_t num_inputs; bool used_textures[2]; @@ -1141,9 +1141,9 @@ static void OPTIMIZE_O3 gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t rdp.textures_changed[i] = false; } bool linear_filter = configFiltering && ((rdp.other_mode_h & (3U << G_MDSFT_TEXTFILT)) != G_TF_POINT); - struct TextureHashmapNode* tex = rendering_state.textures[i]; + struct TextureHashmapNode* tex = sRenderingState.textures[i]; if (tex) { - if (linear_filter != tex->linear_filter || rdp.texture_tile[i].cms != tex->cms || rdp.texture_tile[i].cmt != rendering_state.textures[i]->cmt) { + if (linear_filter != tex->linear_filter || rdp.texture_tile[i].cms != tex->cms || rdp.texture_tile[i].cmt != sRenderingState.textures[i]->cmt) { gfx_flush(); gfx_rapi->set_sampler_parameters(i, linear_filter, rdp.texture_tile[i].cms, rdp.texture_tile[i].cmt); tex->linear_filter = linear_filter; @@ -1666,9 +1666,9 @@ static void gfx_draw_fullscreen_quad() { gfx_rapi->create_or_load_post_process_shader(); gfx_rapi->set_use_alpha(false); - rendering_state.alpha_blend = false; + sRenderingState.alpha_blend = false; gfx_rapi->set_depth_test(false); - rendering_state.depth_test = false; + sRenderingState.depth_test = false; gfx_rapi->draw_triangles(quadVerticies, sizeof(quadVerticies) / sizeof(float), 2); } @@ -2150,10 +2150,10 @@ void gfx_run_basic(Gfx *commands) { // for dummy frames we don't want to do a mu sHasInverseCameraMatrix = false; if (!gfx_wapi->start_frame()) { - dropped_frame = true; + sDroppedFrame = true; return; } - dropped_frame = false; + sDroppedFrame = false; gfx_rapi->reset_framebuffer(); gfx_rapi->start_frame(); @@ -2167,10 +2167,10 @@ void gfx_run(Gfx *commands) { return; }*/ if (!gfx_wapi->start_frame()) { - dropped_frame = true; + sDroppedFrame = true; return; } - dropped_frame = false; + sDroppedFrame = false; bool isLuaPassesActive = false; gfx_process_lua_passes(commands, &isLuaPassesActive); @@ -2240,7 +2240,7 @@ void gfx_end_frame_render(void) { void gfx_display_frame(void) { gfx_wapi->swap_buffers_begin(); - if (!dropped_frame) { + if (!sDroppedFrame) { gfx_rapi->finish_render(); gfx_wapi->swap_buffers_end(); } @@ -2275,26 +2275,26 @@ void gfx_set_builtin_uniforms(void) { gfx_rapi->set_uniform(NULL, "uFilter", SHADER_UNIFORM_TYPE_INT, &configFiltering, 1); - float fog_mul = (float)rendering_state.fog_mul; + float fog_mul = (float)sRenderingState.fog_mul; gfx_rapi->set_uniform(NULL, "uFogMul", SHADER_UNIFORM_TYPE_FLOAT, &fog_mul, 1); - gfx_rapi->set_uniform(NULL, "uFogIntensity", SHADER_UNIFORM_TYPE_FLOAT, &rendering_state.fog_intensity, 1); + gfx_rapi->set_uniform(NULL, "uFogIntensity", SHADER_UNIFORM_TYPE_FLOAT, &sRenderingState.fog_intensity, 1); - float fog_offset = (float)rendering_state.fog_offset; + float fog_offset = (float)sRenderingState.fog_offset; gfx_rapi->set_uniform(NULL, "uFogOffset", SHADER_UNIFORM_TYPE_FLOAT, &fog_offset, 1); float fogColor[3] = { - (rendering_state.rdp_fog_color_r / 255.0f) * (rendering_state.fog_color_r / 255.0f), - (rendering_state.rdp_fog_color_g / 255.0f) * (rendering_state.fog_color_g / 255.0f), - (rendering_state.rdp_fog_color_b / 255.0f) * (rendering_state.fog_color_b / 255.0f) + (sRenderingState.rdp_fog_color_r / 255.0f) * (sRenderingState.fog_color_r / 255.0f), + (sRenderingState.rdp_fog_color_g / 255.0f) * (sRenderingState.fog_color_g / 255.0f), + (sRenderingState.rdp_fog_color_b / 255.0f) * (sRenderingState.fog_color_b / 255.0f) }; gfx_rapi->set_uniform(NULL, "uFogColor", SHADER_UNIFORM_TYPE_VEC3, &fogColor, 1); - gfx_rapi->set_uniform(NULL, "uDepthZSub", SHADER_UNIFORM_TYPE_FLOAT, &rendering_state.depth_z_sub, 1); - gfx_rapi->set_uniform(NULL, "uDepthZMult", SHADER_UNIFORM_TYPE_FLOAT, &rendering_state.depth_z_mult, 1); - gfx_rapi->set_uniform(NULL, "uDepthZAdd", SHADER_UNIFORM_TYPE_FLOAT, &rendering_state.depth_z_add, 1); + gfx_rapi->set_uniform(NULL, "uDepthZSub", SHADER_UNIFORM_TYPE_FLOAT, &sRenderingState.depth_z_sub, 1); + gfx_rapi->set_uniform(NULL, "uDepthZMult", SHADER_UNIFORM_TYPE_FLOAT, &sRenderingState.depth_z_mult, 1); + gfx_rapi->set_uniform(NULL, "uDepthZAdd", SHADER_UNIFORM_TYPE_FLOAT, &sRenderingState.depth_z_add, 1); - gfx_rapi->set_uniform(NULL, "uFogEnabled", SHADER_UNIFORM_TYPE_BOOL, &rendering_state.fog_enabled, 1); + gfx_rapi->set_uniform(NULL, "uFogEnabled", SHADER_UNIFORM_TYPE_BOOL, &sRenderingState.fog_enabled, 1); if (rsp.modelview_matrix_stack_size > 0) { gfx_rapi->set_uniform(NULL, "uModelViewMatrix", SHADER_UNIFORM_TYPE_MAT4, (const float *)rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], 1); @@ -2308,7 +2308,7 @@ void gfx_set_builtin_uniforms(void) { gfx_rapi->set_uniform(NULL, "uViewMatrix", SHADER_UNIFORM_TYPE_MAT4, (const float *)gInverseCameraMatrix.m, 1); } - gfx_rapi->set_uniform(NULL, "uModelProjectionMatrix", SHADER_UNIFORM_TYPE_MAT4, rendering_state.mp_matrix, 1); + gfx_rapi->set_uniform(NULL, "uModelProjectionMatrix", SHADER_UNIFORM_TYPE_MAT4, sRenderingState.mp_matrix, 1); gfx_rapi->set_uniform(NULL, "uProjectionMatrix", SHADER_UNIFORM_TYPE_MAT4, rsp.P_matrix, 1); Mat4 invProjectionMatrix;