/** * Emit a paired ALU instruction. */ static GLboolean emit_paired(void *data, struct radeon_pair_instruction *inst) { PROG_CODE; if (code->inst_end >= 511) { error("emit_alu: Too many instructions"); return GL_FALSE; } int ip = ++code->inst_end; code->inst[ip].inst5 = translate_rgb_op(inst->RGB.Opcode); code->inst[ip].inst4 = translate_alpha_op(inst->Alpha.Opcode); if (inst->RGB.OutputWriteMask || inst->Alpha.OutputWriteMask || inst->Alpha.DepthWriteMask) code->inst[ip].inst0 = R500_INST_TYPE_OUT; else code->inst[ip].inst0 = R500_INST_TYPE_ALU; code->inst[ip].inst0 |= R500_INST_TEX_SEM_WAIT; code->inst[ip].inst0 |= (inst->RGB.WriteMask << 11) | (inst->Alpha.WriteMask << 14); code->inst[ip].inst0 |= (inst->RGB.OutputWriteMask << 15) | (inst->Alpha.OutputWriteMask << 18); if (inst->Alpha.DepthWriteMask) { code->inst[ip].inst4 |= R500_ALPHA_W_OMASK; c->fp->writes_depth = GL_TRUE; } code->inst[ip].inst4 |= R500_ALPHA_ADDRD(inst->Alpha.DestIndex); code->inst[ip].inst5 |= R500_ALU_RGBA_ADDRD(inst->RGB.DestIndex); use_temporary(code, inst->Alpha.DestIndex); use_temporary(code, inst->RGB.DestIndex); if (inst->RGB.Saturate) code->inst[ip].inst0 |= R500_INST_RGB_CLAMP; if (inst->Alpha.Saturate) code->inst[ip].inst0 |= R500_INST_ALPHA_CLAMP; code->inst[ip].inst1 |= R500_RGB_ADDR0(use_source(code, inst->RGB.Src[0])); code->inst[ip].inst1 |= R500_RGB_ADDR1(use_source(code, inst->RGB.Src[1])); code->inst[ip].inst1 |= R500_RGB_ADDR2(use_source(code, inst->RGB.Src[2])); code->inst[ip].inst2 |= R500_ALPHA_ADDR0(use_source(code, inst->Alpha.Src[0])); code->inst[ip].inst2 |= R500_ALPHA_ADDR1(use_source(code, inst->Alpha.Src[1])); code->inst[ip].inst2 |= R500_ALPHA_ADDR2(use_source(code, inst->Alpha.Src[2])); code->inst[ip].inst3 |= translate_arg_rgb(inst, 0) << R500_ALU_RGB_SEL_A_SHIFT; code->inst[ip].inst3 |= translate_arg_rgb(inst, 1) << R500_ALU_RGB_SEL_B_SHIFT; code->inst[ip].inst5 |= translate_arg_rgb(inst, 2) << R500_ALU_RGBA_SEL_C_SHIFT; code->inst[ip].inst4 |= translate_arg_alpha(inst, 0) << R500_ALPHA_SEL_A_SHIFT; code->inst[ip].inst4 |= translate_arg_alpha(inst, 1) << R500_ALPHA_SEL_B_SHIFT; code->inst[ip].inst5 |= translate_arg_alpha(inst, 2) << R500_ALU_RGBA_ALPHA_SEL_C_SHIFT; return GL_TRUE; }
/** * Emit a single TEX instruction */ static int emit_tex(struct r300_fragment_program_compiler *c, struct rc_sub_instruction *inst) { PROG_CODE; if (code->inst_end >= c->Base.max_alu_insts-1) { error("emit_tex: Too many instructions"); return 0; } int ip = ++code->inst_end; code->inst[ip].inst0 = R500_INST_TYPE_TEX | (inst->DstReg.WriteMask << 11) | R500_INST_TEX_SEM_WAIT; code->inst[ip].inst1 = R500_TEX_ID(inst->TexSrcUnit) | R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED; if (inst->TexSrcTarget == RC_TEXTURE_RECT) code->inst[ip].inst1 |= R500_TEX_UNSCALED; switch (inst->Opcode) { case RC_OPCODE_KIL: code->inst[ip].inst1 |= R500_TEX_INST_TEXKILL; break; case RC_OPCODE_TEX: code->inst[ip].inst1 |= R500_TEX_INST_LD; break; case RC_OPCODE_TXB: code->inst[ip].inst1 |= R500_TEX_INST_LODBIAS; break; case RC_OPCODE_TXP: code->inst[ip].inst1 |= R500_TEX_INST_PROJ; break; default: error("emit_tex can't handle opcode %s\n", rc_get_opcode_info(inst->Opcode)->Name); } use_temporary(code, inst->SrcReg[0].Index); if (inst->Opcode != RC_OPCODE_KIL) use_temporary(code, inst->DstReg.Index); code->inst[ip].inst2 = R500_TEX_SRC_ADDR(inst->SrcReg[0].Index) | (translate_strq_swizzle(inst->SrcReg[0].Swizzle) << 8) | R500_TEX_DST_ADDR(inst->DstReg.Index) | R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G | R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A; return 1; }
static int emit_tex(struct r300_emit_state * emit, struct rc_instruction * inst) { unsigned int unit; unsigned int dest; unsigned int opcode; PROG_CODE; if (code->tex.length >= emit->compiler->Base.max_tex_insts) { error("Too many TEX instructions"); return 0; } unit = inst->U.I.TexSrcUnit; dest = inst->U.I.DstReg.Index; switch(inst->U.I.Opcode) { case RC_OPCODE_KIL: opcode = R300_TEX_OP_KIL; break; case RC_OPCODE_TEX: opcode = R300_TEX_OP_LD; break; case RC_OPCODE_TXB: opcode = R300_TEX_OP_TXB; break; case RC_OPCODE_TXP: opcode = R300_TEX_OP_TXP; break; default: error("Unknown texture opcode %s", rc_get_opcode_info(inst->U.I.Opcode)->Name); return 0; } if (inst->U.I.Opcode == RC_OPCODE_KIL) { unit = 0; dest = 0; } else { use_temporary(code, dest); } use_temporary(code, inst->U.I.SrcReg[0].Index); code->tex.inst[code->tex.length++] = ((inst->U.I.SrcReg[0].Index << R300_SRC_ADDR_SHIFT) & R300_SRC_ADDR_MASK) | ((dest << R300_DST_ADDR_SHIFT) & R300_DST_ADDR_MASK) | (unit << R300_TEX_ID_SHIFT) | (opcode << R300_TEX_INST_SHIFT) | (inst->U.I.SrcReg[0].Index >= R300_PFS_NUM_TEMP_REGS ? R400_SRC_ADDR_EXT_BIT : 0) | (dest >= R300_PFS_NUM_TEMP_REGS ? R400_DST_ADDR_EXT_BIT : 0) ; return 1; }
static unsigned int use_source(struct r500_fragment_program_code* code, struct radeon_pair_instruction_source src) { if (src.File == RC_FILE_CONSTANT) { return src.Index | 0x100; } else if (src.File == RC_FILE_TEMPORARY) { use_temporary(code, src.Index); return src.Index; } return 0; }
static unsigned int use_source(struct r300_fragment_program_code* code, struct rc_pair_instruction_source src) { if (!src.Used) return 0; if (src.File == RC_FILE_CONSTANT) { return src.Index | (1 << 5); } else if (src.File == RC_FILE_TEMPORARY || src.File == RC_FILE_INPUT) { use_temporary(code, src.Index); return src.Index & 0x1f; } return 0; }
static unsigned int use_source(struct r500_fragment_program_code* code, struct rc_pair_instruction_source src) { /* From docs: * Note that inline constants set the MSB of ADDR0 and clear ADDR0_CONST. * MSB = 1 << 7 */ if (!src.Used) return 1 << 7; if (src.File == RC_FILE_CONSTANT) { return src.Index | R500_RGB_ADDR0_CONST; } else if (src.File == RC_FILE_TEMPORARY || src.File == RC_FILE_INPUT) { use_temporary(code, src.Index); return src.Index; } return 0; }
/** * Emit a single TEX instruction */ static int emit_tex(struct r300_fragment_program_compiler *c, struct rc_sub_instruction *inst) { int ip; PROG_CODE; if (code->inst_end >= c->Base.max_alu_insts-1) { error("emit_tex: Too many instructions"); return 0; } ip = ++code->inst_end; code->inst[ip].inst0 = R500_INST_TYPE_TEX | (inst->DstReg.WriteMask << 11) | R500_INST_TEX_SEM_WAIT; code->inst[ip].inst1 = R500_TEX_ID(inst->TexSrcUnit) | R500_TEX_SEM_ACQUIRE; if (inst->TexSrcTarget == RC_TEXTURE_RECT) code->inst[ip].inst1 |= R500_TEX_UNSCALED; switch (inst->Opcode) { case RC_OPCODE_KIL: code->inst[ip].inst1 |= R500_TEX_INST_TEXKILL; break; case RC_OPCODE_TEX: code->inst[ip].inst1 |= R500_TEX_INST_LD; break; case RC_OPCODE_TXB: code->inst[ip].inst1 |= R500_TEX_INST_LODBIAS; break; case RC_OPCODE_TXP: code->inst[ip].inst1 |= R500_TEX_INST_PROJ; break; case RC_OPCODE_TXD: code->inst[ip].inst1 |= R500_TEX_INST_DXDY; break; case RC_OPCODE_TXL: code->inst[ip].inst1 |= R500_TEX_INST_LOD; break; default: error("emit_tex can't handle opcode %s\n", rc_get_opcode_info(inst->Opcode)->Name); } use_temporary(code, inst->SrcReg[0].Index); if (inst->Opcode != RC_OPCODE_KIL) use_temporary(code, inst->DstReg.Index); code->inst[ip].inst2 = R500_TEX_SRC_ADDR(inst->SrcReg[0].Index) | (translate_strq_swizzle(inst->SrcReg[0].Swizzle) << 8) | R500_TEX_DST_ADDR(inst->DstReg.Index) | (GET_SWZ(inst->TexSwizzle, 0) << 24) | (GET_SWZ(inst->TexSwizzle, 1) << 26) | (GET_SWZ(inst->TexSwizzle, 2) << 28) | (GET_SWZ(inst->TexSwizzle, 3) << 30) ; if (inst->Opcode == RC_OPCODE_TXD) { use_temporary(code, inst->SrcReg[1].Index); use_temporary(code, inst->SrcReg[2].Index); /* DX and DY parameters are specified in a separate register. */ code->inst[ip].inst3 = R500_DX_ADDR(inst->SrcReg[1].Index) | (translate_strq_swizzle(inst->SrcReg[1].Swizzle) << 8) | R500_DY_ADDR(inst->SrcReg[2].Index) | (translate_strq_swizzle(inst->SrcReg[2].Swizzle) << 24); } return 1; }
/** * Emit a paired ALU instruction. */ static void emit_paired(struct r300_fragment_program_compiler *c, struct rc_pair_instruction *inst) { int ip; PROG_CODE; if (code->inst_end >= c->Base.max_alu_insts-1) { error("emit_alu: Too many instructions"); return; } ip = ++code->inst_end; /* Quirk: MDH/MDV (DDX/DDY) need a NOP on previous non-TEX instructions. */ if (inst->RGB.Opcode == RC_OPCODE_DDX || inst->Alpha.Opcode == RC_OPCODE_DDX || inst->RGB.Opcode == RC_OPCODE_DDY || inst->Alpha.Opcode == RC_OPCODE_DDY) { if (ip > 0) { alu_nop(c, ip - 1); } } code->inst[ip].inst5 = translate_rgb_op(c, inst->RGB.Opcode); code->inst[ip].inst4 = translate_alpha_op(c, inst->Alpha.Opcode); if (inst->RGB.OutputWriteMask || inst->Alpha.OutputWriteMask || inst->Alpha.DepthWriteMask) { code->inst[ip].inst0 = R500_INST_TYPE_OUT; if (inst->WriteALUResult) { error("Cannot write output and ALU result at the same time"); return; } } else { code->inst[ip].inst0 = R500_INST_TYPE_ALU; } code->inst[ip].inst0 |= R500_INST_TEX_SEM_WAIT; code->inst[ip].inst0 |= (inst->RGB.WriteMask << 11); code->inst[ip].inst0 |= inst->Alpha.WriteMask ? 1 << 14 : 0; code->inst[ip].inst0 |= (inst->RGB.OutputWriteMask << 15) | (inst->Alpha.OutputWriteMask << 18); if (inst->Nop) { code->inst[ip].inst0 |= R500_INST_NOP; } if (inst->Alpha.DepthWriteMask) { code->inst[ip].inst4 |= R500_ALPHA_W_OMASK; c->code->writes_depth = 1; } code->inst[ip].inst4 |= R500_ALPHA_ADDRD(inst->Alpha.DestIndex); code->inst[ip].inst5 |= R500_ALU_RGBA_ADDRD(inst->RGB.DestIndex); use_temporary(code, inst->Alpha.DestIndex); use_temporary(code, inst->RGB.DestIndex); if (inst->RGB.Saturate) code->inst[ip].inst0 |= R500_INST_RGB_CLAMP; if (inst->Alpha.Saturate) code->inst[ip].inst0 |= R500_INST_ALPHA_CLAMP; /* Set the presubtract operation. */ switch(inst->RGB.Src[RC_PAIR_PRESUB_SRC].Index) { case RC_PRESUB_BIAS: code->inst[ip].inst1 |= R500_RGB_SRCP_OP_1_MINUS_2RGB0; break; case RC_PRESUB_SUB: code->inst[ip].inst1 |= R500_RGB_SRCP_OP_RGB1_MINUS_RGB0; break; case RC_PRESUB_ADD: code->inst[ip].inst1 |= R500_RGB_SRCP_OP_RGB1_PLUS_RGB0; break; case RC_PRESUB_INV: code->inst[ip].inst1 |= R500_RGB_SRCP_OP_1_MINUS_RGB0; break; default: break; } switch(inst->Alpha.Src[RC_PAIR_PRESUB_SRC].Index) { case RC_PRESUB_BIAS: code->inst[ip].inst2 |= R500_ALPHA_SRCP_OP_1_MINUS_2A0; break; case RC_PRESUB_SUB: code->inst[ip].inst2 |= R500_ALPHA_SRCP_OP_A1_MINUS_A0; break; case RC_PRESUB_ADD: code->inst[ip].inst2 |= R500_ALPHA_SRCP_OP_A1_PLUS_A0; break; case RC_PRESUB_INV: code->inst[ip].inst2 |= R500_ALPHA_SRCP_OP_1_MINUS_A0; break; default: break; } code->inst[ip].inst1 |= R500_RGB_ADDR0(use_source(code, inst->RGB.Src[0])); code->inst[ip].inst1 |= R500_RGB_ADDR1(use_source(code, inst->RGB.Src[1])); code->inst[ip].inst1 |= R500_RGB_ADDR2(use_source(code, inst->RGB.Src[2])); code->inst[ip].inst2 |= R500_ALPHA_ADDR0(use_source(code, inst->Alpha.Src[0])); code->inst[ip].inst2 |= R500_ALPHA_ADDR1(use_source(code, inst->Alpha.Src[1])); code->inst[ip].inst2 |= R500_ALPHA_ADDR2(use_source(code, inst->Alpha.Src[2])); code->inst[ip].inst3 |= translate_arg_rgb(inst, 0) << R500_ALU_RGB_SEL_A_SHIFT; code->inst[ip].inst3 |= translate_arg_rgb(inst, 1) << R500_ALU_RGB_SEL_B_SHIFT; code->inst[ip].inst5 |= translate_arg_rgb(inst, 2) << R500_ALU_RGBA_SEL_C_SHIFT; code->inst[ip].inst4 |= translate_arg_alpha(inst, 0) << R500_ALPHA_SEL_A_SHIFT; code->inst[ip].inst4 |= translate_arg_alpha(inst, 1) << R500_ALPHA_SEL_B_SHIFT; code->inst[ip].inst5 |= translate_arg_alpha(inst, 2) << R500_ALU_RGBA_ALPHA_SEL_C_SHIFT; code->inst[ip].inst3 |= R500_ALU_RGB_TARGET(inst->RGB.Target); code->inst[ip].inst4 |= R500_ALPHA_TARGET(inst->Alpha.Target); if (inst->WriteALUResult) { code->inst[ip].inst3 |= R500_ALU_RGB_WMASK; if (inst->WriteALUResult == RC_ALURESULT_X) code->inst[ip].inst0 |= R500_INST_ALU_RESULT_SEL_RED; else code->inst[ip].inst0 |= R500_INST_ALU_RESULT_SEL_ALPHA; code->inst[ip].inst0 |= translate_alu_result_op(c, inst->ALUResultCompare); } }
/** * Emit one paired ALU instruction. */ static int emit_alu(struct r300_emit_state * emit, struct rc_pair_instruction* inst) { int ip; int j; PROG_CODE; if (code->alu.length >= c->Base.max_alu_insts) { error("Too many ALU instructions"); return 0; } ip = code->alu.length++; code->alu.inst[ip].rgb_inst = translate_rgb_opcode(c, inst->RGB.Opcode); code->alu.inst[ip].alpha_inst = translate_alpha_opcode(c, inst->Alpha.Opcode); for(j = 0; j < 3; ++j) { /* Set the RGB address */ unsigned int src = use_source(code, inst->RGB.Src[j]); unsigned int arg; if (inst->RGB.Src[j].Index >= R300_PFS_NUM_TEMP_REGS) code->alu.inst[ip].r400_ext_addr |= R400_ADDR_EXT_RGB_MSB_BIT(j); code->alu.inst[ip].rgb_addr |= src << (6*j); /* Set the Alpha address */ src = use_source(code, inst->Alpha.Src[j]); if (inst->Alpha.Src[j].Index >= R300_PFS_NUM_TEMP_REGS) code->alu.inst[ip].r400_ext_addr |= R400_ADDR_EXT_A_MSB_BIT(j); code->alu.inst[ip].alpha_addr |= src << (6*j); arg = r300FPTranslateRGBSwizzle(inst->RGB.Arg[j].Source, inst->RGB.Arg[j].Swizzle); arg |= inst->RGB.Arg[j].Abs << 6; arg |= inst->RGB.Arg[j].Negate << 5; code->alu.inst[ip].rgb_inst |= arg << (7*j); arg = r300FPTranslateAlphaSwizzle(inst->Alpha.Arg[j].Source, inst->Alpha.Arg[j].Swizzle); arg |= inst->Alpha.Arg[j].Abs << 6; arg |= inst->Alpha.Arg[j].Negate << 5; code->alu.inst[ip].alpha_inst |= arg << (7*j); } /* Presubtract */ if (inst->RGB.Src[RC_PAIR_PRESUB_SRC].Used) { switch(inst->RGB.Src[RC_PAIR_PRESUB_SRC].Index) { case RC_PRESUB_BIAS: code->alu.inst[ip].rgb_inst |= R300_ALU_SRCP_1_MINUS_2_SRC0; break; case RC_PRESUB_ADD: code->alu.inst[ip].rgb_inst |= R300_ALU_SRCP_SRC1_PLUS_SRC0; break; case RC_PRESUB_SUB: code->alu.inst[ip].rgb_inst |= R300_ALU_SRCP_SRC1_MINUS_SRC0; break; case RC_PRESUB_INV: code->alu.inst[ip].rgb_inst |= R300_ALU_SRCP_1_MINUS_SRC0; break; default: break; } } if (inst->Alpha.Src[RC_PAIR_PRESUB_SRC].Used) { switch(inst->Alpha.Src[RC_PAIR_PRESUB_SRC].Index) { case RC_PRESUB_BIAS: code->alu.inst[ip].alpha_inst |= R300_ALU_SRCP_1_MINUS_2_SRC0; break; case RC_PRESUB_ADD: code->alu.inst[ip].alpha_inst |= R300_ALU_SRCP_SRC1_PLUS_SRC0; break; case RC_PRESUB_SUB: code->alu.inst[ip].alpha_inst |= R300_ALU_SRCP_SRC1_MINUS_SRC0; break; case RC_PRESUB_INV: code->alu.inst[ip].alpha_inst |= R300_ALU_SRCP_1_MINUS_SRC0; break; default: break; } } if (inst->RGB.Saturate) code->alu.inst[ip].rgb_inst |= R300_ALU_OUTC_CLAMP; if (inst->Alpha.Saturate) code->alu.inst[ip].alpha_inst |= R300_ALU_OUTA_CLAMP; if (inst->RGB.WriteMask) { use_temporary(code, inst->RGB.DestIndex); if (inst->RGB.DestIndex >= R300_PFS_NUM_TEMP_REGS) code->alu.inst[ip].r400_ext_addr |= R400_ADDRD_EXT_RGB_MSB_BIT; code->alu.inst[ip].rgb_addr |= ((inst->RGB.DestIndex & 0x1f) << R300_ALU_DSTC_SHIFT) | (inst->RGB.WriteMask << R300_ALU_DSTC_REG_MASK_SHIFT); } if (inst->RGB.OutputWriteMask) { code->alu.inst[ip].rgb_addr |= (inst->RGB.OutputWriteMask << R300_ALU_DSTC_OUTPUT_MASK_SHIFT) | R300_RGB_TARGET(inst->RGB.Target); emit->node_flags |= R300_RGBA_OUT; } if (inst->Alpha.WriteMask) { use_temporary(code, inst->Alpha.DestIndex); if (inst->Alpha.DestIndex >= R300_PFS_NUM_TEMP_REGS) code->alu.inst[ip].r400_ext_addr |= R400_ADDRD_EXT_A_MSB_BIT; code->alu.inst[ip].alpha_addr |= ((inst->Alpha.DestIndex & 0x1f) << R300_ALU_DSTA_SHIFT) | R300_ALU_DSTA_REG; } if (inst->Alpha.OutputWriteMask) { code->alu.inst[ip].alpha_addr |= R300_ALU_DSTA_OUTPUT | R300_ALPHA_TARGET(inst->Alpha.Target); emit->node_flags |= R300_RGBA_OUT; } if (inst->Alpha.DepthWriteMask) { code->alu.inst[ip].alpha_addr |= R300_ALU_DSTA_DEPTH; emit->node_flags |= R300_W_OUT; c->code->writes_depth = 1; } if (inst->Nop) code->alu.inst[ip].rgb_inst |= R300_ALU_INSERT_NOP; /* Handle Output Modifier * According to the r300 docs, there is no RC_OMOD_DISABLE for r300 */ if (inst->RGB.Omod) { if (inst->RGB.Omod == RC_OMOD_DISABLE) { rc_error(&c->Base, "RC_OMOD_DISABLE not supported"); } code->alu.inst[ip].rgb_inst |= (inst->RGB.Omod << R300_ALU_OUTC_MOD_SHIFT); } if (inst->Alpha.Omod) { if (inst->Alpha.Omod == RC_OMOD_DISABLE) { rc_error(&c->Base, "RC_OMOD_DISABLE not supported"); } code->alu.inst[ip].alpha_inst |= (inst->Alpha.Omod << R300_ALU_OUTC_MOD_SHIFT); } return 1; }
static GLuint use_source(struct r500_fragment_program_code* code, struct radeon_pair_instruction_source src) { if (!src.Constant) use_temporary(code, src.Index); return src.Index | src.Constant << 8; }
/** * Emit a paired ALU instruction. */ static void emit_paired(struct r300_fragment_program_compiler *c, struct rc_pair_instruction *inst) { PROG_CODE; if (code->inst_end >= 511) { error("emit_alu: Too many instructions"); return; } int ip = ++code->inst_end; code->inst[ip].inst5 = translate_rgb_op(c, inst->RGB.Opcode); code->inst[ip].inst4 = translate_alpha_op(c, inst->Alpha.Opcode); if (inst->RGB.OutputWriteMask || inst->Alpha.OutputWriteMask || inst->Alpha.DepthWriteMask) { code->inst[ip].inst0 = R500_INST_TYPE_OUT; if (inst->WriteALUResult) { error("%s: cannot write output and ALU result at the same time"); return; } } else { code->inst[ip].inst0 = R500_INST_TYPE_ALU; } code->inst[ip].inst0 |= R500_INST_TEX_SEM_WAIT; code->inst[ip].inst0 |= (inst->RGB.WriteMask << 11) | (inst->Alpha.WriteMask << 14); code->inst[ip].inst0 |= (inst->RGB.OutputWriteMask << 15) | (inst->Alpha.OutputWriteMask << 18); if (inst->Alpha.DepthWriteMask) { code->inst[ip].inst4 |= R500_ALPHA_W_OMASK; c->code->writes_depth = 1; } code->inst[ip].inst4 |= R500_ALPHA_ADDRD(inst->Alpha.DestIndex); code->inst[ip].inst5 |= R500_ALU_RGBA_ADDRD(inst->RGB.DestIndex); use_temporary(code, inst->Alpha.DestIndex); use_temporary(code, inst->RGB.DestIndex); if (inst->RGB.Saturate) code->inst[ip].inst0 |= R500_INST_RGB_CLAMP; if (inst->Alpha.Saturate) code->inst[ip].inst0 |= R500_INST_ALPHA_CLAMP; code->inst[ip].inst1 |= R500_RGB_ADDR0(use_source(code, inst->RGB.Src[0])); code->inst[ip].inst1 |= R500_RGB_ADDR1(use_source(code, inst->RGB.Src[1])); code->inst[ip].inst1 |= R500_RGB_ADDR2(use_source(code, inst->RGB.Src[2])); code->inst[ip].inst2 |= R500_ALPHA_ADDR0(use_source(code, inst->Alpha.Src[0])); code->inst[ip].inst2 |= R500_ALPHA_ADDR1(use_source(code, inst->Alpha.Src[1])); code->inst[ip].inst2 |= R500_ALPHA_ADDR2(use_source(code, inst->Alpha.Src[2])); code->inst[ip].inst3 |= translate_arg_rgb(inst, 0) << R500_ALU_RGB_SEL_A_SHIFT; code->inst[ip].inst3 |= translate_arg_rgb(inst, 1) << R500_ALU_RGB_SEL_B_SHIFT; code->inst[ip].inst5 |= translate_arg_rgb(inst, 2) << R500_ALU_RGBA_SEL_C_SHIFT; code->inst[ip].inst4 |= translate_arg_alpha(inst, 0) << R500_ALPHA_SEL_A_SHIFT; code->inst[ip].inst4 |= translate_arg_alpha(inst, 1) << R500_ALPHA_SEL_B_SHIFT; code->inst[ip].inst5 |= translate_arg_alpha(inst, 2) << R500_ALU_RGBA_ALPHA_SEL_C_SHIFT; code->inst[ip].inst3 |= R500_ALU_RGB_TARGET(inst->RGB.Target); code->inst[ip].inst4 |= R500_ALPHA_TARGET(inst->Alpha.Target); if (inst->WriteALUResult) { code->inst[ip].inst3 |= R500_ALU_RGB_WMASK; if (inst->WriteALUResult == RC_ALURESULT_X) code->inst[ip].inst0 |= R500_INST_ALU_RESULT_SEL_RED; else code->inst[ip].inst0 |= R500_INST_ALU_RESULT_SEL_ALPHA; code->inst[ip].inst0 |= translate_alu_result_op(c, inst->ALUResultCompare); } }