Use the destination write mask to determine which values are really to be read from LDS and load only these.
Signed-off-by: Gert Wollny <gw.foss...@gmail.com> --- src/gallium/drivers/r600/r600_shader.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index a2dc08c596..9fa83189bc 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -377,7 +377,7 @@ static void r600_bytecode_src(struct r600_bytecode_alu_src *bc_src, const struct r600_shader_src *shader_src, unsigned chan); static int do_lds_fetch_values(struct r600_shader_ctx *ctx, unsigned temp_reg, - unsigned dst_reg); + unsigned dst_reg, unsigned mask); static int tgsi_last_instruction(unsigned writemask) { @@ -1025,7 +1025,7 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx) if (r) return r; - do_lds_fetch_values(ctx, temp_reg, dreg); + do_lds_fetch_values(ctx, temp_reg, dreg, 0xF); } else if (d->Semantic.Name == TGSI_SEMANTIC_TESSCOORD) { /* MOV r1.x, r0.x; @@ -1743,14 +1743,18 @@ static int r600_get_byte_address(struct r600_shader_ctx *ctx, int temp_reg, } static int do_lds_fetch_values(struct r600_shader_ctx *ctx, unsigned temp_reg, - unsigned dst_reg) + unsigned dst_reg, unsigned mask) { struct r600_bytecode_alu alu; int r, i; if ((ctx->bc->cf_last->ndw>>1) >= 0x60) ctx->bc->force_add_cf = 1; + for (i = 1; i < 4; i++) { + if (!(mask & (1 << i))) + continue; + r = single_alu_op2(ctx, ALU_OP2_ADD_INT, temp_reg, i, temp_reg, 0, @@ -1759,6 +1763,9 @@ static int do_lds_fetch_values(struct r600_shader_ctx *ctx, unsigned temp_reg, return r; } for (i = 0; i < 4; i++) { + if (! (mask & (1 << i))) + continue; + /* emit an LDS_READ_RET */ memset(&alu, 0, sizeof(alu)); alu.op = LDS_OP1_LDS_READ_RET; @@ -1774,6 +1781,8 @@ static int do_lds_fetch_values(struct r600_shader_ctx *ctx, unsigned temp_reg, return r; } for (i = 0; i < 4; i++) { + if (! (mask & (1 << i))) + continue; /* then read from LDS_OQ_A_POP */ memset(&alu, 0, sizeof(alu)); @@ -1791,6 +1800,16 @@ static int do_lds_fetch_values(struct r600_shader_ctx *ctx, unsigned temp_reg, return 0; } +static int fetch_mask( struct tgsi_src_register *reg) +{ + int mask = 0; + mask |= 1 << reg->SwizzleX; + mask |= 1 << reg->SwizzleY; + mask |= 1 << reg->SwizzleZ; + mask |= 1 << reg->SwizzleW; + return mask; +} + static int fetch_tes_input(struct r600_shader_ctx *ctx, struct tgsi_full_src_register *src, unsigned int dst_reg) { int r; @@ -1807,7 +1826,7 @@ static int fetch_tes_input(struct r600_shader_ctx *ctx, struct tgsi_full_src_reg if (r) return r; - r = do_lds_fetch_values(ctx, temp_reg, dst_reg); + r = do_lds_fetch_values(ctx, temp_reg, dst_reg, fetch_mask(&src->Register)); if (r) return r; return 0; @@ -1833,7 +1852,7 @@ static int fetch_tcs_input(struct r600_shader_ctx *ctx, struct tgsi_full_src_reg if (r) return r; - r = do_lds_fetch_values(ctx, temp_reg, dst_reg); + r = do_lds_fetch_values(ctx, temp_reg, dst_reg, fetch_mask(&src->Register)); if (r) return r; return 0; @@ -1855,7 +1874,7 @@ static int fetch_tcs_output(struct r600_shader_ctx *ctx, struct tgsi_full_src_re if (r) return r; - r = do_lds_fetch_values(ctx, temp_reg, dst_reg); + r = do_lds_fetch_values(ctx, temp_reg, dst_reg, fetch_mask(&src->Register)); if (r) return r; return 0; @@ -2792,7 +2811,7 @@ static int r600_tess_factor_read(struct r600_shader_ctx *ctx, if (r) return r; - do_lds_fetch_values(ctx, temp_reg, dreg); + do_lds_fetch_values(ctx, temp_reg, dreg, 0xf); return 0; } -- 2.13.6 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev