glsl: Handle the binding qualifier for arrays of samplers.

Normally, uniform array variables are initialized by array literals.
That is, val->type->array_elements >= storage->array_elements.

However, samplers are different.  Consider a declaration such as:

   layout(binding = 5) uniform sampler2D[3];

The initializer value is a single integer (5), while the storage has 3
array elements.  The proper behavior here is to increment one for each
element; they should be initialized to 5, 6, and 7.

This patch introduces new code for sampler types which handles both
arrays of samplers and single samplers correctly.

v2: Move into the other function; use binding, not constant_value.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Acked-by: Paul Berry <stereotype441@gmail.com>
This commit is contained in:
Kenneth Graunke 2013-07-17 11:24:11 -07:00
parent 67038c6ba2
commit 34e2ccc9f0
1 changed files with 25 additions and 0 deletions

View File

@ -93,6 +93,31 @@ set_uniform_binding(void *mem_ctx, gl_shader_program *prog,
return;
}
if (storage->type->is_sampler()) {
unsigned elements = MAX2(storage->array_elements, 1);
/* From section 4.4.4 of the GLSL 4.20 specification:
* "If the binding identifier is used with an array, the first element
* of the array takes the specified unit and each subsequent element
* takes the next consecutive unit."
*/
for (unsigned int i = 0; i < elements; i++) {
storage->storage[i].i = binding + i;
}
for (int sh = 0; sh < MESA_SHADER_TYPES; sh++) {
gl_shader *shader = prog->_LinkedShaders[sh];
if (shader && storage->sampler[sh].active) {
for (unsigned i = 0; i < elements; i++) {
unsigned index = storage->sampler[sh].index + i;
shader->SamplerUnits[index] = storage->storage[i].i;
}
}
}
}
storage->initialized = true;
}