From c7631f30ccd5d5a11ba8c5a53b56988259ef7714 Mon Sep 17 00:00:00 2001 From: Ion Agorria Date: Fri, 1 Nov 2024 19:22:40 +0100 Subject: [PATCH] sokol: Don't request vs/fs slot by string each command Also put compare code behind ifdef for testing --- Source/Render/sokol/SokolRenderPipeline.cpp | 159 +++++++++----------- Source/Render/sokol/SokolRenderPipeline.h | 7 +- Source/Render/sokol/SokolRenderState.cpp | 91 ++++++----- 3 files changed, 126 insertions(+), 131 deletions(-) diff --git a/Source/Render/sokol/SokolRenderPipeline.cpp b/Source/Render/sokol/SokolRenderPipeline.cpp index 28bbde9f..3829afb8 100644 --- a/Source/Render/sokol/SokolRenderPipeline.cpp +++ b/Source/Render/sokol/SokolRenderPipeline.cpp @@ -227,93 +227,6 @@ void cSokolRender::RegisterPipeline(SokolPipelineContext context) { fprintf(stderr, "RegisterPipeline: invalid shader ID pipeline '%s'\n", desc.label); return; } - SOKOL_SHADER_ID shader_id = context.shader_funcs->get_id(); - switch (shader_id) { - case SOKOL_SHADER_ID_mesh_color_tex1: - case SOKOL_SHADER_ID_mesh_color_tex2: - if (0 > context.shader_funcs->uniformblock_slot(SG_SHADERSTAGE_VS, "mesh_color_texture_vs_params")) { - fprintf(stderr, "RegisterPipeline: 'mesh_color_texture_vs_params' uniform slot not found at pipeline '%s'\n", desc.label); - xassert(0); - return; - } else if (context.shader_funcs->uniformblock_size(SG_SHADERSTAGE_VS, "mesh_color_texture_vs_params") != sizeof(mesh_color_texture_vs_params_t)) { - fprintf(stderr, "RegisterPipeline: 'mesh_color_texture_vs_params' uniform size doesnt match at pipeline '%s'\n", desc.label); - xassert(0); - return; - } else if (0 > context.shader_funcs->uniformblock_slot(SG_SHADERSTAGE_FS, "mesh_color_texture_fs_params")) { - fprintf(stderr, "RegisterPipeline: 'mesh_color_texture_fs_params' uniform slot not found at pipeline '%s'\n", desc.label); - xassert(0); - return; - } else if (context.shader_funcs->uniformblock_size(SG_SHADERSTAGE_FS, "mesh_color_texture_fs_params") != sizeof(mesh_color_texture_fs_params_t)) { - fprintf(stderr, "RegisterPipeline: 'mesh_color_texture_fs_params' uniform size doesnt match at pipeline '%s'\n", desc.label); - xassert(0); - return; - } - break; - case SOKOL_SHADER_ID_mesh_normal_tex1: - if (0 > context.shader_funcs->uniformblock_slot(SG_SHADERSTAGE_VS, "mesh_normal_texture_vs_params")) { - fprintf(stderr, "RegisterPipeline: 'mesh_normal_texture_vs_params' uniform slot not found at pipeline '%s'\n", desc.label); - xassert(0); - return; - } else if (context.shader_funcs->uniformblock_size(SG_SHADERSTAGE_VS, "mesh_normal_texture_vs_params") != sizeof(mesh_normal_texture_vs_params_t)) { - fprintf(stderr, "RegisterPipeline: 'mesh_normal_texture_vs_params' uniform size doesnt match at pipeline '%s'\n", desc.label); - xassert(0); - return; - } - break; - case SOKOL_SHADER_ID_shadow_tex1: - case SOKOL_SHADER_ID_shadow_normal_tex1: - if (0 > context.shader_funcs->uniformblock_slot(SG_SHADERSTAGE_VS, "shadow_texture_vs_params")) { - fprintf(stderr, "RegisterPipeline: 'shadow_texture_vs_params' uniform slot not found at pipeline '%s'\n", desc.label); - xassert(0); - return; - } else if (context.shader_funcs->uniformblock_size(SG_SHADERSTAGE_VS, "shadow_texture_vs_params") != sizeof(shadow_texture_vs_params_t)) { - fprintf(stderr, "RegisterPipeline: 'shadow_texture_vs_params' uniform size doesnt match at pipeline '%s'\n", desc.label); - xassert(0); - return; - } else if (0 > context.shader_funcs->uniformblock_slot(SG_SHADERSTAGE_FS, "shadow_texture_fs_params")) { - fprintf(stderr, "RegisterPipeline: 'shadow_texture_fs_params' uniform slot not found at pipeline '%s'\n", desc.label); - xassert(0); - return; - } else if (context.shader_funcs->uniformblock_size(SG_SHADERSTAGE_FS, "shadow_texture_fs_params") != sizeof(mesh_color_texture_fs_params_t)) { - fprintf(stderr, "RegisterPipeline: 'shadow_texture_fs_params' uniform size doesnt match at pipeline '%s'\n", desc.label); - xassert(0); - return; - } - break; - case SOKOL_SHADER_ID_mesh_tex1: - if (0 > context.shader_funcs->uniformblock_slot(SG_SHADERSTAGE_VS, "mesh_texture_vs_params")) { - fprintf(stderr, "RegisterPipeline: 'mesh_texture_vs_params' uniform slot not found at pipeline '%s'\n", desc.label); - xassert(0); - return; - } else if (context.shader_funcs->uniformblock_size(SG_SHADERSTAGE_VS, "mesh_texture_vs_params") != sizeof(mesh_texture_vs_params_t)) { - fprintf(stderr, "RegisterPipeline: 'mesh_texture_vs_params' uniform size doesnt match at pipeline '%s'\n", desc.label); - xassert(0); - return; - } - break; - case SOKOL_SHADER_ID_tile_map: - if (0 > context.shader_funcs->uniformblock_slot(SG_SHADERSTAGE_VS, "tile_map_vs_params")) { - fprintf(stderr, "RegisterPipeline: 'tile_map_vs_params' uniform slot not found at pipeline '%s'\n", desc.label); - xassert(0); - return; - } else if (context.shader_funcs->uniformblock_size(SG_SHADERSTAGE_VS, "tile_map_vs_params") != sizeof(tile_map_vs_params_t)) { - fprintf(stderr, "RegisterPipeline: 'tile_map_vs_params' uniform size doesnt match at pipeline '%s'\n", desc.label); - xassert(0); - return; - } else if (0 > context.shader_funcs->uniformblock_slot(SG_SHADERSTAGE_FS, "tile_map_fs_params")) { - fprintf(stderr, "RegisterPipeline: 'tile_map_fs_params' uniform slot not found at pipeline '%s'\n", desc.label); - xassert(0); - return; - } else if (context.shader_funcs->uniformblock_size(SG_SHADERSTAGE_FS, "tile_map_fs_params") != sizeof(tile_map_fs_params_t)) { - fprintf(stderr, "RegisterPipeline: 'tile_map_fs_params' uniform size doesnt match at pipeline '%s'\n", desc.label); - xassert(0); - return; - } - break; - default: - fprintf(stderr, "RegisterPipeline: Unknown shader id '%d' at pipeline '%s'\n", shader_id, desc.label); - return; - } //Check for any missing slots if (context.vertex_fmt & VERTEX_FMT_TEX1 && @@ -339,7 +252,8 @@ void cSokolRender::RegisterPipeline(SokolPipelineContext context) { bind_vertex_fmt(context, VERTEX_FMT_NORMAL); //Created, store on our pipelines - //printf("RegisterPipeline: '%s' at '%d'\n", desc.label, id); + SOKOL_SHADER_ID shader_id = context.shader_funcs->get_id(); + //printf("RegisterPipeline: '%s' at '%d'\n", desc.label, shader_id); SokolPipeline* pipeline = new SokolPipeline { context, sg_make_pipeline(desc), @@ -354,6 +268,75 @@ void cSokolRender::RegisterPipeline(SokolPipelineContext context) { xxassert(0, "RegisterPipeline: invalid pipeline vertex format " + std::string(desc.label)); return; } + const char* vs_params_name = nullptr; + const char* fs_params_name = nullptr; + size_t vs_params_size = 0; + size_t fs_params_size = 0; + switch (shader_id) { + case SOKOL_SHADER_ID_mesh_color_tex1: + case SOKOL_SHADER_ID_mesh_color_tex2: + vs_params_name = "mesh_color_texture_vs_params"; + fs_params_name = "mesh_color_texture_fs_params"; + vs_params_size = sizeof(mesh_color_texture_vs_params_t); + fs_params_size = sizeof(mesh_color_texture_fs_params_t); + break; + case SOKOL_SHADER_ID_mesh_normal_tex1: + vs_params_name = "mesh_normal_texture_vs_params"; + fs_params_name = "mesh_normal_texture_fs_params"; + vs_params_size = sizeof(mesh_normal_texture_vs_params_t); + fs_params_size = sizeof(mesh_normal_texture_fs_params_t); + break; + case SOKOL_SHADER_ID_shadow_tex1: + case SOKOL_SHADER_ID_shadow_normal_tex1: + vs_params_name = "shadow_texture_vs_params"; + fs_params_name = "shadow_texture_fs_params"; + vs_params_size = sizeof(shadow_texture_vs_params_t); + fs_params_size = sizeof(shadow_texture_fs_params_t); + break; + case SOKOL_SHADER_ID_mesh_tex1: + vs_params_name = "mesh_texture_vs_params"; + vs_params_size = sizeof(mesh_texture_vs_params_t); + break; + case SOKOL_SHADER_ID_tile_map: + vs_params_name = "tile_map_vs_params"; + fs_params_name = "tile_map_fs_params"; + vs_params_size = sizeof(tile_map_vs_params_t); + fs_params_size = sizeof(tile_map_fs_params_t); + break; + case SOKOL_SHADER_ID_NONE: + default: + fprintf(stderr, "RegisterPipeline: Unknown shader id '%d' at pipeline '%s'\n", shader_id, desc.label); + break; + } + + if (vs_params_name) { + pipeline->vs_params_slot = context.shader_funcs->uniformblock_slot(SG_SHADERSTAGE_VS, vs_params_name); + if (0 > pipeline->vs_params_slot) { + fprintf(stderr, "RegisterPipeline: '%s' vs uniform slot not found at pipeline '%s'\n", vs_params_name, + desc.label); + xassert(0); + return; + } else if (context.shader_funcs->uniformblock_size(SG_SHADERSTAGE_VS, vs_params_name) != vs_params_size) { + fprintf(stderr, "RegisterPipeline: '%s' vs uniform size doesnt match at pipeline '%s'\n", + vs_params_name, desc.label); + xassert(0); + return; + } + } + if (fs_params_name) { + pipeline->fs_params_slot = context.shader_funcs->uniformblock_slot(SG_SHADERSTAGE_FS, fs_params_name); + if (0 > pipeline->fs_params_slot) { + fprintf(stderr, "RegisterPipeline: '%s' fs uniform slot not found at pipeline '%s'\n", + fs_params_name, desc.label); + xassert(0); + return; + } else if (context.shader_funcs->uniformblock_size(SG_SHADERSTAGE_FS, fs_params_name) != fs_params_size) { + fprintf(stderr, "RegisterPipeline: '%s' fs uniform size doesnt match at pipeline '%s'\n", + fs_params_name, desc.label); + xassert(0); + return; + } + } for (int i = 0; i < PERIMETER_SOKOL_TEXTURES; ++i) { std::string name = "un_tex" + std::to_string(i); pipeline->shader_fs_texture_slot[i] = context.shader_funcs->image_slot(SG_SHADERSTAGE_FS, name.c_str()); diff --git a/Source/Render/sokol/SokolRenderPipeline.h b/Source/Render/sokol/SokolRenderPipeline.h index fbf3de3e..d63ce72c 100644 --- a/Source/Render/sokol/SokolRenderPipeline.h +++ b/Source/Render/sokol/SokolRenderPipeline.h @@ -14,8 +14,11 @@ struct SokolPipeline { //Mapping of texture slots in fragment shader int shader_fs_texture_slot[PERIMETER_SOKOL_TEXTURES] = {}; //Sampler slot - int shader_fs_sampler_slot = 0; - int shader_fs_shadow_sampler_slot = 0; + int shader_fs_sampler_slot = -1; + int shader_fs_shadow_sampler_slot = -1; + //Uniform params slots + int vs_params_slot = -1; + int fs_params_slot = -1; SokolPipeline() = default; ~SokolPipeline(); diff --git a/Source/Render/sokol/SokolRenderState.cpp b/Source/Render/sokol/SokolRenderState.cpp index 16a508d9..74d5d782 100644 --- a/Source/Render/sokol/SokolRenderState.cpp +++ b/Source/Render/sokol/SokolRenderState.cpp @@ -133,18 +133,29 @@ void cSokolRender::DoSokolRendering() { ProcessRenderPass(swapchain_pass, swapchainCommands); } +#define CMDS_COMPARE_PREV_COMMAND void cSokolRender::ProcessRenderPass(sg_pass& render_pass, const std::vector& pass_commands) { std::string pass_group_label = "pass_"; pass_group_label += render_pass.label; sg_push_debug_group(pass_group_label.c_str()); sg_begin_pass(&render_pass); +#ifdef PERIMETER_DEBUG + //printf("@@@ %s @@@\n",pass_group_label.c_str()); +#endif //Iterate each command +#ifdef CMDS_COMPARE_PREV_COMMAND const SokolCommand* prev_command = nullptr; +#ifdef DEBUG_TEST_SAME + int same_i = 0; +#endif +#endif const SokolCommand* command = nullptr; bool open_debug_group = false; for (size_t passcmd_i = 0; passcmd_i < pass_commands.size(); ++passcmd_i) { +#ifdef CMDS_COMPARE_PREV_COMMAND prev_command = command; +#endif command = pass_commands[passcmd_i]; //Make/Close debug group @@ -191,8 +202,8 @@ void cSokolRender::ProcessRenderPass(sg_pass& render_pass, const std::vectorcontext.shader_funcs; +#ifdef CMDS_COMPARE_PREV_COMMAND bool pipeline_diff = !prev_command || prev_command->pipeline != pipeline; bool vs_params_diff = !prev_command || pipeline_diff || prev_command->vs_params_len != command->vs_params_len @@ -209,6 +220,23 @@ void cSokolRender::ProcessRenderPass(sg_pass& render_pass, const std::vectorfs_params_len )); +#ifdef DEBUG_TEST_SAME + if (prev_command && prev_command->vertex_buffer && command->vertex_buffer + && prev_command->pipeline == command->pipeline + && prev_command->base_elements == command->base_elements + && prev_command->indices == command->indices + && !fs_params_diff + && prev_command->vertex_buffer->res.id == command->vertex_buffer->res.id) { + same_i++; + continue; + } else if (0 < same_i) { + if (2< same_i) { + printf("!! Up %d\n", same_i); + } + same_i = 0; + } +#endif + if (!prev_command || vs_params_diff || fs_params_diff || prev_command->vertex_buffer != command->vertex_buffer @@ -219,7 +247,9 @@ void cSokolRender::ProcessRenderPass(sg_pass& render_pass, const std::vectorsokol_images, sizeof(SokolResourceImage*) * PERIMETER_SOKOL_TEXTURES )) - ) { + ) +#endif + { #if defined(PERIMETER_DEBUG) && 0 printf("id: 0x%X fmt: 0x%X vtx: %d idx: %d\n", command->pipeline_id, pipeline->vertex_fmt, @@ -300,47 +330,27 @@ void cSokolRender::ProcessRenderPass(sg_pass& render_pass, const std::vectorget_id(); - const char* vs_params_name = nullptr; - const char* fs_params_name = nullptr; - switch (shader_id) { - case SOKOL_SHADER_ID_mesh_color_tex1: - case SOKOL_SHADER_ID_mesh_color_tex2: - vs_params_name = "mesh_color_texture_vs_params"; - fs_params_name = "mesh_color_texture_fs_params"; - break; - case SOKOL_SHADER_ID_mesh_normal_tex1: - vs_params_name = "mesh_normal_texture_vs_params"; - fs_params_name = "mesh_normal_texture_fs_params"; - break; - case SOKOL_SHADER_ID_shadow_tex1: - case SOKOL_SHADER_ID_shadow_normal_tex1: - vs_params_name = "shadow_texture_vs_params"; - fs_params_name = "shadow_texture_fs_params"; - break; - case SOKOL_SHADER_ID_mesh_tex1: - vs_params_name = "mesh_texture_vs_params"; - break; - case SOKOL_SHADER_ID_tile_map: - vs_params_name = "tile_map_vs_params"; - fs_params_name = "tile_map_fs_params"; - break; - default: - case SOKOL_SHADER_ID_NONE: - xassert(0); - } - - if (vs_params_name && vs_params_diff) { - int vs_params_slot = shader_funcs->uniformblock_slot(SG_SHADERSTAGE_VS, vs_params_name); - xxassert(0 <= vs_params_slot, "No vs slot found"); +#ifdef CMDS_COMPARE_PREV_COMMAND + if (vs_params_diff) +#endif + if (0 <= pipeline->vs_params_slot) { xxassert(command->vs_params, "No vs parameters set in command"); - sg_apply_uniforms(SG_SHADERSTAGE_VS, vs_params_slot, sg_range { command->vs_params, command->vs_params_len }); + sg_apply_uniforms( + SG_SHADERSTAGE_VS, + pipeline->vs_params_slot, + sg_range { command->vs_params, command->vs_params_len } + ); } - if (fs_params_name && fs_params_diff) { - int fs_params_slot = shader_funcs->uniformblock_slot(SG_SHADERSTAGE_FS, fs_params_name); - xxassert(0 <= fs_params_slot, "No fs slot found"); +#ifdef CMDS_COMPARE_PREV_COMMAND + if (fs_params_diff) +#endif + if (0 <= pipeline->fs_params_slot) { xxassert(command->fs_params, "No fs parameters set in command"); - sg_apply_uniforms(SG_SHADERSTAGE_FS, fs_params_slot, sg_range { command->fs_params, command->fs_params_len }); + sg_apply_uniforms( + SG_SHADERSTAGE_FS, + pipeline->fs_params_slot, + sg_range { command->fs_params, command->fs_params_len } + ); } } @@ -834,7 +844,6 @@ void cSokolRender::CreateCommand(VertexBuffer* vb, size_t vertices, IndexBuffer* case SOKOL_SHADER_ID_shadow_normal_tex1: { auto vs_params = reinterpret_cast(cmd->vs_params); auto fs_params = reinterpret_cast(cmd->fs_params); - vs_params->un_mvp = isOrthographicProjSet ? orthoVP : (activeCommandW * activeCommandVP); shader_set_common_params(vs_params, fs_params); break; }