diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c b/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c index 30f033606fb..48765f3fa03 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c @@ -1074,72 +1074,100 @@ trans_arl(const struct instr_translater *t, add_src_reg(ctx, instr, tmp_src, chan)->flags |= IR3_REG_HALF; } -/* texture fetch/sample instructions: */ -static void -trans_samp(const struct instr_translater *t, - struct fd3_compile_context *ctx, +/* + * texture fetch/sample instructions: + */ + +struct tex_info { + int8_t order[4]; + unsigned src_wrmask, flags; +}; + +static const struct tex_info * +get_tex_info(struct fd3_compile_context *ctx, struct tgsi_full_instruction *inst) { - struct ir3_instruction *instr; - struct tgsi_src_register *coord = &inst->Src[0].Register; - struct tgsi_src_register *samp = &inst->Src[1].Register; - unsigned tex = inst->Texture.Texture; - int8_t *order; - unsigned i, flags = 0, src_wrmask; - bool needs_mov = false; + static const struct tex_info tex1d = { + .order = { 0, -1, -1, -1 }, /* coord.x */ + .src_wrmask = TGSI_WRITEMASK_XY, + .flags = 0, + }; + static const struct tex_info tex2d = { + .order = { 0, 1, -1, -1 }, /* coord.xy */ + .src_wrmask = TGSI_WRITEMASK_XY, + .flags = 0, + }; + static const struct tex_info tex3d = { + .order = { 0, 1, 2, -1 }, /* coord.xyz */ + .src_wrmask = TGSI_WRITEMASK_XYZ, + .flags = IR3_INSTR_3D, + }; + static const struct tex_info txp1d = { + .order = { 0, -1, 3, -1 }, /* coord.xw */ + .src_wrmask = TGSI_WRITEMASK_XYZ, + .flags = IR3_INSTR_P, + }; + static const struct tex_info txp2d = { + .order = { 0, 1, 3, -1 }, /* coord.xyw */ + .src_wrmask = TGSI_WRITEMASK_XYZ, + .flags = IR3_INSTR_P, + }; + static const struct tex_info txp3d = { + .order = { 0, 1, 2, 3 }, /* coord.xyzw */ + .src_wrmask = TGSI_WRITEMASK_XYZW, + .flags = IR3_INSTR_P | IR3_INSTR_3D, + }; - switch (t->arg) { + unsigned tex = inst->Texture.Texture; + + switch (inst->Instruction.Opcode) { case TGSI_OPCODE_TEX: switch (tex) { case TGSI_TEXTURE_1D: - order = (int8_t[4]){ 0, -1, -1, -1 }; /* coord.x */ - src_wrmask = TGSI_WRITEMASK_XY; - break; + return &tex1d; case TGSI_TEXTURE_2D: case TGSI_TEXTURE_RECT: - order = (int8_t[4]){ 0, 1, -1, -1 }; /* coord.xy */ - src_wrmask = TGSI_WRITEMASK_XY; - break; + return &tex2d; case TGSI_TEXTURE_3D: case TGSI_TEXTURE_CUBE: - order = (int8_t[4]){ 0, 1, 2, -1 }; /* coord.xyz */ - src_wrmask = TGSI_WRITEMASK_XYZ; - flags |= IR3_INSTR_3D; - break; + return &tex3d; default: compile_error(ctx, "unknown texture type: %s\n", tgsi_texture_names[tex]); - break; + return NULL; } break; case TGSI_OPCODE_TXP: switch (tex) { case TGSI_TEXTURE_1D: - order = (int8_t[4]){ 0, -1, 3, -1 }; /* coord.xw */ - src_wrmask = TGSI_WRITEMASK_XYZ; - break; + return &txp1d; case TGSI_TEXTURE_2D: case TGSI_TEXTURE_RECT: - order = (int8_t[4]){ 0, 1, 3, -1 }; /* coord.xyw */ - src_wrmask = TGSI_WRITEMASK_XYZ; - break; + return &txp2d; case TGSI_TEXTURE_3D: case TGSI_TEXTURE_CUBE: - order = (int8_t[4]){ 0, 1, 2, 3 }; /* coord.xyzw */ - src_wrmask = TGSI_WRITEMASK_XYZW; - flags |= IR3_INSTR_3D; - break; + return &txp3d; default: compile_error(ctx, "unknown texture type: %s\n", tgsi_texture_names[tex]); break; } - flags |= IR3_INSTR_P; - break; - default: - compile_assert(ctx, 0); break; } + compile_assert(ctx, 0); + return NULL; +} + +static struct tgsi_src_register * +get_tex_coord(struct fd3_compile_context *ctx, + struct tgsi_full_instruction *inst, + const struct tex_info *tinf) +{ + struct tgsi_src_register *coord = &inst->Src[0].Register; + struct ir3_instruction *instr; + unsigned tex = inst->Texture.Texture; + bool needs_mov = false; + unsigned i; /* cat5 instruction cannot seem to handle const or relative: */ if (is_rel_or_const(coord)) @@ -1155,8 +1183,8 @@ trans_samp(const struct instr_translater *t, * might need to emit some mov instructions to shuffle things * around: */ - for (i = 1; (i < 4) && (order[i] >= 0) && !needs_mov; i++) - if (src_swiz(coord, i) != (src_swiz(coord, 0) + order[i])) + for (i = 1; (i < 4) && (tinf->order[i] >= 0) && !needs_mov; i++) + if (src_swiz(coord, i) != (src_swiz(coord, 0) + tinf->order[i])) needs_mov = true; if (needs_mov) { @@ -1169,18 +1197,18 @@ trans_samp(const struct instr_translater *t, /* need to move things around: */ tmp_src = get_internal_temp(ctx, &tmp_dst); - for (j = 0; (j < 4) && (order[j] >= 0); j++) { - instr = instr_create(ctx, 1, 0); + for (j = 0; (j < 4) && (tinf->order[j] >= 0); j++) { + instr = instr_create(ctx, 1, 0); /* mov */ 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])); + src_swiz(coord, tinf->order[j])); } /* fix up .y coord: */ if (tex == TGSI_TEXTURE_1D) { - instr = instr_create(ctx, 1, 0); + instr = instr_create(ctx, 1, 0); /* mov */ instr->cat1.src_type = type_mov; instr->cat1.dst_type = type_mov; add_dst_reg(ctx, instr, &tmp_dst, 1); /* .y */ @@ -1190,16 +1218,31 @@ trans_samp(const struct instr_translater *t, coord = tmp_src; } + return coord; +} + +static void +trans_samp(const struct instr_translater *t, + struct fd3_compile_context *ctx, + struct tgsi_full_instruction *inst) +{ + struct ir3_instruction *instr; + struct tgsi_dst_register *dst = &inst->Dst[0].Register; + struct tgsi_src_register *coord; + struct tgsi_src_register *samp = &inst->Src[1].Register; + const struct tex_info *tinf; + + tinf = get_tex_info(ctx, inst); + coord = get_tex_coord(ctx, inst, tinf); + instr = instr_create(ctx, 5, t->opc); instr->cat5.type = get_ftype(ctx); instr->cat5.samp = samp->Index; instr->cat5.tex = samp->Index; - instr->flags |= flags; + instr->flags |= tinf->flags; - add_dst_reg_wrmask(ctx, instr, &inst->Dst[0].Register, 0, - inst->Dst[0].Register.WriteMask); - - add_src_reg_wrmask(ctx, instr, coord, coord->SwizzleX, src_wrmask); + add_dst_reg_wrmask(ctx, instr, dst, 0, dst->WriteMask); + add_src_reg_wrmask(ctx, instr, coord, coord->SwizzleX, tinf->src_wrmask); } /*