(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)
{
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);
/* 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;
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:
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);
/* 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;
INSTR(ELSE, trans_else),
INSTR(ENDIF, trans_endif),
INSTR(END, instr_cat0, .opc = OPC_END),
+ INSTR(KILL, instr_cat0, .opc = OPC_KILL),
};
static int