summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/uniforms.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main/uniforms.h')
-rw-r--r--src/mesa/main/uniforms.h51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h
index 5c1ddedf7a4..3630ad0eeb7 100644
--- a/src/mesa/main/uniforms.h
+++ b/src/mesa/main/uniforms.h
@@ -212,4 +212,55 @@ struct gl_builtin_uniform_desc {
extern const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[];
+/**
+ * \name GLSL uniform arrays and structs require special handling.
+ *
+ * The GL_ARB_shader_objects spec says that if you use
+ * glGetUniformLocation to get the location of an array, you CANNOT
+ * access other elements of the array by adding an offset to the
+ * returned location. For example, you must call
+ * glGetUniformLocation("foo[16]") if you want to set the 16th element
+ * of the array with glUniform().
+ *
+ * HOWEVER, some other OpenGL drivers allow accessing array elements
+ * by adding an offset to the returned array location. And some apps
+ * seem to depend on that behaviour.
+ *
+ * Mesa's gl_uniform_list doesn't directly support this since each
+ * entry in the list describes one uniform variable, not one uniform
+ * element. We could insert dummy entries in the list for each array
+ * element after [0] but that causes complications elsewhere.
+ *
+ * We solve this problem by encoding two values in the location that's
+ * returned by glGetUniformLocation():
+ * a) index into gl_uniform_list::Uniforms[] for the uniform
+ * b) an array/field offset (0 for simple types)
+ *
+ * These two values are encoded in the high and low halves of a GLint.
+ * By putting the uniform number in the high part and the offset in the
+ * low part, we can support the unofficial ability to index into arrays
+ * by adding offsets to the location value.
+ */
+/*@{*/
+/**
+ * Combine the uniform's base location and the offset
+ */
+static inline GLint
+_mesa_uniform_merge_location_offset(unsigned base_location, unsigned offset)
+{
+ return (base_location << 16) | offset;
+}
+
+/**
+ * Separate the uniform base location and parameter offset
+ */
+static inline void
+_mesa_uniform_split_location_offset(GLint location, unsigned *base_location,
+ unsigned *offset)
+{
+ *offset = location & 0xffff;
+ *base_location = location >> 16;
+}
+/*@}*/
+
#endif /* UNIFORMS_H */