ir_set_program_inouts_visitor::mark_whole_variable(ir_variable *var)
{
const glsl_type *type = var->type;
+ bool vertex_input = false;
if (this->shader_stage == MESA_SHADER_GEOMETRY &&
var->data.mode == ir_var_shader_in && type->is_array()) {
type = type->fields.array;
type = type->fields.array;
}
- mark(this->prog, var, 0, type->count_attribute_slots(),
+ if (this->shader_stage == MESA_SHADER_VERTEX &&
+ var->data.mode == ir_var_shader_in)
+ vertex_input = true;
+
+ mark(this->prog, var, 0, type->count_attribute_slots(vertex_input),
this->shader_stage);
}
if (var && var->data.mode == ir_var_shader_out &&
var_counts_against_varying_limit(producer->Stage, var)) {
- output_vectors += var->type->count_attribute_slots();
+ /* outputs for fragment shader can't be doubles */
+ output_vectors += var->type->count_attribute_slots(false);
}
}
if (var && var->data.mode == ir_var_shader_in &&
var_counts_against_varying_limit(consumer->Stage, var)) {
- input_vectors += var->type->count_attribute_slots();
+ /* vertex inputs aren't varying counted */
+ input_vectors += var->type->count_attribute_slots(false);
}
}
return false;
}
- const unsigned slots = var->type->count_attribute_slots();
+ const unsigned slots = var->type->count_attribute_slots(false);
/* If the variable is not a built-in and has a location statically
* assigned in the shader (presumably via a layout qualifier), make sure
foreach_in_list(ir_instruction, node, sh->ir) {
ir_variable *var = node->as_variable();
if (var && var->data.mode == ir_var_shader_out)
- fragment_outputs += var->type->count_attribute_slots();
+ /* since there are no double fs outputs - pass false */
+ fragment_outputs += var->type->count_attribute_slots(false);
}
}
}
}
unsigned
-glsl_type::count_attribute_slots() const
+glsl_type::count_attribute_slots(bool vertex_input_slots) const
{
/* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
*
* allows varying structs, the number of varying slots taken up by a
* varying struct is simply equal to the sum of the number of slots taken
* up by each element.
+ *
+ * Doubles are counted different depending on whether they are vertex
+ * inputs or everything else. Vertex inputs from ARB_vertex_attrib_64bit
+ * take one location no matter what size they are, otherwise dvec3/4
+ * take two locations.
*/
switch (this->base_type) {
case GLSL_TYPE_UINT:
case GLSL_TYPE_INT:
case GLSL_TYPE_FLOAT:
case GLSL_TYPE_BOOL:
- case GLSL_TYPE_DOUBLE:
return this->matrix_columns;
-
+ case GLSL_TYPE_DOUBLE:
+ if (this->vector_elements > 2 && !vertex_input_slots)
+ return this->matrix_columns * 2;
+ else
+ return this->matrix_columns;
case GLSL_TYPE_STRUCT:
case GLSL_TYPE_INTERFACE: {
unsigned size = 0;
for (unsigned i = 0; i < this->length; i++)
- size += this->fields.structure[i].type->count_attribute_slots();
+ size += this->fields.structure[i].type->count_attribute_slots(vertex_input_slots);
return size;
}
case GLSL_TYPE_ARRAY:
- return this->length * this->fields.array->count_attribute_slots();
+ return this->length * this->fields.array->count_attribute_slots(vertex_input_slots);
case GLSL_TYPE_SAMPLER:
case GLSL_TYPE_IMAGE:
* varying slots the type will use up in the absence of varying packing
* (and thus, it can be used to measure the number of varying slots used by
* the varyings that are generated by lower_packed_varyings).
+ *
+ * For vertex shader attributes - doubles only take one slot.
+ * For inter-shader varyings - dvec3/dvec4 take two slots.
*/
- unsigned count_attribute_slots() const;
+ unsigned count_attribute_slots(bool vertex_input_slots) const;
/**
* Alignment in bytes of the start of this type in a std140 uniform