<p dir="ltr">This thing has been trouble since I wrote it. Nice to see it go.</p>
<p dir="ltr">Both patches are:</p>
<p dir="ltr">Reviewed-by: Chris Forbes <<a href="mailto:chrisf@ijw.co.nz">chrisf@ijw.co.nz</a>></p>
<div class="gmail_quote">On May 30, 2015 6:28 AM, "Matt Turner" <<a href="mailto:mattst88@gmail.com">mattst88@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Fri, May 29, 2015 at 6:53 AM, Neil Roberts <<a href="mailto:neil@linux.intel.com">neil@linux.intel.com</a>> wrote:<br>
> Previously when generating the send instruction for a sample<br>
> instruction with an indirect sampler it would use the destination<br>
> register as a temporary store. This breaks when used in combination<br>
> with the opt_sampler_eot optimisation because that forces the<br>
> destination to be null. This patch fixes that by avoiding the temp<br>
> register altogether.<br>
><br>
> The reason the temporary register was needed was because it was trying<br>
> to ensure the binding table index doesn't overflow a byte by and'ing<br>
> it with 0xff. The result is then or'd with samper_index<<8. This patch<br>
> instead just and's the whole thing by 0xfff. This will ensure that a<br>
> bogus sampler index won't overflow into the rest of the message<br>
> descriptor but unlike the previous code it won't ensure that the<br>
> binding table index doesn't overflow into the sampler index. It<br>
> doesn't seem like that should matter very much though because if the<br>
> shader is generating a bogus sampler index then it's going to just get<br>
> garbage out either way.<br>
><br>
> Instead of doing sampler_index<<8|(sampler_index+base_table_index) the<br>
> new code avoids one operation by doing<br>
> sampler_index*0x101+base_table_index which should be equivalent.<br>
> However if we wanted to avoid the multiply for some reason we could do<br>
> this by adding an extra or instruction still without needing the<br>
> temporary register.<br>
><br>
> This fixes a number of Piglit tests on Skylake that were using<br>
> indirect samplers such as:<br>
><br>
>  spec@arb_gpu_shader5@execution@sampler_array_indexing@fs-simple<br>
> ---<br>
>  src/mesa/drivers/dri/i965/brw_fs_generator.cpp   | 17 ++++-------------<br>
>  src/mesa/drivers/dri/i965/brw_vec4_generator.cpp | 16 ++++------------<br>
>  2 files changed, 8 insertions(+), 25 deletions(-)<br>
><br>
> diff --git a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp<br>
> index 0be0f86..ea46b1a 100644<br>
> --- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp<br>
> +++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp<br>
> @@ -779,27 +779,18 @@ fs_generator::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src<br>
>        brw_mark_surface_used(prog_data, sampler + base_binding_table_index);<br>
>     } else {<br>
>        /* Non-const sampler index */<br>
> -      /* Note: this clobbers `dst` as a temporary before emitting the send */<br>
><br>
>        struct brw_reg addr = vec1(retype(brw_address_reg(0), BRW_REGISTER_TYPE_UD));<br>
> -      struct brw_reg temp = vec1(retype(dst, BRW_REGISTER_TYPE_UD));<br>
> -<br>
>        struct brw_reg sampler_reg = vec1(retype(sampler_index, BRW_REGISTER_TYPE_UD));<br>
><br>
>        brw_push_insn_state(p);<br>
>        brw_set_default_mask_control(p, BRW_MASK_DISABLE);<br>
>        brw_set_default_access_mode(p, BRW_ALIGN_1);<br>
><br>
> -      /* Some care required: `sampler` and `temp` may alias:<br>
> -       *    addr = sampler & 0xff<br>
> -       *    temp = (sampler << 8) & 0xf00<br>
> -       *    addr = addr | temp<br>
> -       */<br>
> -      brw_ADD(p, addr, sampler_reg, brw_imm_ud(base_binding_table_index));<br>
> -      brw_SHL(p, temp, sampler_reg, brw_imm_ud(8u));<br>
> -      brw_AND(p, temp, temp, brw_imm_ud(0x0f00));<br>
> -      brw_AND(p, addr, addr, brw_imm_ud(0x0ff));<br>
> -      brw_OR(p, addr, addr, temp);<br>
> +      /* addr = ((sampler * 0x101) + base_binding_table_index) & 0xfff */<br>
> +      brw_MUL(p, addr, sampler_reg, brw_imm_ud(0x101));<br>
> +      brw_ADD(p, addr, addr, brw_imm_ud(base_binding_table_index));<br>
> +      brw_AND(p, addr, addr, brw_imm_ud(0xfff));<br>
><br>
>        brw_pop_insn_state(p);<br>
><br>
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp<br>
> index 20d096c..1d3f5ed 100644<br>
> --- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp<br>
> +++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp<br>
> @@ -398,10 +398,8 @@ vec4_generator::generate_tex(vec4_instruction *inst,<br>
>        brw_mark_surface_used(&prog_data->base, sampler + base_binding_table_index);<br>
>     } else {<br>
>        /* Non-constant sampler index. */<br>
> -      /* Note: this clobbers `dst` as a temporary before emitting the send */<br>
><br>
>        struct brw_reg addr = vec1(retype(brw_address_reg(0), BRW_REGISTER_TYPE_UD));<br>
> -      struct brw_reg temp = vec1(retype(dst, BRW_REGISTER_TYPE_UD));<br>
><br>
<br>
I'd delete the blank line here as well to match the fs code.<br>
<br>
Really nice solution. I'd been trying to figure out the best way to<br>
get an additional temporary in here, but this is clearly better.<br>
<br>
Reviewed-by: Matt Turner <<a href="mailto:mattst88@gmail.com">mattst88@gmail.com</a>><br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</blockquote></div>