On Fri, Mar 13, 2015 at 4:37 AM, Tapani Pälli <tapani.pa...@intel.com> wrote: > Patch adds required helper functions to shaderapi.h and > the actual implementation. > > corresponding Piglit test: > arb_program_interface_query-resource-location > > The added functionality can be tested by tests for following > functions that are refactored by later patches: > > GetAttribLocation > GetUniformLocation > GetFragDataLocation > > Signed-off-by: Tapani Pälli <tapani.pa...@intel.com> > --- > src/mesa/main/program_resource.c | 81 > +++++++++++++++++++++++++++++++++++++++- > src/mesa/main/shader_query.cpp | 64 +++++++++++++++++++++++++++++++ > src/mesa/main/shaderapi.h | 4 ++ > 3 files changed, 148 insertions(+), 1 deletion(-) > > diff --git a/src/mesa/main/program_resource.c > b/src/mesa/main/program_resource.c > index 4fa6ac6..87a0144 100644 > --- a/src/mesa/main/program_resource.c > +++ b/src/mesa/main/program_resource.c > @@ -243,11 +243,90 @@ _mesa_GetProgramResourceiv(GLuint program, GLenum > programInterface, > { > } > > +/** > + * Function verifies syntax of given name for GetProgramResourceLocation > + * and GetProgramResourceLocationIndex for the following cases: > + * > + * "array element portion of a string passed to GetProgramResourceLocation > + * or GetProgramResourceLocationIndex must not have, a "+" sign, extra > + * leading zeroes, or whitespace". > + * > + * Check is written to be compatible with GL_ARB_array_of_arrays. > + */ > +static bool > +invalid_array_element_syntax(const GLchar *name) > +{ > + char *array = strrchr(name, '['); > + > + if (!array) > + return false; > + > + /* No '+' or ' ' allowed anywhere. */ > + if (strchr(name, '+') || strchr(name, ' '))
I guess it'd be mildly better to do a strchr('[') and use that for the second strchr's? You could do it like char *first = strchr(name, '['); char *last = strrchr(first, '['); if (strchr(first, '+') || ... ) That way you avoid iterating over the "name" portion of it unnecessarily. Probably doesn't amount to too much. > + return true; > + > + /* Check that last array index is 0. */ > + if (array[1] == '0' && array[2] != ']') > + return true; > + > + return false; > +} > + > +static struct gl_shader_program * > +lookup_linked_program(GLuint program, const char *caller) > +{ > + GET_CURRENT_CONTEXT(ctx); > + struct gl_shader_program *prog = > + _mesa_lookup_shader_program_err(ctx, program, caller); > + > + if (!prog) > + return NULL; > + > + if (prog->LinkStatus == GL_FALSE) { > + _mesa_error(ctx, GL_INVALID_OPERATION, > + "%s(program not linked)", caller); > + return NULL; > + } > + return prog; > +} > + > GLint GLAPIENTRY > _mesa_GetProgramResourceLocation(GLuint program, GLenum programInterface, > const GLchar *name) > { > - return -1; > + GET_CURRENT_CONTEXT(ctx); > + struct gl_shader_program *shProg = > + lookup_linked_program(program, "glGetProgramResourceLocation"); > + > + if (!shProg || invalid_array_element_syntax(name)) > + return -1; > + > + /* Validate programInterface. */ > + switch (programInterface) { > + case GL_UNIFORM: > + case GL_PROGRAM_INPUT: > + case GL_PROGRAM_OUTPUT: > + break; > + > + /* For reference valid cases requiring addition extension support: > + * GL_ARB_shader_subroutine > + * GL_ARB_tessellation_shader > + * GL_ARB_compute_shader > + */ > + 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: > + > + default: > + _mesa_error(ctx, GL_INVALID_ENUM, > + "glGetProgramResourceLocation(%s %s)", > + _mesa_lookup_enum_by_nr(programInterface), name); > + } > + > + return _mesa_program_resource_location(shProg, programInterface, name); > } > > GLint GLAPIENTRY > diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp > index 77a4af0..4ae00a6 100644 > --- a/src/mesa/main/shader_query.cpp > +++ b/src/mesa/main/shader_query.cpp > @@ -743,3 +743,67 @@ _mesa_get_program_resource_name(struct gl_shader_program > *shProg, > } > return true; > } > + > +static GLint > +program_resource_location(struct gl_shader_program *shProg, > + struct gl_program_resource *res, const char *name) > +{ > + unsigned index, offset; > + int array_index = -1; And I suppose leaving off the initializer here makes gcc complain? > + > + if (res->Type == GL_PROGRAM_INPUT || > + res->Type == GL_PROGRAM_OUTPUT) { put all on one line? > + array_index = array_index_of_resource(res, name); > + if (array_index < 0) > + return -1; > + } > + > + switch (res->Type) { > + case GL_PROGRAM_INPUT: > + return RESOURCE_VAR(res)->data.location + array_index - > VERT_ATTRIB_GENERIC0; > + case GL_PROGRAM_OUTPUT: > + return RESOURCE_VAR(res)->data.location + array_index - > FRAG_RESULT_DATA0; > + case GL_UNIFORM: > + index = _mesa_get_uniform_location(shProg, name, &offset); > + > + if (index == GL_INVALID_INDEX) > + return -1; > + > + /* From the GL_ARB_uniform_buffer_object spec: > + * > + * "The value -1 will be returned if <name> does not correspond to > an > + * active uniform variable name in <program>, if <name> is > associated > + * with a named uniform block, or if <name> starts with the > reserved > + * prefix "gl_"." > + */ > + if (RESOURCE_UNI(res)->block_index != -1 || > + RESOURCE_UNI(res)->atomic_buffer_index != -1) > + return -1; > + > + /* location in remap table + array element offset */ > + return RESOURCE_UNI(res)->remap_location + offset; > + > + default: > + return -1; > + } > +} > + > +/** > + * Function implements following location queries: > + * glGetAttribLocation > + * glGetFragDataLocation > + * glGetUniformLocation > + */ > +GLint > +_mesa_program_resource_location(struct gl_shader_program *shProg, > + GLenum interface, const char *name) > +{ > + struct gl_program_resource *res = > + _mesa_program_resource_find_name(shProg, interface, name); > + > + /* Resource not found. */ > + if (!res) > + return -1; > + > + return program_resource_location(shProg, res, name); > +} > diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h > index 7a7e3e9..73ebf60 100644 > --- a/src/mesa/main/shaderapi.h > +++ b/src/mesa/main/shaderapi.h > @@ -244,6 +244,10 @@ _mesa_get_program_resource_name(struct gl_shader_program > *shProg, > GLsizei bufSize, GLsizei *length, > GLchar *name, const char *caller); > > +extern GLint > +_mesa_program_resource_location(struct gl_shader_program *shProg, > + GLenum interface, const char *name); > + > #ifdef __cplusplus > } > #endif > -- > 2.1.0 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev