Mesa (master): glsl: change uniform location/offset encoding

Brian Paul brianp at kemper.freedesktop.org
Fri May 28 18:53:26 UTC 2010


Module: Mesa
Branch: master
Commit: 5d0e136eff54a34258b5adaeda4cb267831e8234
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5d0e136eff54a34258b5adaeda4cb267831e8234

Author: Brian Paul <brianp at vmware.com>
Date:   Fri May 28 12:52:34 2010 -0600

glsl: change uniform location/offset encoding

This lets Mesa work like other OpenGL implementations with regard
to indexing uniform arrays.  See comments for details.

Note: this is a candidate for the 7.8 branch.

---

 src/mesa/shader/uniforms.c |   38 ++++++++++++++++++++++++++++++--------
 1 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/src/mesa/shader/uniforms.c b/src/mesa/shader/uniforms.c
index 2753223..69758ea 100644
--- a/src/mesa/shader/uniforms.c
+++ b/src/mesa/shader/uniforms.c
@@ -378,16 +378,38 @@ _mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
 
 
 /**
- * The value returned by GetUniformLocation actually encodes two things:
- * 1. the index into the prog->Uniforms[] array for the uniform
- * 2. an offset in the prog->ParameterValues[] array for specifying array
- *    elements or structure fields.
- * This function merges those two values.
+ * GLGL 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.
  */
 static void
 merge_location_offset(GLint *location, GLint offset)
 {
-   *location = *location | (offset << 16);
+   *location = (*location << 16) | offset;
 }
 
 
@@ -397,8 +419,8 @@ merge_location_offset(GLint *location, GLint offset)
 static void
 split_location_offset(GLint *location, GLint *offset)
 {
-   *offset = (*location >> 16);
-   *location = *location & 0xffff;
+   *offset = *location & 0xffff;
+   *location = *location >> 16;
 }
 
 




More information about the mesa-commit mailing list