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

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to