return false;
}
+ } else if (state->is_version(420, 310) &&
+ var->type->without_array()->is_image()) {
+ assert(ctx->Const.MaxImageUnits <= MAX_IMAGE_UNITS);
+ if (max_index >= ctx->Const.MaxImageUnits) {
+ _mesa_glsl_error(loc, state, "Image binding %d exceeds the "
+ " maximum number of image units (%d)", max_index,
+ ctx->Const.MaxImageUnits);
+ return false;
+ }
+
} else {
_mesa_glsl_error(loc, state,
"the \"binding\" qualifier only applies to uniform "
- "blocks, samplers, atomic counters, or arrays thereof");
+ "blocks, opaque variables, or arrays thereof");
return false;
}
}
}
+/**
+ * Initialize an opaque uniform from the value of an explicit binding
+ * qualifier specified in the shader. Atomic counters are different because
+ * they have no storage and should be handled elsewhere.
+ */
void
-set_sampler_binding(gl_shader_program *prog, const char *name, int binding)
+set_opaque_binding(gl_shader_program *prog, const char *name, int binding)
{
struct gl_uniform_storage *const storage =
get_storage(prog->UniformStorage, prog->NumUniformStorage, name);
for (int sh = 0; sh < MESA_SHADER_STAGES; 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;
+ if (shader) {
+ if (storage->type->base_type == GLSL_TYPE_SAMPLER &&
+ storage->sampler[sh].active) {
+ for (unsigned i = 0; i < elements; i++) {
+ const unsigned index = storage->sampler[sh].index + i;
+ shader->SamplerUnits[index] = storage->storage[i].i;
+ }
- shader->SamplerUnits[index] = storage->storage[i].i;
+ } else if (storage->type->base_type == GLSL_TYPE_IMAGE &&
+ storage->image[sh].active) {
+ for (unsigned i = 0; i < elements; i++) {
+ const unsigned index = storage->image[sh].index + i;
+ shader->ImageUnits[index] = storage->storage[i].i;
+ }
}
}
}
if (var->data.explicit_binding) {
const glsl_type *const type = var->type;
- if (type->without_array()->is_sampler()) {
- linker::set_sampler_binding(prog, var->name, var->data.binding);
+ if (type->without_array()->is_sampler() ||
+ type->without_array()->is_image()) {
+ linker::set_opaque_binding(prog, var->name, var->data.binding);
} else if (var->is_in_buffer_block()) {
const glsl_type *const iface_type = var->get_interface_type();