i965/blorp: Make post draw flush more explicit
[mesa.git] / src / mesa / drivers / dri / i965 / brw_blorp.c
index 8020a95f52dfdf692c4361e76d1eb5d8ff58dc2b..d79f529fdc21248cdb097dd6c8ab1d5036c16a44 100644 (file)
@@ -216,13 +216,15 @@ blorp_surf_for_miptree(struct brw_context *brw,
          intel_miptree_resolve_color(brw, mt,
                                      *level, start_layer, num_layers, flags);
 
-         assert(mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_RESOLVED);
+         assert(!intel_miptree_has_color_unresolved(mt, *level, 1,
+                                                    start_layer, num_layers));
          surf->aux_usage = ISL_AUX_USAGE_NONE;
       }
    }
 
    if (is_render_target)
-      intel_miptree_used_for_rendering(brw, mt);
+      intel_miptree_used_for_rendering(brw, mt, *level,
+                                       start_layer, num_layers);
 
    if (surf->aux_usage != ISL_AUX_USAGE_NONE) {
       /* We only really need a clear color if we also have an auxiliary
@@ -806,12 +808,22 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
    if (set_write_disables(irb, ctx->Color.ColorMask[buf], color_write_disable))
       can_fast_clear = false;
 
-   if (irb->mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_NO_MCS ||
+   if (irb->mt->aux_disable & INTEL_AUX_DISABLE_CCS ||
        !brw_is_color_fast_clear_compatible(brw, irb->mt, &ctx->Color.ClearColor))
       can_fast_clear = false;
 
-   const bool is_lossless_compressed = intel_miptree_is_lossless_compressed(
-                                          brw, irb->mt);
+   const unsigned logical_layer = irb_logical_mt_layer(irb);
+   const enum intel_fast_clear_state fast_clear_state =
+      intel_miptree_get_fast_clear_state(irb->mt, irb->mt_level,
+                                         logical_layer);
+
+   /* Surface state can only record one fast clear color value. Therefore
+    * unless different levels/layers agree on the color it can be used to
+    * represent only single level/layer. Here it will be reserved for the
+    * first slice (level 0, layer 0).
+    */
+   if (irb->layer_count > 1 || irb->mt_level || irb->mt_layer)
+      can_fast_clear = false;
 
    if (can_fast_clear) {
       union gl_color_union override_color =
@@ -829,15 +841,14 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
       /* If the buffer is already in INTEL_FAST_CLEAR_STATE_CLEAR, the clear
        * is redundant and can be skipped.
        */
-      if (!color_updated &&
-          irb->mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_CLEAR)
+      if (!color_updated && fast_clear_state == INTEL_FAST_CLEAR_STATE_CLEAR)
          return true;
 
       /* If the MCS buffer hasn't been allocated yet, we need to allocate
        * it now.
        */
       if (!irb->mt->mcs_buf) {
-         assert(!is_lossless_compressed);
+         assert(!intel_miptree_is_lossless_compressed(brw, irb->mt));
          if (!intel_miptree_alloc_non_msrt_mcs(brw, irb->mt, false)) {
             /* MCS allocation failed--probably this will only happen in
              * out-of-memory conditions.  But in any case, try to recover
@@ -848,7 +859,6 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
       }
    }
 
-   const unsigned logical_layer = irb_logical_mt_layer(irb);
    const unsigned num_layers = fb->MaxNumLayers ? irb->layer_count : 1;
 
    /* We can't setup the blorp_surf until we've allocated the MCS above */
@@ -877,7 +887,9 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
        * INTEL_FAST_CLEAR_STATE_CLEAR so that we won't waste time doing
        * redundant clears.
        */
-      irb->mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_CLEAR;
+      intel_miptree_set_fast_clear_state(brw, irb->mt, irb->mt_level,
+                                         logical_layer, num_layers,
+                                         INTEL_FAST_CLEAR_STATE_CLEAR);
    } else {
       DBG("%s (slow) to mt %p level %d layer %d+%d\n", __FUNCTION__,
           irb->mt, irb->mt_level, irb->mt_layer, num_layers);
@@ -896,6 +908,17 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
       blorp_batch_finish(&batch);
    }
 
+   /*
+    * Ivybrigde PRM Vol 2, Part 1, "11.7 MCS Buffer for Render Target(s)":
+    *
+    *  Any transition from any value in {Clear, Render, Resolve} to a
+    *  different value in {Clear, Render, Resolve} requires end of pipe
+    *  synchronization.
+    */
+   brw_emit_pipe_control_flush(brw,
+                               PIPE_CONTROL_RENDER_TARGET_FLUSH |
+                               PIPE_CONTROL_CS_STALL);
+
    return true;
 }
 
@@ -964,7 +987,16 @@ brw_blorp_resolve_color(struct brw_context *brw, struct intel_mipmap_tree *mt,
                      resolve_op);
    blorp_batch_finish(&batch);
 
-   mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_RESOLVED;
+   /*
+    * Ivybrigde PRM Vol 2, Part 1, "11.7 MCS Buffer for Render Target(s)":
+    *
+    *  Any transition from any value in {Clear, Render, Resolve} to a
+    *  different value in {Clear, Render, Resolve} requires end of pipe
+    *  synchronization.
+    */
+   brw_emit_pipe_control_flush(brw,
+                               PIPE_CONTROL_RENDER_TARGET_FLUSH |
+                               PIPE_CONTROL_CS_STALL);
 }
 
 static void