diff options
author | Dave Airlie <[email protected]> | 2017-11-28 13:30:41 +1000 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2017-11-30 09:32:31 +1000 |
commit | 779306c8b6ee3b3f5b8d740d0e297961bb6b06b4 (patch) | |
tree | eec91ce44c6cd67ee2023fc5142741865807b045 /src/gallium/drivers/r600/r600_shader.c | |
parent | 0d044351b7043cd0bc94c1cb9b7a2213f8054414 (diff) |
r600: fix bfe where src/dst are same.
This fixes overlaps where src/dst are the same.
Fixes a bunch of the deqp bitfield tests.
Signed-off-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/gallium/drivers/r600/r600_shader.c')
-rw-r--r-- | src/gallium/drivers/r600/r600_shader.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 78f4e33e05b..c3c1f2c014c 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -6639,7 +6639,7 @@ static int tgsi_make_src_for_op3(struct r600_shader_ctx *ctx, return 0; } -static int tgsi_op3(struct r600_shader_ctx *ctx) +static int tgsi_op3_dst(struct r600_shader_ctx *ctx, int dst) { struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; struct r600_bytecode_alu alu; @@ -6669,7 +6669,11 @@ static int tgsi_op3(struct r600_shader_ctx *ctx) return r; } - tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); + if (dst == -1) { + tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); + } else { + alu.dst.sel = dst; + } alu.dst.chan = i; alu.dst.write = 1; alu.is_op3 = 1; @@ -6683,6 +6687,11 @@ static int tgsi_op3(struct r600_shader_ctx *ctx) return 0; } +static int tgsi_op3(struct r600_shader_ctx *ctx) +{ + return tgsi_op3_dst(ctx, -1); +} + static int tgsi_dp(struct r600_shader_ctx *ctx) { struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; @@ -9602,8 +9611,15 @@ static int tgsi_bfe(struct r600_shader_ctx *ctx) struct r600_bytecode_alu alu; int lasti = tgsi_last_instruction(inst->Dst[0].Register.WriteMask); int r, i; + int dst = -1; - r = tgsi_op3(ctx); + if ((inst->Src[0].Register.File == inst->Dst[0].Register.File && + inst->Src[0].Register.Index == inst->Dst[0].Register.Index) || + (inst->Src[2].Register.File == inst->Dst[0].Register.File && + inst->Src[2].Register.Index == inst->Dst[0].Register.Index)) + dst = r600_get_temp(ctx); + + r = tgsi_op3_dst(ctx, dst); if (r) return r; @@ -9628,10 +9644,13 @@ static int tgsi_bfe(struct r600_shader_ctx *ctx) alu.op = ALU_OP3_CNDE_INT; alu.is_op3 = 1; alu.src[0].sel = ctx->temp_reg; - alu.src[1].chan = i; + alu.src[0].chan = i; tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); - alu.src[1].sel = alu.dst.sel; + if (dst != -1) + alu.src[1].sel = dst; + else + alu.src[1].sel = alu.dst.sel; alu.src[1].chan = i; r600_bytecode_src(&alu.src[2], &ctx->src[0], i); alu.dst.write = 1; |