[Mesa-dev] [PATCH v2 06/24] mesa: glGetProgramResourceName

Matt Turner mattst88 at gmail.com
Mon Apr 20 18:51:22 PDT 2015


On Wed, Apr 1, 2015 at 5:14 AM, Tapani Pälli <tapani.palli at intel.com> wrote:
> Patch adds required helper functions to shaderapi.h and
> the actual implementation.
>
> Name generation copied from '_mesa_get_uniform_name' which can
> be removed later by refactoring functions to use resource list.
>
> The added functionality can be tested by tests for following
> functions that are refactored by later patches:
>
>    GetActiveUniformName
>    GetActiveUniformBlockName
>
> v2: no index for geometry shader inputs (Ilia Mirkin)
>     add bufSize < 0 check and error out
>     validate enum
>
> Signed-off-by: Tapani Pälli <tapani.palli at intel.com>
> ---
>  src/mesa/main/program_resource.c |  23 +++++++++
>  src/mesa/main/shader_query.cpp   | 106 +++++++++++++++++++++++++++++++++++++++
>  src/mesa/main/shaderapi.h        |  10 ++++
>  3 files changed, 139 insertions(+)
>
> diff --git a/src/mesa/main/program_resource.c b/src/mesa/main/program_resource.c
> index 72cc558..638f5f2 100644
> --- a/src/mesa/main/program_resource.c
> +++ b/src/mesa/main/program_resource.c
> @@ -245,6 +245,29 @@ _mesa_GetProgramResourceName(GLuint program, GLenum programInterface,
>                               GLuint index, GLsizei bufSize, GLsizei *length,
>                               GLchar *name)
>  {
> +   GET_CURRENT_CONTEXT(ctx);
> +   struct gl_shader_program *shProg =
> +      _mesa_lookup_shader_program_err(ctx, program,
> +                                      "glGetProgramResourceName");
> +
> +   /* Set user friendly return values in case of errors. */
> +   if (name)
> +      *name = '\0';
> +   if (length)
> +      *length = 0;
> +
> +   if (!shProg || !name)
> +      return;
> +
> +   if (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
> +       !supported_interface_enum(programInterface)) {
> +      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceName(%s)",
> +                  _mesa_lookup_enum_by_nr(programInterface));
> +      return;
> +   }
> +
> +   _mesa_get_program_resource_name(shProg, programInterface, index, bufSize,
> +                                   length, name, "glGetProgramResourceName");
>  }
>
>  void GLAPIENTRY
> diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp
> index 61eec68..ab61be9 100644
> --- a/src/mesa/main/shader_query.cpp
> +++ b/src/mesa/main/shader_query.cpp
> @@ -648,3 +648,109 @@ _mesa_program_resource_index(struct gl_shader_program *shProg,
>        return calc_resource_index(shProg, res);
>     }
>  }
> +
> +/* Find a program resource with specific index in given interface.
> + */
> +struct gl_program_resource *
> +_mesa_program_resource_find_index(struct gl_shader_program *shProg,
> +                                  GLenum interface, GLuint index)
> +{
> +   struct gl_program_resource *res = shProg->ProgramResourceList;
> +   int idx = -1;
> +
> +   for (unsigned i = 0; i < shProg->NumProgramResourceList; i++, res++) {
> +      if (res->Type != interface)
> +         continue;
> +
> +      switch (res->Type) {
> +      case GL_UNIFORM_BLOCK:
> +      case GL_ATOMIC_COUNTER_BUFFER:
> +         if (_mesa_program_resource_index(shProg, res) == index)
> +            return res;
> +

Coverity warns about this fallthrough. Please mark it with /*
fallthrough */ if it's indeed intended.

> +      case GL_TRANSFORM_FEEDBACK_VARYING:
> +      case GL_PROGRAM_INPUT:
> +      case GL_PROGRAM_OUTPUT:
> +      case GL_UNIFORM:
> +         if (++idx == (int) index)
> +            return res;
> +         break;
> +      default:
> +         assert(!"not implemented for given interface");
> +      }
> +   }
> +   return NULL;
> +}
> +
> +/* Get full name of a program resource.
> + */
> +bool
> +_mesa_get_program_resource_name(struct gl_shader_program *shProg,
> +                                GLenum interface, GLuint index,
> +                                GLsizei bufSize, GLsizei *length,
> +                                GLchar *name, const char *caller)
> +{
> +   GET_CURRENT_CONTEXT(ctx);
> +
> +   /* Find resource with given interface and index. */
> +   struct gl_program_resource *res =
> +      _mesa_program_resource_find_index(shProg, interface, index);
> +
> +   /* The error INVALID_VALUE is generated if <index> is greater than
> +   * or equal to the number of entries in the active resource list for
> +   * <programInterface>.
> +   */
> +   if (!res) {
> +      _mesa_error(ctx, GL_INVALID_VALUE, "%s(index %u)", caller, index);
> +      return false;
> +   }
> +
> +   if (bufSize < 0) {
> +      _mesa_error(ctx, GL_INVALID_VALUE, "%s(bufSize %d)", caller, bufSize);
> +      return false;
> +   }
> +
> +   GLsizei localLength;
> +
> +   if (length == NULL)
> +      length = &localLength;
> +
> +   _mesa_copy_string(name, bufSize, length, _mesa_program_resource_name(res));
> +
> +   /* Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0
> +    * spec says:
> +    *
> +    *     "If the active uniform is an array, the uniform name returned in
> +    *     name will always be the name of the uniform array appended with
> +    *     "[0]"."
> +    *
> +    * The same text also appears in the OpenGL 4.2 spec.  It does not,
> +    * however, appear in any previous spec.  Previous specifications are
> +    * ambiguous in this regard.  However, either name can later be passed
> +    * to glGetUniformLocation (and related APIs), so there shouldn't be any
> +    * harm in always appending "[0]" to uniform array names.
> +    *
> +    * Geometry shader stage has different naming convention where the 'normal'
> +    * condition is an array, therefore for variables referenced in geometry
> +    * stage we do not add '[0]'.
> +    *
> +    * Note, that TCS outputs and TES inputs should not have index appended
> +    * either.
> +    */
> +   bool add_index = !(((interface == GL_PROGRAM_INPUT) &&
> +                       res->StageReferences & (1 << MESA_SHADER_GEOMETRY)));
> +
> +   if (add_index && _mesa_program_resource_array_size(res)) {
> +      int i;
> +
> +      /* The comparison is strange because *length does *NOT* include the
> +       * terminating NUL, but maxLength does.
> +       */
> +      for (i = 0; i < 3 && (*length + i + 1) < bufSize; i++)
> +         name[*length + i] = "[0]"[i];
> +
> +      name[*length + i] = '\0';
> +      *length += i;
> +   }
> +   return true;
> +}
> diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h
> index d80252b..7a7e3e9 100644
> --- a/src/mesa/main/shaderapi.h
> +++ b/src/mesa/main/shaderapi.h
> @@ -234,6 +234,16 @@ extern struct gl_program_resource *
>  _mesa_program_resource_find_name(struct gl_shader_program *shProg,
>                                   GLenum interface, const char *name);
>
> +extern struct gl_program_resource *
> +_mesa_program_resource_find_index(struct gl_shader_program *shProg,
> +                                  GLenum interface, GLuint index);
> +
> +extern bool
> +_mesa_get_program_resource_name(struct gl_shader_program *shProg,
> +                                GLenum interface, GLuint index,
> +                                GLsizei bufSize, GLsizei *length,
> +                                GLchar *name, const char *caller);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> --
> 2.1.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list