/** * 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; }
/** * Emit a single TEX instruction */ static GLboolean emit_tex(void *data, struct prog_instruction *inst) { PROG_CODE; if (code->inst_end >= 511) { error("emit_tex: Too many instructions"); return GL_FALSE; } 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 == TEXTURE_RECT_INDEX) code->inst[ip].inst1 |= R500_TEX_UNSCALED; switch (inst->Opcode) { case OPCODE_KIL: code->inst[ip].inst1 |= R500_TEX_INST_TEXKILL; break; case OPCODE_TEX: code->inst[ip].inst1 |= R500_TEX_INST_LD; break; case OPCODE_TXB: code->inst[ip].inst1 |= R500_TEX_INST_LODBIAS; break; case OPCODE_TXP: code->inst[ip].inst1 |= R500_TEX_INST_PROJ; break; default: error("emit_tex can't handle opcode %x\n", inst->Opcode); } code->inst[ip].inst2 = R500_TEX_SRC_ADDR(inst->SrcReg[0].Index) | (translate_strq_swizzle(inst->SrcReg[0]) << 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 GL_TRUE; }
/** * 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; }