[Mesa-dev] [PATCH 10/10] glsl/linker: Pack between varyings.
Paul Berry
stereotype441 at gmail.com
Tue Dec 11 15:09:16 PST 2012
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
More information about the mesa-dev
mailing list