static void emit_insn( struct brw_wm_compile *c, const struct tgsi_full_instruction *inst ) { unsigned opcode = inst->Instruction.Opcode; struct brw_fp_dst dst; struct brw_fp_src src[3]; int i; dst = translate_dst( c, &inst->Dst[0], inst->Instruction.Saturate ); for (i = 0; i < inst->Instruction.NumSrcRegs; i++) src[i] = translate_src( c, &inst->Src[i] ); switch (opcode) { case TGSI_OPCODE_ABS: emit_op1(c, TGSI_OPCODE_MOV, dst, src_abs(src[0])); break; case TGSI_OPCODE_SUB: emit_op2(c, TGSI_OPCODE_ADD, dst, src[0], src_negate(src[1])); break; case TGSI_OPCODE_SCS: emit_op1(c, TGSI_OPCODE_SCS, dst_mask(dst, BRW_WRITEMASK_XY), src[0]); break; case TGSI_OPCODE_DST: precalc_dst(c, dst, src[0], src[1]); break; case TGSI_OPCODE_LIT: precalc_lit(c, dst, src[0]); break; case TGSI_OPCODE_TEX: precalc_tex(c, dst, inst->Texture.Texture, src[1].index, /* use sampler unit for tex idx */ src[0], /* coord */ src[1]); /* sampler */ break; case TGSI_OPCODE_TXP: precalc_txp(c, dst, inst->Texture.Texture, src[1].index, /* use sampler unit for tex idx */ src[0], /* coord */ src[1]); /* sampler */ break; case TGSI_OPCODE_TXB: /* XXX: TXB not done */ precalc_tex(c, dst, inst->Texture.Texture, src[1].index, /* use sampler unit for tex idx*/ src[0], src[1]); break; case TGSI_OPCODE_XPD: emit_op2(c, TGSI_OPCODE_XPD, dst_mask(dst, BRW_WRITEMASK_XYZ), src[0], src[1]); break; case TGSI_OPCODE_KIL: emit_op1(c, TGSI_OPCODE_KIL, dst_mask(dst_undef(), 0), src[0]); break; case TGSI_OPCODE_END: emit_fb_write(c); break; default: if (!c->key.has_flow_control && brw_wm_is_scalar_result(opcode)) emit_scalar_insn(c, opcode, dst, src[0], src[1], src[2]); else emit_op3(c, opcode, dst, src[0], src[1], src[2]); break; } }
static void compile_instruction( struct gl_context *ctx, struct st_translate *t, const struct prog_instruction *inst, boolean clamp_dst_color_output) { struct ureg_program *ureg = t->ureg; GLuint i; struct ureg_dst dst[1] = { { 0 } }; struct ureg_src src[4]; unsigned num_dst; unsigned num_src; num_dst = _mesa_num_inst_dst_regs( inst->Opcode ); num_src = _mesa_num_inst_src_regs( inst->Opcode ); if (num_dst) dst[0] = translate_dst( t, &inst->DstReg, inst->Saturate, clamp_dst_color_output); for (i = 0; i < num_src; i++) src[i] = translate_src( t, &inst->SrcReg[i] ); switch( inst->Opcode ) { case OPCODE_SWZ: emit_swz( t, dst[0], &inst->SrcReg[0] ); return; case OPCODE_BGNLOOP: case OPCODE_CAL: case OPCODE_ELSE: case OPCODE_ENDLOOP: debug_assert(num_dst == 0); ureg_label_insn( ureg, translate_opcode( inst->Opcode ), src, num_src, get_label( t, inst->BranchTarget )); return; case OPCODE_IF: debug_assert(num_dst == 0); ureg_label_insn( ureg, ctx->Const.NativeIntegers ? TGSI_OPCODE_UIF : TGSI_OPCODE_IF, src, num_src, get_label( t, inst->BranchTarget )); return; case OPCODE_TEX: case OPCODE_TXB: case OPCODE_TXD: case OPCODE_TXL: case OPCODE_TXP: src[num_src++] = t->samplers[inst->TexSrcUnit]; ureg_tex_insn( ureg, translate_opcode( inst->Opcode ), dst, num_dst, st_translate_texture_target( inst->TexSrcTarget, inst->TexShadow ), NULL, 0, src, num_src ); return; case OPCODE_SCS: dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XY ); ureg_insn( ureg, translate_opcode( inst->Opcode ), dst, num_dst, src, num_src ); break; case OPCODE_XPD: dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XYZ ); ureg_insn( ureg, translate_opcode( inst->Opcode ), dst, num_dst, src, num_src ); break; case OPCODE_NOISE1: case OPCODE_NOISE2: case OPCODE_NOISE3: case OPCODE_NOISE4: /* At some point, a motivated person could add a better * implementation of noise. Currently not even the nvidia * binary drivers do anything more than this. In any case, the * place to do this is in the GL state tracker, not the poor * driver. */ ureg_MOV( ureg, dst[0], ureg_imm1f(ureg, 0.5) ); break; case OPCODE_DDY: emit_ddy( t, dst[0], &inst->SrcReg[0] ); break; case OPCODE_RSQ: ureg_RSQ( ureg, dst[0], ureg_abs(src[0]) ); break; default: ureg_insn( ureg, translate_opcode( inst->Opcode ), dst, num_dst, src, num_src ); break; } }
static void compile_instruction( struct gl_context *ctx, struct st_translate *t, const struct prog_instruction *inst) { struct ureg_program *ureg = t->ureg; GLuint i; struct ureg_dst dst[1] = { { 0 } }; struct ureg_src src[4]; unsigned num_dst; unsigned num_src; num_dst = _mesa_num_inst_dst_regs( inst->Opcode ); num_src = _mesa_num_inst_src_regs( inst->Opcode ); if (num_dst) dst[0] = translate_dst( t, &inst->DstReg, inst->Saturate); for (i = 0; i < num_src; i++) src[i] = translate_src( t, &inst->SrcReg[i] ); switch( inst->Opcode ) { case OPCODE_SWZ: emit_swz( t, dst[0], &inst->SrcReg[0] ); return; case OPCODE_TEX: case OPCODE_TXB: case OPCODE_TXP: src[num_src++] = t->samplers[inst->TexSrcUnit]; ureg_tex_insn( ureg, translate_opcode( inst->Opcode ), dst, num_dst, st_translate_texture_target( inst->TexSrcTarget, inst->TexShadow ), NULL, 0, src, num_src ); return; case OPCODE_SCS: dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XY ); ureg_insn( ureg, translate_opcode( inst->Opcode ), dst, num_dst, src, num_src ); break; case OPCODE_XPD: dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XYZ ); ureg_insn( ureg, translate_opcode( inst->Opcode ), dst, num_dst, src, num_src ); break; case OPCODE_RSQ: ureg_RSQ( ureg, dst[0], ureg_abs(src[0]) ); break; case OPCODE_ABS: ureg_MOV(ureg, dst[0], ureg_abs(src[0])); break; case OPCODE_SUB: ureg_ADD(ureg, dst[0], src[0], ureg_negate(src[1])); break; default: ureg_insn( ureg, translate_opcode( inst->Opcode ), dst, num_dst, src, num_src ); break; } }