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;
+ 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,
+ };
+
unsigned tex = inst->Texture.Texture;
- int8_t *order;
- unsigned i, flags = 0, src_wrmask;
- bool needs_mov = false;
- switch (t->arg) {
+ 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))
* 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) {
/* 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 */
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;
-
- add_dst_reg_wrmask(ctx, instr, &inst->Dst[0].Register, 0,
- inst->Dst[0].Register.WriteMask);
+ instr->flags |= tinf->flags;
- 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);
}
/*