This patch implements varying packing between varyings. Previously, each varying occupied components 0 through N-1 of its assigned varying slot, so there was no way to pack two varyings into the same slot. For example, if the varyings were a float, a vec2, a vec3, and another vec2, they would be stored as follows:
<----slot1----> <----slot2----> <----slot3----> <----slot4----> slots * * * * * * * * * * * * * * * * flt x x x <vec2-> x x <--vec3---> x <vec3-> x x varyings (Each * represents a varying component, and the "x"s represent wasted space). This change packs the varyings together to eliminate wasted space between varyings, like so: <----slot1----> <----slot2----> <----slot3----> <----slot4----> slots * * * * * * * * * * * * * * * * <vec2-> <vec2-> flt <--vec3---> x x x x x x x x varyings Note that we take advantage of the sort order introduced in previous patches (vec4's first, then vec2's, then scalars, then vec3's) to minimize how often a varying is "double parked" (split across varying slots). --- src/glsl/linker.cpp | 49 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index d6f11a5..80aa260 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -1996,6 +1996,7 @@ private: static unsigned compute_packing_class(ir_variable *var); static packing_order_enum compute_packing_order(ir_variable *var); + static unsigned compute_num_components(ir_variable *var); static int match_comparator(const void *x_generic, const void *y_generic); /** @@ -2012,6 +2013,7 @@ private: * Packing order for this varying, computed by compute_packing_order(). */ packing_order_enum packing_order; + unsigned num_components; /** * The output variable in the producer stage. @@ -2099,6 +2101,8 @@ varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var) = this->compute_packing_class(producer_var); this->matches[this->num_matches].packing_order = this->compute_packing_order(producer_var); + this->matches[this->num_matches].num_components + = this->compute_num_components(producer_var); this->matches[this->num_matches].producer_var = producer_var; this->matches[this->num_matches].consumer_var = consumer_var; this->num_matches++; @@ -2122,20 +2126,19 @@ varying_matches::assign_locations() unsigned generic_location = 0; for (unsigned i = 0; i < this->num_matches; i++) { - this->matches[i].generic_location = generic_location; - - ir_variable *producer_var = this->matches[i].producer_var; - - if (producer_var->type->is_array()) { - const unsigned slots = producer_var->type->length - * producer_var->type->fields.array->matrix_columns; + /* Advance to the next slot if this varying has a different packing + * class than the previous one, and we're not already on a slot + * boundary. + */ + if (i > 0 && generic_location % 4 != 0 && + this->matches[i - 1].packing_class + != this->matches[i].packing_class) { + generic_location += 4 - generic_location % 4; + } - generic_location += 4 * slots; - } else { - const unsigned slots = producer_var->type->matrix_columns; + this->matches[i].generic_location = generic_location; - generic_location += 4 * slots; - } + generic_location += this->matches[i].num_components; } return (generic_location + 3) / 4; @@ -2219,6 +2222,28 @@ varying_matches::compute_packing_order(ir_variable *var) /** + * Compute the number of components that this variable will occupy when + * properly packed. + */ +unsigned +varying_matches::compute_num_components(ir_variable *var) +{ + const glsl_type *type = var->type; + unsigned multipiler = 1; + + if (type->is_array()) { + multipiler *= type->length; + type = type->fields.array; + } + + /* FINISHME: Support for "varying" records in GLSL 1.50. */ + assert(!type->is_record()); + + return multipiler * type->components(); +} + + +/** * Comparison function passed to qsort() to sort varyings by packing_class and * then by packing_order. */ -- 1.8.0.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev