[Mesa-dev] [PATCH 23/27] i965/miptree: Use ISL for MCS layouts

Topi Pohjolainen topi.pohjolainen at gmail.com
Mon Jan 16 09:13:58 UTC 2017


This changes the size of the auxiliary buffer on gen7 and gen8
for arrayed surfaces. Current i965 logic uses qpitch height per
slice whereas ISL knows that msaa is never mipmapped and more
compact layout is sufficient.

Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 src/mesa/drivers/dri/i965/brw_blorp.c            |   6 +-
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c |   7 +-
 src/mesa/drivers/dri/i965/intel_mipmap_tree.c    | 102 ++++-------------------
 src/mesa/drivers/dri/i965/intel_mipmap_tree.h    |   2 +
 4 files changed, 29 insertions(+), 88 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_blorp.c b/src/mesa/drivers/dri/i965/brw_blorp.c
index e6bb120..e76a541 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.c
+++ b/src/mesa/drivers/dri/i965/brw_blorp.c
@@ -173,7 +173,11 @@ blorp_surf_for_miptree(struct brw_context *brw,
    surf->aux_usage = intel_miptree_get_aux_isl_usage(brw, mt);
 
    struct isl_surf *aux_surf = &tmp_surfs[1];
-   intel_miptree_get_aux_isl_surf(brw, mt, surf->aux_usage, aux_surf);
+
+   if (mt->mcs_buf)
+      *aux_surf = mt->mcs_buf->surf;
+   else
+      intel_miptree_get_aux_isl_surf(brw, mt, surf->aux_usage, aux_surf);
 
    if (surf->aux_usage != ISL_AUX_USAGE_NONE) {
       if (surf->aux_usage == ISL_AUX_USAGE_HIZ) {
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 ef7347c..97ca600 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -140,14 +140,17 @@ brw_emit_surface_state(struct brw_context *brw,
    if ((mt->mcs_buf || intel_miptree_sample_with_hiz(brw, mt)) &&
        !(flags & INTEL_AUX_BUFFER_DISABLED)) {
       aux_usage = intel_miptree_get_aux_isl_usage(brw, mt);
-      intel_miptree_get_aux_isl_surf(brw, mt, aux_usage, &aux_surf_s);
-      aux_surf = &aux_surf_s;
 
       if (mt->mcs_buf) {
+         aux_surf = &mt->mcs_buf->surf;
+
          assert(mt->mcs_buf->offset == 0);
          aux_bo = mt->mcs_buf->bo;
          aux_offset = mt->mcs_buf->bo->offset64 + mt->mcs_buf->offset;
       } else {
+         intel_miptree_get_aux_isl_surf(brw, mt, aux_usage, &aux_surf_s);
+         aux_surf = &aux_surf_s;
+
          aux_bo = mt->hiz_buf->aux_base.bo;
          aux_offset = mt->hiz_buf->aux_base.bo->offset64;
       }
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
index 8643ef8..9462e98 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -1460,56 +1460,6 @@ intel_miptree_init_mcs(struct brw_context *brw,
 }
 
 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,
-                             uint32_t layout_flags)
-{
-   struct intel_miptree_aux_buffer *buf = calloc(sizeof(*buf), 1);
-   struct intel_mipmap_tree *temp_mt;
-
-   if (!buf)
-      return NULL;
-
-   /* From the Ivy Bridge PRM, Vol4 Part1 p76, "MCS Base Address":
-    *
-    *     "The MCS surface must be stored as Tile Y."
-    */
-   layout_flags |= MIPTREE_LAYOUT_TILING_Y;
-   temp_mt = miptree_create(brw,
-                            mt->target,
-                            format,
-                            mt->first_level,
-                            mt->last_level,
-                            mcs_width,
-                            mcs_height,
-                            mt->logical_depth0,
-                            0 /* num_samples */,
-                            layout_flags);
-   if (!temp_mt) {
-      free(buf);
-      return NULL;
-   }
-
-   buf->bo = temp_mt->bo;
-   buf->offset = temp_mt->offset;
-   buf->size = temp_mt->total_height * temp_mt->pitch;
-   buf->pitch = temp_mt->pitch;
-   buf->qpitch = temp_mt->qpitch;
-
-   /* Just hang on to the BO which backs the AUX buffer; the rest of the miptree
-    * structure should go away. We use miptree create simply as a means to make
-    * sure all the constraints for the buffer are satisfied.
-    */
-   drm_intel_bo_reference(temp_mt->bo);
-   intel_miptree_release(&temp_mt);
-
-   return buf;
-}
-
-static struct intel_miptree_aux_buffer *
 intel_alloc_aux_buffer(struct brw_context *brw,
                        const char *name,
                        const struct isl_surf *main_surf,
@@ -1543,6 +1493,8 @@ intel_alloc_aux_buffer(struct brw_context *brw,
       return false;
    }
 
+   buf->surf = *aux_surf;
+
    return buf;
 }
 
@@ -1555,42 +1507,22 @@ intel_miptree_alloc_mcs(struct brw_context *brw,
    assert(mt->mcs_buf == NULL);
    assert((mt->aux_disable & INTEL_AUX_DISABLE_MCS) == 0);
 
-   /* 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
-    * accessing this miptree using MCS-specific hardware mechanisms, which
-    * infer the correct format based on num_samples.
+   struct isl_surf temp_main_surf;
+   struct isl_surf temp_mcs_surf;
+
+   /* Create first an ISL presentation for the main color surface and let ISL
+    * calculate equivalent MCS surface against it.
     */
-   mesa_format format;
-   switch (num_samples) {
-   case 2:
-   case 4:
-      /* 8 bits/pixel are required for MCS data when using 4x MSAA (2 bits for
-       * each sample).
-       */
-      format = MESA_FORMAT_R_UNORM8;
-      break;
-   case 8:
-      /* 32 bits/pixel are required for MCS data when using 8x MSAA (3 bits
-       * for each sample, plus 8 padding bits).
-       */
-      format = MESA_FORMAT_R_UINT32;
-      break;
-   case 16:
-      /* 64 bits/pixel are required for MCS data when using 16x MSAA (4 bits
-       * for each sample).
-       */
-      format = MESA_FORMAT_RG_UINT32;
-      break;
-   default:
-      unreachable("Unrecognized sample count in intel_miptree_alloc_mcs");
-   };
-
-   mt->mcs_buf =
-      intel_mcs_miptree_buf_create(brw, mt,
-                                   format,
-                                   mt->logical_width0,
-                                   mt->logical_height0,
-                                   MIPTREE_LAYOUT_ACCELERATED_UPLOAD);
+   intel_miptree_get_isl_surf(brw, mt, &temp_main_surf);
+   isl_surf_get_mcs_surf(&brw->isl_dev, &temp_main_surf, &temp_mcs_surf);
+
+   assert(temp_mcs_surf.size &&
+          (temp_mcs_surf.size % temp_mcs_surf.row_pitch == 0));
+
+   const uint32_t alloc_flags = BO_ALLOC_FOR_RENDER;
+   mt->mcs_buf = intel_alloc_aux_buffer(brw, "mcs-miptree",
+                                        &temp_main_surf, &temp_mcs_surf,
+                                        alloc_flags, mt);
    if (!mt->mcs_buf)
       return false;
 
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
index f3c8268..d36f7f2 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
@@ -273,6 +273,8 @@ enum intel_aux_disable {
  */
 struct intel_miptree_aux_buffer
 {
+   struct isl_surf surf;
+
    /**
     * Buffer object containing the pixel data.
     *
-- 
2.5.5



More information about the mesa-dev mailing list