freedreno/a3xx/compiler: refactor trans_samp()

Split it up into some smaller fxns so it doesn't grow into a huge
monster as we add things.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
This commit is contained in:
Rob Clark 2014-05-19 17:34:54 -04:00
parent 1686a0edc0
commit 08b9180819
1 changed files with 91 additions and 48 deletions

View File

@ -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);
}
/*