<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Jun 15, 2017 at 4:11 AM, Chris Wilson <span dir="ltr"><<a href="mailto:chris@chris-wilson.co.uk" target="_blank">chris@chris-wilson.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Quoting Kenneth Graunke (2017-06-14 21:41:56)<br>
<div><div class="h5">> On Tuesday, June 13, 2017 2:53:24 PM PDT Jason Ekstrand wrote:<br>
> > From: Topi Pohjolainen <<a href="mailto:topi.pohjolainen@intel.com">topi.pohjolainen@intel.com</a>><br>
> ><br>
> > v2 (Jason Ekstrand):<br>
> >  - Take a flags parameter to control the flushes<br>
> >  - Refactoring<br>
> ><br>
> > Signed-off-by: Topi Pohjolainen <<a href="mailto:topi.pohjolainen@intel.com">topi.pohjolainen@intel.com</a>><br>
> > ---<br>
> >  src/mesa/drivers/dri/i965/brw_<wbr>context.h      |  1 +<br>
> >  src/mesa/drivers/dri/i965/brw_<wbr>pipe_control.c | 96 +++++++++++++++++++++++++++-<br>
> >  2 files changed, 96 insertions(+), 1 deletion(-)<br>
> ><br>
> > diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_context.h b/src/mesa/drivers/dri/i965/<wbr>brw_context.h<br>
> > index 7b9be8a..b137409 100644<br>
> > --- a/src/mesa/drivers/dri/i965/<wbr>brw_context.h<br>
> > +++ b/src/mesa/drivers/dri/i965/<wbr>brw_context.h<br>
> > @@ -1641,6 +1641,7 @@ void brw_emit_pipe_control_flush(<wbr>struct brw_context *brw, uint32_t flags);<br>
> >  void brw_emit_pipe_control_write(<wbr>struct brw_context *brw, uint32_t flags,<br>
> >                                   struct brw_bo *bo, uint32_t offset,<br>
> >                                   uint64_t imm);<br>
> > +void brw_emit_end_of_pipe_sync(<wbr>struct brw_context *brw, uint32_t flags);<br>
> >  void brw_emit_mi_flush(struct brw_context *brw);<br>
> >  void brw_emit_post_sync_nonzero_<wbr>flush(struct brw_context *brw);<br>
> >  void brw_emit_depth_stall_flushes(<wbr>struct brw_context *brw);<br>
> > diff --git a/src/mesa/drivers/dri/i965/<wbr>brw_pipe_control.c b/src/mesa/drivers/dri/i965/<wbr>brw_pipe_control.c<br>
> > index 39bb9c7..338e4fc 100644<br>
> > --- a/src/mesa/drivers/dri/i965/<wbr>brw_pipe_control.c<br>
> > +++ b/src/mesa/drivers/dri/i965/<wbr>brw_pipe_control.c<br>
> > @@ -271,7 +271,6 @@ gen7_emit_cs_stall_flush(<wbr>struct brw_context *brw)<br>
> >                                 brw->workaround_bo, 0, 0);<br>
> >  }<br>
> ><br>
> > -<br>
> >  /**<br>
> >   * Emits a PIPE_CONTROL with a non-zero post-sync operation, for<br>
> >   * implementing two workarounds on gen6.  From section 1.4.7.1<br>
> > @@ -320,6 +319,101 @@ brw_emit_post_sync_nonzero_<wbr>flush(struct brw_context *brw)<br>
> >                                 brw->workaround_bo, 0, 0);<br>
> >  }<br>
> ><br>
> > +/*<br>
> > + * From Sandybridge PRM, volume 2, "1.7.2 End-of-Pipe Synchronization":<br>
> > + *<br>
> > + *  Write synchronization is a special case of end-of-pipe<br>
> > + *  synchronization that requires that the render cache and/or depth<br>
> > + *  related caches are flushed to memory, where the data will become<br>
> > + *  globally visible. This type of synchronization is required prior to<br>
> > + *  SW (CPU) actually reading the result data from memory, or initiating<br>
> > + *  an operation that will use as a read surface (such as a texture<br>
> > + *  surface) a previous render target and/or depth/stencil buffer<br>
> > + *<br>
> > + *<br>
> > + * From Haswell PRM, volume 2, part 1, "End-of-Pipe Synchronization":<br>
> > + *<br>
> > + *  Exercising the write cache flush bits (Render Target Cache Flush<br>
> > + *  Enable, Depth Cache Flush Enable, DC Flush) in PIPE_CONTROL only<br>
> > + *  ensures the write caches are flushed and doesn't guarantee the data<br>
> > + *  is globally visible.<br>
> > + *<br>
> > + *  SW can track the completion of the end-of-pipe-synchronization by<br>
> > + *  using "Notify Enable" and "PostSync Operation - Write Immediate<br>
> > + *  Data" in the PIPE_CONTROL command.<br>
> > + */<br>
> > +void<br>
> > +brw_emit_end_of_pipe_sync(<wbr>struct brw_context *brw, uint32_t flags)<br>
> > +{<br>
> > +   if (brw->gen >= 6) {<br>
> > +      /* From Sandybridge PRM, volume 2, "1.7.3.1 Writing a Value to Memory":<br>
> > +       *<br>
> > +       *    "The most common action to perform upon reaching a synchronization<br>
> > +       *    point is to write a value out to memory. An immediate value<br>
> > +       *    (included with the synchronization command) may be written."<br>
> > +       *<br>
> > +       *<br>
> > +       * From Broadwell PRM, volume 7, "End-of-Pipe Synchronization":<br>
> > +       *<br>
> > +       *    "In case the data flushed out by the render engine is to be read<br>
> > +       *    back in to the render engine in coherent manner, then the render<br>
> > +       *    engine has to wait for the fence completion before accessing the<br>
> > +       *    flushed data. This can be achieved by following means on various<br>
> > +       *    products: PIPE_CONTROL command with CS Stall and the required<br>
> > +       *    write caches flushed with Post-Sync-Operation as Write Immediate<br>
> > +       *    Data.<br>
> > +       *<br>
> > +       *    Example:<br>
> > +       *       - Workload-1 (3D/GPGPU/MEDIA)<br>
> > +       *       - PIPE_CONTROL (CS Stall, Post-Sync-Operation Write Immediate<br>
> > +       *         Data, Required Write Cache Flush bits set)<br>
> > +       *       - Workload-2 (Can use the data produce or output by Workload-1)<br>
> > +       */<br>
> > +      brw_emit_pipe_control_write(<wbr>brw,<br>
> > +                                  flags | PIPE_CONTROL_CS_STALL |<br>
> > +                                  PIPE_CONTROL_WRITE_IMMEDIATE,<br>
> > +                                  brw->workaround_bo, 0, 0);<br>
> > +<br>
> > +      if (brw->is_haswell) {<br>
> > +         /* Haswell needs addition work-arounds:<br>
> > +          *<br>
> > +          * From Haswell PRM, volume 2, part 1, "End-of-Pipe Synchronization":<br>
> > +          *<br>
> > +          *    Option 1:<br>
> > +          *    PIPE_CONTROL command with the CS Stall and the required write<br>
> > +          *    caches flushed with Post-SyncOperation as Write Immediate Data<br>
> > +          *    followed by eight dummy MI_STORE_DATA_IMM (write to scratch<br>
> > +          *    spce) commands.<br>
> > +          *<br>
> > +          *    Example:<br>
> > +          *       - Workload-1<br>
> > +          *       - PIPE_CONTROL (CS Stall, Post-Sync-Operation Write<br>
> > +          *         Immediate Data, Required Write Cache Flush bits set)<br>
> > +          *       - MI_STORE_DATA_IMM (8 times) (Dummy data, Scratch Address)<br>
> > +          *       - Workload-2 (Can use the data produce or output by<br>
> > +          *         Workload-1)<br>
> > +          *<br>
> > +          * Unfortunately, both the PRMs and the internal docs are a bit<br>
> > +          * out-of-date in this regard.  What the windows driver does (and<br>
> > +          * this appears to actually work) is to emit a register read from the<br>
> > +          * memory address written by the pipe control above.<br>
> > +          *<br>
> > +          * What register we load into doesn't matter.  We choose an indirect<br>
> > +          * rendering register because we know it always exists and doesn't<br>
> > +          * require command parser support.  This is perfectly safe to do<br>
> > +          * since we always re-load all of the indirect draw registers right<br>
> > +          * before 3DPRIMITIVE when needed anyway.<br>
> > +          */<br>
> > +         brw_load_register_mem(brw, GEN7_3DPRIM_START_INSTANCE,<br>
> > +                               brw->workaround_bo,<br>
> > +                               I915_GEM_DOMAIN_INSTRUCTION, 0, 0);<br>
><br>
> This does require command parser support.  Your MI_LOAD_REGISTER_MEM will be<br>
> converted to MI_NOOP if the command parser is not enabled.  That means that<br>
> the workaround effectively won't happen for users with kernels older than 4.2<br>
> (specifically kernel sha 245054a1fe33c06ad233e0d58a27ec<wbr>7b64db9284).<br>
><br>
> ChromeOS in particular was running a 3.8 based kernel, with no command<br>
> parser, last I checked, which means they won't get this bug fix.  Applying<br>
> a kernel patch may actually be a faster route to getting this bug fixed,<br>
> for them, at least.  For normal Linux distro users, this Mesa patch is<br>
> probably the fastest approach.  ChromeOS should update their kernel to 4.4+<br>
> anyway.<br>
<br>
</div></div>The kernel does have a LRI after a flush before signaling the batch is<br>
complete. I don't see a need to add another...<br>
<br>
The question is whether this posting is required for GPU visibility of<br>
results or just CPU? I suspect this is just for CPU in which case it<br>
doesn't belong here at all, but before flagging rendering as ready for<br>
async (i.e. not involving the kernel) inspection.<br></blockquote><div><br></div><div>The docs, if you choose to believe them, seem to indicate that this is needed for GPU visibility as well as CPU. <br></div></div><br></div></div>