summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/main/shader_query.cpp43
1 files changed, 42 insertions, 1 deletions
diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp
index 84cbfbcd4af..59ec3d7f693 100644
--- a/src/mesa/main/shader_query.cpp
+++ b/src/mesa/main/shader_query.cpp
@@ -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)
+ found = true;
+ else if (rname_has_array_index_zero &&
+ strncmp(rname, name, baselen_without_array_index) == 0)
+ found = true;
- if (strncmp(rname, name, baselen) == 0) {
+ if (found) {
switch (programInterface) {
case GL_UNIFORM_BLOCK:
case GL_SHADER_STORAGE_BLOCK: