From 5266c0a0c82de625ccac57e7559f57399f761e9e Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Fri, 20 Aug 2010 15:02:19 -0700 Subject: [PATCH] i965: Add support for FB writes on Sandybridge. --- src/mesa/drivers/dri/i965/brw_eu_emit.c | 52 ++++++++++++++++++++----- src/mesa/drivers/dri/i965/brw_wm_emit.c | 34 +++++++++++++++- 2 files changed, 74 insertions(+), 12 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c index 523f119f435..c9b4770fd9a 100644 --- a/src/mesa/drivers/dri/i965/brw_eu_emit.c +++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c @@ -372,9 +372,23 @@ static void brw_set_dp_write_message( struct brw_context *brw, GLuint send_commit_msg) { struct intel_context *intel = &brw->intel; - brw_set_src1(insn, brw_imm_d(0)); + brw_set_src1(insn, brw_imm_ud(0)); - if (intel->gen == 5) { + if (intel->gen >= 6) { + insn->bits3.dp_render_cache.binding_table_index = binding_table_index; + insn->bits3.dp_render_cache.msg_control = msg_control; + insn->bits3.dp_render_cache.pixel_scoreboard_clear = pixel_scoreboard_clear; + insn->bits3.dp_render_cache.msg_type = msg_type; + insn->bits3.dp_render_cache.send_commit_msg = send_commit_msg; + insn->bits3.dp_render_cache.header_present = 0; /* XXX */ + insn->bits3.dp_render_cache.response_length = response_length; + insn->bits3.dp_render_cache.msg_length = msg_length; + insn->bits3.dp_render_cache.end_of_thread = end_of_thread; + insn->header.destreg__conditionalmod = BRW_MESSAGE_TARGET_DATAPORT_WRITE; + /* XXX really need below? */ + insn->bits2.send_gen5.sfid = BRW_MESSAGE_TARGET_DATAPORT_WRITE; + insn->bits2.send_gen5.end_of_thread = end_of_thread; + } else if (intel->gen == 5) { insn->bits3.dp_write_gen5.binding_table_index = binding_table_index; insn->bits3.dp_write_gen5.msg_control = msg_control; insn->bits3.dp_write_gen5.pixel_scoreboard_clear = pixel_scoreboard_clear; @@ -1344,22 +1358,40 @@ void brw_fb_WRITE(struct brw_compile *p, GLuint response_length, GLboolean eot) { - struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND); - + struct intel_context *intel = &p->brw->intel; + struct brw_instruction *insn; + GLuint msg_control, msg_type; + + insn = next_insn(p, BRW_OPCODE_SEND); insn->header.predicate_control = 0; /* XXX */ - insn->header.compression_control = BRW_COMPRESSION_NONE; - insn->header.destreg__conditionalmod = msg_reg_nr; - + insn->header.compression_control = BRW_COMPRESSION_NONE; + + if (intel->gen >= 6) { + /* headerless version, just submit color payload */ + src0 = brw_message_reg(msg_reg_nr); + + if (msg_length >= 8) + msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE; + else + msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01; + msg_type = BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE_GEN6; + } else { + insn->header.destreg__conditionalmod = msg_reg_nr; + + msg_control = BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE; + msg_type = BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE; + } + brw_set_dest(insn, dest); brw_set_src0(insn, src0); brw_set_dp_write_message(p->brw, insn, binding_table_index, - BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE, /* msg_control */ - BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE, /* msg_type */ + msg_control, + msg_type, msg_length, 1, /* pixel scoreboard */ - response_length, + response_length, eot, 0 /* send_commit_msg */); } diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c index f2ace7d13d6..78de2ceda95 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_emit.c +++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c @@ -1230,6 +1230,7 @@ static void fire_fb_write( struct brw_wm_compile *c, GLuint eot ) { struct brw_compile *p = &c->func; + struct intel_context *intel = &p->brw->intel; struct brw_reg dst; if (c->dispatch_width == 16) @@ -1240,6 +1241,7 @@ static void fire_fb_write( struct brw_wm_compile *c, /* Pass through control information: */ /* mov (8) m1.0<1>:ud r1.0<8;8,1>:ud { Align1 NoMask } */ + if (intel->gen < 6) /* gen6, use headerless for fb write */ { brw_push_insn_state(p); brw_set_mask_control(p, BRW_MASK_DISABLE); /* ? */ @@ -1297,6 +1299,8 @@ void emit_fb_write(struct brw_wm_compile *c, struct intel_context *intel = &brw->intel; GLuint nr = 2; GLuint channel; + int step = 0; + int base_reg; /* For gen6 fb write with no header, starting from color payload directly!. */ /* Reserve a space for AA - may not be needed: */ @@ -1308,6 +1312,11 @@ void emit_fb_write(struct brw_wm_compile *c, */ brw_push_insn_state(p); + if (intel->gen >= 6) + base_reg = nr; + else + base_reg = 0; + for (channel = 0; channel < 4; channel++) { if (intel->gen >= 6) { /* gen6 SIMD16 single source DP write looks like: @@ -1339,6 +1348,16 @@ void emit_fb_write(struct brw_wm_compile *c, brw_MOV(p, brw_message_reg(nr + channel + BRW_MRF_COMPR4), arg0[channel]); + } else if (intel->gen >= 6) { + brw_set_compression_control(p, BRW_COMPRESSION_NONE); + brw_MOV(p, brw_message_reg(nr + channel + step), arg0[channel]); + if (c->dispatch_width == 16) { + brw_set_compression_control(p, BRW_COMPRESSION_NONE); + brw_MOV(p, + brw_message_reg(nr + channel + step + 1), + sechalf(arg0[channel])); + ++step; + } } else { /* mov (8) m2.0<1>:ud r28.0<8;8,1>:ud { Align1 } */ /* mov (8) m6.0<1>:ud r29.0<8;8,1>:ud { Align1 SecHalf } */ @@ -1357,7 +1376,18 @@ void emit_fb_write(struct brw_wm_compile *c, } /* skip over the regs populated above: */ - nr += 8; + if (intel->gen < 6) { + nr += 8; /* XXX: always uses SIMD16 write currently. */ + } else { + if (c->dispatch_width == 16) + nr += 8; + else + nr += 4; + + /* Subtract off the message header, since we send headerless. */ + nr -= 2; + } + brw_pop_insn_state(p); if (c->key.source_depth_to_render_target) @@ -1394,7 +1424,7 @@ void emit_fb_write(struct brw_wm_compile *c, if (c->key.aa_dest_stencil_reg) emit_aa(c, arg1, 2); - fire_fb_write(c, 0, nr, target, eot); + fire_fb_write(c, base_reg, nr, target, eot); } else { struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD)); -- 2.30.2