<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Dec 14, 2016 at 12:45 AM, 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">We want to perform the URB read to a vec4 temporary, with no writemask,<br>
then issue a MOV to swizzle the data and store it to the actual<br>
destination, using the final writemask.<br>
<br>
We were doing this wrong.  For example, let's say we wanted to read<br>
a vec2 stored in components 2-3 of a vec4.  We would generate a URB<br>
read message of:<br>
<br>
   SEND <actual destination>.XY <header with mask set to XY><br>
   MOV <actual destination>.XY <actual destination>.ZW<br>
<br>
This doesn't work, because the URB message reads the .XY components<br>
of the vec4, rather than the ZW.  It writes to the right place, but<br>
with the wrong data.  Then the MOV comes along and overwrites it<br>
with data that didn't even come from the URB at all.<br>
<br>
Instead we want to do:<br>
<br>
   SEND <temporary>.ZW <header with mask set to ZW><br>
   MOV <actual destination>.XY <temporary>.ZW<br>
<br>
or more simply:<br>
<br>
   SEND <temporary>.XYZW <header with mask set to XYZW><br>
   MOV <actual destination>.XY <temporary>.ZW<br>
<br>
Cc: <a href="mailto:mesa-stable@lists.freedesktop.org">mesa-stable@lists.freedesktop.<wbr>org</a><br>
Signed-off-by: Kenneth Graunke <<a href="mailto:kenneth@whitecape.org">kenneth@whitecape.org</a>><br>
---<br>
 src/mesa/drivers/dri/i965/brw_<wbr>vec4_tcs.cpp | 7 ++++---<br>
 1 file changed, 4 insertions(+), 3 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_vec4_tcs.cpp b/src/mesa/drivers/dri/i965/<wbr>brw_vec4_tcs.cpp<br>
index c7278e4..9d090eb 100644<br>
--- a/src/mesa/drivers/dri/i965/<wbr>brw_vec4_tcs.cpp<br>
+++ b/src/mesa/drivers/dri/i965/<wbr>brw_vec4_tcs.cpp<br>
@@ -219,9 +219,10 @@ vec4_tcs_visitor::emit_output_<wbr>urb_read(const dst_reg &dst,<br>
    read->base_mrf = -1;<br>
<br>
    if (first_component) {<br>
-      src_reg src = src_reg(dst);<br>
-      src.swizzle = BRW_SWZ_COMP_INPUT(first_<wbr>component);<br>
-      emit(MOV(dst, src));<br>
+      read->dst = retype(dst_reg(this, glsl_type::ivec4_type), dst.type);<br>
+      emit(MOV(dst, swizzle(src_reg(read->dst),<br>
+                            BRW_SWZ_COMP_INPUT(first_<wbr>component))));<br>
+      inst->src[0] = brw_imm_ud(WRITEMASK_XYZW);<br></blockquote><div><br></div><div>This works.  I'm not sure how I feel about this much modification of the two instructions after the fact though.  Why not just change the SET_OUTPUT_URB_OFFSETS to have brw_imm_ud(dst.writemask << first_component) and then you would only be whacking the read instruction itself.<br><br></div><div>Also, there's a comment that says that the read ignores writemasks which it clearly doesn't.  We should probably fix that.<br><br></div><div>In any case, this does what it says it does and my suggestion is purely cosmetic.<br><br></div><div>Reviewed-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
    }<br>
 }<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
2.10.2<br>
<br>
______________________________<wbr>_________________<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/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>