i965: Drop the aux mt when not used
authorBen Widawsky <benjamin.widawsky@intel.com>
Fri, 21 Oct 2016 13:20:39 +0000 (14:20 +0100)
committerLionel Landwerlin <lionel.g.landwerlin@intel.com>
Tue, 8 Nov 2016 16:13:57 +0000 (16:13 +0000)
This patch will preserve the BO & offset, and not the miptree for the
aux_mcs buffer. Eventually it might make sense to pull put the sizing
function in miptree creation, but for now this should be sufficient
and not too hideous.

v2: Save BO's offset too (Lionel)

v3: Squash previous patch storing the size of the allocated aux buffer
    (Lionel)
    Fix memory leak with mcs_buf->bo (Lionel)

Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> (v1)
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> (v2)
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
src/mesa/drivers/dri/i965/brw_blorp.c
src/mesa/drivers/dri/i965/brw_wm_surface_state.c
src/mesa/drivers/dri/i965/intel_mipmap_tree.c
src/mesa/drivers/dri/i965/intel_mipmap_tree.h

index d733b35a6ba4a2ef7c549a102545bc2386c173f8..5adb4c615d8cbd625417dfbf97d1d04d36358ad8 100644 (file)
@@ -194,8 +194,8 @@ blorp_surf_for_miptree(struct brw_context *brw,
       };
 
       if (mt->mcs_buf) {
-         surf->aux_addr.buffer = mt->mcs_buf->mt->bo;
-         surf->aux_addr.offset = mt->mcs_buf->mt->offset;
+         surf->aux_addr.buffer = mt->mcs_buf->bo;
+         surf->aux_addr.offset = mt->mcs_buf->offset;
       } else {
          assert(surf->aux_usage == ISL_AUX_USAGE_HIZ);
          struct intel_mipmap_tree *hiz_mt = mt->hiz_buf->mt;
index d6b799c46bb64f0dedd64a6d515be01804dfb530..bff423e19dc1a47c1bb01fabbb841c58fc5bcc6a 100644 (file)
@@ -146,8 +146,8 @@ brw_emit_surface_state(struct brw_context *brw,
    if (mt->mcs_buf && !(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_buf->mt->offset == 0);
-      aux_offset = mt->mcs_buf->mt->bo->offset64;
+      assert(mt->mcs_buf->offset == 0);
+      aux_offset = mt->mcs_buf->bo->offset64;
 
       /* We only really need a clear color if we also have an auxiliary
        * surfacae.  Without one, it does nothing.
@@ -181,7 +181,7 @@ brw_emit_surface_state(struct brw_context *brw,
       assert((aux_offset & 0xfff) == 0);
       drm_intel_bo_emit_reloc(brw->batch.bo,
                               *surf_offset + 4 * ss_info.aux_reloc_dw,
-                              mt->mcs_buf->mt->bo,
+                              mt->mcs_buf->bo,
                               dw[ss_info.aux_reloc_dw] & 0xfff,
                               read_domains, write_domains);
    }
index 7623d28aad110c58b01188416b0ec533de53b48b..c41b68228efd077a7cca50105aa571a977902a10 100644 (file)
@@ -1020,7 +1020,7 @@ intel_miptree_release(struct intel_mipmap_tree **mt)
          free((*mt)->hiz_buf);
       }
       if ((*mt)->mcs_buf) {
-         intel_miptree_release(&(*mt)->mcs_buf->mt);
+         drm_intel_bo_unreference((*mt)->mcs_buf->bo);
          free((*mt)->mcs_buf);
       }
       intel_resolve_map_clear(&(*mt)->hiz_map);
@@ -1499,13 +1499,12 @@ intel_miptree_init_mcs(struct brw_context *brw,
    const int ret = brw_bo_map_gtt(brw, mt->mcs_buf->bo, "miptree");
    if (unlikely(ret)) {
       fprintf(stderr, "Failed to map mcs buffer into GTT\n");
-      intel_miptree_release(&mt->mcs_buf->mt);
+      drm_intel_bo_unreference(mt->mcs_buf->bo);
       free(mt->mcs_buf);
       return;
    }
    void *data = mt->mcs_buf->bo->virtual;
-   memset(data, init_value,
-          mt->mcs_buf->mt->total_height * mt->mcs_buf->mt->pitch);
+   memset(data, init_value, mt->mcs_buf->size);
    drm_intel_bo_unmap(mt->mcs_buf->bo);
    mt->fast_clear_state = INTEL_FAST_CLEAR_STATE_CLEAR;
 }
@@ -1519,6 +1518,7 @@ intel_mcs_miptree_buf_create(struct brw_context *brw,
                              uint32_t layout_flags)
 {
    struct intel_miptree_aux_buffer *buf = calloc(sizeof(*buf), 1);
+   struct intel_mipmap_tree *temp_mt;
 
    if (!buf)
       return NULL;
@@ -1528,7 +1528,7 @@ intel_mcs_miptree_buf_create(struct brw_context *brw,
     *     "The MCS surface must be stored as Tile Y."
     */
    layout_flags |= MIPTREE_LAYOUT_TILING_Y;
-   buf->mt = miptree_create(brw,
+   temp_mt = miptree_create(brw,
                             mt->target,
                             format,
                             mt->first_level,
@@ -1538,14 +1538,23 @@ intel_mcs_miptree_buf_create(struct brw_context *brw,
                             mt->logical_depth0,
                             0 /* num_samples */,
                             layout_flags);
-   if (!buf->mt) {
+   if (!temp_mt) {
       free(buf);
       return NULL;
    }
 
-   buf->bo = buf->mt->bo;
-   buf->pitch = buf->mt->pitch;
-   buf->qpitch = buf->mt->qpitch;
+   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;
 }
@@ -3247,8 +3256,8 @@ intel_miptree_get_aux_isl_surf(struct brw_context *brw,
 {
    uint32_t aux_pitch, aux_qpitch;
    if (mt->mcs_buf) {
-      aux_pitch = mt->mcs_buf->mt->pitch;
-      aux_qpitch = mt->mcs_buf->mt->qpitch;
+      aux_pitch = mt->mcs_buf->pitch;
+      aux_qpitch = mt->mcs_buf->qpitch;
 
       if (mt->num_samples > 1) {
          assert(mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS);
index 5d6cf3b46dcb184bca1688fe2ba19dc7b943ce52..0b4b35389d030afe462cd223ffd6580420e4b44c 100644 (file)
@@ -338,6 +338,27 @@ struct intel_miptree_aux_buffer
     */
    drm_intel_bo *bo;
 
+   /**
+    * Offset into bo where the surface starts.
+    *
+    * @see intel_mipmap_aux_buffer::bo
+    *
+    * @see RENDER_SURFACE_STATE.AuxiliarySurfaceBaseAddress
+    * @see 3DSTATE_DEPTH_BUFFER.SurfaceBaseAddress
+    * @see 3DSTATE_HIER_DEPTH_BUFFER.SurfaceBaseAddress
+    * @see 3DSTATE_STENCIL_BUFFER.SurfaceBaseAddress
+    */
+   uint32_t offset;
+
+   /*
+    * Size of the MCS surface.
+    *
+    * This is needed when doing any gtt mapped operations on the buffer (which
+    * will be Y-tiled). It is possible that it will not be the same as bo->size
+    * when the drm allocator rounds up the requested size.
+    */
+   size_t size;
+
    /**
     * Pitch in bytes.
     *