From 557d4918adf4cb99c4410af3bdf51c5eb3fc1d17 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 4 Nov 2012 23:04:30 +0100 Subject: [PATCH] glsl: store read vector in a temp in vec_index_to_cond Vector indexing on matrixes generates several copy of the constant matrix, for instance vec=mat4[i][j] generates : vec=mat4[i].x; vec=(j==1)?mat4[i].y; vec=(j==2)?mat4[i].z; vec=(j==3)?mat4[i].w; In the case of constant matrixes, the mat4[i] expression generates copy of the 16 elements of the matrix 4 times ; indirect addressing also prevents some conservative CSE algorithms (like the one in LLVM) from factoring the mat4[i] expression. This patch will make the vec_index_to_cond pass generates : temp = mat4[i]; vec=temp.x; vec=(j==1)?temp.y; vec=(j==2)?temp.z; vec=(j==3)?temp.w; Reviewed-by: Kenneth Graunke --- src/glsl/lower_vec_index_to_cond_assign.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/glsl/lower_vec_index_to_cond_assign.cpp b/src/glsl/lower_vec_index_to_cond_assign.cpp index 789f62afed1..f85875f49fa 100644 --- a/src/glsl/lower_vec_index_to_cond_assign.cpp +++ b/src/glsl/lower_vec_index_to_cond_assign.cpp @@ -68,9 +68,9 @@ ir_rvalue * ir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue *ir) { ir_dereference_array *orig_deref = ir->as_dereference_array(); - ir_assignment *assign; - ir_variable *index, *var; - ir_dereference *deref; + ir_assignment *assign, *value_assign; + ir_variable *index, *var, *value; + ir_dereference *deref, *deref_value; unsigned i; if (!orig_deref) @@ -95,6 +95,14 @@ ir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue assign = new(base_ir) ir_assignment(deref, orig_deref->array_index, NULL); list.push_tail(assign); + /* Store the value inside a temp, thus avoiding matrixes duplication */ + value = new(base_ir) ir_variable(orig_deref->array->type, "vec_value_tmp", + ir_var_temporary); + list.push_tail(value); + deref_value = new(base_ir) ir_dereference_variable(value); + value_assign = new(base_ir) ir_assignment(deref_value, orig_deref->array); + list.push_tail(value_assign); + /* Temporary where we store whichever value we swizzle out. */ var = new(base_ir) ir_variable(ir->type, "vec_index_tmp_v", ir_var_temporary); @@ -117,7 +125,7 @@ ir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue * underlying variable. */ ir_rvalue *swizzle = - new(base_ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL), + new(base_ir) ir_swizzle(deref_value->clone(mem_ctx, NULL), i, 0, 0, 0, 1); deref = new(base_ir) ir_dereference_variable(var);