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;
}
Beispiel #2
0
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 {
Beispiel #3
0
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);
}
Beispiel #4
0
/* 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);
}
Beispiel #5
0
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;
}
Beispiel #6
0
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);
}
Beispiel #7
0
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;
	}
}