[Mesa-dev] [PATCH 07/14] i965: Wrap MCS miptree in intel_miptree_aux_buffer

Jordan Justen jordan.l.justen at intel.com
Tue Jul 15 18:32:15 PDT 2014


This will allow us to treat HiZ and MCS the same when using as an
auxiliary surface buffer.

Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
---
 src/mesa/drivers/dri/i965/brw_blorp_clear.cpp     |  2 +-
 src/mesa/drivers/dri/i965/gen7_blorp.cpp          |  4 +-
 src/mesa/drivers/dri/i965/gen7_wm_surface_state.c |  8 +-
 src/mesa/drivers/dri/i965/gen8_surface_state.c    |  8 +-
 src/mesa/drivers/dri/i965/intel_mipmap_tree.c     | 96 ++++++++++++++---------
 src/mesa/drivers/dri/i965/intel_mipmap_tree.h     |  8 +-
 6 files changed, 75 insertions(+), 51 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_blorp_clear.cpp b/src/mesa/drivers/dri/i965/brw_blorp_clear.cpp
index df34c72..d4c3c3d 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp_clear.cpp
+++ b/src/mesa/drivers/dri/i965/brw_blorp_clear.cpp
@@ -526,7 +526,7 @@ do_single_blorp_clear(struct brw_context *brw, struct gl_framebuffer *fb,
       /* If the MCS buffer hasn't been allocated yet, we need to allocate
        * it now.
        */
-      if (!irb->mt->mcs_mt) {
+      if (!irb->mt->mcs_buf) {
          if (!intel_miptree_alloc_non_msrt_mcs(brw, irb->mt)) {
             /* MCS allocation failed--probably this will only happen in
              * out-of-memory conditions.  But in any case, try to recover
diff --git a/src/mesa/drivers/dri/i965/gen7_blorp.cpp b/src/mesa/drivers/dri/i965/gen7_blorp.cpp
index ebfe6d1..dd87c7f 100644
--- a/src/mesa/drivers/dri/i965/gen7_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/gen7_blorp.cpp
@@ -196,8 +196,8 @@ gen7_blorp_emit_surface_state(struct brw_context *brw,
    surf[3] = pitch_bytes - 1;
 
    surf[4] = gen7_surface_msaa_bits(surface->num_samples, surface->msaa_layout);
-   if (surface->mt->mcs_mt) {
-      gen7_set_surface_mcs_info(brw, surf, wm_surf_offset, surface->mt->mcs_mt,
+   if (surface->mt->mcs_buf) {
+      gen7_set_surface_mcs_info(brw, surf, wm_surf_offset, surface->mt->mcs_buf->mt,
                                 is_render_target);
    }
 
diff --git a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
index 01120af..dabc3b1 100644
--- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
@@ -359,9 +359,9 @@ gen7_update_texture_surface(struct gl_context *ctx,
          SET_FIELD(brw_swizzle_to_scs(GET_SWZ(swizzle, 3), need_scs_green_to_blue), GEN7_SURFACE_SCS_A);
    }
 
-   if (mt->mcs_mt) {
+   if (mt->mcs_buf) {
       gen7_set_surface_mcs_info(brw, surf, *surf_offset,
-                                mt->mcs_mt, false /* is RT */);
+                                mt->mcs_buf->mt, false /* is RT */);
    }
 
    /* Emit relocation to surface contents */
@@ -538,9 +538,9 @@ gen7_update_renderbuffer_surface(struct brw_context *brw,
              min_array_element << GEN7_SURFACE_MIN_ARRAY_ELEMENT_SHIFT |
              (depth - 1) << GEN7_SURFACE_RENDER_TARGET_VIEW_EXTENT_SHIFT;
 
-   if (irb->mt->mcs_mt) {
+   if (irb->mt->mcs_buf) {
       gen7_set_surface_mcs_info(brw, surf, brw->wm.base.surf_offset[surf_index],
-                                irb->mt->mcs_mt, true /* is RT */);
+                                irb->mt->mcs_buf->mt, true /* is RT */);
    }
 
    surf[7] = irb->mt->fast_clear_color_value;
diff --git a/src/mesa/drivers/dri/i965/gen8_surface_state.c b/src/mesa/drivers/dri/i965/gen8_surface_state.c
index 40eb2ea..c9b0842 100644
--- a/src/mesa/drivers/dri/i965/gen8_surface_state.c
+++ b/src/mesa/drivers/dri/i965/gen8_surface_state.c
@@ -155,8 +155,8 @@ gen8_update_texture_surface(struct gl_context *ctx,
       pitch = mt->pitch;
    }
 
-   if (mt->mcs_mt) {
-      aux_mt = mt->mcs_mt;
+   if (mt->mcs_buf) {
+      aux_mt = mt->mcs_buf->mt;
       aux_mode = GEN8_SURFACE_AUX_MODE_MCS;
    }
 
@@ -362,8 +362,8 @@ gen8_update_renderbuffer_surface(struct brw_context *brw,
                        __FUNCTION__, _mesa_get_format_name(rb_format));
    }
 
-   if (mt->mcs_mt) {
-      aux_mt = mt->mcs_mt;
+   if (mt->mcs_buf) {
+      aux_mt = mt->mcs_buf->mt;
       aux_mode = GEN8_SURFACE_AUX_MODE_MCS;
    }
 
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
index b804a5c..14c5381 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -829,7 +829,10 @@ intel_miptree_release(struct intel_mipmap_tree **mt)
             drm_intel_bo_unreference((*mt)->hiz_buf->bo);
          free((*mt)->hiz_buf);
       }
-      intel_miptree_release(&(*mt)->mcs_mt);
+      if ((*mt)->mcs_buf) {
+         intel_miptree_release(&(*mt)->mcs_buf->mt);
+         free((*mt)->mcs_buf);
+      }
       intel_resolve_map_clear(&(*mt)->hiz_map);
 
       for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
@@ -1234,13 +1237,52 @@ intel_miptree_copy_teximage(struct brw_context *brw,
    intel_obj->needs_validate = true;
 }
 
+static struct intel_miptree_aux_buffer *
+intel_mcs_miptree_buf_create(struct brw_context *brw,
+                             struct intel_mipmap_tree *mt,
+                             mesa_format format,
+                             unsigned mcs_width,
+                             unsigned mcs_height)
+{
+   struct intel_miptree_aux_buffer *buf = calloc(sizeof(*buf), 1);
+
+   if (!buf)
+      return NULL;
+
+   /* From the Ivy Bridge PRM, Vol4 Part1 p76, "MCS Base Address":
+    *
+    *     "The MCS surface must be stored as Tile Y."
+    */
+   buf->mt = intel_miptree_create(brw,
+                                  mt->target,
+                                  format,
+                                  mt->first_level,
+                                  mt->last_level,
+                                  mcs_width,
+                                  mcs_height,
+                                  mt->logical_depth0,
+                                  true,
+                                  0,
+                                  INTEL_MIPTREE_TILING_Y);
+   if (!buf->mt) {
+      free(buf);
+      return NULL;
+   }
+
+   buf->bo = buf->mt->bo;
+   buf->pitch = buf->mt->pitch;
+   buf->qpitch = buf->mt->qpitch;
+
+   return buf;
+}
+
 bool
 intel_miptree_alloc_mcs(struct brw_context *brw,
                         struct intel_mipmap_tree *mt,
                         GLuint num_samples)
 {
    assert(brw->gen >= 7); /* MCS only used on Gen7+ */
-   assert(mt->mcs_mt == NULL);
+   assert(mt->mcs_buf == NULL);
 
    /* Choose the correct format for the MCS buffer.  All that really matters
     * is that we allocate the right buffer size, since we'll always be
@@ -1266,21 +1308,10 @@ intel_miptree_alloc_mcs(struct brw_context *brw,
       unreachable("Unrecognized sample count in intel_miptree_alloc_mcs");
    };
 
-   /* From the Ivy Bridge PRM, Vol4 Part1 p76, "MCS Base Address":
-    *
-    *     "The MCS surface must be stored as Tile Y."
-    */
-   mt->mcs_mt = intel_miptree_create(brw,
-                                     mt->target,
-                                     format,
-                                     mt->first_level,
-                                     mt->last_level,
-                                     mt->logical_width0,
-                                     mt->logical_height0,
-                                     mt->logical_depth0,
-                                     true,
-                                     0 /* num_samples */,
-                                     INTEL_MIPTREE_TILING_Y);
+   mt->mcs_buf = intel_mcs_miptree_buf_create(brw, mt,
+                                              format,
+                                              mt->logical_width0,
+                                              mt->logical_height0);
 
    /* From the Ivy Bridge PRM, Vol 2 Part 1 p326:
     *
@@ -1292,12 +1323,12 @@ intel_miptree_alloc_mcs(struct brw_context *brw,
     *
     * Note: the clear value for MCS buffers is all 1's, so we memset to 0xff.
     */
-   void *data = intel_miptree_map_raw(brw, mt->mcs_mt);
-   memset(data, 0xff, mt->mcs_mt->total_height * mt->mcs_mt->pitch);
-   intel_miptree_unmap_raw(brw, mt->mcs_mt);
+   void *data = intel_miptree_map_raw(brw, mt->mcs_buf->mt);
+   memset(data, 0xff, mt->mcs_buf->mt->total_height * mt->mcs_buf->mt->pitch);
+   intel_miptree_unmap_raw(brw, mt->mcs_buf->mt);
    mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_CLEAR;
 
-   return mt->mcs_mt;
+   return mt->mcs_buf;
 }
 
 
@@ -1305,7 +1336,7 @@ bool
 intel_miptree_alloc_non_msrt_mcs(struct brw_context *brw,
                                  struct intel_mipmap_tree *mt)
 {
-   assert(mt->mcs_mt == NULL);
+   assert(mt->mcs_buf == NULL);
 
    /* The format of the MCS buffer is opaque to the driver; all that matters
     * is that we get its size and pitch right.  We'll pretend that the format
@@ -1327,19 +1358,12 @@ intel_miptree_alloc_non_msrt_mcs(struct brw_context *brw,
    unsigned mcs_height =
       ALIGN(mt->logical_height0, height_divisor) / height_divisor;
    assert(mt->logical_depth0 == 1);
-   mt->mcs_mt = intel_miptree_create(brw,
-                                     mt->target,
-                                     format,
-                                     mt->first_level,
-                                     mt->last_level,
-                                     mcs_width,
-                                     mcs_height,
-                                     mt->logical_depth0,
-                                     true,
-                                     0 /* num_samples */,
-                                     INTEL_MIPTREE_TILING_Y);
+   mt->mcs_buf = intel_mcs_miptree_buf_create(brw, mt,
+                                              format,
+                                              mcs_width,
+                                              mcs_height);
 
-   return mt->mcs_mt;
+   return mt->mcs_buf;
 }
 
 
@@ -1780,9 +1804,9 @@ intel_miptree_make_shareable(struct brw_context *brw,
     */
    assert(mt->msaa_layout == INTEL_MSAA_LAYOUT_NONE);
 
-   if (mt->mcs_mt) {
+   if (mt->mcs_buf) {
       intel_miptree_resolve_color(brw, mt);
-      intel_miptree_release(&mt->mcs_mt);
+      intel_miptree_release(&mt->mcs_buf->mt);
       mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_NO_MCS;
    }
 }
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
index 2a421a1..d0cf65f 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
@@ -419,15 +419,15 @@ struct intel_mipmap_tree
    struct intel_mipmap_tree *stencil_mt;
 
    /**
-    * \brief MCS miptree.
+    * \brief MCS auxiliary buffer.
     *
-    * This miptree contains the "multisample control surface", which stores
+    * This buffer contains the "multisample control surface", which stores
     * the necessary information to implement compressed MSAA
     * (INTEL_MSAA_FORMAT_CMS) and "fast color clear" behaviour on Gen7+.
     *
-    * NULL if no MCS miptree is in use for this surface.
+    * NULL if no MCS buffer is in use for this surface.
     */
-   struct intel_mipmap_tree *mcs_mt;
+   struct intel_miptree_aux_buffer *mcs_buf;
 
    /**
     * Fast clear state for this buffer.
-- 
2.0.0



More information about the mesa-dev mailing list