main: Remove interface block array index for doing the name comparison

From ARB_program_query_interface spec:

"uint GetProgramResourceIndex(uint program, enum programInterface,
                                   const char *name);
 [...]
 If <name> exactly matches the name string of one of the active resources
 for <programInterface>, the index of the matched resource is returned.
 Additionally, if <name> would exactly match the name string of an active
 resource if "[0]" were appended to <name>, the index of the matched
 resource is returned. [...]"

"A string provided to GetProgramResourceLocation or
 GetProgramResourceLocationIndex is considered to match an active variable
 if:
[...]
   * if the string identifies the base name of an active array, where the
     string would exactly match the name of the variable if the suffix
     "[0]" were appended to the string;
[...]
"

Fixes the following two dEQP-GLES31 tests:

dEQP-GLES31.functional.program_interface_query.shader_storage_block.resource_list.block_array
dEQP-GLES31.functional.program_interface_query.shader_storage_block.resource_list.block_array_single_element

v2:
- Add AoA support (Timothy)
- Apply it too for GetUniformLocation(), GetUniformName() and others
  because ARB_program_interface_query says that they are equivalent
  to GetProgramResourceLocation() and GetProgramResourceName() (Tapani)

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
This commit is contained in:
Samuel Iglesias Gonsalvez
2015-10-21 14:34:29 +02:00
parent 3359ad6cda
commit 4565b6f4fb
+42 -1
View File
@@ -543,8 +543,49 @@ _mesa_program_resource_find_name(struct gl_shader_program *shProg,
/* Resource basename. */
const char *rname = _mesa_program_resource_name(res);
unsigned baselen = strlen(rname);
unsigned baselen_without_array_index = baselen;
const char *rname_last_square_bracket = strrchr(rname, '[');
bool found = false;
bool rname_has_array_index_zero = false;
/* From ARB_program_interface_query spec:
*
* "uint GetProgramResourceIndex(uint program, enum programInterface,
* const char *name);
* [...]
* If <name> exactly matches the name string of one of the active
* resources for <programInterface>, the index of the matched resource is
* returned. Additionally, if <name> would exactly match the name string
* of an active resource if "[0]" were appended to <name>, the index of
* the matched resource is returned. [...]"
*
* "A string provided to GetProgramResourceLocation or
* GetProgramResourceLocationIndex is considered to match an active variable
* if:
*
* * the string exactly matches the name of the active variable;
*
* * if the string identifies the base name of an active array, where the
* string would exactly match the name of the variable if the suffix
* "[0]" were appended to the string; [...]"
*/
/* Remove array's index from interface block name comparison only if
* array's index is zero and the resulting string length is the same
* than the provided name's length.
*/
if (rname_last_square_bracket) {
baselen_without_array_index -= strlen(rname_last_square_bracket);
rname_has_array_index_zero =
(strncmp(rname_last_square_bracket, "[0]\0", 4) == 0) &&
(baselen_without_array_index == strlen(name));
}
if (strncmp(rname, name, baselen) == 0) {
if (strncmp(rname, name, baselen) == 0)
found = true;
else if (rname_has_array_index_zero &&
strncmp(rname, name, baselen_without_array_index) == 0)
found = true;
if (found) {
switch (programInterface) {
case GL_UNIFORM_BLOCK:
case GL_SHADER_STORAGE_BLOCK: