diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp index d457e4d0cd9..ac726f494a7 100644 --- a/src/glsl/link_uniforms.cpp +++ b/src/glsl/link_uniforms.cpp @@ -730,6 +730,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog) assert(sizeof(prog->SamplerTargets) == sizeof(parcel.targets)); memcpy(prog->SamplerTargets, parcel.targets, sizeof(prog->SamplerTargets)); + prog->UniformLocationBaseScale = (1U<<16); #ifndef NDEBUG for (unsigned i = 0; i < num_user_uniforms; i++) { diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 23c3a0d08b9..3e440f579be 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2418,6 +2418,21 @@ struct gl_shader_program struct gl_uniform_block *UniformBlocks; unsigned NumUniformBlocks; + /** + * Scale factor for the uniform base location + * + * This is used to generate locations (returned by \c glGetUniformLocation) + * of uniforms. The base location of the uniform is multiplied by this + * value, and the array index is added. + * + * \note + * Must be >= 1. + * + * \sa + * _mesa_uniform_merge_location_offset, _mesa_uniform_split_location_offset + */ + unsigned UniformLocationBaseScale; + /** * Indices into the _LinkedShaders's UniformBlocks[] array for each stage * they're used in, or -1. diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c index 59daff5bf0a..04943204faa 100644 --- a/src/mesa/main/shaderobj.c +++ b/src/mesa/main/shaderobj.c @@ -283,6 +283,7 @@ _mesa_clear_shader_program_data(struct gl_context *ctx, ralloc_free(shProg->UniformStorage); shProg->NumUserUniformStorage = 0; shProg->UniformStorage = NULL; + shProg->UniformLocationBaseScale = 0; } if (shProg->UniformHash) { diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h index 853a27ca747..421232db298 100644 --- a/src/mesa/main/uniforms.h +++ b/src/mesa/main/uniforms.h @@ -271,7 +271,9 @@ static inline GLint _mesa_uniform_merge_location_offset(const struct gl_shader_program *prog, unsigned base_location, unsigned offset) { - return (base_location << 16) | offset; + assert(prog->UniformLocationBaseScale >= 0); + assert(offset < prog->UniformLocationBaseScale); + return (base_location * prog->UniformLocationBaseScale) + offset; } /** @@ -282,8 +284,8 @@ _mesa_uniform_split_location_offset(const struct gl_shader_program *prog, GLint location, unsigned *base_location, unsigned *offset) { - *offset = location & 0xffff; - *base_location = location >> 16; + *offset = location % prog->UniformLocationBaseScale; + *base_location = location / prog->UniformLocationBaseScale; } /*@}*/