<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Apr 14, 2016 at 2:32 PM, Kenneth Graunke <span dir="ltr"><<a href="mailto:kenneth@whitecape.org" target="_blank">kenneth@whitecape.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Tuesday, March 22, 2016 3:33:39 PM PDT Jason Ekstrand wrote:<br>
> While we're at it, we also add support for the possibility that the<br>
> indirect is, in fact, a constant.  This shouldn't happen in the common case<br>
> (if it does, that means NIR failed to constant-fold something), but it's<br>
> possible so we should handle it.<br>
> ---<br>
>  src/mesa/drivers/dri/i965/brw_fs.cpp           |  4 ++<br>
>  src/mesa/drivers/dri/i965/brw_fs_generator.cpp | 67 ++++++++++++++++++++<br>
+-----<br>
>  2 files changed, 58 insertions(+), 13 deletions(-)<br>
><br>
> diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/<br>
i965/brw_fs.cpp<br>
> index d41c8a8..91487c9 100644<br>
> --- a/src/mesa/drivers/dri/i965/brw_fs.cpp<br>
> +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp<br>
> @@ -4481,6 +4481,10 @@ get_lowered_simd_width(const struct brw_device_info<br>
*devinfo,<br>
>     case SHADER_OPCODE_TYPED_SURFACE_WRITE_LOGICAL:<br>
>        return 8;<br>
><br>
> +   case SHADER_OPCODE_MOV_INDIRECT:<br>
> +      /* Prior to Broadwell, we only have 8 address subregisters */<br>
> +      return devinfo->gen < 8 ? 8 : inst->exec_size;<br>
> +<br>
>     default:<br>
>        return inst->exec_size;<br>
>     }<br>
> diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/<br>
drivers/dri/i965/brw_fs_generator.cpp<br>
> index 35400cb..4e89a8a 100644<br>
> --- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp<br>
> +++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp<br>
> @@ -351,22 +351,63 @@ fs_generator::generate_mov_indirect(fs_inst *inst,<br>
><br>
>     unsigned imm_byte_offset = <a href="http://reg.nr" rel="noreferrer" target="_blank">reg.nr</a> * REG_SIZE + reg.subnr;<br>
><br>
> -   /* We use VxH indirect addressing, clobbering a0.0 through a0.7. */<br>
> -   struct brw_reg addr = vec8(brw_address_reg(0));<br>
> +   if (indirect_byte_offset.file == BRW_IMMEDIATE_VALUE) {<br>
> +      imm_byte_offset += indirect_byte_offset.ud;<br>
><br>
> -   /* The destination stride of an instruction (in bytes) must be greater<br>
> -    * than or equal to the size of the rest of the instruction.  Since the<br>
> -    * address register is of type UW, we can't use a D-type instruction.<br>
> -    * In order to get around this, re re-type to UW and use a stride.<br>
> -    */<br>
> -   indirect_byte_offset =<br>
> -      retype(spread(indirect_byte_offset, 2), BRW_REGISTER_TYPE_UW);<br>
> +      <a href="http://reg.nr" rel="noreferrer" target="_blank">reg.nr</a> = imm_byte_offset / REG_SIZE;<br>
> +      reg.subnr = imm_byte_offset % REG_SIZE;<br>
> +      brw_MOV(p, dst, reg);<br>
> +   } else {<br>
> +      /* Prior to Broadwell, there are only 8 address registers. */<br>
> +      assert(inst->exec_size == 8 || devinfo->gen >= 8);<br>
> +<br>
> +      /* We use VxH indirect addressing, clobbering a0.0 through a0.7. */<br>
> +      struct brw_reg addr = vec8(brw_address_reg(0));<br>
> +<br>
> +      /* The destination stride of an instruction (in bytes) must be<br>
greater<br>
> +       * than or equal to the size of the rest of the instruction.  Since<br>
the<br>
> +       * address register is of type UW, we can't use a D-type instruction.<br>
> +       * In order to get around this, re re-type to UW and use a stride.<br>
> +       */<br>
> +      indirect_byte_offset =<br>
> +         retype(spread(indirect_byte_offset, 2), BRW_REGISTER_TYPE_UW);<br>
> +<br>
> +      struct brw_reg ind_src;<br>
> +      if (devinfo->gen < 8) {<br>
> +         /* Prior to broadwell, we have a restriction that the bottom 5<br>
bits<br>
> +          * of the base offset and the bottom 5 bits of the indirect must<br>
add<br>
> +          * to less than 32.  In other words, the hardware needs to be able<br>
to<br>
> +          * add the bottom five bits of the two to get the subnumber and<br>
add<br>
> +          * the next 7 bits of each to get the actual register number.<br>
Since<br>
> +          * the indirect may cause us to cross a register boundary, this<br>
makes<br>
> +          * it almost useless.  We could try and do something clever where<br>
we<br>
> +          * use a actual base offset if base_offset % 32 == 0 but that<br>
would<br>
> +          * mean we were generating different code depending on the base<br>
> +          * offset.  Instead, for the sake of consistency, we'll just do<br>
the<br>
> +          * add ourselves.<br>
> +          */<br>
> +         brw_ADD(p, addr, indirect_byte_offset,<br>
brw_imm_uw(imm_byte_offset));<br>
> +         ind_src = brw_VxH_indirect(0, 0);<br>
> +      } else {<br>
> +         brw_MOV(p, addr, indirect_byte_offset);<br>
> +         ind_src = brw_VxH_indirect(0, imm_byte_offset);<br>
> +      }<br>
><br>
> -   /* Prior to Broadwell, there are only 8 address registers. */<br>
> -   assert(inst->exec_size == 8 || devinfo->gen >= 8);<br>
> +      brw_inst *mov = brw_MOV(p, dst, retype(ind_src, dst.type));<br>
><br>
> -   brw_MOV(p, addr, indirect_byte_offset);<br>
> -   brw_MOV(p, dst, retype(brw_VxH_indirect(0, imm_byte_offset), dst.type));<br>
> +      if (devinfo->gen == 6 && dst.file == BRW_MESSAGE_REGISTER_FILE &&<br>
> +          !inst->get_next()->is_head_sentinel() &&<br>
> +          ((fs_inst *)inst->get_next())->mlen > 0) {<br>
<br>
</div></div>Don't you mean:<br>
<span class=""><br>
if (devinfo->gen == 6 && dst.file == BRW_MESSAGE_REGISTER_FILE &&<br>
</span>    !inst->get_prev()->is_head_sentinel() &&<br>
    ((fs_inst *) inst->get_prev())->mlen > 0) {<br>
<br>
Seems like you're walking forward while facing backward...<br></blockquote><div><br></div><div>I think I want is_tail_sentinel() but I do want to look at the next instruction<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5"><br>
> +         /* From the Sandybridge PRM:<br>
> +          *<br>
> +          *    "[Errata: DevSNB(SNB)] If MRF register is updated by any<br>
> +          *    instruction that “indexed/indirect” source AND is followed<br>
by a<br>
> +          *    send, the instruction requires a “Switch”. This is to avoid<br>
> +          *    race condition where send may dispatch before MRF is<br>
updated."<br>
> +          */<br>
> +         brw_inst_set_thread_control(devinfo, mov, BRW_THREAD_SWITCH);<br>
> +      }<br>
> +   }<br>
>  }<br>
><br>
>  void<br>
</div></div></blockquote></div><br></div></div>