Beispiel #1
0
/**
 * Emit code for TXP.
 */
static void precalc_txp( struct brw_wm_compile *c,
			       const struct prog_instruction *inst )
{
   struct prog_src_register src0 = inst->SrcReg[0];

   if (projtex(c, inst)) {
      struct prog_dst_register tmp = get_temp(c);
      struct prog_instruction tmp_inst;

      /* tmp0.w = RCP inst.arg[0][3]
       */
      emit_op(c,
	      OPCODE_RCP,
	      dst_mask(tmp, WRITEMASK_W),
	      0,
	      src_swizzle1(src0, GET_SWZ(src0.Swizzle, W)),
	      src_undef(),
	      src_undef());

      /* tmp0.xyz =  MUL inst.arg[0], tmp0.wwww
       */
      emit_op(c,
	      OPCODE_MUL,
	      dst_mask(tmp, WRITEMASK_XYZ),
	      0,
	      src0,
	      src_swizzle1(src_reg_from_dst(tmp), W),
	      src_undef());

      /* dst = precalc(TEX tmp0)
       */
      tmp_inst = *inst;
      tmp_inst.SrcReg[0] = src_reg_from_dst(tmp);
      precalc_tex(c, &tmp_inst);

      release_temp(c, tmp);
   }
   else
   {
      /* dst = precalc(TEX src0)
       */
      precalc_tex(c, inst);
   }
}
Beispiel #2
0
/**
 * Emit code for TXP.
 */
static void precalc_txp( struct brw_wm_compile *c,
			 struct brw_fp_dst dst,
			 unsigned target,
			 unsigned unit,
			 struct brw_fp_src src0,
                         struct brw_fp_src sampler )
{
   if (projtex(c, target, src0)) {
      struct brw_fp_dst tmp = get_temp(c);

      /* tmp0.w = RCP inst.arg[0][3]
       */
      emit_op1(c,
	      TGSI_OPCODE_RCP,
	      dst_mask(tmp, BRW_WRITEMASK_W),
	      src_scalar(src0, W));

      /* tmp0.xyz =  MUL inst.arg[0], tmp0.wwww
       */
      emit_op2(c,
	       TGSI_OPCODE_MUL,
	       dst_mask(tmp, BRW_WRITEMASK_XYZ),
	       src0,
	       src_scalar(src_reg_from_dst(tmp), W));

      /* dst = TEX tmp0
       */
      precalc_tex(c, 
		  dst,
		  target,
		  unit,
		  src_reg_from_dst(tmp),
                  sampler );

      release_temp(c, tmp);
   }
   else
   {
      /* dst = TEX src0
       */
      precalc_tex(c, dst, target, unit, src0, sampler);
   }
}
Beispiel #3
0
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;
   }
}
Beispiel #4
0
/**
 * Initial pass for fragment program code generation.
 * This function is used by both the GLSL and non-GLSL paths.
 */
void brw_wm_pass_fp( struct brw_wm_compile *c )
{
   struct brw_fragment_program *fp = c->fp;
   GLuint insn;

   if (INTEL_DEBUG & DEBUG_WM) {
      printf("pre-fp:\n");
      _mesa_print_program(&fp->program.Base); 
      printf("\n");
   }

   c->pixel_xy = src_undef();
   c->delta_xy = src_undef();
   c->pixel_w = src_undef();
   c->nr_fp_insns = 0;
   c->fp->tex_units_used = 0x0;

   /* Emit preamble instructions.  This is where special instructions such as
    * WM_CINTERP, WM_LINTERP, WM_PINTERP and WM_WPOSXY are emitted to
    * compute shader inputs from varying vars.
    */
   for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) {
      const struct prog_instruction *inst = &fp->program.Base.Instructions[insn];
      validate_src_regs(c, inst);
      validate_dst_regs(c, inst);
   }

   /* Loop over all instructions doing assorted simplifications and
    * transformations.
    */
   for (insn = 0; insn < fp->program.Base.NumInstructions; insn++) {
      const struct prog_instruction *inst = &fp->program.Base.Instructions[insn];
      struct prog_instruction *out;

      /* Check for INPUT values, emit INTERP instructions where
       * necessary:
       */

      switch (inst->Opcode) {
      case OPCODE_SWZ: 
	 out = emit_insn(c, inst);
	 out->Opcode = OPCODE_MOV;
	 break;
	 
      case OPCODE_ABS:
	 out = emit_insn(c, inst);
	 out->Opcode = OPCODE_MOV;
	 out->SrcReg[0].Negate = NEGATE_NONE;
	 out->SrcReg[0].Abs = 1;
	 break;

      case OPCODE_SUB: 
	 out = emit_insn(c, inst);
	 out->Opcode = OPCODE_ADD;
	 out->SrcReg[1].Negate ^= NEGATE_XYZW;
	 break;

      case OPCODE_SCS: 
	 out = emit_insn(c, inst);
	 /* This should probably be done in the parser. 
	  */
	 out->DstReg.WriteMask &= WRITEMASK_XY;
	 break;
	 
      case OPCODE_DST:
	 precalc_dst(c, inst);
	 break;

      case OPCODE_LIT:
	 precalc_lit(c, inst);
	 break;

      case OPCODE_TEX:
	 precalc_tex(c, inst);
	 break;

      case OPCODE_TXP:
	 precalc_txp(c, inst);
	 break;

      case OPCODE_TXB:
	 out = emit_insn(c, inst);
	 out->TexSrcUnit = fp->program.Base.SamplerUnits[inst->TexSrcUnit];
         assert(out->TexSrcUnit < BRW_MAX_TEX_UNIT);
	 break;

      case OPCODE_XPD: 
	 out = emit_insn(c, inst);
	 /* This should probably be done in the parser. 
	  */
	 out->DstReg.WriteMask &= WRITEMASK_XYZ;
	 break;

      case OPCODE_KIL: 
	 out = emit_insn(c, inst);
	 /* This should probably be done in the parser. 
	  */
	 out->DstReg.WriteMask = 0;
	 break;
      case OPCODE_END:
	 emit_render_target_writes(c);
	 break;
      case OPCODE_PRINT:
	 break;
      default:
	 if (brw_wm_is_scalar_result(inst->Opcode))
	    emit_scalar_insn(c, inst);
	 else
	    emit_insn(c, inst);
	 break;
      }
   }

   if (INTEL_DEBUG & DEBUG_WM) {
      printf("pass_fp:\n");
      print_insns( c->prog_instructions, c->nr_fp_insns );
      printf("\n");
   }
}