Mesa (master): i965: Add support for FB writes on Sandybridge.

Eric Anholt anholt at kemper.freedesktop.org
Fri Aug 20 23:18:22 UTC 2010


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

Author: Zhenyu Wang <zhenyuw at linux.intel.com>
Date:   Fri Aug 20 15:02:19 2010 -0700

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 523f119..c9b4770 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 f2ace7d..78de2ce 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));




More information about the mesa-commit mailing list