i965: Maximum allowed size of SEND messages is 15 (4 bits)
authorIago Toral Quiroga <itoral@igalia.com>
Fri, 18 Sep 2015 06:15:52 +0000 (08:15 +0200)
committerIago Toral Quiroga <itoral@igalia.com>
Mon, 21 Sep 2015 10:47:03 +0000 (12:47 +0200)
Until now we only used MRFs 1..15 for regular SEND messages, so the
message length could not possibly exceed the maximum size. Soon we'll
allow to use MRF registers 1..23 in gen6, so we need to be careful
not to build messages that can go beyond the limit. That could occur,
specifically, when building URB write messages, which we may need to
split in chunks due to their size. Previously we would simply go and
create a new message when we reached MRF 13 (since 13..15 were
reserved for spilling), now we also want to check the size of the
message explicitly.

Besides adding that condition to split URB write messages properly,
this patch also adds asserts in the generator. Notice that
brw_inst_set_mlen already asserts for this, but asserting in the
generators is easy and can make debugging easier in some cases.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_fs_generator.cpp
src/mesa/drivers/dri/i965/brw_inst.h
src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp

index 90805e45ad7af476fcd26a68e8c6e44065f3f191..688f431f5c64ab9b72e5c361b420ad39f1d0d2f3 100644 (file)
@@ -1558,6 +1558,8 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)
       brw_set_default_acc_write_control(p, inst->writes_accumulator);
       brw_set_default_exec_size(p, cvt(inst->exec_size) - 1);
 
+      assert(inst->mlen <= BRW_MAX_MSG_LENGTH);
+
       switch (inst->exec_size) {
       case 1:
       case 2:
index 46eff1dd3812e152fe1121db1f2307515554def5..c5132ba15ed2e274d6232b5c58049a085bd075cb 100644 (file)
@@ -39,6 +39,9 @@
 extern "C" {
 #endif
 
+/** Maximum SEND message length */
+#define BRW_MAX_MSG_LENGTH 15
+
 /* brw_context.h has a forward declaration of brw_inst, so name the struct. */
 typedef struct brw_inst {
    uint64_t data[2];
index 195033358fb87bd6f41e1e25ed463cf925bd7ce3..f11d3c3615df7b7f418790515d4cd3d376ab1bcb 100644 (file)
@@ -1134,6 +1134,8 @@ vec4_generator::generate_code(const cfg_t *cfg)
       brw_set_default_mask_control(p, inst->force_writemask_all);
       brw_set_default_acc_write_control(p, inst->writes_accumulator);
 
+      assert(inst->mlen <= BRW_MAX_MSG_LENGTH);
+
       unsigned pre_emit_nr_insn = p->nr_insn;
 
       if (dst.width == BRW_WIDTH_4) {
index 0465770440553c4ceebbf6bb245336fad3eb5984..e210bb4ad2cfba05e7c4cc1c18777de9d4818d47 100644 (file)
@@ -3318,9 +3318,10 @@ vec4_visitor::emit_vertex()
                        prog_data->vue_map.slot_to_varying[slot]);
 
          /* If this was max_usable_mrf, we can't fit anything more into this
-          * URB WRITE.
+          * URB WRITE. Same thing if we reached the maximum length available.
           */
-         if (mrf > max_usable_mrf) {
+         if (mrf > max_usable_mrf ||
+             align_interleaved_urb_mlen(devinfo, mrf - base_mrf + 1) > BRW_MAX_MSG_LENGTH) {
             slot++;
             break;
          }