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

Vincent Lejeune vljn at ovi.com
Tue Jan 24 08:43:49 PST 2012


---
 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