[Mesa-dev] [PATCH 4/5] glsl: Adds a vec_packing function

Vincent Lejeune vljn at ovi.com
Tue Jan 24 13:05:13 PST 2012


This commit adds a basic packing function for varyings.
It merges vec3 with float and vec2 with vec2 when possible, but does
neither try to merge vec2 with floats nor floats with floats.
By default the packing does not occur as this function is used mostly
for debug purpose only.
---
 src/glsl/linker.cpp |  133 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 133 insertions(+), 0 deletions(-)

diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 9c65f92..9c2fad5 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -1839,6 +1839,139 @@ default_packing_function(ir_variable **produced_var,
 
 
 /**
+ * Packing function that attempts to pack vec3 with float and vec2 together.
+ * Does not take interpolation into account.
+ */
+void
+vec_packing_function(ir_variable **produced_var,
+                                     ir_variable **consumed_var,
+                                     unsigned size,
+                                     int *first_produced_index,
+                                     int *first_consumed_index)
+{
+   void *ctx = ralloc_context(NULL);
+   location_tree **vec3_storage_p = NULL;
+   location_tree **vec3_storage_c = NULL;
+   unsigned vec3_count = 0;
+
+   location_tree **vec2_storage_p = NULL;
+   location_tree **vec2_storage_c = NULL;
+   unsigned vec2_count = 0;
+
+   location_tree **float_storage_p = NULL;
+   location_tree **float_storage_c = NULL;
+   unsigned float_count = 0;
+
+   int p_index = *first_produced_index;
+   int c_index = *first_consumed_index;
+
+   for (unsigned i = 0; i < size; i++) {
+      const glsl_type *const type = produced_var[i]->type;
+      if (!type->is_scalar() && !type->is_vector()) {
+         set_vanilla_location_to_variable(produced_var[i]->complete_location, type, p_index);
+         if (consumed_var)
+            set_vanilla_location_to_variable(consumed_var[i]->complete_location, type, c_index);
+      }
+      else {
+         switch (type->vector_elements) {
+            case 3:
+               vec3_count ++;
+               vec3_storage_p = reralloc(ctx, vec3_storage_p, union location_tree *, vec3_count);
+               vec3_storage_p[vec3_count - 1] = produced_var[i]->complete_location;
+               if (consumed_var) {
+                  vec3_storage_c = reralloc(ctx, vec3_storage_c, union location_tree *, vec3_count);
+                  vec3_storage_c[vec3_count - 1] = consumed_var[i]->complete_location;
+               }
+               break;
+            case 2:
+               vec2_count ++;
+               vec2_storage_p = reralloc(ctx, vec2_storage_p, union location_tree *, vec2_count);
+               vec2_storage_p[vec2_count - 1] = produced_var[i]->complete_location;
+               if (consumed_var) {
+                  vec2_storage_c = reralloc(ctx, vec2_storage_c, union location_tree *, vec2_count);
+                  vec2_storage_c[vec2_count - 1] = consumed_var[i]->complete_location;
+               }
+               break;
+            case 1:
+               float_count ++;
+               float_storage_p = reralloc(ctx, float_storage_p, union location_tree *, float_count);
+               float_storage_p[float_count - 1] = produced_var[i]->complete_location;
+               if (consumed_var) {
+                  float_storage_c = reralloc(ctx, float_storage_c, union location_tree *, float_count);
+                  float_storage_c[float_count - 1] = consumed_var[i]->complete_location;
+               }
+               break;
+            default:
+               set_vanilla_location_to_variable(produced_var[i]->complete_location, type, p_index);
+               if (consumed_var)
+                  set_vanilla_location_to_variable(consumed_var[i]->complete_location, type, c_index);
+               break;
+         }
+      }
+   }
+
+   while (vec3_count > 0 && float_count > 0) {
+      vec3_storage_p[vec3_count - 1]->AsLeaf.Offset = 16 * p_index;
+      float_storage_p[float_count - 1]->AsLeaf.Offset = 16 * p_index + 12;
+      p_index++;
+      if (consumed_var) {
+         vec3_storage_c[vec3_count - 1]->AsLeaf.Offset = 16 * c_index;
+         float_storage_c[float_count - 1]->AsLeaf.Offset = 16 * c_index + 12;
+         c_index++;
+      }
+      vec3_count --;
+      float_count --;
+   }
+
+   while (vec2_count > 1 ) {
+      vec2_storage_p[vec2_count - 1]->AsLeaf.Offset = 16 * p_index;
+      vec2_storage_p[vec2_count - 2]->AsLeaf.Offset = 16 * p_index + 8;
+      p_index++;
+      if (consumed_var) {
+         vec2_storage_c[vec2_count - 1]->AsLeaf.Offset = 16 * c_index;
+         vec2_storage_c[vec2_count - 2]->AsLeaf.Offset = 16 * c_index + 8;
+         c_index++;
+      }
+      vec2_count --;
+      vec2_count --;
+   }
+
+   while(vec3_count > 0) {
+      vec3_storage_p[vec3_count - 1]->AsLeaf.Offset = 16 * p_index;
+      p_index++;
+      if (consumed_var) {
+         vec3_storage_c[vec3_count - 1]->AsLeaf.Offset = 16 * c_index;
+         c_index++;
+      }
+      vec3_count --;
+   }
+
+   while(vec2_count > 0) {
+      vec2_storage_p[vec2_count - 1]->AsLeaf.Offset = 16 * p_index;
+      p_index++;
+      if (consumed_var) {
+         vec2_storage_c[vec2_count - 1]->AsLeaf.Offset = 16 * c_index;
+         c_index++;
+      }
+      vec2_count --;
+   }
+
+   while(float_count > 0) {
+      float_storage_p[float_count - 1]->AsLeaf.Offset = 16 * p_index;
+      p_index++;
+      if (consumed_var) {
+         float_storage_c[float_count - 1]->AsLeaf.Offset = 16 * c_index;
+         c_index++;
+      }
+      float_count --;
+   }
+
+   *first_produced_index = p_index;
+   *first_consumed_index = c_index;
+}
+
+
+/**
  * Assign locations for all variables that are produced in one pipeline stage
  * (the "producer") and consumed in the next stage (the "consumer").
  *
-- 
1.7.7



More information about the mesa-dev mailing list