summaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
authorPaul Berry <[email protected]>2013-01-28 14:21:59 -0800
committerPaul Berry <[email protected]>2013-02-08 11:17:17 -0800
commit49a5f829f7fe4c4b1985b18dcf9e92ae590d913e (patch)
tree4a396495bfa208603ed7ca68d8d0a3ae4868fd0c /src/glsl
parent5265c42e52b304d3d63dc2a8fbb5d835ad79a7ac (diff)
mesa/glsl: Separate parsing logic from _mesa_get_uniform_location.
The parsing logic is moved to a new function in the GLSL module, parse_program_resource_name(). This name was chosen because it should eventually be useful for handling everything that OpenGL 4.3 calls "program resources" (e.g. uniforms, vertex inputs, fragment outputs, and transform feedback varyings). Future patches will make use of this function for linking transform feedback varyings. NOTE: This is a candidate for the 9.1 branch. Reviewed-by: Jordan Justen <[email protected]> Reviewed-by: Matt Turner <[email protected]> (cherry picked from commit b92900d26a54ef997f2920d6a7371bb7c9caabf8)
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/linker.cpp59
-rw-r--r--src/glsl/program.h4
2 files changed, 63 insertions, 0 deletions
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 63ce178f44c..57e7a9ad369 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -200,6 +200,65 @@ linker_warning(gl_shader_program *prog, const char *fmt, ...)
}
+/**
+ * Given a string identifying a program resource, break it into a base name
+ * and an optional array index in square brackets.
+ *
+ * If an array index is present, \c out_base_name_end is set to point to the
+ * "[" that precedes the array index, and the array index itself is returned
+ * as a long.
+ *
+ * If no array index is present (or if the array index is negative or
+ * mal-formed), \c out_base_name_end, is set to point to the null terminator
+ * at the end of the input string, and -1 is returned.
+ *
+ * Only the final array index is parsed; if the string contains other array
+ * indices (or structure field accesses), they are left in the base name.
+ *
+ * No attempt is made to check that the base name is properly formed;
+ * typically the caller will look up the base name in a hash table, so
+ * ill-formed base names simply turn into hash table lookup failures.
+ */
+long
+parse_program_resource_name(const GLchar *name,
+ const GLchar **out_base_name_end)
+{
+ /* Section 7.3.1 ("Program Interfaces") of the OpenGL 4.3 spec says:
+ *
+ * "When an integer array element or block instance number is part of
+ * the name string, it will be specified in decimal form without a "+"
+ * or "-" sign or any extra leading zeroes. Additionally, the name
+ * string will not include white space anywhere in the string."
+ */
+
+ const size_t len = strlen(name);
+ *out_base_name_end = name + len;
+
+ if (len == 0 || name[len-1] != ']')
+ return -1;
+
+ /* Walk backwards over the string looking for a non-digit character. This
+ * had better be the opening bracket for an array index.
+ *
+ * Initially, i specifies the location of the ']'. Since the string may
+ * contain only the ']' charcater, walk backwards very carefully.
+ */
+ unsigned i;
+ for (i = len - 1; (i > 0) && isdigit(name[i-1]); --i)
+ /* empty */ ;
+
+ if ((i == 0) || name[i-1] != '[')
+ return -1;
+
+ long array_index = strtol(&name[i], NULL, 10);
+ if (array_index < 0)
+ return -1;
+
+ *out_base_name_end = name + (i - 1);
+ return array_index;
+}
+
+
void
link_invalidate_variable_locations(gl_shader *sh, int input_base,
int output_base)
diff --git a/src/glsl/program.h b/src/glsl/program.h
index 437ca1462fa..46ce9dcccd8 100644
--- a/src/glsl/program.h
+++ b/src/glsl/program.h
@@ -33,3 +33,7 @@ linker_error(gl_shader_program *prog, const char *fmt, ...)
extern void
linker_warning(gl_shader_program *prog, const char *fmt, ...)
PRINTFLIKE(2, 3);
+
+extern long
+parse_program_resource_name(const GLchar *name,
+ const GLchar **out_base_name_end);