i965/rbc: Consult rb settings for texture surface setup
authorTopi Pohjolainen <topi.pohjolainen@intel.com>
Wed, 31 Aug 2016 07:08:17 +0000 (10:08 +0300)
committerTopi Pohjolainen <topi.pohjolainen@intel.com>
Mon, 12 Sep 2016 08:46:13 +0000 (11:46 +0300)
Once mcs buffer gets allocated without delay for lossless
compression (same as we do for msaa), one gets regression in:

GL45-CTS.texture_barrier_ARB.same-texel-rw

Setting the auxiliary surface for both sampling engine and data
port seems to fix this. I haven't found any hardware documentation
backing this though.

v2 (Jason): Prepare also for the case where surface is sampled with
            non-compressible format forcing also rendering without
            compression.
v3: Split asserts and decision making.
v4: Detailed comment provided by Jason explaining the need for using
    auxiliary buffer for texturing when the same surface is also
    used as render target.
    Added check for existence of renderbuffer before considering if
    underlying miptree matches.

Signed-off-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/mesa/drivers/dri/i965/brw_wm_surface_state.c

index 62a4eb8ed2776d322414f2c0360c30f70af0e652..f12df8f634e72691664ee14014031a92e7da58e3 100644 (file)
@@ -140,9 +140,7 @@ brw_emit_surface_state(struct brw_context *brw,
    struct isl_surf *aux_surf = NULL, aux_surf_s;
    uint64_t aux_offset = 0;
    enum isl_aux_usage aux_usage = ISL_AUX_USAGE_NONE;
-   if (mt->mcs_mt &&
-       ((view.usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) ||
-        mt->fast_clear_state != INTEL_FAST_CLEAR_STATE_RESOLVED)) {
+   if (mt->mcs_mt && !(flags & INTEL_AUX_BUFFER_DISABLED)) {
       intel_miptree_get_aux_isl_surf(brw, mt, &aux_surf_s, &aux_usage);
       aux_surf = &aux_surf_s;
       assert(mt->mcs_mt->offset == 0);
@@ -425,6 +423,58 @@ swizzle_to_scs(GLenum swizzle, bool need_green_to_blue)
    return (need_green_to_blue && scs == HSW_SCS_GREEN) ? HSW_SCS_BLUE : scs;
 }
 
+static unsigned
+brw_find_matching_rb(const struct gl_framebuffer *fb,
+                     const struct intel_mipmap_tree *mt)
+{
+   for (unsigned i = 0; i < fb->_NumColorDrawBuffers; i++) {
+      const struct intel_renderbuffer *irb =
+         intel_renderbuffer(fb->_ColorDrawBuffers[i]);
+
+      if (irb && irb->mt == mt)
+         return i;
+   }
+
+   return fb->_NumColorDrawBuffers;
+}
+
+static bool
+brw_disable_aux_surface(const struct brw_context *brw,
+                        const struct intel_mipmap_tree *mt)
+{
+   /* Nothing to disable. */
+   if (!mt->mcs_mt)
+      return false;
+
+   /* There are special cases only for lossless compression. */
+   if (!intel_miptree_is_lossless_compressed(brw, mt))
+      return mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_RESOLVED;
+
+   const struct gl_framebuffer *fb = brw->ctx.DrawBuffer;
+   const unsigned rb_index = brw_find_matching_rb(fb, mt);
+
+   /* 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().
+    */
+   if (rb_index < fb->_NumColorDrawBuffers) {
+      if (brw->draw_aux_buffer_disabled[rb_index]) {
+         assert(mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_RESOLVED);
+      }
+
+      return brw->draw_aux_buffer_disabled[rb_index];
+   }
+
+   return mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_RESOLVED;
+}
+
 void
 brw_update_texture_surface(struct gl_context *ctx,
                            unsigned unit,
@@ -542,7 +592,8 @@ brw_update_texture_surface(struct gl_context *ctx,
           obj->Target == GL_TEXTURE_CUBE_MAP_ARRAY)
          view.usage |= ISL_SURF_USAGE_CUBE_BIT;
 
-      const int flags = 0;
+      const int flags =
+         brw_disable_aux_surface(brw, mt) ? INTEL_AUX_BUFFER_DISABLED : 0;
       brw_emit_surface_state(brw, mt, flags, mt->target, view,
                              surface_state_infos[brw->gen].tex_mocs,
                              surf_offset, surf_index,
@@ -1113,7 +1164,8 @@ update_renderbuffer_read_surfaces(struct brw_context *brw)
                .usage = ISL_SURF_USAGE_TEXTURE_BIT,
             };
 
-            const int flags = 0;
+            const int flags = brw->draw_aux_buffer_disabled[i] ?
+                                 INTEL_AUX_BUFFER_DISABLED : 0;
             brw_emit_surface_state(brw, irb->mt, flags, target, view,
                                    surface_state_infos[brw->gen].tex_mocs,
                                    surf_offset, surf_index,
@@ -1672,8 +1724,9 @@ update_image_surface(struct brw_context *brw,
             };
 
             const int surf_index = surf_offset - &brw->wm.base.surf_offset[0];
-
-            const int flags = 0;
+            const int flags =
+               mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_RESOLVED ?
+               INTEL_AUX_BUFFER_DISABLED : 0;
             brw_emit_surface_state(brw, mt, flags, mt->target, view,
                                    surface_state_infos[brw->gen].tex_mocs,
                                    surf_offset, surf_index,