Beispiel #1
0
/**
 * Can be used as a transformation for @ref radeonClauseLocalTransform,
 * no userData necessary.
 *
 * Eliminates the following ALU instructions:
 *  ABS, CEIL, DPH, DST, FLR, LIT, LRP, POW, SEQ, SFL, SGE, SGT, SLE, SLT, SNE, SUB, SWZ, XPD
 * using:
 *  MOV, ADD, MUL, MAD, FRC, DP3, LG2, EX2, CMP
 *
 * Transforms RSQ to Radeon's native RSQ by explicitly setting
 * absolute value.
 *
 * @note should be applicable to R300 and R500 fragment programs.
 */
int radeonTransformALU(
	struct radeon_compiler * c,
	struct rc_instruction* inst,
	void* unused)
{
	switch(inst->U.I.Opcode) {
	case RC_OPCODE_ABS: transform_ABS(c, inst); return 1;
	case RC_OPCODE_CEIL: transform_CEIL(c, inst); return 1;
	case RC_OPCODE_CLAMP: transform_CLAMP(c, inst); return 1;
	case RC_OPCODE_DP2: transform_DP2(c, inst); return 1;
	case RC_OPCODE_DPH: transform_DPH(c, inst); return 1;
	case RC_OPCODE_DST: transform_DST(c, inst); return 1;
	case RC_OPCODE_FLR: transform_FLR(c, inst); return 1;
	case RC_OPCODE_LIT: transform_LIT(c, inst); return 1;
	case RC_OPCODE_LRP: transform_LRP(c, inst); return 1;
	case RC_OPCODE_POW: transform_POW(c, inst); return 1;
	case RC_OPCODE_RSQ: transform_RSQ(c, inst); return 1;
	case RC_OPCODE_SEQ: transform_SEQ(c, inst); return 1;
	case RC_OPCODE_SFL: transform_SFL(c, inst); return 1;
	case RC_OPCODE_SGE: transform_SGE(c, inst); return 1;
	case RC_OPCODE_SGT: transform_SGT(c, inst); return 1;
	case RC_OPCODE_SLE: transform_SLE(c, inst); return 1;
	case RC_OPCODE_SLT: transform_SLT(c, inst); return 1;
	case RC_OPCODE_SNE: transform_SNE(c, inst); return 1;
	case RC_OPCODE_SSG: transform_SSG(c, inst); return 1;
	case RC_OPCODE_SUB: transform_SUB(c, inst); return 1;
	case RC_OPCODE_SWZ: transform_SWZ(c, inst); return 1;
	case RC_OPCODE_XPD: transform_XPD(c, inst); return 1;
	default:
		return 0;
	}
}
Beispiel #2
0
static void transform_r300_vertex_CMP(struct radeon_compiler* c,
	struct rc_instruction* inst)
{
	/* There is no decent CMP available, so let's rig one up.
	 * CMP is defined as dst = src0 < 0.0 ? src1 : src2
	 * The following sequence consumes zero to two temps and two extra slots
	 * (the second temp and the second slot is consumed by transform_LRP),
	 * but should be equivalent:
	 *
	 * SLT tmp0, src0, 0.0
	 * LRP dst, tmp0, src1, src2
	 *
	 * Yes, I know, I'm a mad scientist. ~ C. & M. */
	struct rc_dst_register dst = try_to_reuse_dst(c, inst);

	/* SLT tmp0, src0, 0.0 */
	emit2(c, inst->Prev, RC_OPCODE_SLT, 0,
		dst,
		inst->U.I.SrcReg[0], builtin_zero);

	/* LRP dst, tmp0, src1, src2 */
	transform_LRP(c,
		emit3(c, inst->Prev, RC_OPCODE_LRP, 0,
		      inst->U.I.DstReg,
		      srcreg(RC_FILE_TEMPORARY, dst.Index), inst->U.I.SrcReg[1],  inst->U.I.SrcReg[2]));

	rc_remove_instruction(inst);
}
/**
 * For use with rc_local_transform, this transforms non-native ALU
 * instructions of the r300 up to r500 vertex engine.
 */
int r300_transform_vertex_alu(
	struct radeon_compiler * c,
	struct rc_instruction* inst,
	void* unused)
{
	switch(inst->U.I.Opcode) {
	case RC_OPCODE_ABS: transform_r300_vertex_ABS(c, inst); return 1;
	case RC_OPCODE_CEIL: transform_CEIL(c, inst); return 1;
	case RC_OPCODE_CLAMP: transform_CLAMP(c, inst); return 1;
	case RC_OPCODE_CMP: transform_r300_vertex_CMP(c, inst); return 1;
	case RC_OPCODE_DP2: transform_r300_vertex_DP2(c, inst); return 1;
	case RC_OPCODE_DP3: transform_r300_vertex_DP3(c, inst); return 1;
	case RC_OPCODE_DPH: transform_DPH(c, inst); return 1;
	case RC_OPCODE_FLR: transform_FLR(c, inst); return 1;
	case RC_OPCODE_LIT: transform_r300_vertex_fix_LIT(c, inst); return 1;
	case RC_OPCODE_LRP: transform_LRP(c, inst); return 1;
	case RC_OPCODE_SEQ:
		if (!c->is_r500) {
			transform_r300_vertex_SEQ(c, inst);
			return 1;
		}
		return 0;
	case RC_OPCODE_SFL: transform_SFL(c, inst); return 1;
	case RC_OPCODE_SGT: transform_r300_vertex_SGT(c, inst); return 1;
	case RC_OPCODE_SLE: transform_r300_vertex_SLE(c, inst); return 1;
	case RC_OPCODE_SNE:
		if (!c->is_r500) {
			transform_r300_vertex_SNE(c, inst);
			return 1;
		}
		return 0;
	case RC_OPCODE_SSG: transform_r300_vertex_SSG(c, inst); return 1;
	case RC_OPCODE_SUB: transform_SUB(c, inst); return 1;
	case RC_OPCODE_SWZ: transform_SWZ(c, inst); return 1;
	case RC_OPCODE_TRUNC: transform_vertex_TRUNC(c, inst); return 1;
	case RC_OPCODE_XPD: transform_XPD(c, inst); return 1;
	default:
		return 0;
	}
}