<p dir="ltr"></p>
<p dir="ltr">On Sep 7, 2016 9:30 PM, "Pohjolainen, Topi" <<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]<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 data<br>
> > > port seems to fix this. I haven't found any hardware documentation<br>
> > > backing this though.<br>
> > ><br>
> > > v2 (Jason): Prepare also for the case where surface is sampled with<br>
> > > non-compressible format forcing also rendering without<br>
> > > compression.<br>
> > > v3: Split asserts and decision making.<br>
> > ><br>
> > > Signed-off-by: Topi Pohjolainen <[2]<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 *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 != 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>
> > > + 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 compressed<br>
> > surface<br>
> > > + * to be sampled without auxiliary surface and to be written with<br>
> > auxiliary<br>
> > > + * surface confuses the hardware. Therefore sampler engine must<br>
> > be provided<br>
> > > + * with auxiliary buffer regardless of the fast clear state if<br>
> > the same<br>
> > > + * surface is also going to be written during the same 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 == 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 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 in case<br>
> the same surface is written as render target with aux enabled. Hardware<br>
> doesn't seem to like this. This is specifically for that purpose checking<br>
> the flag.</p>
<p dir="ltr">Let me see if I understand this correctly: this handles the case where the miptree is bound as both a render target and a texture and there is nothing about the texture view scenario causing it to skip compression and, for some reason, the surface starts of the draw call fully resolved. If *any* drawing has been done without a resolve, we would be in the UNRESOLVED state and this wouldn't be needed. That's terribly specific but also a valid use case.</p>
<p dir="ltr">We could potentially handle this by setting the render target surfaces to UNRESOLVED a bit earlier in the pipeline setup code. I believe we flag things as unresolved rather late; in particular, after we've done our texture state setup. The other option is to do exactly what you did and add a comment. That's probably the best option. With a good comment added,</p>
<p dir="ltr">Reviewed-by: Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>></p>
<p dir="ltr">--Jason</p>
<p dir="ltr">> ><br>
> > > + }<br>
> > > +<br>
> > > + return mt->fast_clear_state == 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 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, view,<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 = brw->draw_aux_buffer_disabled[i] ?<br>
> > > + INTEL_AUX_BUFFER_DISABLED : 0;<br>
> > > brw_emit_surface_state(brw, irb->mt, flags, 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 *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. Can we<br>
> > make this check an assert and always pass AUX_BUFFER_DISABLED?<br>
> ><br>
> > > brw_emit_surface_state(brw, mt, flags, 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]<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> > > [4]<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@intel.com">topi.pohjolainen@intel.com</a><br>
> > 3. mailto:<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> > 4. <a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br></p>