diff options
author | Rob Clark <[email protected]> | 2013-10-27 10:19:58 -0400 |
---|---|---|
committer | Rob Clark <[email protected]> | 2013-11-01 20:18:44 -0400 |
commit | 310fd5839cd5f221680de8a80ae97e099e0116b7 (patch) | |
tree | 99135b663db1f5823e4e9b090a3ac8a8ba5eabbc /src | |
parent | 4ddd4e83c70d1437caea0b9c61f89aade38e993e (diff) |
freedreno/a3xx/compiler: relative addressing fixes.
Handle some relative addressing constraints: cannot handle const or
relative in cat5 and src2 of cat3.
Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/freedreno/a3xx/fd3_compiler.c | 76 |
1 files changed, 48 insertions, 28 deletions
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c b/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c index 352afcf39aa..5e94a6f397a 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c @@ -433,6 +433,18 @@ is_const(struct tgsi_src_register *src) (src->File == TGSI_FILE_IMMEDIATE); } +static inline bool +is_relative(struct tgsi_src_register *src) +{ + return src->Indirect; +} + +static inline bool +is_rel_or_const(struct tgsi_src_register *src) +{ + return is_relative(src) || is_const(src); +} + static type_t get_ftype(struct fd3_compile_context *ctx) { @@ -467,7 +479,7 @@ get_unconst(struct fd3_compile_context *ctx, struct tgsi_src_register *src) struct tgsi_dst_register tmp_dst; struct tgsi_src_register *tmp_src; - compile_assert(ctx, is_const(src)); + compile_assert(ctx, is_rel_or_const(src)); tmp_src = get_internal_temp(ctx, &tmp_dst); @@ -845,8 +857,8 @@ trans_dotp(const struct instr_translater *t, /* in particular, can't handle const for src1 for cat3/mad: */ - if (is_const(src1)) { - if (!is_const(src0)) { + if (is_rel_or_const(src1)) { + if (!is_rel_or_const(src0)) { struct tgsi_src_register *tmp; tmp = src0; src0 = src1; @@ -1065,7 +1077,8 @@ trans_samp(const struct instr_translater *t, struct tgsi_src_register *samp = &inst->Src[1].Register; unsigned tex = inst->Texture.Texture; int8_t *order; - unsigned i, j, flags = 0; + unsigned i, flags = 0; + bool needs_mov = false; switch (t->arg) { case TGSI_OPCODE_TEX: @@ -1089,38 +1102,44 @@ trans_samp(const struct instr_translater *t, flags |= IR3_INSTR_3D; } + /* cat5 instruction cannot seem to handle const or relative: */ + if (is_rel_or_const(coord)) + needs_mov = true; + /* The texture sample instructions need to coord in successive * registers/components (ie. src.xy but not src.yx). And TXP * needs the .w component in .z for 2D.. so in some cases we * might need to emit some mov instructions to shuffle things * around: */ - for (i = 1; (i < 4) && (order[i] >= 0); i++) { - if (src_swiz(coord, i) != (src_swiz(coord, 0) + order[i])) { - struct tgsi_dst_register tmp_dst; - struct tgsi_src_register *tmp_src; - - type_t type_mov = get_ftype(ctx); - - /* need to move things around: */ - tmp_src = get_internal_temp(ctx, &tmp_dst); - - for (j = 0; (j < 4) && (order[j] >= 0); j++) { - instr = ir3_instr_create(ctx->ir, 1, 0); - instr->cat1.src_type = type_mov; - instr->cat1.dst_type = type_mov; - add_dst_reg(ctx, instr, &tmp_dst, j); - add_src_reg(ctx, instr, coord, - src_swiz(coord, order[j])); - } + for (i = 1; (i < 4) && (order[i] >= 0) && !needs_mov; i++) + if (src_swiz(coord, i) != (src_swiz(coord, 0) + order[i])) + needs_mov = true; - coord = tmp_src; + if (needs_mov) { + struct tgsi_dst_register tmp_dst; + struct tgsi_src_register *tmp_src; + unsigned j; - if (j < 4) - ir3_instr_create(ctx->ir, 0, OPC_NOP)->repeat = 4 - j - 1; + type_t type_mov = get_ftype(ctx); - break; + /* need to move things around: */ + tmp_src = get_internal_temp(ctx, &tmp_dst); + + for (j = 0; (j < 4) && (order[j] >= 0); j++) { + instr = ir3_instr_create(ctx->ir, 1, 0); + instr->cat1.src_type = type_mov; + instr->cat1.dst_type = type_mov; + add_dst_reg(ctx, instr, &tmp_dst, j); + add_src_reg(ctx, instr, coord, + src_swiz(coord, order[j])); } + + coord = tmp_src; + + if (j < 4) + ir3_instr_create(ctx->ir, 0, OPC_NOP)->repeat = 4 - j - 1; + } instr = ir3_instr_create(ctx->ir, 5, t->opc); @@ -1483,8 +1502,8 @@ instr_cat3(const struct instr_translater *t, /* in particular, can't handle const for src1 for cat3.. * for mad, we can swap first two src's if needed: */ - if (is_const(src1)) { - if (is_mad(t->opc) && !is_const(src0)) { + if (is_rel_or_const(src1)) { + if (is_mad(t->opc) && !is_rel_or_const(src0)) { struct tgsi_src_register *tmp; tmp = src0; src0 = src1; @@ -1568,6 +1587,7 @@ static const struct instr_translater translaters[TGSI_OPCODE_LAST] = { INSTR(ELSE, trans_else), INSTR(ENDIF, trans_endif), INSTR(END, instr_cat0, .opc = OPC_END), + INSTR(KILL, instr_cat0, .opc = OPC_KILL), }; static int |