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