<p dir="ltr"></p>
<p dir="ltr">On Sep 8, 2016 11:13 PM, "Pohjolainen, Topi" <<a href="mailto:topi.pohjolainen@gmail.com">topi.pohjolainen@gmail.com</a>> wrote:<br>
><br>
> On Thu, Sep 08, 2016 at 08:49:56AM -0700, Jason Ekstrand wrote:<br>
> >    On Sep 7, 2016 9:30 PM, "Pohjolainen, Topi"<br>
> >    <[1]<a href="mailto:topi.pohjolainen@gmail.com">topi.pohjolainen@gmail.com</a>> wrote:<br>
> >    ><br>
> >    > On Wed, Sep 07, 2016 at 03:25:30PM -0700, Jason Ekstrand wrote:<br>
> >    > >    On Sep 7, 2016 10:24 AM, "Topi Pohjolainen"<br>
> >    > >    <[1][2]<a href="mailto:topi.pohjolainen@gmail.com">topi.pohjolainen@gmail.com</a>> wrote:<br>
> >    > >    ><br>
> >    > >    > Once mcs buffer gets allocated without delay for lossless<br>
> >    > >    > compression (same as we do for msaa), one gets regression in:<br>
> >    > >    ><br>
> >    > >    > GL45-CTS.texture_barrier_ARB.same-texel-rw<br>
> >    > >    ><br>
> >    > >    > Setting the auxiliary surface for both sampling engine and<br>
> >    data<br>
> >    > >    > port seems to fix this. I haven't found any hardware<br>
> >    documentation<br>
> >    > >    > backing this though.<br>
> >    > >    ><br>
> >    > >    > v2 (Jason): Prepare also for the case where surface is sampled<br>
> >    with<br>
> >    > >    >             non-compressible format forcing also rendering<br>
> >    without<br>
> >    > >    >             compression.<br>
> >    > >    > v3: Split asserts and decision making.<br>
> >    > >    ><br>
> >    > >    > Signed-off-by: Topi Pohjolainen<br>
> >    <[2][3]<a href="mailto:topi.pohjolainen@intel.com">topi.pohjolainen@intel.com</a>><br>
> >    > >    > ---<br>
> >    > >    >  src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 63<br>
> >    > >    +++++++++++++++++++++---<br>
> >    > >    >  1 file changed, 56 insertions(+), 7 deletions(-)<br>
> >    > >    ><br>
> >    > >    > diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c<br>
> >    > >    b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c<br>
> >    > >    > index c1273c5..054c5c8 100644<br>
> >    > >    > --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c<br>
> >    > >    > +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c<br>
> >    > >    > @@ -140,9 +140,7 @@ brw_emit_surface_state(struct brw_context<br>
> >    *brw,<br>
> >    > >    >     struct isl_surf *aux_surf = NULL, aux_surf_s;<br>
> >    > >    >     uint64_t aux_offset = 0;<br>
> >    > >    >     enum isl_aux_usage aux_usage = ISL_AUX_USAGE_NONE;<br>
> >    > >    > -   if (mt->mcs_mt &&<br>
> >    > >    > -       ((view.usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) ||<br>
> >    > >    > -        mt->fast_clear_state !=<br>
> >    INTEL_FAST_CLEAR_STATE_RESOLVED)) {<br>
> >    > >    > +   if (mt->mcs_mt && !(flags & INTEL_AUX_BUFFER_DISABLED)) {<br>
> >    > >    >        intel_miptree_get_aux_isl_surf(brw, mt, &aux_surf_s,<br>
> >    > >    &aux_usage);<br>
> >    > >    >        aux_surf = &aux_surf_s;<br>
> >    > >    >        assert(mt->mcs_mt->offset == 0);<br>
> >    > >    > @@ -425,6 +423,54 @@ swizzle_to_scs(GLenum swizzle, bool<br>
> >    > >    need_green_to_blue)<br>
> >    > >    >     return (need_green_to_blue && scs == HSW_SCS_GREEN) ?<br>
> >    > >    HSW_SCS_BLUE : scs;<br>
> >    > >    >  }<br>
> >    > >    ><br>
> >    > >    > +static unsigned<br>
> >    > >    > +brw_find_matching_rb(const struct gl_framebuffer *fb,<br>
> >    > >    > +                     const struct intel_mipmap_tree *mt)<br>
> >    > >    > +{<br>
> >    > >    > +   for (unsigned i = 0; i < fb->_NumColorDrawBuffers; i++) {<br>
> >    > >    > +      const struct intel_renderbuffer *irb =<br>
> >    > >    > +         intel_renderbuffer(fb->_ColorDrawBuffers[i]);<br>
> >    > >    > +<br>
> >    > >    > +      if (irb->mt == mt)<br>
> >    > >    > +         return i;<br>
> >    > >    > +   }<br>
> >    > >    > +<br>
> >    > >    > +   return fb->_NumColorDrawBuffers;<br>
> >    > >    > +}<br>
> >    > >    > +<br>
> >    > >    > +static bool<br>
> >    > >    > +brw_disable_aux_surface(const struct brw_context *brw,<br>
> >    > >    > +                        const struct intel_mipmap_tree *mt)<br>
> >    > >    > +{<br>
> >    > >    > +   /* Nothing to disable. */<br>
> >    > >    > +   if (!mt->mcs_mt)<br>
> >    > >    > +      return false;<br>
> >    > >    > +<br>
> >    > >    > +   /* There are special cases only for lossless compression.<br>
> >    */<br>
> >    > >    > +   if (!intel_miptree_is_lossless_compressed(brw, mt))<br>
> >    > >    > +      return mt->fast_clear_state ==<br>
> >    > >    INTEL_FAST_CLEAR_STATE_RESOLVED;<br>
> >    > >    > +<br>
> >    > >    > +   const struct gl_framebuffer *fb = brw->ctx.DrawBuffer;<br>
> >    > >    > +   const unsigned rb_index = brw_find_matching_rb(fb, mt);<br>
> >    > >    > +<br>
> >    > >    > +   /* In practise it looks that setting the same lossless<br>
> >    compressed<br>
> >    > >    surface<br>
> >    > >    > +    * to be sampled without auxiliary surface and to be<br>
> >    written with<br>
> >    > >    auxiliary<br>
> >    > >    > +    * surface confuses the hardware. Therefore sampler engine<br>
> >    must<br>
> >    > >    be provided<br>
> >    > >    > +    * with auxiliary buffer regardless of the fast clear<br>
> >    state if<br>
> >    > >    the same<br>
> >    > >    > +    * surface is also going to be written during the same<br>
> >    rendering<br>
> >    > >    pass with<br>
> >    > >    > +    * auxiliary buffer enabled.<br>
> >    > >    > +    */<br>
> >    > >    > +   if (rb_index < fb->_NumColorDrawBuffers) {<br>
> >    > >    > +      if (brw->draw_aux_buffer_disabled[rb_index]) {<br>
> >    > >    > +         assert(mt->fast_clear_state ==<br>
> >    > >    INTEL_FAST_CLEAR_STATE_RESOLVED);<br>
> >    > >    > +      }<br>
> >    > >    > +<br>
> >    > >    > +      return brw->draw_aux_buffer_disabled[rb_index];<br>
> >    > ><br>
> >    > >    Can we use "mt->fast_clear_state ==<br>
> >    INTEL_FAST_CLEAR_STATE_RESOLVED"<br>
> >    > >    here as well?  For render targets we want to look at<br>
> >    > >    aux_buffer_disabled but for textures (which is the only case<br>
> >    that uses<br>
> >    > >    this function), fast_clear_state should be sufficient.<br>
> >    ><br>
> >    > Like the comment says, we can't skip setting aux buffer for sampling<br>
> >    in case<br>
> >    > the same surface is written as render target with aux enabled.<br>
> >    Hardware<br>
> >    > doesn't seem to like this. This is specifically for that purpose<br>
> >    checking<br>
> >    > the flag.<br>
> ><br>
> >    Let me see if I understand this correctly: this handles the case where<br>
> >    the miptree is bound as both a render target and a texture and there is<br>
> >    nothing about the texture view scenario causing it to skip compression<br>
> >    and, for some reason, the surface starts of the draw call fully<br>
> >    resolved.  If *any* drawing has been done without a resolve, we would<br>
> >    be in the UNRESOLVED state and this wouldn't be needed.  That's<br>
> >    terribly specific but also a valid use case.<br>
> ><br>
> >    We could potentially handle this by setting the render target surfaces<br>
> >    to UNRESOLVED a bit earlier in the pipeline setup code.  I believe we<br>
> >    flag things as unresolved rather late; in particular, after we've done<br>
> >    our texture state setup. The other option is to do exactly what you did<br>
> >    and add a comment.  That's probably the best option.  With a good<br>
> >    comment added,<br>
><br>
> So, above there is already:<br>
><br>
>     * In practise it looks that setting the same lossless compressed surface<br>
>     * to be sampled without auxiliary surface and to be written with auxiliary<br>
>     * surface confuses the hardware. Therefore sampler engine must be provided<br>
>     * with auxiliary buffer regardless of the fast clear state if the same<br>
>     * surface is also going to be written during the same rendering pass with<br>
>     * auxiliary buffer enabled.<br>
><br>
> What would you add?</p>
<p dir="ltr">Hmmm... I think my reservations about that convent are because it sounds like a workaround.  How about this:</p>
<p dir="ltr">If we are drawing into this with compression enabled, then we must also enable compression when texturing from it regardless of fast_clear_state.  If we don't then, after the first draw call with this setup, there will be data in the CCS which won't get picked up by subsequent texturing operations as required by ARB_texture_barrier.  Since we don't want to re-emit the binding table or do a resolve operation every draw call, the easiest thing to do is just enable compression on the texturing side.  This is completely safe to do since, if compressed texturing weren't allowed, we would have disabled compression of render targets in whatever_that_function_is_called().</p>
<p dir="ltr">> ><br>
> >    Reviewed-by: Jason Ekstrand <[4]<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>><br>
> ><br>
> >    --Jason<br>
> ><br>
> >    > ><br>
> >    > >    > +   }<br>
> >    > >    > +<br>
> >    > >    > +   return mt->fast_clear_state ==<br>
> >    INTEL_FAST_CLEAR_STATE_RESOLVED;<br>
> >    > >    > +}<br>
> >    > >    > +<br>
> >    > >    >  void<br>
> >    > >    >  brw_update_texture_surface(struct gl_context *ctx,<br>
> >    > >    >                             unsigned unit,<br>
> >    > >    > @@ -542,7 +588,8 @@ brw_update_texture_surface(struct<br>
> >    gl_context<br>
> >    > >    *ctx,<br>
> >    > >    >            obj->Target == GL_TEXTURE_CUBE_MAP_ARRAY)<br>
> >    > >    >           view.usage |= ISL_SURF_USAGE_CUBE_BIT;<br>
> >    > >    ><br>
> >    > >    > -      const int flags = 0;<br>
> >    > >    > +      const int flags =<br>
> >    > >    > +         brw_disable_aux_surface(brw, mt) ?<br>
> >    > >    INTEL_AUX_BUFFER_DISABLED : 0;<br>
> >    > >    >        brw_emit_surface_state(brw, mt, flags, mt->target,<br>
> >    view,<br>
> >    > >    ><br>
> >    surface_state_infos[brw->gen].tex_mocs,<br>
> >    > >    >                               surf_offset, surf_index,<br>
> >    > >    > @@ -1113,7 +1160,8 @@ update_renderbuffer_read_surfaces(struct<br>
> >    > >    brw_context *brw)<br>
> >    > >    >                 .usage = ISL_SURF_USAGE_TEXTURE_BIT,<br>
> >    > >    >              };<br>
> >    > >    ><br>
> >    > >    > -            const int flags = 0;<br>
> >    > >    > +            const int flags =<br>
> >    brw->draw_aux_buffer_disabled[i] ?<br>
> >    > >    > +                                 INTEL_AUX_BUFFER_DISABLED :<br>
> >    0;<br>
> >    > >    >              brw_emit_surface_state(brw, irb->mt, flags,<br>
> >    target,<br>
> >    > >    view,<br>
> >    > >    ><br>
> >    > >    surface_state_infos[brw->gen].tex_mocs,<br>
> >    > >    >                                     surf_offset, surf_index,<br>
> >    > >    > @@ -1672,8 +1720,9 @@ update_image_surface(struct brw_context<br>
> >    *brw,<br>
> >    > >    >              };<br>
> >    > >    ><br>
> >    > >    >              const int surf_index = surf_offset -<br>
> >    > >    &brw->wm.base.surf_offset[0];<br>
> >    > >    > -<br>
> >    > >    > -            const int flags = 0;<br>
> >    > >    > +            const int flags =<br>
> >    > >    > +               mt->fast_clear_state ==<br>
> >    > >    INTEL_FAST_CLEAR_STATE_RESOLVED ?<br>
> >    > >    > +               INTEL_AUX_BUFFER_DISABLED : 0;<br>
> >    > ><br>
> >    > >    According to brw_context, images should *always* be resolved.<br>
> >    Can we<br>
> >    > >    make this check an assert and always pass AUX_BUFFER_DISABLED?<br>
> >    > ><br>
> >    > >    >              brw_emit_surface_state(brw, mt, flags,<br>
> >    mt->target, view,<br>
> >    > >    ><br>
> >    > >    surface_state_infos[brw->gen].tex_mocs,<br>
> >    > >    >                                     surf_offset, surf_index,<br>
> >    > >    > --<br>
> >    > >    > 2.5.5<br>
> >    > >    ><br>
> >    > >    > _______________________________________________<br>
> >    > >    > mesa-dev mailing list<br>
> >    > >    > [3][5]<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> >    > >    > [4][6]<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
> >    > ><br>
> >    > > References<br>
> >    > ><br>
> >    > >    1. mailto:[7]<a href="mailto:topi.pohjolainen@gmail.com">topi.pohjolainen@gmail.com</a><br>
> >    > >    2. mailto:[8]<a href="mailto:topi.pohjolainen@intel.com">topi.pohjolainen@intel.com</a><br>
> >    > >    3. mailto:[9]<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> >    > >    4. [10]<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
> ><br>
> > References<br>
> ><br>
> >    1. mailto:<a href="mailto:topi.pohjolainen@gmail.com">topi.pohjolainen@gmail.com</a><br>
> >    2. mailto:<a href="mailto:topi.pohjolainen@gmail.com">topi.pohjolainen@gmail.com</a><br>
> >    3. mailto:<a href="mailto:topi.pohjolainen@intel.com">topi.pohjolainen@intel.com</a><br>
> >    4. mailto:<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a><br>
> >    5. mailto:<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> >    6. <a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
> >    7. mailto:<a href="mailto:topi.pohjolainen@gmail.com">topi.pohjolainen@gmail.com</a><br>
> >    8. mailto:<a href="mailto:topi.pohjolainen@intel.com">topi.pohjolainen@intel.com</a><br>
> >    9. mailto:<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> >   10. <a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br></p>