static void push_predicate(struct fd2_compile_context *ctx, struct tgsi_src_register *src) { struct ir2_instruction *alu; struct tgsi_dst_register pred_dst; if (ctx->pred_depth == 0) { /* assign predicate register: */ ctx->pred_reg = ctx->num_regs[TGSI_FILE_TEMPORARY]; get_predicate(ctx, &pred_dst, NULL); alu = ir2_instr_create_alu_s(ctx->so->ir, PRED_SETNEs); add_dst_reg(ctx, alu, &pred_dst); add_src_reg(ctx, alu, src); } else { struct tgsi_src_register pred_src; get_predicate(ctx, &pred_dst, &pred_src); alu = ir2_instr_create_alu_v(ctx->so->ir, MULv); add_dst_reg(ctx, alu, &pred_dst); add_src_reg(ctx, alu, &pred_src); add_src_reg(ctx, alu, src); // XXX need to make PRED_SETE_PUSHv IR2_PRED_NONE.. but need to make // sure src reg is valid if it was calculated with a predicate // condition.. alu->pred = IR2_PRED_NONE; } /* save previous pred state to restore in pop_predicate(): */ ctx->pred_stack[ctx->pred_depth++] = ctx->so->ir->pred; }
static void translate_tex(struct fd2_compile_context *ctx, struct tgsi_full_instruction *inst, unsigned opc) { struct ir2_instruction *instr; struct ir2_register *reg; struct tgsi_dst_register tmp_dst; struct tgsi_src_register tmp_src; const struct tgsi_src_register *coord; bool using_temp = (inst->Dst[0].Register.File == TGSI_FILE_OUTPUT) || inst->Instruction.Saturate; int idx; if (using_temp || (opc == TGSI_OPCODE_TXP)) get_internal_temp(ctx, &tmp_dst, &tmp_src); if (opc == TGSI_OPCODE_TXP) { static const char *swiz[] = { [TGSI_SWIZZLE_X] = "xxxx", [TGSI_SWIZZLE_Y] = "yyyy", [TGSI_SWIZZLE_Z] = "zzzz", [TGSI_SWIZZLE_W] = "wwww", }; /* TXP - Projective Texture Lookup: * * coord.x = src0.x / src.w * coord.y = src0.y / src.w * coord.z = src0.z / src.w * coord.w = src0.w * bias = 0.0 * * dst = texture_sample(unit, coord, bias) */ instr = ir2_instr_create_alu(next_exec_cf(ctx), MAXv, RECIP_IEEE); /* MAXv: */ add_dst_reg(ctx, instr, &tmp_dst)->swizzle = "___w"; add_src_reg(ctx, instr, &inst->Src[0].Register); add_src_reg(ctx, instr, &inst->Src[0].Register); /* RECIP_IEEE: */ add_dst_reg(ctx, instr, &tmp_dst)->swizzle = "x___"; add_src_reg(ctx, instr, &inst->Src[0].Register)->swizzle = swiz[inst->Src[0].Register.SwizzleW]; instr = ir2_instr_create_alu(next_exec_cf(ctx), MULv, ~0); add_dst_reg(ctx, instr, &tmp_dst)->swizzle = "xyz_"; add_src_reg(ctx, instr, &tmp_src)->swizzle = "xxxx"; add_src_reg(ctx, instr, &inst->Src[0].Register); coord = &tmp_src; } else {
static void add_regs_vector_2(struct fd2_compile_context *ctx, struct tgsi_full_instruction *inst, struct ir2_instruction *alu) { assert(inst->Instruction.NumSrcRegs == 2); assert(inst->Instruction.NumDstRegs == 1); add_dst_reg(ctx, alu, &inst->Dst[0].Register); add_src_reg(ctx, alu, &inst->Src[0].Register); add_src_reg(ctx, alu, &inst->Src[1].Register); add_vector_clamp(inst, alu); }
/* POW(a,b) = EXP2(b * LOG2(a)) */ static void translate_pow(struct fd2_compile_context *ctx, struct tgsi_full_instruction *inst) { struct tgsi_dst_register tmp_dst; struct tgsi_src_register tmp_src; struct ir2_instruction *alu; get_internal_temp(ctx, &tmp_dst, &tmp_src); alu = ir2_instr_create_alu(next_exec_cf(ctx), ~0, LOG_CLAMP); add_regs_dummy_vector(alu); add_dst_reg(ctx, alu, &tmp_dst); add_src_reg(ctx, alu, &inst->Src[0].Register); alu = ir2_instr_create_alu(next_exec_cf(ctx), MULv, ~0); add_dst_reg(ctx, alu, &tmp_dst); add_src_reg(ctx, alu, &tmp_src); add_src_reg(ctx, alu, &inst->Src[1].Register); /* NOTE: some of the instructions, like EXP_IEEE, seem hard- * coded to take their input from the w component. */ switch(inst->Dst[0].Register.WriteMask) { case TGSI_WRITEMASK_X: tmp_src.SwizzleW = TGSI_SWIZZLE_X; break; case TGSI_WRITEMASK_Y: tmp_src.SwizzleW = TGSI_SWIZZLE_Y; break; case TGSI_WRITEMASK_Z: tmp_src.SwizzleW = TGSI_SWIZZLE_Z; break; case TGSI_WRITEMASK_W: tmp_src.SwizzleW = TGSI_SWIZZLE_W; break; default: DBG("invalid writemask!"); assert(0); break; } alu = ir2_instr_create_alu(next_exec_cf(ctx), ~0, EXP_IEEE); add_regs_dummy_vector(alu); add_dst_reg(ctx, alu, &inst->Dst[0].Register); add_src_reg(ctx, alu, &tmp_src); add_scalar_clamp(inst, alu); }
static void pop_predicate(struct fd2_compile_context *ctx) { /* NOTE blob compiler seems to always puts PRED_* instrs in a CF by * themselves: */ ctx->cf = NULL; /* restore previous predicate state: */ ctx->so->ir->pred = ctx->pred_stack[--ctx->pred_depth]; if (ctx->pred_depth != 0) { struct ir2_instruction *alu; struct tgsi_dst_register pred_dst; struct tgsi_src_register pred_src; get_predicate(ctx, &pred_dst, &pred_src); alu = ir2_instr_create_alu(next_exec_cf(ctx), ~0, PRED_SET_POPs); add_regs_dummy_vector(alu); add_dst_reg(ctx, alu, &pred_dst); add_src_reg(ctx, alu, &pred_src); alu->pred = IR2_PRED_NONE; } else { /* predicate register no longer needed: */ ctx->pred_reg = -1; } ctx->cf = NULL; }
static void add_regs_vector_3(struct fd2_compile_context *ctx, struct tgsi_full_instruction *inst, struct ir2_instruction *alu) { assert(inst->Instruction.NumSrcRegs == 3); assert(inst->Instruction.NumDstRegs == 1); add_dst_reg(ctx, alu, &inst->Dst[0].Register); /* maybe should re-arrange the syntax some day, but * in assembler/disassembler and what ir.c expects * is: MULADDv Rdst = Rsrc2 + Rsrc0 * Rscr1 */ add_src_reg(ctx, alu, &inst->Src[2].Register); add_src_reg(ctx, alu, &inst->Src[0].Register); add_src_reg(ctx, alu, &inst->Src[1].Register); add_vector_clamp(inst, alu); }
static void push_predicate(struct fd2_compile_context *ctx, struct tgsi_src_register *src) { struct ir2_instruction *alu; struct tgsi_dst_register pred_dst; /* NOTE blob compiler seems to always puts PRED_* instrs in a CF by * themselves: */ ctx->cf = NULL; if (ctx->pred_depth == 0) { /* assign predicate register: */ ctx->pred_reg = ctx->num_regs[TGSI_FILE_TEMPORARY]; get_predicate(ctx, &pred_dst, NULL); alu = ir2_instr_create_alu(next_exec_cf(ctx), ~0, PRED_SETNEs); add_regs_dummy_vector(alu); add_dst_reg(ctx, alu, &pred_dst); add_src_reg(ctx, alu, src); } else { struct tgsi_src_register pred_src; get_predicate(ctx, &pred_dst, &pred_src); alu = ir2_instr_create_alu(next_exec_cf(ctx), MULv, ~0); add_dst_reg(ctx, alu, &pred_dst); add_src_reg(ctx, alu, &pred_src); add_src_reg(ctx, alu, src); // XXX need to make PRED_SETE_PUSHv IR2_PRED_NONE.. but need to make // sure src reg is valid if it was calculated with a predicate // condition.. alu->pred = IR2_PRED_NONE; } /* save previous pred state to restore in pop_predicate(): */ ctx->pred_stack[ctx->pred_depth++] = ctx->so->ir->pred; ctx->cf = NULL; }
static void pop_predicate(struct fd2_compile_context *ctx) { /* restore previous predicate state: */ ctx->so->ir->pred = ctx->pred_stack[--ctx->pred_depth]; if (ctx->pred_depth != 0) { struct ir2_instruction *alu; struct tgsi_dst_register pred_dst; struct tgsi_src_register pred_src; get_predicate(ctx, &pred_dst, &pred_src); alu = ir2_instr_create_alu_s(ctx->so->ir, PRED_SET_POPs); add_dst_reg(ctx, alu, &pred_dst); add_src_reg(ctx, alu, &pred_src); alu->pred = IR2_PRED_NONE; } else { /* predicate register no longer needed: */ ctx->pred_reg = -1; } }