extsrc/mesa/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
/* gen5's sampler has slots for u, v, r, array index, then optional
 * parameters like shadow comparitor or LOD bias.  If optional
 * parameters aren't present, those base slots are optional and don't
 * need to be included in the message.
 *
 * We don't fill in the unnecessary slots regardless, which may look
 * surprising in the disassembly.
 */
gen5's sampler has slots for u, v, r, array index, then optional
parameters like shadow comparitor or LOD bias.  If optional
parameters aren't present, those base slots are optional and don't
need to be included in the message.

We don't fill in the unnecessary slots regardless, which may look
surprising in the disassembly.
gen5 ' s sampler has slots for u v r array index then optional parameters like shadow comparitor or LOD bias . If optional parameters aren ' t present those base slots are optional and don ' t need to be included in the message . We don ' t fill in the unnecessary slots regardless which may look surprising in the disassembly .
fs_inst *
fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
			      int sampler)
{
   int mlen = 0;
   int base_mrf = 2;
   int reg_width = c->dispatch_width / 8;
   bool header_present = false;
   const int vector_elements =
      ir->coordinate ? ir->coordinate->type->vector_elements : 0;
   if (ir->offset) {
      header_present = true;
      mlen++;
      base_mrf--;
   }
   for (int i = 0; i < vector_elements; i++) {
      fs_inst *inst = emit(BRW_OPCODE_MOV,
			   fs_reg(MRF, base_mrf + mlen + i * reg_width,
				  coordinate.type),
			   coordinate);
      if (i < 3 && c->key.tex.gl_clamp_mask[i] & (1 << sampler))
	 inst->saturate = true;
      coordinate.reg_offset++;
   }
   mlen += vector_elements * reg_width;
   if (ir->shadow_comparitor && ir->op != ir_txd) {
      mlen = MAX2(mlen, header_present + 4 * reg_width);
      ir->shadow_comparitor->accept(this);
      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
      mlen += reg_width;
   }
   fs_inst *inst = NULL;
   switch (ir->op) {
   case ir_tex:
      inst = emit(SHADER_OPCODE_TEX, dst);
      break;
   case ir_txb:
      ir->lod_info.bias->accept(this);
      mlen = MAX2(mlen, header_present + 4 * reg_width);
      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
      mlen += reg_width;
      inst = emit(FS_OPCODE_TXB, dst);
      break;
   case ir_txl:
      ir->lod_info.lod->accept(this);
      mlen = MAX2(mlen, header_present + 4 * reg_width);
      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
      mlen += reg_width;
      inst = emit(SHADER_OPCODE_TXL, dst);
      break;
   case ir_txd: {
      ir->lod_info.grad.dPdx->accept(this);
      fs_reg dPdx = this->result;
      ir->lod_info.grad.dPdy->accept(this);
      fs_reg dPdy = this->result;
      mlen = MAX2(mlen, header_present + 4 * reg_width); 
      for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) {
	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx);
	 dPdx.reg_offset++;
	 mlen += reg_width;
	 emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy);
	 dPdy.reg_offset++;
	 mlen += reg_width;
      }
      inst = emit(SHADER_OPCODE_TXD, dst);
      break;
   }
   case ir_txs:
      ir->lod_info.lod->accept(this);
      emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), this->result);
      mlen += reg_width;
      inst = emit(SHADER_OPCODE_TXS, dst);
      break;
   case ir_txf:
      mlen = header_present + 4 * reg_width;
      ir->lod_info.lod->accept(this);
      emit(BRW_OPCODE_MOV,
	   fs_reg(MRF, base_mrf + mlen - reg_width, BRW_REGISTER_TYPE_UD),
	   this->result);
      inst = emit(SHADER_OPCODE_TXF, dst);
      break;
   }
   inst->base_mrf = base_mrf;
   inst->mlen = mlen;
   inst->header_present = header_present;
   if (mlen > 11) {
      fail("Message length >11 disallowed by hardware\n");
   }
   return inst;
}
fs_inst * fs_visitor :: emit_texture_gen5 ( ir_texture * ir , fs_reg dst , fs_reg coordinate , int sampler ) { int mlen = 0 ; int base_mrf = 2 ; int reg_width = c -> dispatch_width / 8 ; bool header_present = false ; const int vector_elements = ir -> coordinate ? ir -> coordinate -> type -> vector_elements : 0 ; if ( ir -> offset ) { header_present = true ; mlen ++ ; base_mrf -- ; } for ( int i = 0 ; i < vector_elements ; i ++ ) { fs_inst * inst = emit ( BRW_OPCODE_MOV , fs_reg ( MRF , base_mrf + mlen + i * reg_width , coordinate . type ) , coordinate ) ; if ( i < 3 && c -> key . tex . gl_clamp_mask [ i ] & ( 1 << sampler ) ) inst -> saturate = true ; coordinate . reg_offset ++ ; } mlen += vector_elements * reg_width ; if ( ir -> shadow_comparitor && ir -> op != ir_txd ) { mlen = MAX2 ( mlen , header_present + 4 * reg_width ) ; ir -> shadow_comparitor -> accept ( this ) ; emit ( BRW_OPCODE_MOV , fs_reg ( MRF , base_mrf + mlen ) , this -> result ) ; mlen += reg_width ; } fs_inst * inst = NULL ; switch ( ir -> op ) { case ir_tex : inst = emit ( SHADER_OPCODE_TEX , dst ) ; break ; case ir_txb : ir -> lod_info . bias -> accept ( this ) ; mlen = MAX2 ( mlen , header_present + 4 * reg_width ) ; emit ( BRW_OPCODE_MOV , fs_reg ( MRF , base_mrf + mlen ) , this -> result ) ; mlen += reg_width ; inst = emit ( FS_OPCODE_TXB , dst ) ; break ; case ir_txl : ir -> lod_info . lod -> accept ( this ) ; mlen = MAX2 ( mlen , header_present + 4 * reg_width ) ; emit ( BRW_OPCODE_MOV , fs_reg ( MRF , base_mrf + mlen ) , this -> result ) ; mlen += reg_width ; inst = emit ( SHADER_OPCODE_TXL , dst ) ; break ; case ir_txd : { ir -> lod_info . grad . dPdx -> accept ( this ) ; fs_reg dPdx = this -> result ; ir -> lod_info . grad . dPdy -> accept ( this ) ; fs_reg dPdy = this -> result ; mlen = MAX2 ( mlen , header_present + 4 * reg_width ) ; for ( int i = 0 ; i < ir -> lod_info . grad . dPdx -> type -> vector_elements ; i ++ ) { emit ( BRW_OPCODE_MOV , fs_reg ( MRF , base_mrf + mlen ) , dPdx ) ; dPdx . reg_offset ++ ; mlen += reg_width ; emit ( BRW_OPCODE_MOV , fs_reg ( MRF , base_mrf + mlen ) , dPdy ) ; dPdy . reg_offset ++ ; mlen += reg_width ; } inst = emit ( SHADER_OPCODE_TXD , dst ) ; break ; } case ir_txs : ir -> lod_info . lod -> accept ( this ) ; emit ( BRW_OPCODE_MOV , fs_reg ( MRF , base_mrf + mlen , BRW_REGISTER_TYPE_UD ) , this -> result ) ; mlen += reg_width ; inst = emit ( SHADER_OPCODE_TXS , dst ) ; break ; case ir_txf : mlen = header_present + 4 * reg_width ; ir -> lod_info . lod -> accept ( this ) ; emit ( BRW_OPCODE_MOV , fs_reg ( MRF , base_mrf + mlen - reg_width , BRW_REGISTER_TYPE_UD ) , this -> result ) ; inst = emit ( SHADER_OPCODE_TXF , dst ) ; break ; } inst -> base_mrf = base_mrf ; inst -> mlen = mlen ; inst -> header_present = header_present ; if ( mlen > 11 ) { fail ( " \n " ) ; } return inst ; }
gen5's sampler has slots for u, v, r, array index, then optional
 parameters like shadow comparitor or LOD bias.
gen5 ' s sampler has slots for u v r array index then optional parameters like shadow comparitor or LOD bias .
/* The offsets set up by the ir_texture visitor are in the
       * m1 header, so we can't go headerless.
       */ /* skip over 'ai' */ /**
       *  P   =  u,    v,    r
       * dPdx = dudx, dvdx, drdx
       * dPdy = dudy, dvdy, drdy
       *
       * Load up these values:
       * - dudx   dudy   dvdx   dvdy   drdx   drdy
       * - dPdx.x dPdy.x dPdx.y dPdy.y dPdx.z dPdy.z
       */