[Mesa-dev] [PATCH v2 04/24] mesa: glGetProgramInterfaceiv

Martin Peres martin.peres at linux.intel.com
Mon Apr 13 02:27:25 PDT 2015


On 01/04/15 15:14, Tapani Pälli wrote:
> Patch adds required helper functions to shaderapi.h and
> the actual implementation.
>
> v2: code cleanup (Ilia Mirkin)
>      fix array size fo xfb varyings
>      validate programInterface and throw error
>
> corresponding Piglit test:
>     arb_program_interface_query-getprograminterfaceiv
>
> Signed-off-by: Tapani Pälli <tapani.palli at intel.com>
> ---
>   src/mesa/main/program_resource.c | 119 +++++++++++++++++++++++++++++++++++++++
>   src/mesa/main/shader_query.cpp   |  59 +++++++++++++++++++
>   src/mesa/main/shaderapi.h        |   7 +++
>   3 files changed, 185 insertions(+)
>
> diff --git a/src/mesa/main/program_resource.c b/src/mesa/main/program_resource.c
> index b3b93aa..0da934a 100644
> --- a/src/mesa/main/program_resource.c
> +++ b/src/mesa/main/program_resource.c
> @@ -23,12 +23,131 @@
>    *
>    */
>   
> +#include "main/enums.h"
> +#include "main/macros.h"
> +#include "main/mtypes.h"
> +#include "main/shaderapi.h"
> +#include "main/shaderobj.h"
>   #include "program_resource.h"
>   
> +static bool
> +supported_interface_enum(GLenum iface)
> +{
> +   switch (iface) {
> +   case GL_UNIFORM:
> +   case GL_UNIFORM_BLOCK:
> +   case GL_PROGRAM_INPUT:
> +   case GL_PROGRAM_OUTPUT:
> +   case GL_TRANSFORM_FEEDBACK_VARYING:
> +   case GL_ATOMIC_COUNTER_BUFFER:
> +      return true;
> +   case GL_VERTEX_SUBROUTINE:
> +   case GL_TESS_CONTROL_SUBROUTINE:
> +   case GL_TESS_EVALUATION_SUBROUTINE:
> +   case GL_GEOMETRY_SUBROUTINE:
> +   case GL_FRAGMENT_SUBROUTINE:
> +   case GL_COMPUTE_SUBROUTINE:
> +   case GL_VERTEX_SUBROUTINE_UNIFORM:
> +   case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
> +   case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
> +   case GL_GEOMETRY_SUBROUTINE_UNIFORM:
> +   case GL_FRAGMENT_SUBROUTINE_UNIFORM:
> +   case GL_COMPUTE_SUBROUTINE_UNIFORM:
> +   case GL_BUFFER_VARIABLE:
> +   case GL_SHADER_STORAGE_BLOCK:
Thanks for doing this :)
> +   default:
> +      return false;
> +   }
> +}
> +
>   void GLAPIENTRY
>   _mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface,
>                               GLenum pname, GLint *params)
>   {
> +   GET_CURRENT_CONTEXT(ctx);
> +   unsigned i;
> +   struct gl_shader_program *shProg =
> +      _mesa_lookup_shader_program_err(ctx, program,
> +                                      "glGetProgramInterfaceiv");
> +   if (!shProg)
> +      return;
> +
> +   if (!params) {
> +      _mesa_error(ctx, GL_INVALID_OPERATION,
> +                  "glGetProgramInterfaceiv(params NULL)");
> +      return;
> +   }
> +
> +   /* Validate interface. */
> +   if (!supported_interface_enum(programInterface)) {
> +      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramInterfaceiv(%s)",
> +                  _mesa_lookup_enum_by_nr(programInterface));
> +      return;
> +   }
> +
> +   /* Validate pname against interface. */
> +   switch(pname) {
> +   case GL_ACTIVE_RESOURCES:
> +      for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++)
> +         if (shProg->ProgramResourceList[i].Type == programInterface)
> +            (*params)++;
> +      break;
> +   case GL_MAX_NAME_LENGTH:
> +      if (programInterface == GL_ATOMIC_COUNTER_BUFFER) {
> +         _mesa_error(ctx, GL_INVALID_OPERATION,
> +                     "glGetProgramInterfaceiv(%s pname %s)",
> +                     _mesa_lookup_enum_by_nr(programInterface),
> +                     _mesa_lookup_enum_by_nr(pname));
> +         return;
> +      }
> +      /* Name length consists of base name, 3 additional chars '[0]' if
> +       * resource is an array and finally 1 char for string terminator.
> +       */
> +      for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++) {
> +         if (shProg->ProgramResourceList[i].Type != programInterface)
> +            continue;
> +         const char *name =
> +            _mesa_program_resource_name(&shProg->ProgramResourceList[i]);
> +         unsigned array_size =
> +            _mesa_program_resource_array_size(&shProg->ProgramResourceList[i]);
> +         *params = MAX2(*params, strlen(name) + (array_size ? 3 : 0) + 1);
> +      }
> +      break;
> +   case GL_MAX_NUM_ACTIVE_VARIABLES:
> +      switch (programInterface) {
> +      case GL_UNIFORM_BLOCK:
> +         for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++) {
> +            if (shProg->ProgramResourceList[i].Type == programInterface) {
> +               struct gl_uniform_block *block =
> +                  (struct gl_uniform_block *)
> +                  shProg->ProgramResourceList[i].Data;
> +               *params = MAX2(*params, block->NumUniforms);
> +            }
> +         }
> +         break;
> +      case GL_ATOMIC_COUNTER_BUFFER:
> +         for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++) {
> +            if (shProg->ProgramResourceList[i].Type == programInterface) {
> +               struct gl_active_atomic_buffer *buffer =
> +                  (struct gl_active_atomic_buffer *)
> +                  shProg->ProgramResourceList[i].Data;
> +               *params = MAX2(*params, buffer->NumUniforms);
> +            }
> +         }
> +         break;
> +      case GL_MAX_NUM_COMPATIBLE_SUBROUTINES:
Why did you add GL_MAX_NUM_COMPATIBLE_SUBROUTINE here?
> +      default:
> +        _mesa_error(ctx, GL_INVALID_OPERATION,
> +                    "glGetProgramInterfaceiv(%s pname %s)",
> +                    _mesa_lookup_enum_by_nr(programInterface),
> +                    _mesa_lookup_enum_by_nr(pname));
> +      };
> +      break;
> +   default:
> +      _mesa_error(ctx, GL_INVALID_OPERATION,
> +                  "glGetProgramInterfaceiv(pname %s)",
> +                  _mesa_lookup_enum_by_nr(pname));
> +   }
>   }
>   
>   GLuint GLAPIENTRY
> diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp
> index df9081b..4e0247e 100644
> --- a/src/mesa/main/shader_query.cpp
> +++ b/src/mesa/main/shader_query.cpp
> @@ -34,11 +34,29 @@
>   #include "shaderobj.h"
>   #include "program/hash_table.h"
>   #include "../glsl/program.h"
> +#include "uniforms.h"
> +#include "main/enums.h"
>   
>   extern "C" {
>   #include "shaderapi.h"
>   }
>   
> +/**
> + * Declare convenience functions to return resource data in a given type.
> + * Warning! this is not type safe so be *very* careful when using these.
> + */
> +#define DECL_RESOURCE_FUNC(name, type) \
> +const type * RESOURCE_ ## name (gl_program_resource *res) { \
> +   assert(res->Data); \
> +   return (type *) res->Data; \
> +}
> +
> +DECL_RESOURCE_FUNC(VAR, ir_variable);
> +DECL_RESOURCE_FUNC(UBO, gl_uniform_block);
> +DECL_RESOURCE_FUNC(UNI, gl_uniform_storage);
> +DECL_RESOURCE_FUNC(ATC, gl_active_atomic_buffer);
> +DECL_RESOURCE_FUNC(XFB, gl_transform_feedback_varying_info);
> +
>   void GLAPIENTRY
>   _mesa_BindAttribLocation(GLhandleARB program, GLuint index,
>                               const GLcharARB *name)
> @@ -498,3 +516,44 @@ _mesa_GetFragDataLocation(GLuint program, const GLchar *name)
>   
>      return -1;
>   }
> +
> +const char*
> +_mesa_program_resource_name(struct gl_program_resource *res)
> +{
> +   switch (res->Type) {
> +   case GL_UNIFORM_BLOCK:
> +      return RESOURCE_UBO(res)->Name;
> +   case GL_TRANSFORM_FEEDBACK_VARYING:
> +      return RESOURCE_XFB(res)->Name;
> +   case GL_PROGRAM_INPUT:
> +   case GL_PROGRAM_OUTPUT:
> +      return RESOURCE_VAR(res)->name;
> +   case GL_UNIFORM:
> +      return RESOURCE_UNI(res)->name;
> +   default:
> +      assert(!"support for resource type not implemented");
> +   }
> +   return NULL;
> +}
> +
> +
> +unsigned
> +_mesa_program_resource_array_size(struct gl_program_resource *res)
> +{
> +   switch (res->Type) {
> +   case GL_TRANSFORM_FEEDBACK_VARYING:
> +      return RESOURCE_XFB(res)->Size > 1 ?
> +             RESOURCE_XFB(res)->Size : 0;
> +   case GL_PROGRAM_INPUT:
> +   case GL_PROGRAM_OUTPUT:
> +      return RESOURCE_VAR(res)->data.max_array_access;
> +   case GL_UNIFORM:
> +      return RESOURCE_UNI(res)->array_elements;
> +   case GL_ATOMIC_COUNTER_BUFFER:
> +   case GL_UNIFORM_BLOCK:
> +      return 0;
> +   default:
> +      assert(!"support for resource type not implemented");
> +   }
> +   return 0;
> +}
> diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h
> index 047d256..6db52f7 100644
> --- a/src/mesa/main/shaderapi.h
> +++ b/src/mesa/main/shaderapi.h
> @@ -219,6 +219,13 @@ extern GLuint GLAPIENTRY
>   _mesa_CreateShaderProgramv(GLenum type, GLsizei count,
>                              const GLchar* const *strings);
>   
> +/* GL_ARB_program_resource_query */
> +extern const char*
> +_mesa_program_resource_name(struct gl_program_resource *res);
> +
> +extern unsigned
> +_mesa_program_resource_array_size(struct gl_program_resource *res);
> +
>   #ifdef __cplusplus
>   }
>   #endif

Looks good to me:
Reviewed-by: Martin Peres <martin.peres at linux.intel.com>


More information about the mesa-dev mailing list