On 10/14/2013 01:33 AM, Chris Forbes wrote: > Rewrites textureGatherOffsets(s, p, offsets) into > > gvec4( > textureGatherOffset(s, p, offsets[0]).w, > textureGatherOffset(s, p, offsets[1]).w, > textureGatherOffset(s, p, offsets[2]).w, > textureGatherOffset(s, p, offsets[3]).w > ) > > Signed-off-by: Chris Forbes <chr...@ijw.co.nz> > --- > src/mesa/drivers/dri/i965/Makefile.sources | 1 + > src/mesa/drivers/dri/i965/brw_context.h | 1 + > .../drivers/dri/i965/brw_lower_offset_array.cpp | 93 > ++++++++++++++++++++++ > src/mesa/drivers/dri/i965/brw_shader.cpp | 1 + > 4 files changed, 96 insertions(+) > create mode 100644 src/mesa/drivers/dri/i965/brw_lower_offset_array.cpp > > diff --git a/src/mesa/drivers/dri/i965/Makefile.sources > b/src/mesa/drivers/dri/i965/Makefile.sources > index b8e83ef..816ecc1 100644 > --- a/src/mesa/drivers/dri/i965/Makefile.sources > +++ b/src/mesa/drivers/dri/i965/Makefile.sources > @@ -68,6 +68,7 @@ i965_FILES = \ > brw_gs_surface_state.c \ > brw_interpolation_map.c \ > brw_lower_texture_gradients.cpp \ > + brw_lower_offset_array.cpp \ > brw_misc_state.c \ > brw_object_purgeable.c \ > brw_performance_monitor.c \ > diff --git a/src/mesa/drivers/dri/i965/brw_context.h > b/src/mesa/drivers/dri/i965/brw_context.h > index 5725ef6..84ff552 100644 > --- a/src/mesa/drivers/dri/i965/brw_context.h > +++ b/src/mesa/drivers/dri/i965/brw_context.h > @@ -1731,6 +1731,7 @@ brw_program_reloc(struct brw_context *brw, uint32_t > state_offset, > bool brw_do_cubemap_normalize(struct exec_list *instructions); > bool brw_lower_texture_gradients(struct brw_context *brw, > struct exec_list *instructions); > +bool brw_do_lower_offset_arrays(struct exec_list *instructions); > > struct opcode_desc { > char *name; > diff --git a/src/mesa/drivers/dri/i965/brw_lower_offset_array.cpp > b/src/mesa/drivers/dri/i965/brw_lower_offset_array.cpp > new file mode 100644 > index 0000000..c512406 > --- /dev/null > +++ b/src/mesa/drivers/dri/i965/brw_lower_offset_array.cpp > @@ -0,0 +1,93 @@ > +/* > + * Copyright © 2013 Intel Corporation > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice (including the next > + * paragraph) shall be included in all copies or substantial portions of the > + * Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER > + * DEALINGS IN THE SOFTWARE. > + */ > + > +/** > + * \file brw_lower_offset_array.cpp > + * > + * IR lower pass to decompose ir_texture ir_tg4 with an array of offsets > + * into four ir_tg4s with a single ivec2 offset, select the .w component of > each, > + * and return those four values packed into a gvec4. > + * > + * \author Chris Forbes <chr...@ijw.co.nz> > + */ > + > +#include "glsl/glsl_types.h" > +#include "glsl/ir.h" > +#include "program/prog_instruction.h" /* For WRITEMASK_* */ > + > +class brw_lower_offset_array_visitor : public ir_hierarchical_visitor { > +public: > + brw_lower_offset_array_visitor() > + { > + progress = false; > + } > + > + ir_visitor_status visit_leave(ir_texture *ir); > + > + bool progress; > +}; > + > +ir_visitor_status > +brw_lower_offset_array_visitor::visit_leave(ir_texture *ir) > +{ > + if (ir->op != ir_tg4 || !ir->offset || !ir->offset->type->is_array()) > + return visit_continue; > + > + void *mem_ctx = ralloc_parent(ir); > + > + ir_variable *var = new (mem_ctx) ir_variable(ir->type, "result", > ir_var_auto); > + base_ir->insert_before(var); > + > + for (int i = 0; i < 4; i++) { > + ir_texture *tex = ir->clone(mem_ctx, NULL); > + tex->offset = new (mem_ctx) ir_dereference_array(tex->offset, > + new (mem_ctx) ir_constant(i)); > + > + ir_assignment *assign = new (mem_ctx) ir_assignment( > + new (mem_ctx) ir_dereference_variable(var), > + new (mem_ctx) ir_swizzle(tex, 3, 0, 0, 0, 1)); /* .w */ > + > + assign->write_mask = 1 << i;
You might consider using ir_builder...it's much easier to work with. For example, the above four lines become: assign(var, swizzle_w(tex), 1 << i); That's probably all it actually buys you at this point, but it might be worth it just for that. Either way, this series is: Reviewed-by: Kenneth Graunke <kenn...@whitecape.org> > + > + base_ir->insert_before(assign); > + } > + > + base_ir->replace_with(new (mem_ctx) ir_dereference_variable(var)); > + > + progress = true; > + return visit_continue; > +} > + > +extern "C" { > + > +bool > +brw_do_lower_offset_arrays(exec_list *instructions) > +{ > + brw_lower_offset_array_visitor v; > + > + visit_list_elements(&v, instructions); > + > + return v.progress; > +} > + > +} > diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp > b/src/mesa/drivers/dri/i965/brw_shader.cpp > index 5da1b0f..5090d22 100644 > --- a/src/mesa/drivers/dri/i965/brw_shader.cpp > +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp > @@ -168,6 +168,7 @@ brw_link_shader(struct gl_context *ctx, struct > gl_shader_program *shProg) > do_vec_index_to_cond_assign(shader->ir); > lower_vector_insert(shader->ir, true); > brw_do_cubemap_normalize(shader->ir); > + brw_do_lower_offset_arrays(shader->ir); > lower_noise(shader->ir); > lower_quadop_vector(shader->ir, false); > > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev