From 0cd6cea8a3e9339fc69f9de0da6b40e4f9d5f4fe Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 8 Oct 2010 14:35:34 -0700 Subject: [PATCH] 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 0ea31015667..f8a130c8140 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 5ec8c54582b..fb4bab763cc 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); -- 2.30.2