intel/compiler: Handle bits 15:12 in brw_send_indirect_split_message()
authorKenneth Graunke <kenneth@whitecape.org>
Mon, 26 Aug 2019 06:43:29 +0000 (23:43 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Tue, 27 Aug 2019 21:20:07 +0000 (14:20 -0700)
Annoyingly, these bits exist in some extended message descriptors
(in particular render target writes), but they don't have any
corresponding bits in the ISA encoding.  So we can't use an immediate
and have to fall back to an indirect extended descriptor.

Thanks to Jason Ekstrand for reminding me that you can still set these
bits via an indirect descriptor, even if they don't exist in the ISA.

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/intel/compiler/brw_eu_emit.c

index 1fb5156..c26a22f 100644 (file)
@@ -2594,7 +2594,8 @@ brw_send_indirect_split_message(struct brw_codegen *p,
       desc = addr;
    }
 
-   if (ex_desc.file == BRW_IMMEDIATE_VALUE) {
+   if (ex_desc.file == BRW_IMMEDIATE_VALUE &&
+       (ex_desc.ud & INTEL_MASK(15, 12)) == 0) {
       ex_desc.ud |= ex_desc_imm;
    } else {
       struct brw_reg addr = retype(brw_address_reg(2), BRW_REGISTER_TYPE_UD);
@@ -2615,7 +2616,16 @@ brw_send_indirect_split_message(struct brw_codegen *p,
        * descriptor which comes from the address register.  If we don't OR
        * those two bits in, the external unit may get confused and hang.
        */
-      brw_OR(p, addr, ex_desc, brw_imm_ud(ex_desc_imm | sfid | eot << 5));
+      unsigned imm_part = ex_desc_imm | sfid | eot << 5;
+
+      if (ex_desc.file == BRW_IMMEDIATE_VALUE) {
+         /* ex_desc bits 15:12 don't exist in the instruction encoding, so
+          * we may have fallen back to an indirect extended descriptor.
+          */
+         brw_MOV(p, addr, brw_imm_ud(ex_desc.ud | imm_part));
+      } else {
+         brw_OR(p, addr, ex_desc, brw_imm_ud(imm_part));
+      }
 
       brw_pop_insn_state(p);
       ex_desc = addr;