Mesa (main): mesa: precompute strlen in gl_resource_name::length and use it

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Oct 29 12:03:49 UTC 2021


Module: Mesa
Branch: main
Commit: 22d51f3c92285efcdb47019aa445d8f4535f4b14
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=22d51f3c92285efcdb47019aa445d8f4535f4b14

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Fri Oct 22 19:22:53 2021 -0400

mesa: precompute strlen in gl_resource_name::length and use it

Reviewed-by: Timothy Arceri <tarceri at itsqueeze.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13507>

---

 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,



More information about the mesa-commit mailing list