diff options
Diffstat (limited to 'src/mesa/main/uniforms.h')
-rw-r--r-- | src/mesa/main/uniforms.h | 51 |
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 */ |