[Mesa-dev] [PATCH 12/26] i965: Add plumbing for fast clear layer/level details

Topi Pohjolainen topi.pohjolainen at gmail.com
Tue Oct 11 19:26:44 UTC 2016


Until now fast clear has been supported only for non-layered and
non-mipmapped buffers. However, from gen8 onwards there is hardware
support also for layered/mipmapped. Once this is enabled, fast clear
operations target specific layer/level and call for the state to be
tracked in the same granularity. This is the first step providing
the details from callers to the state tracking.

Patch introduces new interface for reading and writing the state
hiding the upcoming bookkeeping changes in the call sites. There is
bunch of sanity checks added that will be relaxed per hardware
generation later on when the actual functionality is enabled.

Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 src/mesa/drivers/dri/i965/brw_blorp.c            | 32 +++++++++++++---------
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 34 ++++++++++++++++--------
 2 files changed, 42 insertions(+), 24 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_blorp.c b/src/mesa/drivers/dri/i965/brw_blorp.c
index 83f47aa..677886a 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.c
+++ b/src/mesa/drivers/dri/i965/brw_blorp.c
@@ -141,7 +141,7 @@ blorp_surf_for_miptree(struct brw_context *brw,
                        struct blorp_surf *surf,
                        struct intel_mipmap_tree *mt,
                        bool is_render_target,
-                       unsigned *level,
+                       unsigned *level, unsigned layer,
                        struct isl_surf tmp_surfs[2])
 {
    intel_miptree_get_isl_surf(brw, mt, &tmp_surfs[0]);
@@ -177,7 +177,8 @@ blorp_surf_for_miptree(struct brw_context *brw,
 
    /* For textures that are in the RESOLVED state, we ignore the MCS */
    if (mt->mcs_mt && !is_render_target &&
-       mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_RESOLVED)
+       intel_miptree_get_fast_clear_state(mt, *level, layer) ==
+       INTEL_FAST_CLEAR_STATE_RESOLVED)
       surf->aux_usage = ISL_AUX_USAGE_NONE;
 
    if (surf->aux_usage != ISL_AUX_USAGE_NONE) {
@@ -369,9 +370,9 @@ brw_blorp_blit_miptrees(struct brw_context *brw,
    struct isl_surf tmp_surfs[4];
    struct blorp_surf src_surf, dst_surf;
    blorp_surf_for_miptree(brw, &src_surf, src_mt, false,
-                          &src_level, &tmp_surfs[0]);
+                          &src_level, src_logical_layer, &tmp_surfs[0]);
    blorp_surf_for_miptree(brw, &dst_surf, dst_mt, true,
-                          &dst_level, &tmp_surfs[2]);
+                          &dst_level, dst_logical_layer, &tmp_surfs[2]);
 
    struct isl_swizzle src_isl_swizzle = {
       .r = swizzle_to_scs(GET_SWZ(src_swizzle, 0)),
@@ -431,9 +432,9 @@ brw_blorp_copy_miptrees(struct brw_context *brw,
    struct isl_surf tmp_surfs[4];
    struct blorp_surf src_surf, dst_surf;
    blorp_surf_for_miptree(brw, &src_surf, src_mt, false,
-                          &src_level, &tmp_surfs[0]);
+                          &src_level, src_layer, &tmp_surfs[0]);
    blorp_surf_for_miptree(brw, &dst_surf, dst_mt, true,
-                          &dst_level, &tmp_surfs[2]);
+                          &dst_level, dst_layer, &tmp_surfs[2]);
 
    struct blorp_batch batch;
    blorp_batch_init(&brw->blorp, &batch, brw);
@@ -789,6 +790,8 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
                              irb->mt, irb->mt_layer);
    const bool is_lossless_compressed = intel_miptree_is_lossless_compressed(
                                           brw, irb->mt);
