static void lower_texture_rect(struct r300_fragment_program_compiler *compiler,
							   struct rc_instruction *inst)
{
	struct rc_instruction *inst_rect;
	unsigned temp = rc_find_free_temporary(&compiler->Base);

	if (inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
		compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords) {
		inst_rect = rc_insert_new_instruction(&compiler->Base, inst->Prev);

		inst_rect->U.I.Opcode = RC_OPCODE_MUL;
		inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
		inst_rect->U.I.DstReg.Index = temp;
		inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
		inst_rect->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
		inst_rect->U.I.SrcReg[1].Index =
				rc_constants_add_state(&compiler->Base.Program.Constants,
									   RC_STATE_R300_TEXRECT_FACTOR, inst->U.I.TexSrcUnit);

		reset_srcreg(&inst->U.I.SrcReg[0]);
		inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
		inst->U.I.SrcReg[0].Index = temp;

		inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
	}
}
static struct rc_src_register shadow_ambient(struct r300_fragment_program_compiler *compiler,
											 int tmu)
{
	struct rc_src_register reg = { 0, };

	if (compiler->enable_shadow_ambient) {
		reg.File = RC_FILE_CONSTANT;
		reg.Index = rc_constants_add_state(&compiler->Base.Program.Constants,
										   RC_STATE_SHADOW_AMBIENT, tmu);
		reg.Swizzle = RC_SWIZZLE_WWWW;
	} else {
		reg.File = RC_FILE_NONE;
		reg.Swizzle = RC_SWIZZLE_0000;
	}
	return reg;
}
static void scale_texcoords(struct r300_fragment_program_compiler *compiler,
			    struct rc_instruction *inst,
			    unsigned state_constant)
{
	struct rc_instruction *inst_mov;

	unsigned temp = rc_find_free_temporary(&compiler->Base);

	inst_mov = rc_insert_new_instruction(&compiler->Base, inst->Prev);

	inst_mov->U.I.Opcode = RC_OPCODE_MUL;
	inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
	inst_mov->U.I.DstReg.Index = temp;
	inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
	inst_mov->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
	inst_mov->U.I.SrcReg[1].Index =
			rc_constants_add_state(&compiler->Base.Program.Constants,
					       state_constant, inst->U.I.TexSrcUnit);

	reset_srcreg(&inst->U.I.SrcReg[0]);
	inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
	inst->U.I.SrcReg[0].Index = temp;
}
/**
 * Introduce standard code fragment to deal with fragment.position.
 */
void rc_transform_fragment_wpos(struct radeon_compiler * c, unsigned wpos, unsigned new_input,
                                int full_vtransform)
{
	unsigned tempregi = rc_find_free_temporary(c);
	struct rc_instruction * inst_rcp;
	struct rc_instruction * inst_mul;
	struct rc_instruction * inst_mad;
	struct rc_instruction * inst;

	c->Program.InputsRead &= ~(1 << wpos);
	c->Program.InputsRead |= 1 << new_input;

	/* perspective divide */
	inst_rcp = rc_insert_new_instruction(c, &c->Program.Instructions);
	inst_rcp->U.I.Opcode = RC_OPCODE_RCP;

	inst_rcp->U.I.DstReg.File = RC_FILE_TEMPORARY;
	inst_rcp->U.I.DstReg.Index = tempregi;
	inst_rcp->U.I.DstReg.WriteMask = RC_MASK_W;

	inst_rcp->U.I.SrcReg[0].File = RC_FILE_INPUT;
	inst_rcp->U.I.SrcReg[0].Index = new_input;
	inst_rcp->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_WWWW;

	inst_mul = rc_insert_new_instruction(c, inst_rcp);
	inst_mul->U.I.Opcode = RC_OPCODE_MUL;

	inst_mul->U.I.DstReg.File = RC_FILE_TEMPORARY;
	inst_mul->U.I.DstReg.Index = tempregi;
	inst_mul->U.I.DstReg.WriteMask = RC_MASK_XYZ;

	inst_mul->U.I.SrcReg[0].File = RC_FILE_INPUT;
	inst_mul->U.I.SrcReg[0].Index = new_input;

	inst_mul->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
	inst_mul->U.I.SrcReg[1].Index = tempregi;
	inst_mul->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_WWWW;

	/* viewport transformation */
	inst_mad = rc_insert_new_instruction(c, inst_mul);
	inst_mad->U.I.Opcode = RC_OPCODE_MAD;

	inst_mad->U.I.DstReg.File = RC_FILE_TEMPORARY;
	inst_mad->U.I.DstReg.Index = tempregi;
	inst_mad->U.I.DstReg.WriteMask = RC_MASK_XYZ;

	inst_mad->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
	inst_mad->U.I.SrcReg[0].Index = tempregi;
	inst_mad->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZ0;

	inst_mad->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
	inst_mad->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_XYZ0;

	inst_mad->U.I.SrcReg[2].File = RC_FILE_CONSTANT;
	inst_mad->U.I.SrcReg[2].Swizzle = RC_SWIZZLE_XYZ0;

	if (full_vtransform) {
		inst_mad->U.I.SrcReg[1].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_VIEWPORT_SCALE, 0);
		inst_mad->U.I.SrcReg[2].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_VIEWPORT_OFFSET, 0);
	} else {
		inst_mad->U.I.SrcReg[1].Index =
		inst_mad->U.I.SrcReg[2].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_WINDOW_DIMENSION, 0);
	}

	for (inst = inst_mad->Next; inst != &c->Program.Instructions; inst = inst->Next) {
		const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
		unsigned i;

		for(i = 0; i < opcode->NumSrcRegs; i++) {
			if (inst->U.I.SrcReg[i].File == RC_FILE_INPUT &&
			    inst->U.I.SrcReg[i].Index == wpos) {
				inst->U.I.SrcReg[i].File = RC_FILE_TEMPORARY;
				inst->U.I.SrcReg[i].Index = tempregi;
			}
		}
	}
}