This commit should generates less ARL instructions when dealing with indirect addressing.
v2: fix glsl-vs-array piglit test --- src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 60 +++++++++++++++++----------- 1 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 2bfa622..df47db7 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -483,6 +483,8 @@ static st_src_reg undef_src = st_src_reg(PROGRAM_UNDEFINED, 0, GLSL_TYPE_ERROR); static st_dst_reg undef_dst = st_dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP, GLSL_TYPE_ERROR); static st_dst_reg address_reg = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT); +static int available_address_writemask = WRITEMASK_X; +static GLuint available_address_swizzle = SWIZZLE_X; static void fail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3); @@ -748,29 +750,10 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, st_src_reg src0, st_src_reg src1, st_src_reg src2) { glsl_to_tgsi_instruction *inst = new(mem_ctx) glsl_to_tgsi_instruction(); - int num_reladdr = 0, i; + int i; op = get_opcode(ir, op, dst, src0, src1); - /* If we have to do relative addressing, we want to load the ARL - * reg directly for one of the regs, and preload the other reladdr - * sources into temps. - */ - num_reladdr += dst.reladdr != NULL; - num_reladdr += src0.reladdr != NULL; - num_reladdr += src1.reladdr != NULL; - num_reladdr += src2.reladdr != NULL; - - reladdr_to_temp(ir, &src2, &num_reladdr); - reladdr_to_temp(ir, &src1, &num_reladdr); - reladdr_to_temp(ir, &src0, &num_reladdr); - - if (dst.reladdr) { - emit_arl(ir, address_reg, *dst.reladdr); - num_reladdr--; - } - assert(num_reladdr == 0); - inst->op = op; inst->dst = dst; inst->src[0] = src0; @@ -2113,6 +2096,31 @@ glsl_to_tgsi_visitor::visit(ir_swizzle *ir) this->result = src; } +static +void update_address_mask_availability(void) +{ + switch (available_address_writemask) { + case WRITEMASK_X: + available_address_writemask = WRITEMASK_Y; + available_address_swizzle = SWIZZLE_Y; + break; + case WRITEMASK_Y: + available_address_writemask = WRITEMASK_Z; + available_address_swizzle = SWIZZLE_Z; + break; + case WRITEMASK_Z: + available_address_writemask = WRITEMASK_W; + available_address_swizzle = SWIZZLE_W; + break; + case WRITEMASK_W: + available_address_writemask = WRITEMASK_X; + available_address_swizzle = SWIZZLE_X; + break; + default: + assert(0); + } +} + void glsl_to_tgsi_visitor::handle_dereference(ir_dereference *ir) { @@ -2157,8 +2165,12 @@ glsl_to_tgsi_visitor::handle_dereference(ir_dereference *ir) this->result, st_src_reg_for_type(index_reg.type,element_size),index_reg); } } + address_reg.writemask = available_address_writemask; + emit_arl(ir,address_reg,index_reg); result.reladdr = ralloc(mem_ctx, st_src_reg); - memcpy(result.reladdr, &index_reg, sizeof(index_reg)); + *(result.reladdr) = st_src_reg(address_reg); + result.reladdr->swizzle = available_address_swizzle; + update_address_mask_availability(); } } @@ -4294,8 +4306,10 @@ translate_dst(struct st_translate *t, if (saturate) dst = ureg_saturate(dst); - if (dst_reg->reladdr != NULL) + if (dst_reg->reladdr != NULL) { dst = ureg_dst_indirect(dst, ureg_src(t->address[0])); + dst.IndirectSwizzle = GET_SWZ(dst_reg->reladdr->swizzle,0); + } return dst; } @@ -4327,7 +4341,7 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg) src.Indirect = 1; src.IndirectFile = addr.File; src.IndirectIndex = addr.Index; - src.IndirectSwizzle = addr.SwizzleX; + src.IndirectSwizzle = GET_SWZ(src_reg->reladdr->swizzle,0); if (src_reg->file != PROGRAM_INPUT && src_reg->file != PROGRAM_OUTPUT) { -- 1.7.7 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev