Mesa (master): i965: Give the math opcodes information on base mrf/mrf len.

Eric Anholt anholt at kemper.freedesktop.org
Mon Oct 11 19:11:55 UTC 2010


Module: Mesa
Branch: master
Commit: 0cd6cea8a3e9339fc69f9de0da6b40e4f9d5f4fe
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0cd6cea8a3e9339fc69f9de0da6b40e4f9d5f4fe

Author: Eric Anholt <eric at anholt.net>
Date:   Fri Oct  8 14:35:34 2010 -0700

i965: Give the math opcodes information on base mrf/mrf len.

This is progress towards enabling a compute-to-MRF pass.

---

 src/mesa/drivers/dri/i965/brw_fs.cpp |   63 +++++++++++++++++++++++++++------
 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 0ea3101..f8a130c 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 5ec8c54..fb4bab7 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);




More information about the mesa-commit mailing list