+   const enum intel_fast_clear_state fast_clear_state =
+      intel_miptree_get_fast_clear_state(irb->mt, irb->mt_level, layer);
 
    if (can_fast_clear) {
       union gl_color_union override_color;
@@ -820,7 +823,7 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
        * it is available without consulting the surface state.
        */
       if ((!color_updated || !is_lossless_compressed) &&
-          irb->mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_CLEAR)
+          fast_clear_state == INTEL_FAST_CLEAR_STATE_CLEAR)
          return true;
 
       /* If the MCS buffer hasn't been allocated yet, we need to allocate
@@ -842,7 +845,7 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
    struct isl_surf isl_tmp[2];
    struct blorp_surf surf;
    unsigned level = irb->mt_level;
-   blorp_surf_for_miptree(brw, &surf, irb->mt, true, &level, isl_tmp);
+   blorp_surf_for_miptree(brw, &surf, irb->mt, true, &level, layer, isl_tmp);
    const unsigned num_layers = fb->MaxNumLayers ? irb->layer_count : 1;
 
    if (can_fast_clear) {
@@ -861,7 +864,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(irb->mt, irb->mt_level,
+                                         layer, num_layers,
+                                         INTEL_FAST_CLEAR_STATE_CLEAR);
    } else {
       intel_miptree_used_for_rendering(brw, irb->mt, level, layer, num_layers);
 
@@ -924,7 +929,7 @@ void
 brw_blorp_resolve_color(struct brw_context *brw, struct intel_mipmap_tree *mt,
                         unsigned level, unsigned layer)
 {
-   DBG("%s to mt %p\n", __FUNCTION__, mt);
+   DBG("%s to mt %p level %u layer %u\n", __FUNCTION__, mt, level, layer);
 
    const mesa_format format = _mesa_get_srgb_format_linear(mt->format);
 
@@ -932,7 +937,7 @@ brw_blorp_resolve_color(struct brw_context *brw, struct intel_mipmap_tree *mt,
 
    struct isl_surf isl_tmp[2];
    struct blorp_surf surf;
-   blorp_surf_for_miptree(brw, &surf, mt, true, &level, isl_tmp);
+   blorp_surf_for_miptree(brw, &surf, mt, true, &level, layer, isl_tmp);
 
    struct blorp_batch batch;
    blorp_batch_init(&brw->blorp, &batch, brw);
@@ -940,7 +945,8 @@ brw_blorp_resolve_color(struct brw_context *brw, struct intel_mipmap_tree *mt,
                      brw_blorp_to_isl_format(brw, format, true));
    blorp_batch_finish(&batch);
 
-   mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_RESOLVED;
+   intel_miptree_set_fast_clear_state(mt, level, layer, 1,
+                                      INTEL_FAST_CLEAR_STATE_RESOLVED);
 }
 
 static void
@@ -953,7 +959,7 @@ gen6_blorp_hiz_exec(struct brw_context *brw, struct intel_mipmap_tree *mt,
 
    struct isl_surf isl_tmp[2];
    struct blorp_surf surf;
-   blorp_surf_for_miptree(brw, &surf, mt, true, &level, isl_tmp);
+   blorp_surf_for_miptree(brw, &surf, mt, true, &level, layer, isl_tmp);
 
    struct blorp_batch batch;
    blorp_batch_init(&brw->blorp, &batch, brw);
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index 5e9a7c1..249f8f5 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -435,20 +435,24 @@ brw_find_matching_rb(const struct gl_framebuffer *fb,
 
 static inline bool
 brw_texture_view_sane(const struct brw_context *brw,
-                      const struct intel_mipmap_tree *mt, unsigned format)
+                      const struct intel_mipmap_tree *mt,
+                      const struct isl_view *view)
 {
    /* There are special cases only for lossless compression. */
    if (!intel_miptree_is_lossless_compressed(brw, mt))
       return true;
 
    if (isl_format_supports_lossless_compression(&brw->screen->devinfo,
-                                                format))
+                                                view->format))
       return true;
 
    /* Logic elsewhere needs to take care to resolve the color buffer prior
     * to sampling it as non-compressed.
     */
-   if (mt->fast_clear_state != INTEL_FAST_CLEAR_STATE_RESOLVED)
+   const enum intel_fast_clear_state fast_clear_state =
+      intel_miptree_get_fast_clear_state(mt, view->base_level,
+                                         view->base_array_layer);
+   if (fast_clear_state != INTEL_FAST_CLEAR_STATE_RESOLVED)
       return false;
 
    const struct gl_framebuffer *fb = brw->ctx.DrawBuffer;
@@ -467,15 +471,20 @@ brw_texture_view_sane(const struct brw_context *brw,
 
 static bool
 brw_disable_aux_surface(const struct brw_context *brw,
-                        const struct intel_mipmap_tree *mt)
+                        const struct intel_mipmap_tree *mt,
+                        const struct isl_view *view)
 {
    /* Nothing to disable. */
    if (!mt->mcs_mt)
       return false;
 
+   const bool is_unresolved = intel_miptree_has_color_unresolved(
+                                 mt, view->base_level, view->levels,
+                                 view->base_array_layer, view->array_len);
+
    /* 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;
+      return !is_unresolved;
 
    const struct gl_framebuffer *fb = brw->ctx.DrawBuffer;
    const unsigned rb_index = brw_find_matching_rb(fb, mt);
@@ -493,13 +502,13 @@ brw_disable_aux_surface(const struct brw_context *brw,
     */
    if (rb_index < fb->_NumColorDrawBuffers) {
       if (brw->draw_aux_buffer_disabled[rb_index]) {
-         assert(mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_RESOLVED);
+         assert(!is_unresolved);
       }
 
       return brw->draw_aux_buffer_disabled[rb_index];
    }
 
-   return mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_RESOLVED;
+   return !is_unresolved;
 }
 
 void
@@ -619,10 +628,10 @@ brw_update_texture_surface(struct gl_context *ctx,
           obj->Target == GL_TEXTURE_CUBE_MAP_ARRAY)
          view.usage |= ISL_SURF_USAGE_CUBE_BIT;
 
-      assert(brw_texture_view_sane(brw, mt, format));
+      assert(brw_texture_view_sane(brw, mt, &view));
 
-      const int flags =
-         brw_disable_aux_surface(brw, mt) ? INTEL_AUX_BUFFER_DISABLED : 0;
+      const int flags = brw_disable_aux_surface(brw, mt, &view) ?
+                           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,
@@ -1750,8 +1759,11 @@ update_image_surface(struct brw_context *brw,
             };
 
             const int surf_index = surf_offset - &brw->wm.base.surf_offset[0];
+            const enum intel_fast_clear_state fast_clear_state =
+               intel_miptree_get_fast_clear_state(mt, view.base_level,
+                                                  view.base_array_layer);
             const int flags =
-               mt->fast_clear_state == INTEL_FAST_CLEAR_STATE_RESOLVED ?
+               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,
-- 
2.5.5



More information about the mesa-dev mailing list