From 5dc22cadb5ed4a7cf8c7d1cbaf7296c27e567e0f Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 9 Dec 2015 16:06:48 +1000 Subject: [PATCH] glsl: fix count_attribute_slots to allow for different 64-bit handling So vertex shader input attributes are handled different than internal varyings between shader stages, dvec3 and dvec4 only count as one slot for vertex attributes, but for internal varyings, they count as 2. This patch comments all the uses of this API to clarify what we pass in, except one which needs further investigation Signed-off-by: Dave Airlie Reviewed-by: Timothy Arceri --- src/glsl/ir_set_program_inouts.cpp | 7 ++++++- src/glsl/link_varyings.cpp | 6 ++++-- src/glsl/linker.cpp | 5 +++-- src/glsl/nir/glsl_types.cpp | 18 +++++++++++++----- src/glsl/nir/glsl_types.h | 5 ++++- 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/glsl/ir_set_program_inouts.cpp b/src/glsl/ir_set_program_inouts.cpp index 782f1b1ebc8..838b5e7cf08 100644 --- a/src/glsl/ir_set_program_inouts.cpp +++ b/src/glsl/ir_set_program_inouts.cpp @@ -146,6 +146,7 @@ void 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; @@ -169,7 +170,11 @@ ir_set_program_inouts_visitor::mark_whole_variable(ir_variable *var) 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); } diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp index 71750d1b42b..9f6467bd29b 100644 --- a/src/glsl/link_varyings.cpp +++ b/src/glsl/link_varyings.cpp @@ -1712,7 +1712,8 @@ check_against_output_limit(struct gl_context *ctx, 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); } } @@ -1753,7 +1754,8 @@ check_against_input_limit(struct gl_context *ctx, 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); } } diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 46d3d00d7fa..ff22b3df713 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -2466,7 +2466,7 @@ assign_attribute_or_color_locations(gl_shader_program *prog, 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 @@ -2995,7 +2995,8 @@ check_image_resources(struct gl_context *ctx, struct gl_shader_program *prog) 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); } } } diff --git a/src/glsl/nir/glsl_types.cpp b/src/glsl/nir/glsl_types.cpp index 3cf2f03f9ba..44d30565e4d 100644 --- a/src/glsl/nir/glsl_types.cpp +++ b/src/glsl/nir/glsl_types.cpp @@ -1640,7 +1640,7 @@ glsl_type::std430_size(bool row_major) const } 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: * @@ -1661,27 +1661,35 @@ glsl_type::count_attribute_slots() const * 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: diff --git a/src/glsl/nir/glsl_types.h b/src/glsl/nir/glsl_types.h index 26f25a1d3f3..0b837278cdd 100644 --- a/src/glsl/nir/glsl_types.h +++ b/src/glsl/nir/glsl_types.h @@ -324,8 +324,11 @@ struct glsl_type { * 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 -- 2.30.2