diff options
author | Dave Airlie <airlied@redhat.com> | 2015-12-09 16:06:48 +1000 |
---|---|---|
committer | Emil Velikov <emil.l.velikov@gmail.com> | 2016-01-08 12:05:26 +0200 |
commit | 343fc2c3a33a4967fcc75bf1cc5b3baffba8fa5d (patch) | |
tree | 35b6f2f699942abcb565073d72a300d6c0465c32 | |
parent | 703ad597483c3bb6e26aa2e173382f7f7a129534 (diff) |
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 <airlied@redhat.com>
Reviewed-by: Timothy Arceri <timothy.arceri@collabora.com>
(cherry picked from commit 5dc22cadb5ed4a7cf8c7d1cbaf7296c27e567e0f)
-rw-r--r-- | src/glsl/ir_set_program_inouts.cpp | 7 | ||||
-rw-r--r-- | src/glsl/link_varyings.cpp | 6 | ||||
-rw-r--r-- | src/glsl/linker.cpp | 5 | ||||
-rw-r--r-- | src/glsl/nir/glsl_types.cpp | 18 | ||||
-rw-r--r-- | 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 782f1b1ebc..838b5e7cf0 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 560906a3ea..269cfd5d29 100644 --- a/src/glsl/link_varyings.cpp +++ b/src/glsl/link_varyings.cpp @@ -1710,7 +1710,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); } } @@ -1751,7 +1752,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 3faee7a190..bccd4d4d7f 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -2473,7 +2473,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 @@ -2964,7 +2964,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 9cc3715db8..a7cbaea000 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 26f25a1d3f..0b837278cd 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 |