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 {
/* 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); }
/* Creates shader: * EXEC ADDR(0x3) CNT(0x1) * (S)FETCH: VERTEX R1.xyz1 = R0.x FMT_32_32_32_FLOAT * UNSIGNED STRIDE(12) CONST(26, 0) * ALLOC POSITION SIZE(0x0) * EXEC ADDR(0x4) CNT(0x1) * ALU: MAXv export62 = R1, R1 ; gl_Position * ALLOC PARAM/PIXEL SIZE(0x0) * EXEC_END ADDR(0x5) CNT(0x0) */ static struct fd2_shader_stateobj * create_solid_vp(void) { struct fd2_shader_stateobj *so = create_shader(SHADER_VERTEX); struct ir2_cf *cf; struct ir2_instruction *instr; if (!so) return NULL; so->ir = ir2_shader_create(); cf = ir2_cf_create(so->ir, EXEC); instr = ir2_instr_create_vtx_fetch(cf, 26, 0, FMT_32_32_32_FLOAT, false, 12); ir2_reg_create(instr, 1, "xyz1", 0); ir2_reg_create(instr, 0, "x", 0); cf = ir2_cf_create_alloc(so->ir, SQ_POSITION, 0); cf = ir2_cf_create(so->ir, EXEC); instr = ir2_instr_create_alu(cf, MAXv, ~0); ir2_reg_create(instr, 62, NULL, IR2_REG_EXPORT); ir2_reg_create(instr, 1, NULL, 0); ir2_reg_create(instr, 1, NULL, 0); cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0); cf = ir2_cf_create(so->ir, EXEC_END); return assemble(so); }
/* Creates shader: * EXEC ADDR(0x2) CNT(0x1) * (S)FETCH: SAMPLE R0.xyzw = R0.xyx CONST(0) LOCATION(CENTER) * ALLOC PARAM/PIXEL SIZE(0x0) * EXEC_END ADDR(0x3) CNT(0x1) * ALU: MAXv export0 = R0, R0 ; gl_FragColor * NOP */ static struct fd2_shader_stateobj * create_blit_fp(void) { struct fd2_shader_stateobj *so = create_shader(SHADER_FRAGMENT); struct ir2_cf *cf; struct ir2_instruction *instr; if (!so) return NULL; so->ir = ir2_shader_create(); cf = ir2_cf_create(so->ir, EXEC); instr = ir2_instr_create_tex_fetch(cf, 0); ir2_reg_create(instr, 0, "xyzw", 0); ir2_reg_create(instr, 0, "xyx", 0); instr->sync = true; cf = ir2_cf_create_alloc(so->ir, SQ_PARAMETER_PIXEL, 0); cf = ir2_cf_create(so->ir, EXEC_END); instr = ir2_instr_create_alu(cf, MAXv, ~0); ir2_reg_create(instr, 0, NULL, IR2_REG_EXPORT); ir2_reg_create(instr, 0, NULL, 0); ir2_reg_create(instr, 0, NULL, 0); return assemble(so); }
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 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; }