From 36d1c555edef238648cf18f3a3adb4ea3805f1b9 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Fri, 21 Oct 2016 14:20:39 +0100 Subject: [PATCH] i965: Drop the aux mt when not used 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 (v1) Signed-off-by: Lionel Landwerlin (v2) Reviewed-by: Topi Pohjolainen --- src/mesa/drivers/dri/i965/brw_blorp.c | 4 +-- .../drivers/dri/i965/brw_wm_surface_state.c | 6 ++-- src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 31 ++++++++++++------- src/mesa/drivers/dri/i965/intel_mipmap_tree.h | 21 +++++++++++++ 4 files changed, 46 insertions(+), 16 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_blorp.c b/src/mesa/drivers/dri/i965/brw_blorp.c index d733b35a6ba..5adb4c615d8 100644 --- a/src/mesa/drivers/dri/i965/brw_blorp.c +++ b/src/mesa/drivers/dri/i965/brw_blorp.c @@ -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; 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 d6b799c46bb..bff423e19dc 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -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); } diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index 7623d28aad1..c41b68228ef 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -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); diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h index 5d6cf3b46dc..0b4b35389d0 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h @@ -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. * -- 2.30.2