From 22d51f3c92285efcdb47019aa445d8f4535f4b14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Fri, 22 Oct 2021 19:22:53 -0400 Subject: [PATCH] mesa: precompute strlen in gl_resource_name::length and use it Reviewed-by: Timothy Arceri Part-of: --- src/compiler/glsl/ir_uniform.h | 1 + src/compiler/glsl/linker.cpp | 5 ++ src/mesa/main/program_resource.c | 2 +- src/mesa/main/shader_query.cpp | 111 ++++++++++++++++++++++++++----- src/mesa/main/shaderapi.c | 22 +++--- src/mesa/main/shaderapi.h | 9 ++- 6 files changed, 119 insertions(+), 31 deletions(-) diff --git a/src/compiler/glsl/ir_uniform.h b/src/compiler/glsl/ir_uniform.h index 3322b97abdd..8f91bb0a285 100644 --- a/src/compiler/glsl/ir_uniform.h +++ b/src/compiler/glsl/ir_uniform.h @@ -91,6 +91,7 @@ struct gl_opaque_uniform_index { struct gl_resource_name { char *string; + int length; /* strlen(string) or 0 */ }; struct gl_uniform_storage { diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index 0b4633a0d59..44a710d7ffa 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -5041,4 +5041,9 @@ done: void resource_name_updated(struct gl_resource_name *name) { + if (name->string) { + name->length = strlen(name->string); + } else { + name->length = 0; + } } diff --git a/src/mesa/main/program_resource.c b/src/mesa/main/program_resource.c index fda59c561b3..5ddacc7cab2 100644 --- a/src/mesa/main/program_resource.c +++ b/src/mesa/main/program_resource.c @@ -140,7 +140,7 @@ _mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface, if (shProg->data->ProgramResourceList[i].Type != programInterface) continue; unsigned len = - _mesa_program_resource_name_len(&shProg->data->ProgramResourceList[i]); + _mesa_program_resource_name_length_array(&shProg->data->ProgramResourceList[i]); *params = MAX2(*params, len + 1); } break; diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp index 15d503105e9..86813470434 100644 --- a/src/mesa/main/shader_query.cpp +++ b/src/mesa/main/shader_query.cpp @@ -286,8 +286,7 @@ _mesa_longest_attribute_name_length(struct gl_shader_program *shProg) * returned. If no active attributes exist, zero is returned. If * no name reflection information is available, one is returned." */ - const size_t length = RESOURCE_VAR(res)->name.string != NULL ? - strlen(RESOURCE_VAR(res)->name.string) : 0; + const size_t length = RESOURCE_VAR(res)->name.length; if (length >= longest) longest = length + 1; @@ -489,6 +488,84 @@ _mesa_program_resource_name(struct gl_program_resource *res) return NULL; } +int +_mesa_program_resource_name_length(struct gl_program_resource *res) +{ + switch (res->Type) { + case GL_UNIFORM_BLOCK: + case GL_SHADER_STORAGE_BLOCK: + return RESOURCE_UBO(res)->name.length; + case GL_TRANSFORM_FEEDBACK_VARYING: + return RESOURCE_XFV(res)->name.length; + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + return RESOURCE_VAR(res)->name.length; + case GL_UNIFORM: + case GL_BUFFER_VARIABLE: + return RESOURCE_UNI(res)->name.length; + case GL_VERTEX_SUBROUTINE_UNIFORM: + case GL_GEOMETRY_SUBROUTINE_UNIFORM: + case GL_FRAGMENT_SUBROUTINE_UNIFORM: + case GL_COMPUTE_SUBROUTINE_UNIFORM: + case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: + case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: + return RESOURCE_UNI(res)->name.length - MESA_SUBROUTINE_PREFIX_LEN; + case GL_VERTEX_SUBROUTINE: + case GL_GEOMETRY_SUBROUTINE: + case GL_FRAGMENT_SUBROUTINE: + case GL_COMPUTE_SUBROUTINE: + case GL_TESS_CONTROL_SUBROUTINE: + case GL_TESS_EVALUATION_SUBROUTINE: + return RESOURCE_SUB(res)->name.length; + default: + break; + } + return 0; +} + +bool +_mesa_program_get_resource_name(struct gl_program_resource *res, + struct gl_resource_name *out) +{ + switch (res->Type) { + case GL_UNIFORM_BLOCK: + case GL_SHADER_STORAGE_BLOCK: + *out = RESOURCE_UBO(res)->name; + return out->string != NULL; + case GL_TRANSFORM_FEEDBACK_VARYING: + *out = RESOURCE_XFV(res)->name; + return out->string != NULL; + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + *out = RESOURCE_VAR(res)->name; + return out->string != NULL; + case GL_UNIFORM: + case GL_BUFFER_VARIABLE: + *out = RESOURCE_UNI(res)->name; + return out->string != NULL; + case GL_VERTEX_SUBROUTINE_UNIFORM: + case GL_GEOMETRY_SUBROUTINE_UNIFORM: + case GL_FRAGMENT_SUBROUTINE_UNIFORM: + case GL_COMPUTE_SUBROUTINE_UNIFORM: + case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: + case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: + *out = RESOURCE_UNI(res)->name; + out->string += MESA_SUBROUTINE_PREFIX_LEN; + out->length -= MESA_SUBROUTINE_PREFIX_LEN; + assert(out->string); /* always non-NULL */ + return true; + case GL_VERTEX_SUBROUTINE: + case GL_GEOMETRY_SUBROUTINE: + case GL_FRAGMENT_SUBROUTINE: + case GL_COMPUTE_SUBROUTINE: + case GL_TESS_CONTROL_SUBROUTINE: + case GL_TESS_EVALUATION_SUBROUTINE: + *out = RESOURCE_SUB(res)->name; + return out->string != NULL; + default: + return false; + } +} unsigned _mesa_program_resource_array_size(struct gl_program_resource *res) @@ -611,16 +688,15 @@ _mesa_program_resource_find_name(struct gl_shader_program *shProg, if (res->Type != programInterface) continue; - /* Resource basename. */ - const char *rname = _mesa_program_resource_name(res); + struct gl_resource_name rname; /* Since ARB_gl_spirv lack of name reflections is a possibility */ - if (rname == NULL) + if (!_mesa_program_get_resource_name(res, &rname)) continue; - unsigned baselen = strlen(rname); + int baselen = rname.length; int baselen_without_array_index = baselen; - const char *rname_last_square_bracket = strrchr(rname, '['); + const char *rname_last_square_bracket = strrchr(rname.string, '['); bool found = false; bool rname_has_array_index_zero = false; /* From ARB_program_interface_query spec: @@ -649,16 +725,16 @@ _mesa_program_resource_find_name(struct gl_shader_program *shProg, * than the provided name's length. */ if (rname_last_square_bracket) { - baselen_without_array_index -= strlen(rname_last_square_bracket); + baselen_without_array_index -= rname_last_square_bracket - rname.string; rname_has_array_index_zero = (strcmp(rname_last_square_bracket, "[0]") == 0) && (baselen_without_array_index == len); } - if (strncmp(rname, name, baselen) == 0) + if (len >= baselen && strncmp(rname.string, name, baselen) == 0) found = true; else if (rname_has_array_index_zero && - strncmp(rname, name, baselen_without_array_index) == 0) + strncmp(rname.string, name, baselen_without_array_index) == 0) found = true; if (found) { @@ -960,17 +1036,16 @@ add_index_to_name(struct gl_program_resource *res) * base name + 3 for '[0]' if resource is an array. */ extern unsigned -_mesa_program_resource_name_len(struct gl_program_resource *res) +_mesa_program_resource_name_length_array(struct gl_program_resource *res) { - const char* name = _mesa_program_resource_name(res); + int length = _mesa_program_resource_name_length(res); /* For shaders constructed from SPIR-V binaries, variables may not * have names associated with them. */ - if (!name) + if (!length) return 0; - unsigned length = strlen(name); if (_mesa_program_resource_array_size(res) && add_index_to_name(res)) length += 3; return length; @@ -1385,7 +1460,7 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg, goto invalid_operation; default: /* Resource name length + terminator. */ - *val = _mesa_program_resource_name_len(res) + 1; + *val = _mesa_program_resource_name_length_array(res) + 1; } return 1; case GL_TYPE: @@ -1943,9 +2018,9 @@ _mesa_create_program_resource_hash(struct gl_shader_program *shProg) struct gl_program_resource *res = shProg->data->ProgramResourceList; for (unsigned i = 0; i < shProg->data->NumProgramResourceList; i++, res++) { - const char *name = _mesa_program_resource_name(res); - if (name) { - uint32_t key = compute_resource_key(res->Type, name, strlen(name)); + struct gl_resource_name name; + if (_mesa_program_get_resource_name(res, &name)) { + uint32_t key = compute_resource_key(res->Type, name.string, name.length); _mesa_hash_table_u64_insert(shProg->data->ProgramResourceHash, key, res); } diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index f1498fb44d3..c66ceeb470e 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -795,8 +795,7 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, * * We are setting 0 here, as below it will add 1 for the NUL character. */ - const GLint base_len = - strlen_or_zero(shProg->data->UniformStorage[i].name.string); + const GLint base_len = shProg->data->UniformStorage[i].name.length; /* Add one for the terminating NUL character for a non-array, and * 4 for the "[0]" and the NUL for an array. @@ -847,15 +846,17 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, shProg->TransformFeedback.NumVarying; for (i = 0; i < num_varying; i++) { - const char *name = in_shader_varyings ? - shProg->last_vert_prog->sh.LinkedTransformFeedback->Varyings[i].name.string - : shProg->TransformFeedback.VaryingNames[i]; + int len; /* Add one for the terminating NUL character. We have to use * strlen_or_zero, as for shaders constructed from SPIR-V binaries, * it is possible that no name reflection information is available. */ - const GLint len = strlen_or_zero(name) + 1; + if (in_shader_varyings) { + len = shProg->last_vert_prog->sh.LinkedTransformFeedback->Varyings[i].name.length + 1; + } else { + len = strlen_or_zero(shProg->TransformFeedback.VaryingNames[i]) + 1; + } if (len > max_len) max_len = len; @@ -919,8 +920,7 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, * zero is returned. If no name reflection information is * available, one is returned." */ - const GLint len = - strlen_or_zero(shProg->data->UniformBlocks[i].name.string) + 1; + const GLint len = shProg->data->UniformBlocks[i].name.length + 1; if (len > max_len) max_len = len; @@ -2979,7 +2979,7 @@ _mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype, case GL_UNIFORM_NAME_LENGTH: res = _mesa_program_resource_find_index(shProg, resource_type, index); if (res) { - values[0] = strlen(_mesa_program_resource_name(res)) + 1 + values[0] = _mesa_program_resource_name_length(res) + 1 + ((_mesa_program_resource_array_size(res) != 0) ? 3 : 0); } break; @@ -3224,7 +3224,7 @@ _mesa_GetProgramStageiv(GLuint program, GLenum shadertype, for (i = 0; i < p->sh.NumSubroutineFunctions; i++) { res = _mesa_program_resource_find_index(shProg, resource_type, i); if (res) { - const GLint len = strlen(_mesa_program_resource_name(res)) + 1; + const GLint len = _mesa_program_resource_name_length(res) + 1; if (len > max_len) max_len = len; } @@ -3243,7 +3243,7 @@ _mesa_GetProgramStageiv(GLuint program, GLenum shadertype, for (i = 0; i < p->sh.NumSubroutineUniformRemapTable; i++) { res = _mesa_program_resource_find_index(shProg, resource_type, i); if (res) { - const GLint len = strlen(_mesa_program_resource_name(res)) + 1 + const GLint len = _mesa_program_resource_name_length(res) + 1 + ((_mesa_program_resource_array_size(res) != 0) ? 3 : 0); if (len > max_len) diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h index 10ef268f8fd..13778a43a97 100644 --- a/src/mesa/main/shaderapi.h +++ b/src/mesa/main/shaderapi.h @@ -281,6 +281,13 @@ _mesa_CreateShaderProgramv(GLenum type, GLsizei count, extern const char* _mesa_program_resource_name(struct gl_program_resource *res); +int +_mesa_program_resource_name_length(struct gl_program_resource *res); + +bool +_mesa_program_get_resource_name(struct gl_program_resource *res, + struct gl_resource_name *out); + extern unsigned _mesa_program_resource_array_size(struct gl_program_resource *res); @@ -311,7 +318,7 @@ _mesa_get_program_resource_name(struct gl_shader_program *shProg, const char *caller); extern unsigned -_mesa_program_resource_name_len(struct gl_program_resource *res); +_mesa_program_resource_name_length_array(struct gl_program_resource *res); extern GLint _mesa_program_resource_location(struct gl_shader_program *shProg,