[Mesa-dev] [PATCH 01/20] mesa: fix and simplify resource query for arrays

Timothy Arceri t_arceri at yahoo.com.au
Wed Jul 29 22:50:31 PDT 2015



On 30 July 2015 3:27:41 pm AEST, "Tapani Pälli" <tapani.palli at intel.com> wrote:
>On 07/30/2015 08:25 AM, Tapani Pälli wrote:
>> Hi Timothy;
>>
>> Would it be OK for you to wait a bit with these 3 first patches? I'm 
>> currently going through failing PIQ tests and I have a 1 line fix to 
>> valid_program_resource_index_name() that together with your patch 
>> "glsl: set stage flag for structs and arrays in resource list" will 
>> fix all of the failing "ES31-CTS.program_interface_query.uniform" 
>> tests. Frankly I don't see the value of such a big refactor necessary
>
>> for this.

The value is in removing almost 200 lines of complicated code trying to solve the same problem in different ways. How its this not a good thing? 

Also once this is done we can also work towards removing UniformHash from Mesa.




>>
>
>Woops, make it "ES31-CTS.program_interface_query.uniform-types", not 
>"ES31-CTS.program_interface_query.uniform". It looks to me that most 
>tests fail just because of not figuring out the correct index for the 
>resource and that can be fixed by a valid_program_resource_index_name 
>change.
>
>
>>
>> On 07/29/2015 04:56 PM, Timothy Arceri wrote:
>>> This removes the need for multiple functions designed to validate an
>
>>> array
>>> subscript and replaces them with a call to a single function.
>>>
>>> The change also means that validation is now only done once and the 
>>> index
>>> is retrived at the same time, as a result the getUniformLocation
>code 
>>> can
>>> be simplified saving an extra hash table lookup (and yet another
>>> validation call).
>>>
>>> This chage also fixes some tests in:
>>> ES31-CTS.program_interface_query.uniform
>>>
>>> V3: rebase on subroutines, and move the resource index array == 0
>>> check into _mesa_GetProgramResourceIndex() to simplify things
>further
>>>
>>> V2: Fix bounds checks for program input/output, split unrelated 
>>> comment fix
>>> and _mesa_get_uniform_location() removal into their own patch.
>>>
>>> Cc: Tapani Pälli <tapani.palli at intel.com>
>>> ---
>>>   src/mesa/main/program_resource.c |  14 ++--
>>>   src/mesa/main/shader_query.cpp   | 174 
>>> +++++++++++++++++++++------------------
>>>   src/mesa/main/shaderapi.c        |   2 +-
>>>   src/mesa/main/shaderapi.h        |   3 +-
>>>   src/mesa/main/uniforms.c         |   5 +-
>>>   5 files changed, 106 insertions(+), 92 deletions(-)
>>>
>>> diff --git a/src/mesa/main/program_resource.c 
>>> b/src/mesa/main/program_resource.c
>>> index 641ef22..fdbd5b3 100644
>>> --- a/src/mesa/main/program_resource.c
>>> +++ b/src/mesa/main/program_resource.c
>>> @@ -229,6 +229,7 @@ _mesa_GetProgramResourceIndex(GLuint program, 
>>> GLenum programInterface,
>>>                                 const GLchar *name)
>>>   {
>>>      GET_CURRENT_CONTEXT(ctx);
>>> +   unsigned array_index = 0;
>>>      struct gl_program_resource *res;
>>>      struct gl_shader_program *shProg =
>>>         _mesa_lookup_shader_program_err(ctx, program,
>>> @@ -268,13 +269,10 @@ _mesa_GetProgramResourceIndex(GLuint program, 
>>> GLenum programInterface,
>>>      case GL_PROGRAM_OUTPUT:
>>>      case GL_UNIFORM:
>>>      case GL_TRANSFORM_FEEDBACK_VARYING:
>>> -      /* Validate name syntax for array variables */
>>> -      if (!valid_program_resource_index_name(name))
>>> -         return GL_INVALID_INDEX;
>>> -      /* fall-through */
>>>      case GL_UNIFORM_BLOCK:
>>> -      res = _mesa_program_resource_find_name(shProg, 
>>> programInterface, name);
>>> -      if (!res)
>>> +      res = _mesa_program_resource_find_name(shProg, 
>>> programInterface, name,
>>> +                                             &array_index);
>>> +      if (!res || array_index > 0)
>>>            return GL_INVALID_INDEX;
>>>           return _mesa_program_resource_index(shProg, res);
>>> @@ -403,7 +401,7 @@ _mesa_GetProgramResourceLocation(GLuint program,
>
>>> GLenum programInterface,
>>>      struct gl_shader_program *shProg =
>>>         lookup_linked_program(program,
>"glGetProgramResourceLocation");
>>>   -   if (!shProg || !name || invalid_array_element_syntax(name))
>>> +   if (!shProg || !name)
>>>         return -1;
>>>        /* Validate programInterface. */
>>> @@ -453,7 +451,7 @@ _mesa_GetProgramResourceLocationIndex(GLuint 
>>> program, GLenum programInterface,
>>>      struct gl_shader_program *shProg =
>>>         lookup_linked_program(program, 
>>> "glGetProgramResourceLocationIndex");
>>>   -   if (!shProg || !name || invalid_array_element_syntax(name))
>>> +   if (!shProg || !name)
>>>         return -1;
>>>        /* From the GL_ARB_program_interface_query spec:
>>> diff --git a/src/mesa/main/shader_query.cpp 
>>> b/src/mesa/main/shader_query.cpp
>>> index 3e52a09..dd11b81 100644
>>> --- a/src/mesa/main/shader_query.cpp
>>> +++ b/src/mesa/main/shader_query.cpp
>>> @@ -44,7 +44,8 @@ extern "C" {
>>>     static GLint
>>>   program_resource_location(struct gl_shader_program *shProg,
>>> -                          struct gl_program_resource *res, const 
>>> char *name);
>>> +                          struct gl_program_resource *res, const 
>>> char *name,
>>> +                          unsigned array_index);
>>>     /**
>>>    * Declare convenience functions to return resource data in a
>given 
>>> type.
>>> @@ -272,13 +273,15 @@ _mesa_GetAttribLocation(GLhandleARB program, 
>>> const GLcharARB * name)
>>>      if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL)
>>>         return -1;
>>>   +   unsigned array_index = 0;
>>>      struct gl_program_resource *res =
>>> -      _mesa_program_resource_find_name(shProg, GL_PROGRAM_INPUT,
>name);
>>> +      _mesa_program_resource_find_name(shProg, GL_PROGRAM_INPUT,
>name,
>>> +                                       &array_index);
>>>        if (!res)
>>>         return -1;
>>>   -   GLint loc = program_resource_location(shProg, res, name);
>>> +   GLint loc = program_resource_location(shProg, res, name, 
>>> array_index);
>>>        /* The extra check against against 0 is made because of 
>>> builtin-attribute
>>>       * locations that have offset applied. Function 
>>> program_resource_location
>>> @@ -456,13 +459,15 @@ _mesa_GetFragDataLocation(GLuint program,
>const 
>>> GLchar *name)
>>>      if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)
>>>         return -1;
>>>   +   unsigned array_index = 0;
>>>      struct gl_program_resource *res =
>>> -      _mesa_program_resource_find_name(shProg, GL_PROGRAM_OUTPUT, 
>>> name);
>>> +      _mesa_program_resource_find_name(shProg, GL_PROGRAM_OUTPUT,
>name,
>>> +                                       &array_index);
>>>        if (!res)
>>>         return -1;
>>>   -   GLint loc = program_resource_location(shProg, res, name);
>>> +   GLint loc = program_resource_location(shProg, res, name, 
>>> array_index);
>>>        /* The extra check against against 0 is made because of 
>>> builtin-attribute
>>>       * locations that have offset applied. Function 
>>> program_resource_location
>>> @@ -552,39 +557,32 @@ _mesa_program_resource_array_size(struct 
>>> gl_program_resource *res)
>>>      return 0;
>>>   }
>>>   -static int
>>> -array_index_of_resource(struct gl_program_resource *res,
>>> -                        const char *name)
>>> +/**
>>> + * Checks if array subscript is valid and if so sets array_index.
>>> + */
>>> +static bool
>>> +valid_array_index(const GLchar *name, unsigned *array_index)
>>>   {
>>> -   assert(res->Data);
>>> +   unsigned idx = 0;
>>> +   const GLchar *out_base_name_end;
>>>   -   switch (res->Type) {
>>> -   case GL_PROGRAM_INPUT:
>>> -   case GL_PROGRAM_OUTPUT:
>>> -      return get_matching_index(RESOURCE_VAR(res), name);
>>> -   default:
>>> -      assert(!"support for resource type not implemented");
>>> -      return -1;
>>> -   }
>>> +   idx = parse_program_resource_name(name, &out_base_name_end);
>>> +   if (idx < 0)
>>> +      return false;
>>> +
>>> +   if (array_index)
>>> +      *array_index = idx;
>>> +
>>> +   return true;
>>>   }
>>>     /* Find a program resource with specific name in given
>interface.
>>>    */
>>>   struct gl_program_resource *
>>>   _mesa_program_resource_find_name(struct gl_shader_program *shProg,
>>> -                                 GLenum programInterface, const
>char 
>>> *name)
>>> +                                 GLenum programInterface, const
>char 
>>> *name,
>>> +                                 unsigned *array_index)
>>>   {
>>> -   GET_CURRENT_CONTEXT(ctx);
>>> -   const char *full_name = name;
>>> -
>>> -   /* When context has 'VertexID_is_zero_based' set, gl_VertexID
>has 
>>> been
>>> -    * lowered to gl_VertexIDMESA.
>>> -    */
>>> -   if (name && ctx->Const.VertexID_is_zero_based) {
>>> -      if (strcmp(name, "gl_VertexID") == 0)
>>> -         full_name = "gl_VertexIDMESA";
>>> -   }
>>> -
>>>      struct gl_program_resource *res = shProg->ProgramResourceList;
>>>      for (unsigned i = 0; i < shProg->NumProgramResourceList; i++, 
>>> res++) {
>>>         if (res->Type != programInterface)
>>> @@ -594,38 +592,46 @@ _mesa_program_resource_find_name(struct 
>>> gl_shader_program *shProg,
>>>         const char *rname = _mesa_program_resource_name(res);
>>>         unsigned baselen = strlen(rname);
>>>   -      switch (programInterface) {
>>> -      case GL_TRANSFORM_FEEDBACK_VARYING:
>>> -      case GL_UNIFORM_BLOCK:
>>> -      case GL_UNIFORM:
>>> -      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:
>>> -      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:
>>> -         if (strncmp(rname, name, baselen) == 0) {
>>> +      if (strncmp(rname, name, baselen) == 0) {
>>> +         switch (programInterface) {
>>> +         case GL_UNIFORM_BLOCK:
>>>               /* Basename match, check if array or struct. */
>>>               if (name[baselen] == '\0' ||
>>>                   name[baselen] == '[' ||
>>>                   name[baselen] == '.') {
>>>                  return res;
>>>               }
>>> +            break;
>>> +         case GL_TRANSFORM_FEEDBACK_VARYING:
>>> +         case GL_UNIFORM:
>>> +         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:
>>> +         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:
>>> +            if (name[baselen] == '.') {
>>> +               return res;
>>> +            }
>>> +            /* fall-through */
>>> +         case GL_PROGRAM_INPUT:
>>> +         case GL_PROGRAM_OUTPUT:
>>> +            if (name[baselen] == '\0') {
>>> +               return res;
>>> +            } else if (name[baselen] == '[' &&
>>> +                valid_array_index(name, array_index)) {
>>> +               return res;
>>> +            }
>>> +            break;
>>> +         default:
>>> +            assert(!"not implemented for given interface");
>>>            }
>>> -         break;
>>> -      case GL_PROGRAM_INPUT:
>>> -      case GL_PROGRAM_OUTPUT:
>>> -         if (array_index_of_resource(res, full_name) >= 0)
>>> -            return res;
>>> -         break;
>>> -      default:
>>> -         assert(!"not implemented for given interface");
>>>         }
>>>      }
>>>      return NULL;
>>> @@ -787,19 +793,9 @@ _mesa_get_program_resource_name(struct 
>>> gl_shader_program *shProg,
>>>     static GLint
>>>   program_resource_location(struct gl_shader_program *shProg,
>>> -                          struct gl_program_resource *res, const 
>>> char *name)
>>> +                          struct gl_program_resource *res, const 
>>> char *name,
>>> +                          unsigned array_index)
>>>   {
>>> -   unsigned index, offset;
>>> -   int array_index = -1;
>>> -   long offset_ret;
>>> -   const GLchar *base_name_end;
>>> -
>>> -   if (res->Type == GL_PROGRAM_INPUT || res->Type == 
>>> GL_PROGRAM_OUTPUT) {
>>> -      array_index = array_index_of_resource(res, name);
>>> -      if (array_index < 0)
>>> -         return -1;
>>> -   }
>>> -
>>>      /* Built-in locations should report GL_INVALID_INDEX. */
>>>      if (is_gl_identifier(name))
>>>         return GL_INVALID_INDEX;
>>> @@ -810,13 +806,22 @@ program_resource_location(struct 
>>> gl_shader_program *shProg,
>>>       */
>>>      switch (res->Type) {
>>>      case GL_PROGRAM_INPUT:
>>> +      /* If the input is an array, fail if the index is out of 
>>> bounds. */
>>> +      if (array_index > 0
>>> +          && array_index >= RESOURCE_VAR(res)->type->length) {
>>> +         return -1;
>>> +      }
>>>         return RESOURCE_VAR(res)->data.location + array_index - 
>>> VERT_ATTRIB_GENERIC0;
>>>      case GL_PROGRAM_OUTPUT:
>>> +      /* If the output is an array, fail if the index is out of 
>>> bounds. */
>>> +      if (array_index > 0
>>> +          && array_index >= RESOURCE_VAR(res)->type->length) {
>>> +         return -1;
>>> +      }
>>>         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)
>>> +      /* If the uniform is built-in, fail. */
>>> +      if (RESOURCE_UNI(res)->builtin)
>>>            return -1;
>>>           /* From the GL_ARB_uniform_buffer_object spec:
>>> @@ -830,17 +835,21 @@ program_resource_location(struct 
>>> gl_shader_program *shProg,
>>>             RESOURCE_UNI(res)->atomic_buffer_index != -1)
>>>            return -1;
>>>   -      /* location in remap table + array element offset */
>>> -      return RESOURCE_UNI(res)->remap_location + offset;
>>> -
>>> +      /* fallthrough */
>>>      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:
>>> -      offset_ret = parse_program_resource_name(name,
>&base_name_end);
>>> -      return RESOURCE_UNI(res)->remap_location + ((offset_ret !=
>-1) 
>>> ? offset_ret : 0);
>>> +      /* If the uniform is an array, fail if the index is out of 
>>> bounds. */
>>> +      if (array_index > 0
>>> +          && array_index >= RESOURCE_UNI(res)->array_elements) {
>>> +         return -1;
>>> +      }
>>> +
>>> +      /* location in remap table + array element offset */
>>> +      return RESOURCE_UNI(res)->remap_location + array_index;
>>>      default:
>>>         return -1;
>>>      }
>>> @@ -854,14 +863,16 @@ GLint
>>>   _mesa_program_resource_location(struct gl_shader_program *shProg,
>>>                                   GLenum programInterface, const
>char 
>>> *name)
>>>   {
>>> +   unsigned array_index = 0;
>>>      struct gl_program_resource *res =
>>> -      _mesa_program_resource_find_name(shProg, programInterface,
>name);
>>> +      _mesa_program_resource_find_name(shProg, programInterface,
>name,
>>> +                                       &array_index);
>>>        /* Resource not found. */
>>>      if (!res)
>>>         return -1;
>>>   -   return program_resource_location(shProg, res, name);
>>> +   return program_resource_location(shProg, res, name,
>array_index);
>>>   }
>>>     /**
>>> @@ -873,7 +884,7 @@ _mesa_program_resource_location_index(struct 
>>> gl_shader_program *shProg,
>>>                                         GLenum programInterface, 
>>> const char *name)
>>>   {
>>>      struct gl_program_resource *res =
>>> -      _mesa_program_resource_find_name(shProg, programInterface,
>name);
>>> +      _mesa_program_resource_find_name(shProg, programInterface, 
>>> name, NULL);
>>>        /* Non-existent variable or resource is not referenced by 
>>> fragment stage. */
>>>      if (!res || !(res->StageReferences & (1 <<
>MESA_SHADER_FRAGMENT)))
>>> @@ -949,7 +960,8 @@ get_buffer_property(struct gl_shader_program 
>>> *shProg,
>>>            for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; 
>>> i++) {
>>>               const char *iname = 
>>> RESOURCE_UBO(res)->Uniforms[i].IndexName;
>>>               struct gl_program_resource *uni =
>>> -               _mesa_program_resource_find_name(shProg, GL_UNIFORM,
>
>>> iname);
>>> +               _mesa_program_resource_find_name(shProg, GL_UNIFORM,
>
>>> iname,
>>> +                                                NULL);
>>>               if (!uni)
>>>                  continue;
>>>               (*val)++;
>>> @@ -959,7 +971,8 @@ get_buffer_property(struct gl_shader_program 
>>> *shProg,
>>>            for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; 
>>> i++) {
>>>               const char *iname = 
>>> RESOURCE_UBO(res)->Uniforms[i].IndexName;
>>>               struct gl_program_resource *uni =
>>> -               _mesa_program_resource_find_name(shProg, GL_UNIFORM,
>
>>> iname);
>>> +               _mesa_program_resource_find_name(shProg, GL_UNIFORM,
>
>>> iname,
>>> +                                                NULL);
>>>               if (!uni)
>>>                  continue;
>>>               *val++ =
>>> @@ -1099,7 +1112,8 @@ _mesa_program_resource_prop(struct 
>>> gl_shader_program *shProg,
>>>         case GL_PROGRAM_INPUT:
>>>         case GL_PROGRAM_OUTPUT:
>>>            *val = program_resource_location(shProg, res,
>>> - _mesa_program_resource_name(res));
>>> + _mesa_program_resource_name(res),
>>> +                                          0);
>>>            return 1;
>>>         default:
>>>            goto invalid_operation;
>>> diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
>>> index 0887c68..b702dcd 100644
>>> --- a/src/mesa/main/shaderapi.c
>>> +++ b/src/mesa/main/shaderapi.c
>>> @@ -2229,7 +2229,7 @@ _mesa_GetSubroutineIndex(GLuint program,
>GLenum 
>>> shadertype,
>>>      }
>>>        resource_type = _mesa_shader_stage_to_subroutine(stage);
>>> -   res = _mesa_program_resource_find_name(shProg, resource_type,
>name);
>>> +   res = _mesa_program_resource_find_name(shProg, resource_type, 
>>> name, NULL);
>>>      if (!res) {
>>>         _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
>>>        return -1;
>>> diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h
>>> index c081f74..0a10191 100644
>>> --- a/src/mesa/main/shaderapi.h
>>> +++ b/src/mesa/main/shaderapi.h
>>> @@ -232,7 +232,8 @@ _mesa_program_resource_index(struct 
>>> gl_shader_program *shProg,
>>>     extern struct gl_program_resource *
>>>   _mesa_program_resource_find_name(struct gl_shader_program *shProg,
>>> -                                 GLenum programInterface, const
>char 
>>> *name);
>>> +                                 GLenum programInterface, const
>char 
>>> *name,
>>> +                                 unsigned *array_index);
>>>     extern struct gl_program_resource *
>>>   _mesa_program_resource_find_index(struct gl_shader_program
>*shProg,
>>> diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c
>>> index 6ba746e..ff1df72 100644
>>> --- a/src/mesa/main/uniforms.c
>>> +++ b/src/mesa/main/uniforms.c
>>> @@ -952,7 +952,7 @@ _mesa_GetUniformBlockIndex(GLuint program,
>>>        struct gl_program_resource *res =
>>>         _mesa_program_resource_find_name(shProg, GL_UNIFORM_BLOCK,
>>> -                                       uniformBlockName);
>>> +                                       uniformBlockName, NULL);
>>>      if (!res)
>>>         return GL_INVALID_INDEX;
>>>   @@ -987,7 +987,8 @@ _mesa_GetUniformIndices(GLuint program,
>>>        for (i = 0; i < uniformCount; i++) {
>>>         struct gl_program_resource *res =
>>> -         _mesa_program_resource_find_name(shProg, GL_UNIFORM, 
>>> uniformNames[i]);
>>> +         _mesa_program_resource_find_name(shProg, GL_UNIFORM, 
>>> uniformNames[i],
>>> +                                          NULL);
>>>         uniformIndices[i] = _mesa_program_resource_index(shProg,
>res);
>>>      }
>>>   }
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.


More information about the mesa-dev mailing list