From c991045d38ad0d4ccbd8b7355811b85341eda3a2 Mon Sep 17 00:00:00 2001 From: Nanley Chery Date: Wed, 7 Aug 2019 16:02:51 -0700 Subject: [PATCH] iris: Create an unusable secondary aux surface The HIZ_CCS and MCS_CCS auxiliary surface modes require that drivers store information about two aux buffers. We choose to represent this as HiZ/MCS being the primary aux surface and the CCS as an secondary/extra aux surface. This representation has the effect of placing most of the code that will have to choose between the two aux surfaces around the aux-map entry points. Reviewed-by: Sagar Ghuge Reviewed-by: Kenneth Graunke --- src/gallium/drivers/iris/iris_resource.c | 45 ++++++++++++++++++++---- src/gallium/drivers/iris/iris_resource.h | 10 ++++++ 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c index b25f43ac2ad..554ebb7961b 100644 --- a/src/gallium/drivers/iris/iris_resource.c +++ b/src/gallium/drivers/iris/iris_resource.c @@ -287,6 +287,7 @@ void iris_resource_disable_aux(struct iris_resource *res) { iris_bo_unreference(res->aux.bo); + iris_bo_unreference(res->aux.extra_aux.bo); iris_bo_unreference(res->aux.clear_color_bo); free(res->aux.state); @@ -296,6 +297,8 @@ iris_resource_disable_aux(struct iris_resource *res) res->aux.has_hiz = 0; res->aux.surf.size_B = 0; res->aux.bo = NULL; + res->aux.extra_aux.surf.size_B = 0; + res->aux.extra_aux.bo = NULL; res->aux.clear_color_bo = NULL; res->aux.state = NULL; } @@ -393,9 +396,14 @@ map_aux_addresses(struct iris_screen *screen, struct iris_resource *res) if (devinfo->gen >= 12 && isl_aux_usage_has_ccs(res->aux.usage)) { void *aux_map_ctx = iris_bufmgr_get_aux_map_context(screen->bufmgr); assert(aux_map_ctx); + const bool has_extra_ccs = res->aux.extra_aux.surf.size_B > 0; + struct iris_bo *aux_bo = has_extra_ccs ? + res->aux.extra_aux.bo : res->aux.bo; + const unsigned aux_offset = has_extra_ccs ? + res->aux.extra_aux.offset : res->aux.offset; gen_aux_map_add_image(aux_map_ctx, &res->surf, res->bo->gtt_offset, - res->aux.bo->gtt_offset + res->aux.offset); - res->bo->aux_map_address = res->aux.bo->gtt_offset; + aux_bo->gtt_offset + aux_offset); + res->bo->aux_map_address = aux_bo->gtt_offset; } } @@ -450,10 +458,19 @@ iris_resource_configure_aux(struct iris_screen *screen, ((!res->mod_info && !(INTEL_DEBUG & DEBUG_NO_RBC)) || (res->mod_info && res->mod_info->aux_usage != ISL_AUX_USAGE_NONE)) && isl_surf_get_ccs_surf(&screen->isl_dev, &res->surf, &res->aux.surf, - NULL, 0); - - /* We should have at most one aux surface. */ - assert(has_mcs + has_hiz + has_ccs <= 1); + &res->aux.extra_aux.surf, 0); + + /* Having both HIZ and MCS is impossible. */ + assert(!has_mcs || !has_hiz); + + /* Ensure aux surface creation for MCS_CCS and HIZ_CCS is correct. */ + if (has_ccs && (has_mcs || has_hiz)) { + assert(res->aux.extra_aux.surf.size_B > 0 && + res->aux.extra_aux.surf.usage & ISL_SURF_USAGE_CCS_BIT); + assert(res->aux.surf.size_B > 0 && + res->aux.surf.usage & + (ISL_SURF_USAGE_HIZ_BIT | ISL_SURF_USAGE_MCS_BIT)); + } if (res->mod_info && has_ccs) { /* Only allow a CCS modifier if the aux was created successfully. */ @@ -537,6 +554,13 @@ iris_resource_configure_aux(struct iris_screen *screen, uint64_t size = res->aux.surf.size_B; + /* Allocate space in the buffer for storing the CCS. */ + if (res->aux.extra_aux.surf.size_B > 0) { + res->aux.extra_aux.offset = + ALIGN(size, res->aux.extra_aux.surf.alignment_B); + size = res->aux.extra_aux.offset + res->aux.extra_aux.surf.size_B; + } + /* Allocate space in the buffer for storing the clear color. On modern * platforms (gen > 9), we can read it directly from such buffer. * @@ -584,6 +608,10 @@ iris_resource_init_aux_buf(struct iris_resource *res, uint32_t alloc_flags, res->aux.surf.size_B); } + /* Resolved is usually a safe state for CCS_E. */ + memset((char*)map + res->aux.extra_aux.offset, 0, + res->aux.extra_aux.surf.size_B); + /* Zero the indirect clear color to match ::fast_clear_color. */ memset((char *)map + res->aux.clear_color_offset, 0, clear_color_state_size); @@ -591,6 +619,11 @@ iris_resource_init_aux_buf(struct iris_resource *res, uint32_t alloc_flags, iris_bo_unmap(res->aux.bo); } + if (res->aux.extra_aux.surf.size_B > 0) { + res->aux.extra_aux.bo = res->aux.bo; + iris_bo_reference(res->aux.extra_aux.bo); + } + if (clear_color_state_size > 0) { res->aux.clear_color_bo = res->aux.bo; iris_bo_reference(res->aux.clear_color_bo); diff --git a/src/gallium/drivers/iris/iris_resource.h b/src/gallium/drivers/iris/iris_resource.h index 806fe34d631..3b22b8c4a18 100644 --- a/src/gallium/drivers/iris/iris_resource.h +++ b/src/gallium/drivers/iris/iris_resource.h @@ -106,6 +106,16 @@ struct iris_resource { /** Offset into 'bo' where the auxiliary surface starts. */ uint32_t offset; + struct { + struct isl_surf surf; + + /** The buffer object containing the auxiliary data. */ + struct iris_bo *bo; + + /** Offset into 'bo' where the auxiliary surface starts. */ + uint32_t offset; + } extra_aux; + /** * Fast clear color for this surface. For depth surfaces, the clear * value is stored as a float32 in the red component. -- 2.30.2