On Fri, Feb 20, 2015 at 4:10 AM, Ilia Mirkin <imir...@alum.mit.edu> wrote: > Signed-off-by: Ilia Mirkin <imir...@alum.mit.edu> > --- > > This works with a modified varying-packing test for everything except > dvec4 array which crashes in st/mesa somewhere. Still working on that > one. The IR generated here kinda stinks, but I couldn't get an > assignment with a swizzle to work.
Ugh, looks like this is a no-go for GS due to the temp vars. But this change gets it mostly working. I also had to switch doubles to *always* getting packed, even for dvec2 and dvec4... I think there's some variable storage/linking-related logic which doesn't take the double size into account properly. -ilia > > src/glsl/lower_packed_varyings.cpp | 88 > +++++++++++++++++++++++++++++--------- > 1 file changed, 67 insertions(+), 21 deletions(-) > > diff --git a/src/glsl/lower_packed_varyings.cpp > b/src/glsl/lower_packed_varyings.cpp > index 5e844c7..f9e3e85 100644 > --- a/src/glsl/lower_packed_varyings.cpp > +++ b/src/glsl/lower_packed_varyings.cpp > @@ -146,7 +146,11 @@ > > #include "glsl_symbol_table.h" > #include "ir.h" > +#include "ir_builder.h" > #include "ir_optimization.h" > +#include "program/prog_instruction.h" > + > +using namespace ir_builder; > > namespace { > > @@ -168,8 +172,8 @@ public: > void run(exec_list *instructions); > > private: > - ir_assignment *bitwise_assign_pack(ir_rvalue *lhs, ir_rvalue *rhs); > - ir_assignment *bitwise_assign_unpack(ir_rvalue *lhs, ir_rvalue *rhs); > + void bitwise_assign_pack(ir_rvalue *lhs, ir_rvalue *rhs); > + void bitwise_assign_unpack(ir_rvalue *lhs, ir_rvalue *rhs); > unsigned lower_rvalue(ir_rvalue *rvalue, unsigned fine_location, > ir_variable *unpacked_var, const char *name, > bool gs_input_toplevel, unsigned vertex_index); > @@ -274,6 +278,7 @@ lower_packed_varyings_visitor::run(exec_list > *instructions) > } > } > > +#define SWIZZLE_ZWZW MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_Z, > SWIZZLE_W) > > /** > * Make an ir_assignment from \c rhs to \c lhs, performing appropriate > @@ -281,7 +286,7 @@ lower_packed_varyings_visitor::run(exec_list > *instructions) > * > * This function is called when packing varyings. > */ > -ir_assignment * > +void > lower_packed_varyings_visitor::bitwise_assign_pack(ir_rvalue *lhs, > ir_rvalue *rhs) > { > @@ -300,12 +305,28 @@ > lower_packed_varyings_visitor::bitwise_assign_pack(ir_rvalue *lhs, > rhs = new(this->mem_ctx) > ir_expression(ir_unop_bitcast_f2i, lhs->type, rhs); > break; > + case GLSL_TYPE_DOUBLE: > + assert(rhs->type->vector_elements <= 2); > + if (rhs->type->vector_elements == 2) { > + ir_variable *t = new(mem_ctx) ir_variable(lhs->type, "pack", > ir_var_temporary); > + > + assert(lhs->type->vector_elements == 4); > + this->out_instructions->push_tail(t); > + this->out_instructions->push_tail( > + assign(t, u2i(expr(ir_unop_unpack_double_2x32, > swizzle_x(rhs->clone(mem_ctx, NULL)))), 0x3)); > + this->out_instructions->push_tail( > + assign(t, u2i(expr(ir_unop_unpack_double_2x32, > swizzle_y(rhs))), 0xc)); > + rhs = deref(t).val; > + } else { > + rhs = u2i(expr(ir_unop_unpack_double_2x32, rhs)); > + } > + break; > default: > assert(!"Unexpected type conversion while lowering varyings"); > break; > } > } > - return new(this->mem_ctx) ir_assignment(lhs, rhs); > + this->out_instructions->push_tail(new (this->mem_ctx) ir_assignment(lhs, > rhs)); > } > > > @@ -315,7 +336,7 @@ > lower_packed_varyings_visitor::bitwise_assign_pack(ir_rvalue *lhs, > * > * This function is called when unpacking varyings. > */ > -ir_assignment * > +void > lower_packed_varyings_visitor::bitwise_assign_unpack(ir_rvalue *lhs, > ir_rvalue *rhs) > { > @@ -334,12 +355,27 @@ > lower_packed_varyings_visitor::bitwise_assign_unpack(ir_rvalue *lhs, > rhs = new(this->mem_ctx) > ir_expression(ir_unop_bitcast_i2f, lhs->type, rhs); > break; > + case GLSL_TYPE_DOUBLE: > + assert(lhs->type->vector_elements <= 2); > + if (lhs->type->vector_elements == 2) { > + ir_variable *t = new(mem_ctx) ir_variable(lhs->type, "unpack", > ir_var_temporary); > + assert(rhs->type->vector_elements == 4); > + this->out_instructions->push_tail(t); > + this->out_instructions->push_tail( > + assign(t, expr(ir_unop_pack_double_2x32, > i2u(swizzle_xy(rhs->clone(mem_ctx, NULL)))), 0x1)); > + this->out_instructions->push_tail( > + assign(t, expr(ir_unop_pack_double_2x32, > i2u(swizzle(rhs->clone(mem_ctx, NULL), SWIZZLE_ZWZW, 2))), 0x2)); > + rhs = deref(t).val; > + } else { > + rhs = expr(ir_unop_pack_double_2x32, i2u(rhs)); > + } > + break; > default: > assert(!"Unexpected type conversion while lowering varyings"); > break; > } > } > - return new(this->mem_ctx) ir_assignment(lhs, rhs); > + this->out_instructions->push_tail(new(this->mem_ctx) ir_assignment(lhs, > rhs)); > } > > > @@ -372,6 +408,7 @@ lower_packed_varyings_visitor::lower_rvalue(ir_rvalue > *rvalue, > bool gs_input_toplevel, > unsigned vertex_index) > { > + unsigned dmul = rvalue->type->is_double() ? 2 : 1; > /* When gs_input_toplevel is set, we should be looking at a geometry > shader > * input array. > */ > @@ -405,17 +442,26 @@ lower_packed_varyings_visitor::lower_rvalue(ir_rvalue > *rvalue, > return this->lower_arraylike(rvalue, rvalue->type->matrix_columns, > fine_location, unpacked_var, name, > false, vertex_index); > - } else if (rvalue->type->vector_elements + fine_location % 4 > 4) { > + } else if (rvalue->type->vector_elements * dmul + > + fine_location % 4 > 4) { > /* This vector is going to be "double parked" across two varying slots, > - * so handle it as two separate assignments. > + * so handle it as two separate assignments. For doubles, a dvec3/dvec4 > + * can end up being spread over 3 slots. However the second splitting > + * will happen later, here we just always want to split into 2. > */ > - unsigned left_components = 4 - fine_location % 4; > - unsigned right_components > - = rvalue->type->vector_elements - left_components; > + unsigned left_components, right_components; > unsigned left_swizzle_values[4] = { 0, 0, 0, 0 }; > unsigned right_swizzle_values[4] = { 0, 0, 0, 0 }; > char left_swizzle_name[4] = { 0, 0, 0, 0 }; > char right_swizzle_name[4] = { 0, 0, 0, 0 }; > + > + left_components = 4 - fine_location % 4; > + if (rvalue->type->is_double()) { > + /* We might actually end up with 0 left components! */ > + left_components /= 2; > + } > + right_components = rvalue->type->vector_elements - left_components; > + > for (unsigned i = 0; i < left_components; i++) { > left_swizzle_values[i] = i; > left_swizzle_name[i] = "xyzw"[i]; > @@ -433,9 +479,13 @@ lower_packed_varyings_visitor::lower_rvalue(ir_rvalue > *rvalue, > = ralloc_asprintf(this->mem_ctx, "%s.%s", name, left_swizzle_name); > char *right_name > = ralloc_asprintf(this->mem_ctx, "%s.%s", name, right_swizzle_name); > - fine_location = this->lower_rvalue(left_swizzle, fine_location, > - unpacked_var, left_name, false, > - vertex_index); > + if (left_components) > + fine_location = this->lower_rvalue(left_swizzle, fine_location, > + unpacked_var, left_name, false, > + vertex_index); > + else > + /* Top up the fine location to the next slot */ > + fine_location++; > return this->lower_rvalue(right_swizzle, fine_location, unpacked_var, > right_name, false, vertex_index); > } else { > @@ -443,7 +493,7 @@ lower_packed_varyings_visitor::lower_rvalue(ir_rvalue > *rvalue, > * varying. > */ > unsigned swizzle_values[4] = { 0, 0, 0, 0 }; > - unsigned components = rvalue->type->vector_elements; > + unsigned components = rvalue->type->vector_elements * dmul; > unsigned location = fine_location / 4; > unsigned location_frac = fine_location % 4; > for (unsigned i = 0; i < components; ++i) > @@ -454,13 +504,9 @@ lower_packed_varyings_visitor::lower_rvalue(ir_rvalue > *rvalue, > ir_swizzle *swizzle = new(this->mem_ctx) > ir_swizzle(packed_deref, swizzle_values, components); > if (this->mode == ir_var_shader_out) { > - ir_assignment *assignment > - = this->bitwise_assign_pack(swizzle, rvalue); > - this->out_instructions->push_tail(assignment); > + this->bitwise_assign_pack(swizzle, rvalue); > } else { > - ir_assignment *assignment > - = this->bitwise_assign_unpack(rvalue, swizzle); > - this->out_instructions->push_tail(assignment); > + this->bitwise_assign_unpack(rvalue, swizzle); > } > return fine_location + components; > } > -- > 2.0.5 > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev