i965: Factor out code for setting Message Descriptors.
authorKenneth Graunke <kenneth@whitecape.org>
Sat, 8 Oct 2011 04:09:08 +0000 (21:09 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Tue, 18 Oct 2011 22:57:55 +0000 (15:57 -0700)
Every brw_set_???_message function had duplicated code, per-generation,
to set the Message Descriptor and Extended Message Descriptor bits
(SFID, message length, response length, header present, end of thread).

However, these fields are actually specified as part of the SEND
instruction itself; individual types of messages don't even specify
them (except for header present, but that's in the same bit location).

Since these are exactly the same regardless of the message type, just
create a function to set them, using the generic message structs.  This
not only shortens the code, but hides a lot of the per-generation
complexity (like the SFID being in destreg__conditionalmod) in one spot.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_eu_emit.c

index 36ed2eed079bb9b2cd7ebff994f94b921c0ed309..078e289d35b91081d2299bdcb287e8aa8f3fb551 100644 (file)
@@ -370,7 +370,48 @@ void brw_set_src1(struct brw_compile *p,
    }
 }
 
+/**
+ * Set the Message Descriptor and Extended Message Descriptor fields
+ * for SEND messages.
+ *
+ * \note This zeroes out the Function Control bits, so it must be called
+ *       \b before filling out any message-specific data.  Callers can
+ *       choose not to fill in irrelevant bits; they will be zero.
+ */
+static void
+brw_set_message_descriptor(struct brw_compile *p,
+                          struct brw_instruction *inst,
+                          enum brw_message_target sfid,
+                          unsigned msg_length,
+                          unsigned response_length,
+                          bool header_present,
+                          bool end_of_thread)
+{
+   struct intel_context *intel = &p->brw->intel;
+
+   brw_set_src1(p, inst, brw_imm_d(0));
 
+   if (intel->gen >= 5) {
+      inst->bits3.generic_gen5.header_present = header_present;
+      inst->bits3.generic_gen5.response_length = response_length;
+      inst->bits3.generic_gen5.msg_length = msg_length;
+      inst->bits3.generic_gen5.end_of_thread = end_of_thread;
+
+      if (intel->gen >= 6) {
+        /* On Gen6+ Message target/SFID goes in bits 27:24 of the header */
+        inst->header.destreg__conditionalmod = sfid;
+      } else {
+        /* Set Extended Message Descriptor (ex_desc) */
+        inst->bits2.send_gen5.sfid = sfid;
+        inst->bits2.send_gen5.end_of_thread = end_of_thread;
+      }
+   } else {
+      inst->bits3.generic.response_length = response_length;
+      inst->bits3.generic.msg_length = msg_length;
+      inst->bits3.generic.msg_target = sfid;
+      inst->bits3.generic.end_of_thread = end_of_thread;
+   }
+}
 
 static void brw_set_math_message( struct brw_compile *p,
                                  struct brw_instruction *insn,
@@ -409,7 +450,8 @@ static void brw_set_math_message( struct brw_compile *p,
       break;
    }
 
-   brw_set_src1(p, insn, brw_imm_d(0));
+   brw_set_message_descriptor(p, insn, BRW_SFID_MATH,
+                             msg_length, response_length, false, false);
    if (intel->gen == 5) {
       insn->bits3.math_gen5.function = function;
       insn->bits3.math_gen5.int_type = integer_type;
@@ -417,22 +459,12 @@ static void brw_set_math_message( struct brw_compile *p,
       insn->bits3.math_gen5.saturate = saturate;
       insn->bits3.math_gen5.data_type = dataType;
       insn->bits3.math_gen5.snapshot = 0;
-      insn->bits3.math_gen5.header_present = 0;
-      insn->bits3.math_gen5.response_length = response_length;
-      insn->bits3.math_gen5.msg_length = msg_length;
-      insn->bits3.math_gen5.end_of_thread = 0;
-      insn->bits2.send_gen5.sfid = BRW_SFID_MATH;
-      insn->bits2.send_gen5.end_of_thread = 0;
    } else {
       insn->bits3.math.function = function;
       insn->bits3.math.int_type = integer_type;
       insn->bits3.math.precision = low_precision;
       insn->bits3.math.saturate = saturate;
       insn->bits3.math.data_type = dataType;
-      insn->bits3.math.response_length = response_length;
-      insn->bits3.math.msg_length = msg_length;
-      insn->bits3.math.msg_target = BRW_SFID_MATH;
-      insn->bits3.math.end_of_thread = 0;
    }
 }
 
@@ -445,24 +477,15 @@ static void brw_set_ff_sync_message(struct brw_compile *p,
 {
    struct brw_context *brw = p->brw;
    struct intel_context *intel = &brw->intel;
-   brw_set_src1(p, insn, brw_imm_d(0));
 
+   brw_set_message_descriptor(p, insn, BRW_SFID_URB,
+                             1, response_length, true, end_of_thread);
    insn->bits3.urb_gen5.opcode = 1; /* FF_SYNC */
    insn->bits3.urb_gen5.offset = 0; /* Not used by FF_SYNC */
    insn->bits3.urb_gen5.swizzle_control = 0; /* Not used by FF_SYNC */
    insn->bits3.urb_gen5.allocate = allocate;
    insn->bits3.urb_gen5.used = 0; /* Not used by FF_SYNC */
    insn->bits3.urb_gen5.complete = 0; /* Not used by FF_SYNC */
-   insn->bits3.urb_gen5.header_present = 1;
-   insn->bits3.urb_gen5.response_length = response_length; /* may be 1 or 0 */
-   insn->bits3.urb_gen5.msg_length = 1;
-   insn->bits3.urb_gen5.end_of_thread = end_of_thread;
-   if (intel->gen >= 6) {
-      insn->header.destreg__conditionalmod = BRW_SFID_URB;
-   } else {
-      insn->bits2.send_gen5.sfid = BRW_SFID_URB;
-      insn->bits2.send_gen5.end_of_thread = end_of_thread;
-   }
 }
 
 static void brw_set_urb_message( struct brw_compile *p,
@@ -478,8 +501,9 @@ static void brw_set_urb_message( struct brw_compile *p,
 {
    struct brw_context *brw = p->brw;
    struct intel_context *intel = &brw->intel;
-   brw_set_src1(p, insn, brw_imm_d(0));
 
+   brw_set_message_descriptor(p, insn, BRW_SFID_URB,
+                             msg_length, response_length, true, end_of_thread);
    if (intel->gen == 7) {
       insn->bits3.urb_gen7.opcode = 0; /* URB_WRITE_HWORD */
       insn->bits3.urb_gen7.offset = offset;
@@ -488,11 +512,6 @@ static void brw_set_urb_message( struct brw_compile *p,
       /* per_slot_offset = 0 makes it ignore offsets in message header */
       insn->bits3.urb_gen7.per_slot_offset = 0;
       insn->bits3.urb_gen7.complete = complete;
-      insn->bits3.urb_gen7.header_present = 1;
-      insn->bits3.urb_gen7.response_length = response_length;
-      insn->bits3.urb_gen7.msg_length = msg_length;
-      insn->bits3.urb_gen7.end_of_thread = end_of_thread;
-      insn->header.destreg__conditionalmod = BRW_SFID_URB;
    } else if (intel->gen >= 5) {
       insn->bits3.urb_gen5.opcode = 0; /* URB_WRITE */
       insn->bits3.urb_gen5.offset = offset;
@@ -500,20 +519,6 @@ static void brw_set_urb_message( struct brw_compile *p,
       insn->bits3.urb_gen5.allocate = allocate;
       insn->bits3.urb_gen5.used = used;        /* ? */
       insn->bits3.urb_gen5.complete = complete;
-      insn->bits3.urb_gen5.header_present = 1;
-      insn->bits3.urb_gen5.response_length = response_length;
-      insn->bits3.urb_gen5.msg_length = msg_length;
-      insn->bits3.urb_gen5.end_of_thread = end_of_thread;
-      if (intel->gen >= 6) {
-        /* For SNB, the SFID bits moved to the condmod bits, and
-         * EOT stayed in bits3 above.  Does the EOT bit setting
-         * below on Ironlake even do anything?
-         */
-        insn->header.destreg__conditionalmod = BRW_SFID_URB;
-      } else {
-        insn->bits2.send_gen5.sfid = BRW_SFID_URB;
-        insn->bits2.send_gen5.end_of_thread = end_of_thread;
-      }
    } else {
       insn->bits3.urb.opcode = 0;      /* ? */
       insn->bits3.urb.offset = offset;
@@ -521,10 +526,6 @@ static void brw_set_urb_message( struct brw_compile *p,
       insn->bits3.urb.allocate = allocate;
       insn->bits3.urb.used = used;     /* ? */
       insn->bits3.urb.complete = complete;
-      insn->bits3.urb.response_length = response_length;
-      insn->bits3.urb.msg_length = msg_length;
-      insn->bits3.urb.msg_target = BRW_SFID_URB;
-      insn->bits3.urb.end_of_thread = end_of_thread;
    }
 }
 
@@ -543,59 +544,47 @@ brw_set_dp_write_message(struct brw_compile *p,
 {
    struct brw_context *brw = p->brw;
    struct intel_context *intel = &brw->intel;
-   brw_set_src1(p, insn, brw_imm_ud(0));
+   unsigned sfid;
 
    if (intel->gen >= 7) {
       /* Use the Render Cache for RT writes; otherwise use the Data Cache */
-      unsigned sfid = GEN7_SFID_DATAPORT_DATA_CACHE;
       if (msg_type == GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE)
         sfid = GEN6_SFID_DATAPORT_RENDER_CACHE;
+      else
+        sfid = GEN7_SFID_DATAPORT_DATA_CACHE;
+   } else if (intel->gen == 6) {
+      /* Use the render cache for all write messages. */
+      sfid = GEN6_SFID_DATAPORT_RENDER_CACHE;
+   } else {
+      sfid = BRW_SFID_DATAPORT_WRITE;
+   }
 
-      insn->header.destreg__conditionalmod = sfid;
+   brw_set_message_descriptor(p, insn, sfid, msg_length, response_length,
+                             header_present, end_of_thread);
 
+   if (intel->gen >= 7) {
       insn->bits3.gen7_dp.binding_table_index = binding_table_index;
       insn->bits3.gen7_dp.msg_control = msg_control;
       insn->bits3.gen7_dp.pixel_scoreboard_clear = pixel_scoreboard_clear;
       insn->bits3.gen7_dp.msg_type = msg_type;
-      insn->bits3.gen7_dp.header_present = header_present;
-      insn->bits3.gen7_dp.response_length = response_length;
-      insn->bits3.gen7_dp.msg_length = msg_length;
-      insn->bits3.gen7_dp.end_of_thread = end_of_thread;
    } else if (intel->gen == 6) {
       insn->bits3.gen6_dp.binding_table_index = binding_table_index;
       insn->bits3.gen6_dp.msg_control = msg_control;
       insn->bits3.gen6_dp.pixel_scoreboard_clear = pixel_scoreboard_clear;
       insn->bits3.gen6_dp.msg_type = msg_type;
       insn->bits3.gen6_dp.send_commit_msg = send_commit_msg;
-      insn->bits3.gen6_dp.header_present = header_present;
-      insn->bits3.gen6_dp.response_length = response_length;
-      insn->bits3.gen6_dp.msg_length = msg_length;
-      insn->bits3.gen6_dp.end_of_thread = end_of_thread;
-
-      /* We always use the render cache for write messages */
-      insn->header.destreg__conditionalmod = GEN6_SFID_DATAPORT_RENDER_CACHE;
    } 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;
       insn->bits3.dp_write_gen5.msg_type = msg_type;
       insn->bits3.dp_write_gen5.send_commit_msg = send_commit_msg;
-      insn->bits3.dp_write_gen5.header_present = header_present;
-      insn->bits3.dp_write_gen5.response_length = response_length;
-      insn->bits3.dp_write_gen5.msg_length = msg_length;
-      insn->bits3.dp_write_gen5.end_of_thread = end_of_thread;
-      insn->bits2.send_gen5.sfid = BRW_SFID_DATAPORT_WRITE;
-      insn->bits2.send_gen5.end_of_thread = end_of_thread;
    } else {
       insn->bits3.dp_write.binding_table_index = binding_table_index;
       insn->bits3.dp_write.msg_control = msg_control;
       insn->bits3.dp_write.pixel_scoreboard_clear = pixel_scoreboard_clear;
       insn->bits3.dp_write.msg_type = msg_type;
       insn->bits3.dp_write.send_commit_msg = send_commit_msg;
-      insn->bits3.dp_write.response_length = response_length;
-      insn->bits3.dp_write.msg_length = msg_length;
-      insn->bits3.dp_write.msg_target = BRW_SFID_DATAPORT_WRITE;
-      insn->bits3.dp_write.end_of_thread = end_of_thread;
    }
 }
 
@@ -611,68 +600,48 @@ brw_set_dp_read_message(struct brw_compile *p,
 {
    struct brw_context *brw = p->brw;
    struct intel_context *intel = &brw->intel;
-   brw_set_src1(p, insn, brw_imm_d(0));
+   unsigned sfid;
+
+   if (intel->gen >= 7) {
+      sfid = GEN7_SFID_DATAPORT_DATA_CACHE;
+   } else if (intel->gen == 6) {
+      if (target_cache == BRW_DATAPORT_READ_TARGET_RENDER_CACHE)
+        sfid = GEN6_SFID_DATAPORT_RENDER_CACHE;
+      else
+        sfid = GEN6_SFID_DATAPORT_SAMPLER_CACHE;
+   } else {
+      sfid = BRW_SFID_DATAPORT_READ;
+   }
+
+   brw_set_message_descriptor(p, insn, sfid, msg_length, response_length,
+                             true, false);
 
    if (intel->gen >= 7) {
       insn->bits3.gen7_dp.binding_table_index = binding_table_index;
       insn->bits3.gen7_dp.msg_control = msg_control;
       insn->bits3.gen7_dp.pixel_scoreboard_clear = 0;
       insn->bits3.gen7_dp.msg_type = msg_type;
-      insn->bits3.gen7_dp.header_present = 1;
-      insn->bits3.gen7_dp.response_length = response_length;
-      insn->bits3.gen7_dp.msg_length = msg_length;
-      insn->bits3.gen7_dp.end_of_thread = 0;
-      insn->header.destreg__conditionalmod = GEN7_SFID_DATAPORT_DATA_CACHE;
    } else if (intel->gen == 6) {
-      uint32_t target_function;
-
-      if (target_cache == BRW_DATAPORT_READ_TARGET_RENDER_CACHE)
-        target_function = GEN6_SFID_DATAPORT_RENDER_CACHE;
-      else
-        target_function = GEN6_SFID_DATAPORT_SAMPLER_CACHE;
-
       insn->bits3.gen6_dp.binding_table_index = binding_table_index;
       insn->bits3.gen6_dp.msg_control = msg_control;
       insn->bits3.gen6_dp.pixel_scoreboard_clear = 0;
       insn->bits3.gen6_dp.msg_type = msg_type;
       insn->bits3.gen6_dp.send_commit_msg = 0;
-      insn->bits3.gen6_dp.header_present = 1;
-      insn->bits3.gen6_dp.response_length = response_length;
-      insn->bits3.gen6_dp.msg_length = msg_length;
-      insn->bits3.gen6_dp.end_of_thread = 0;
-      insn->header.destreg__conditionalmod = target_function;
    } else if (intel->gen == 5) {
       insn->bits3.dp_read_gen5.binding_table_index = binding_table_index;
       insn->bits3.dp_read_gen5.msg_control = msg_control;
       insn->bits3.dp_read_gen5.msg_type = msg_type;
       insn->bits3.dp_read_gen5.target_cache = target_cache;
-      insn->bits3.dp_read_gen5.header_present = 1;
-      insn->bits3.dp_read_gen5.response_length = response_length;
-      insn->bits3.dp_read_gen5.msg_length = msg_length;
-      insn->bits3.dp_read_gen5.pad1 = 0;
-      insn->bits3.dp_read_gen5.end_of_thread = 0;
-      insn->bits2.send_gen5.sfid = BRW_SFID_DATAPORT_READ;
-      insn->bits2.send_gen5.end_of_thread = 0;
    } else if (intel->is_g4x) {
       insn->bits3.dp_read_g4x.binding_table_index = binding_table_index; /*0:7*/
       insn->bits3.dp_read_g4x.msg_control = msg_control;  /*8:10*/
       insn->bits3.dp_read_g4x.msg_type = msg_type;  /*11:13*/
       insn->bits3.dp_read_g4x.target_cache = target_cache;  /*14:15*/
-      insn->bits3.dp_read_g4x.response_length = response_length;  /*16:19*/
-      insn->bits3.dp_read_g4x.msg_length = msg_length;  /*20:23*/
-      insn->bits3.dp_read_g4x.msg_target = BRW_SFID_DATAPORT_READ; /*24:27*/
-      insn->bits3.dp_read_g4x.pad1 = 0;
-      insn->bits3.dp_read_g4x.end_of_thread = 0;
    } else {
       insn->bits3.dp_read.binding_table_index = binding_table_index; /*0:7*/
       insn->bits3.dp_read.msg_control = msg_control;  /*8:11*/
       insn->bits3.dp_read.msg_type = msg_type;  /*12:13*/
       insn->bits3.dp_read.target_cache = target_cache;  /*14:15*/
-      insn->bits3.dp_read.response_length = response_length;  /*16:19*/
-      insn->bits3.dp_read.msg_length = msg_length;  /*20:23*/
-      insn->bits3.dp_read.msg_target = BRW_SFID_DATAPORT_READ; /*24:27*/
-      insn->bits3.dp_read.pad1 = 0;  /*28:30*/
-      insn->bits3.dp_read.end_of_thread = 0;  /*31*/
    }
 }
 
@@ -688,50 +657,29 @@ static void brw_set_sampler_message(struct brw_compile *p,
 {
    struct brw_context *brw = p->brw;
    struct intel_context *intel = &brw->intel;
-   brw_set_src1(p, insn, brw_imm_d(0));
+
+   brw_set_message_descriptor(p, insn, BRW_SFID_SAMPLER, msg_length,
+                             response_length, header_present, false);
 
    if (intel->gen >= 7) {
       insn->bits3.sampler_gen7.binding_table_index = binding_table_index;
       insn->bits3.sampler_gen7.sampler = sampler;
       insn->bits3.sampler_gen7.msg_type = msg_type;
       insn->bits3.sampler_gen7.simd_mode = simd_mode;
-      insn->bits3.sampler_gen7.header_present = header_present;
-      insn->bits3.sampler_gen7.response_length = response_length;
-      insn->bits3.sampler_gen7.msg_length = msg_length;
-      insn->bits3.sampler_gen7.end_of_thread = 0;
-      insn->header.destreg__conditionalmod = BRW_SFID_SAMPLER;
    } else if (intel->gen >= 5) {
       insn->bits3.sampler_gen5.binding_table_index = binding_table_index;
       insn->bits3.sampler_gen5.sampler = sampler;
       insn->bits3.sampler_gen5.msg_type = msg_type;
       insn->bits3.sampler_gen5.simd_mode = simd_mode;
-      insn->bits3.sampler_gen5.header_present = header_present;
-      insn->bits3.sampler_gen5.response_length = response_length;
-      insn->bits3.sampler_gen5.msg_length = msg_length;
-      insn->bits3.sampler_gen5.end_of_thread = 0;
-      if (intel->gen >= 6)
-         insn->header.destreg__conditionalmod = BRW_SFID_SAMPLER;
-      else {
-         insn->bits2.send_gen5.sfid = BRW_SFID_SAMPLER;
-         insn->bits2.send_gen5.end_of_thread = 0;
-      }
    } else if (intel->is_g4x) {
       insn->bits3.sampler_g4x.binding_table_index = binding_table_index;
       insn->bits3.sampler_g4x.sampler = sampler;
       insn->bits3.sampler_g4x.msg_type = msg_type;
-      insn->bits3.sampler_g4x.response_length = response_length;
-      insn->bits3.sampler_g4x.msg_length = msg_length;
-      insn->bits3.sampler_g4x.end_of_thread = 0;
-      insn->bits3.sampler_g4x.msg_target = BRW_SFID_SAMPLER;
    } else {
       insn->bits3.sampler.binding_table_index = binding_table_index;
       insn->bits3.sampler.sampler = sampler;
       insn->bits3.sampler.msg_type = msg_type;
       insn->bits3.sampler.return_format = BRW_SAMPLER_RETURN_FORMAT_FLOAT32;
-      insn->bits3.sampler.response_length = response_length;
-      insn->bits3.sampler.msg_length = msg_length;
-      insn->bits3.sampler.end_of_thread = 0;
-      insn->bits3.sampler.msg_target = BRW_SFID_SAMPLER;
    }
 }