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