Beispiel #1
0
/**
 * Checks if array subscript is valid and if so sets array_index.
 */
static bool
valid_array_index(const GLchar *name, unsigned *array_index)
{
   long idx = 0;
   const GLchar *out_base_name_end;

   idx = parse_program_resource_name(name, &out_base_name_end);
   if (idx < 0)
      return false;

   if (array_index)
      *array_index = idx;

   return true;
}
Beispiel #2
0
/**
 * Called via glGetUniformLocation().
 *
 * Returns the uniform index into UniformStorage (also the
 * glGetActiveUniformsiv uniform index), and stores the referenced
 * array offset in *offset, or GL_INVALID_INDEX (-1).
 */
extern "C" unsigned
_mesa_get_uniform_location(struct gl_shader_program *shProg,
                           const GLchar *name,
                           unsigned *out_offset)
{
   /* Page 80 (page 94 of the PDF) of the OpenGL 2.1 spec says:
    *
    *     "The first element of a uniform array is identified using the
    *     name of the uniform array appended with "[0]". Except if the last
    *     part of the string name indicates a uniform array, then the
    *     location of the first element of that array can be retrieved by
    *     either using the name of the uniform array, or the name of the
    *     uniform array appended with "[0]"."
    *
    * Note: since uniform names are not allowed to use whitespace, and array
    * indices within uniform names are not allowed to use "+", "-", or leading
    * zeros, it follows that each uniform has a unique name up to the possible
    * ambiguity with "[0]" noted above.  Therefore we don't need to worry
    * about mal-formed inputs--they will properly fail when we try to look up
    * the uniform name in shProg->UniformHash.
    */

   const GLchar *base_name_end;
   long offset = parse_program_resource_name(name, &base_name_end);
   bool array_lookup = offset >= 0;
   char *name_copy;

   if (array_lookup) {
      name_copy = (char *) malloc(base_name_end - name + 1);
      memcpy(name_copy, name, base_name_end - name);
      name_copy[base_name_end - name] = '\0';
   } else {
      name_copy = (char *) name;
      offset = 0;
   }

   unsigned location = 0;
   const bool found = shProg->UniformHash->get(location, name_copy);

   assert(!found
	  || strcmp(name_copy, shProg->UniformStorage[location].name) == 0);

   /* Free the temporary buffer *before* possibly returning an error.
    */
   if (name_copy != name)
      free(name_copy);

   if (!found)
      return GL_INVALID_INDEX;

   /* If the uniform is an array, fail if the index is out of bounds.
    * (A negative index is caught above.)  This also fails if the uniform
    * is not an array, but the user is trying to index it, because
    * array_elements is zero and offset >= 0.
    */
   if (array_lookup
       && offset >= (long) shProg->UniformStorage[location].array_elements) {
      return GL_INVALID_INDEX;
   }

   *out_offset = offset;
   return location;
}