diff options
Diffstat (limited to 'src/mesa/drivers')
| -rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.cpp | 63 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.h | 6 | 
2 files changed, 57 insertions, 12 deletions
| diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 0ea3101566..f8a130c814 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -514,6 +514,43 @@ fs_visitor::emit_frontfacing_interpolation(ir_variable *ir)     return reg;  } +fs_inst * +fs_visitor::emit_math(fs_opcodes opcode, fs_reg dst, fs_reg src) +{ +   switch (opcode) { +   case FS_OPCODE_RCP: +   case FS_OPCODE_RSQ: +   case FS_OPCODE_SQRT: +   case FS_OPCODE_EXP2: +   case FS_OPCODE_LOG2: +   case FS_OPCODE_SIN: +   case FS_OPCODE_COS: +      break; +   default: +      assert(!"not reached: bad math opcode"); +      return NULL; +   } +   fs_inst *inst = emit(fs_inst(opcode, dst, src)); + +   inst->base_mrf = 2; +   inst->mlen = 1; + +   return inst; +} + +fs_inst * +fs_visitor::emit_math(fs_opcodes opcode, fs_reg dst, fs_reg src0, fs_reg src1) +{ +   assert(opcode == FS_OPCODE_POW); + +   fs_inst *inst = emit(fs_inst(opcode, dst, src0, src1)); + +   inst->base_mrf = 2; +   inst->mlen = 2; + +   return inst; +} +  void  fs_visitor::visit(ir_variable *ir)  { @@ -668,24 +705,24 @@ fs_visitor::visit(ir_expression *ir)        break;     case ir_unop_rcp: -      emit(fs_inst(FS_OPCODE_RCP, this->result, op[0])); +      emit_math(FS_OPCODE_RCP, this->result, op[0]);        break;     case ir_unop_exp2: -      emit(fs_inst(FS_OPCODE_EXP2, this->result, op[0])); +      emit_math(FS_OPCODE_EXP2, this->result, op[0]);        break;     case ir_unop_log2: -      emit(fs_inst(FS_OPCODE_LOG2, this->result, op[0])); +      emit_math(FS_OPCODE_LOG2, this->result, op[0]);        break;     case ir_unop_exp:     case ir_unop_log:        assert(!"not reached: should be handled by ir_explog_to_explog2");        break;     case ir_unop_sin: -      emit(fs_inst(FS_OPCODE_SIN, this->result, op[0])); +      emit_math(FS_OPCODE_SIN, this->result, op[0]);        break;     case ir_unop_cos: -      emit(fs_inst(FS_OPCODE_COS, this->result, op[0])); +      emit_math(FS_OPCODE_COS, this->result, op[0]);        break;     case ir_unop_dFdx: @@ -768,11 +805,11 @@ fs_visitor::visit(ir_expression *ir)        break;     case ir_unop_sqrt: -      emit(fs_inst(FS_OPCODE_SQRT, this->result, op[0])); +      emit_math(FS_OPCODE_SQRT, this->result, op[0]);        break;     case ir_unop_rsq: -      emit(fs_inst(FS_OPCODE_RSQ, this->result, op[0])); +      emit_math(FS_OPCODE_RSQ, this->result, op[0]);        break;     case ir_unop_i2f: @@ -819,7 +856,7 @@ fs_visitor::visit(ir_expression *ir)        break;     case ir_binop_pow: -      inst = emit(fs_inst(FS_OPCODE_POW, this->result, op[0], op[1])); +      emit_math(FS_OPCODE_POW, this->result, op[0], op[1]);        break;     case ir_unop_bit_not: @@ -1492,7 +1529,7 @@ fs_visitor::emit_interpolation_setup_gen4()  		interp_reg(FRAG_ATTRIB_WPOS, 3)));     /* Compute the pixel 1/W value from wpos.w. */     this->pixel_w = fs_reg(this, glsl_type::float_type); -   emit(fs_inst(FS_OPCODE_RCP, this->pixel_w, wpos_w)); +   emit_math(FS_OPCODE_RCP, this->pixel_w, wpos_w);     this->current_annotation = NULL;  } @@ -1520,7 +1557,7 @@ fs_visitor::emit_interpolation_setup_gen6()     this->current_annotation = "compute 1/pos.w";     this->wpos_w = fs_reg(brw_vec8_grf(c->key.source_w_reg, 0));     this->pixel_w = fs_reg(this, glsl_type::float_type); -   emit(fs_inst(FS_OPCODE_RCP, this->pixel_w, wpos_w)); +   emit_math(FS_OPCODE_RCP, this->pixel_w, wpos_w);     this->delta_x = fs_reg(brw_vec8_grf(2, 0));     this->delta_y = fs_reg(brw_vec8_grf(3, 0)); @@ -1714,15 +1751,17 @@ fs_visitor::generate_math(fs_inst *inst,        break;     } +   assert(inst->mlen >= 1); +     if (inst->opcode == FS_OPCODE_POW) { -      brw_MOV(p, brw_message_reg(3), src[1]); +      brw_MOV(p, brw_message_reg(inst->base_mrf + 1), src[1]);     }     brw_math(p, dst,  	    op,  	    inst->saturate ? BRW_MATH_SATURATE_SATURATE :  	    BRW_MATH_SATURATE_NONE, -	    2, src[0], +	    inst->base_mrf, src[0],  	    BRW_MATH_DATA_VECTOR,  	    BRW_MATH_PRECISION_FULL);  } diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 5ec8c54582..fb4bab763c 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -193,6 +193,8 @@ public:        this->eot = false;        this->header_present = false;        this->shadow_compare = false; +      this->mlen = 0; +      this->base_mrf = 0;     }     fs_inst() @@ -241,6 +243,7 @@ public:     int conditional_mod; /**< BRW_CONDITIONAL_* */     int mlen; /**< SEND message length */ +   int base_mrf; /**< First MRF in the SEND message, if mlen is nonzero. */     int sampler;     int target; /**< MRT target. */     bool eot; @@ -350,6 +353,9 @@ public:     void emit_interpolation_setup_gen6();     fs_inst *emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate);     fs_inst *emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate); +   fs_inst *emit_math(fs_opcodes op, fs_reg dst, fs_reg src0); +   fs_inst *emit_math(fs_opcodes op, fs_reg dst, fs_reg src0, fs_reg src1); +     void emit_fb_writes();     void emit_assignment_writes(fs_reg &l, fs_reg &r,  			       const glsl_type *type, bool predicated); | 
