}
-/**
- * Generate a string describing the mode of a variable
- */
-static const char *
-mode_string(const ir_variable *var)
-{
- switch (var->mode) {
- case ir_var_auto:
- return (var->read_only) ? "global constant" : "global variable";
-
- case ir_var_uniform: return "uniform";
- case ir_var_shader_in: return "shader input";
- case ir_var_shader_out: return "shader output";
-
- case ir_var_const_in:
- case ir_var_temporary:
- default:
- assert(!"Should not get here.");
- return "invalid variable";
- }
-}
-
-
/**
* Perform validation of global variables used across multiple shaders
*/
existing->explicit_binding = true;
}
+ if (var->type->contains_atomic() &&
+ var->atomic.offset != existing->atomic.offset) {
+ linker_error(prog, "offset specifications for %s "
+ "`%s' have differing values\n",
+ mode_string(var), var->name);
+ return;
+ }
+
/* Validate layout qualifiers for gl_FragDepth.
*
* From the AMD/ARB_conservative_depth specs:
*/
static void fixup_type(const glsl_type **type, unsigned max_array_access)
{
- if ((*type)->is_array() && (*type)->length == 0) {
+ if ((*type)->is_unsized_array()) {
*type = glsl_type::get_array_instance((*type)->fields.array,
max_array_access + 1);
assert(*type != NULL);
{
for (unsigned i = 0; i < type->length; i++) {
const glsl_type *elem_type = type->fields.structure[i].type;
- if (elem_type->is_array() && elem_type->length == 0)
+ if (elem_type->is_unsized_array())
return true;
}
return false;
/* GL_ARB_uniform_buffer_object says that std140 uniforms
* will not be eliminated. Since we always do std140, just
* don't resize arrays in UBOs.
+ *
+ * Atomic counters are supposed to get deterministic
+ * locations assigned based on the declaration ordering and
+ * sizes, array compaction would mess that up.
*/
- if (var->is_in_uniform_block())
+ if (var->is_in_uniform_block() || var->type->contains_atomic())
continue;
unsigned int size = var->max_array_access;
prog->UniformBlockStageIndex[i] = NULL;
}
+ ralloc_free(prog->AtomicBuffers);
+ prog->AtomicBuffers = NULL;
+ prog->NumAtomicBuffers = 0;
+
/* Separate the shaders into groups based on their type.
*/
struct gl_shader **vert_shader_list;
if (prog->_LinkedShaders[i] == NULL)
continue;
- validate_interstage_interface_blocks(prog, prog->_LinkedShaders[prev],
- prog->_LinkedShaders[i]);
+ validate_interstage_inout_blocks(prog, prog->_LinkedShaders[prev],
+ prog->_LinkedShaders[i]);
if (!prog->LinkStatus)
goto done;
prev = i;
}
+ /* Cross-validate uniform blocks between shader stages */
+ validate_interstage_uniform_blocks(prog, prog->_LinkedShaders,
+ MESA_SHADER_TYPES);
+ if (!prog->LinkStatus)
+ goto done;
for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) {
if (prog->_LinkedShaders[i] != NULL)
update_array_sizes(prog);
link_assign_uniform_locations(prog);
+ link_assign_atomic_counter_resources(ctx, prog);
store_fragdepth_layout(prog);
check_resources(ctx, prog);
+ link_check_atomic_counter_resources(ctx, prog);
+
if (!prog->LinkStatus)
goto done;
if (prog->_LinkedShaders[i] == NULL)
continue;
+ /* Do a final validation step to make sure that the IR wasn't
+ * invalidated by any modifications performed after intrastage linking.
+ */
+ validate_ir_tree(prog->_LinkedShaders[i]->ir);
+
/* Retain any live IR, but trash the rest. */
reparent_ir(prog->_LinkedShaders[i]->ir, prog->_LinkedShaders[i]->ir);