static struct brw_fp_instruction * emit_tex_op(struct brw_wm_compile *c, GLuint op, struct brw_fp_dst dest, GLuint tex_unit, GLuint target, GLuint sampler, struct brw_fp_src src0, struct brw_fp_src src1, struct brw_fp_src src2 ) { struct brw_fp_instruction *inst = get_fp_inst(c); if (tex_unit || target) assert(op == TGSI_OPCODE_TXP || op == TGSI_OPCODE_TXB || op == TGSI_OPCODE_TEX || op == WM_FB_WRITE); inst->opcode = op; inst->dst = dest; inst->tex_unit = tex_unit; inst->target = target; inst->sampler = sampler; inst->src[0] = src0; inst->src[1] = src1; inst->src[2] = src2; return inst; }
/* Many Mesa opcodes produce the same value across all the result channels. * We'd rather not have to support that splatting in the opcode implementations, * and brw_wm_pass*.c wants to optimize them out by shuffling references around * anyway. We can easily get both by emitting the opcode to one channel, and * then MOVing it to the others, which brw_wm_pass*.c already understands. */ static struct prog_instruction *emit_scalar_insn(struct brw_wm_compile *c, const struct prog_instruction *inst0) { struct prog_instruction *inst; unsigned int dst_chan; unsigned int other_channel_mask; if (inst0->DstReg.WriteMask == 0) return NULL; dst_chan = _mesa_ffs(inst0->DstReg.WriteMask) - 1; inst = get_fp_inst(c); *inst = *inst0; inst->DstReg.WriteMask = 1 << dst_chan; other_channel_mask = inst0->DstReg.WriteMask & ~(1 << dst_chan); if (other_channel_mask != 0) { inst = emit_op(c, OPCODE_MOV, dst_mask(inst0->DstReg, other_channel_mask), 0, src_swizzle1(src_reg_from_dst(inst0->DstReg), dst_chan), src_undef(), src_undef()); } return inst; }
static struct prog_instruction *emit_insn(struct brw_wm_compile *c, const struct prog_instruction *inst0) { struct prog_instruction *inst = get_fp_inst(c); *inst = *inst0; return inst; }
static struct prog_instruction * emit_tex_op(struct brw_wm_compile *c, GLuint op, struct prog_dst_register dest, GLuint saturate, GLuint tex_src_unit, GLuint tex_src_target, GLuint tex_shadow, struct prog_src_register src0, struct prog_src_register src1, struct prog_src_register src2 ) { struct prog_instruction *inst = get_fp_inst(c); assert(tex_src_unit < BRW_MAX_TEX_UNIT || tex_src_unit == TEX_UNIT_NONE); assert(tex_src_target < NUM_TEXTURE_TARGETS || tex_src_target == TEX_TARGET_NONE); /* update mask of which texture units are referenced by this program */ if (tex_src_unit != TEX_UNIT_NONE) c->fp->tex_units_used |= (1 << tex_src_unit); memset(inst, 0, sizeof(*inst)); inst->Opcode = op; inst->DstReg = dest; inst->SaturateMode = saturate; inst->TexSrcUnit = tex_src_unit; inst->TexSrcTarget = tex_src_target; inst->TexShadow = tex_shadow; inst->SrcReg[0] = src0; inst->SrcReg[1] = src1; inst->SrcReg[2] = src2; return inst; }
static struct prog_instruction * emit_op(struct brw_wm_compile *c, GLuint op, struct prog_dst_register dest, GLuint saturate, GLuint tex_src_unit, GLuint tex_src_target, struct prog_src_register src0, struct prog_src_register src1, struct prog_src_register src2 ) { struct prog_instruction *inst = get_fp_inst(c); memset(inst, 0, sizeof(*inst)); inst->Opcode = op; inst->DstReg = dest; inst->SaturateMode = saturate; inst->TexSrcUnit = tex_src_unit; inst->TexSrcTarget = tex_src_target; inst->SrcReg[0] = src0; inst->SrcReg[1] = src1; inst->SrcReg[2] = src2; return inst; }