[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