<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, May 24, 2016 at 12:18 AM, Francisco Jerez <span dir="ltr"><<a href="mailto:currojerez@riseup.net" target="_blank">currojerez@riseup.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Alternatively we could have extended the current semantics to 32-wide<br>
mode by changing brw_broadcast() to emit multiple indexed MOV<br>
instructions in the generator copying the selected value to all<br>
destination registers, but it seemed rather silly to waste EU cycles<br>
unnecessarily copying the exact same value 32 times in the GRF.<br></blockquote><div><br></div><div>It appears as if emit_uniformize in fs_builder sets stride == 0 on the result the version in vec4_visitor does not.  It's probably not needed for correctness since I think the generator will always take channel 0 anyway, but we should fix it none the less.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The vstride change in the Align16 path is required to avoid assertions<br>
in validate_reg() since the change causes the execution size of the<br>
MOV and SEL instructions to be equal to the source region width.<br>
---<br>
 src/mesa/drivers/dri/i965/brw_defines.h          |  6 ++++++<br>
 src/mesa/drivers/dri/i965/brw_eu_emit.c          | 12 +++++++++---<br>
 src/mesa/drivers/dri/i965/brw_fs_generator.cpp   |  1 +<br>
 src/mesa/drivers/dri/i965/brw_vec4_generator.cpp |  1 +<br>
 4 files changed, 17 insertions(+), 3 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h<br>
index 702eb5a..8794d44 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_defines.h<br>
+++ b/src/mesa/drivers/dri/i965/brw_defines.h<br>
@@ -1080,6 +1080,12 @@ enum opcode {<br>
    /**<br>
     * Pick the channel from its first source register given by the index<br>
     * specified as second source.  Useful for variable indexing of surfaces.<br>
+    *<br>
+    * Note that because the result of this instruction is by definition<br>
+    * uniform and it can always be splatted to multiple channels using a<br>
+    * scalar regioning mode, only the first channel of the destination region<br>
+    * is guaranteed to be updated, which implies that BROADCAST instructions<br>
+    * should usually be marked force_writemask_all.<br>
     */<br>
    SHADER_OPCODE_BROADCAST,<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c<br>
index b11398c..ee7462f 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c<br>
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c<br>
@@ -3425,6 +3425,10 @@ brw_broadcast(struct brw_codegen *p,<br>
    const bool align1 = brw_inst_access_mode(devinfo, p->current) == BRW_ALIGN_1;<br>
    brw_inst *inst;<br>
<br>
+   brw_push_insn_state(p);<br>
+   brw_set_default_mask_control(p, BRW_MASK_DISABLE);<br>
+   brw_set_default_exec_size(p, align1 ? BRW_EXECUTE_1 : BRW_EXECUTE_4);<br>
+<br>
    assert(src.file == BRW_GENERAL_REGISTER_FILE &&<br>
           src.address_mode == BRW_ADDRESS_DIRECT);<br>
<br>
@@ -3475,19 +3479,21 @@ brw_broadcast(struct brw_codegen *p,<br>
           */<br>
          inst = brw_MOV(p,<br>
                         brw_null_reg(),<br>
-                        stride(brw_swizzle(idx, BRW_SWIZZLE_XXXX), 0, 4, 1));<br>
+                        stride(brw_swizzle(idx, BRW_SWIZZLE_XXXX), 4, 4, 1));<br>
          brw_inst_set_pred_control(devinfo, inst, BRW_PREDICATE_NONE);<br>
          brw_inst_set_cond_modifier(devinfo, inst, BRW_CONDITIONAL_NZ);<br>
          brw_inst_set_flag_reg_nr(devinfo, inst, 1);<br>
<br>
          /* and use predicated SEL to pick the right channel. */<br>
          inst = brw_SEL(p, dst,<br>
-                        stride(suboffset(src, 4), 0, 4, 1),<br>
-                        stride(src, 0, 4, 1));<br>
+                        stride(suboffset(src, 4), 4, 4, 1),<br>
+                        stride(src, 4, 4, 1));<br>
          brw_inst_set_pred_control(devinfo, inst, BRW_PREDICATE_NORMAL);<br>
          brw_inst_set_flag_reg_nr(devinfo, inst, 1);<br>
       }<br>
    }<br>
+<br>
+   brw_pop_insn_state(p);<br>
 }<br>
<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 6421870..804c639 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_fs_generator.cpp<br>
+++ b/src/mesa/drivers/dri/i965/brw_fs_generator.cpp<br>
@@ -2017,6 +2017,7 @@ fs_generator::generate_code(const cfg_t *cfg, int dispatch_width)<br>
          break;<br>
<br>
       case SHADER_OPCODE_BROADCAST:<br>
+         assert(inst->force_writemask_all);<br>
          brw_broadcast(p, dst, src[0], src[1]);<br>
          break;<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 baf4422..bb0254e 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp<br>
+++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp<br>
@@ -1886,6 +1886,7 @@ generate_code(struct brw_codegen *p,<br>
          break;<br>
<br>
       case SHADER_OPCODE_BROADCAST:<br>
+         assert(inst->force_writemask_all);<br>
          brw_broadcast(p, dst, src[0], src[1]);<br>
          break;<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
2.7.3<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>