From c50f8b2fc94913a7c96468ba930091710147b302 Mon Sep 17 00:00:00 2001 From: Nanley Chery Date: Mon, 19 Aug 2019 09:17:26 -0700 Subject: [PATCH] intel: Support HIZ_CCS in isl_surf_get_ccs_surf Add an extra aux parameter which will be filled out with CCS if the first two isl_surf parameters fit the requirements for HiZ_CCS. Reviewed-by: Kenneth Graunke --- src/gallium/drivers/iris/iris_resource.c | 2 +- src/intel/isl/isl.c | 39 ++++++++++++++++--- src/intel/isl/isl.h | 3 +- src/intel/vulkan/anv_image.c | 3 +- src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 8 ++-- src/mesa/drivers/dri/i965/intel_screen.c | 8 ++-- 6 files changed, 47 insertions(+), 16 deletions(-) diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c index d7a6973ef54..9bd9835e71b 100644 --- a/src/gallium/drivers/iris/iris_resource.c +++ b/src/gallium/drivers/iris/iris_resource.c @@ -461,7 +461,7 @@ iris_resource_configure_aux(struct iris_screen *screen, else initial_state = ISL_AUX_STATE_PASS_THROUGH; *alloc_flags |= BO_ALLOC_ZEROED; - ok = isl_surf_get_ccs_surf(isl_dev, &res->surf, &res->aux.surf, 0); + ok = isl_surf_get_ccs_surf(isl_dev, &res->surf, &res->aux.surf, NULL, 0); break; } diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c index 909da464dd2..954c7102b80 100644 --- a/src/intel/isl/isl.c +++ b/src/intel/isl/isl.c @@ -1829,13 +1829,28 @@ isl_surf_get_mcs_surf(const struct isl_device *dev, bool isl_surf_get_ccs_surf(const struct isl_device *dev, const struct isl_surf *surf, - struct isl_surf *ccs_surf, + struct isl_surf *aux_surf, + struct isl_surf *extra_aux_surf, uint32_t row_pitch_B) { - if (surf->samples > 1) + assert(aux_surf); + + /* An uninitialized surface is needed to get a CCS surface. */ + if (aux_surf->size_B > 0 && + (extra_aux_surf == NULL || extra_aux_surf->size_B > 0)) { + return false; + } + + /* A surface can't have two CCS surfaces. */ + if (aux_surf->usage & ISL_SURF_USAGE_CCS_BIT) + return false; + + /* Only multisampled depth buffers with HiZ can have CCS. */ + if (surf->samples > 1 && !(aux_surf->usage & ISL_SURF_USAGE_HIZ_BIT)) return false; - assert(surf->msaa_layout == ISL_MSAA_LAYOUT_NONE); + assert(surf->msaa_layout == ISL_MSAA_LAYOUT_NONE || + surf->msaa_layout == ISL_MSAA_LAYOUT_INTERLEAVED); /* CCS support does not exist prior to Gen7 */ if (ISL_DEV_GEN(dev) <= 6) @@ -1845,8 +1860,20 @@ isl_surf_get_ccs_surf(const struct isl_device *dev, return false; /* Callers don't yet support this configuration. */ - if (isl_surf_usage_is_depth_or_stencil(surf->usage)) + if (isl_surf_usage_is_stencil(surf->usage)) + return false; + + /* [TGL+] CCS can only be added to a non-D16-formatted depth buffer if it + * has HiZ. If not for GEN:BUG:1406512483 "deprecate compression enable + * states", D16 would be supported. Supporting D16 requires being able to + * specify that the control surface is present and simultaneously disabling + * compression. The above bug makes it so that it's not possible to specify + * this configuration. + */ + if (isl_surf_usage_is_depth(surf->usage) && (aux_surf->size_B == 0 || + ISL_DEV_GEN(dev) < 12 || surf->format == ISL_FORMAT_R16_UNORM)) { return false; + } /* The PRM doesn't say this explicitly, but fast-clears don't appear to * work for 3D textures until gen9 where the layout of 3D textures changes @@ -1966,6 +1993,8 @@ isl_surf_get_ccs_surf(const struct isl_device *dev, /* On Gen12, the CCS is a scaled-down version of the main surface. We * model this as the CCS compressing a 2D-view of the entire surface. */ + struct isl_surf *ccs_surf = + aux_surf->size_B > 0 ? extra_aux_surf : aux_surf; const bool ok = isl_surf_init(dev, ccs_surf, .dim = ISL_SURF_DIM_2D, @@ -1982,7 +2011,7 @@ isl_surf_get_ccs_surf(const struct isl_device *dev, assert(!ok || ccs_surf->size_B == surf->size_B / 256); return ok; } else { - return isl_surf_init(dev, ccs_surf, + return isl_surf_init(dev, aux_surf, .dim = surf->dim, .format = ccs_format, .width = surf->logical_level0_px.width, diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h index 2a840f48f72..d50f86f6892 100644 --- a/src/intel/isl/isl.h +++ b/src/intel/isl/isl.h @@ -1872,7 +1872,8 @@ isl_surf_get_mcs_surf(const struct isl_device *dev, bool isl_surf_get_ccs_surf(const struct isl_device *dev, const struct isl_surf *surf, - struct isl_surf *ccs_surf, + struct isl_surf *aux_surf, + struct isl_surf *extra_aux_surf, uint32_t row_pitch_B /**< Ignored if 0 */); #define isl_surf_fill_state(dev, state, ...) \ diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index dc4d9724baa..c34cf209e75 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -451,7 +451,8 @@ make_surface(const struct anv_device *dev, assert(image->planes[plane].aux_surface.isl.size_B == 0); ok = isl_surf_get_ccs_surf(&dev->isl_dev, &image->planes[plane].surface.isl, - &image->planes[plane].aux_surface.isl, 0); + &image->planes[plane].aux_surface.isl, + NULL, 0); if (ok) { /* Disable CCS when it is not useful (i.e., when you can't render diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index f135125b58c..2fa9f7dfb81 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -712,7 +712,7 @@ create_ccs_buf_for_image(struct brw_context *brw, struct intel_mipmap_tree *mt, enum isl_aux_state initial_state) { - struct isl_surf temp_ccs_surf; + struct isl_surf temp_ccs_surf = {0,}; /* CCS is only supported for very simple miptrees */ assert(image->aux_offset != 0 && image->aux_pitch != 0); @@ -727,7 +727,7 @@ create_ccs_buf_for_image(struct brw_context *brw, /* We shouldn't already have a CCS */ assert(!mt->aux_buf); - if (!isl_surf_get_ccs_surf(&brw->isl_dev, &mt->surf, &temp_ccs_surf, + if (!isl_surf_get_ccs_surf(&brw->isl_dev, &mt->surf, &temp_ccs_surf, NULL, image->aux_pitch)) return false; @@ -1576,7 +1576,7 @@ intel_miptree_alloc_aux(struct brw_context *brw, /* Get the aux buf allocation parameters for this miptree. */ enum isl_aux_state initial_state; uint8_t memset_value; - struct isl_surf aux_surf; + struct isl_surf aux_surf = {0,}; bool aux_surf_ok = false; switch (mt->aux_usage) { @@ -1624,7 +1624,7 @@ intel_miptree_alloc_aux(struct brw_context *brw, initial_state = ISL_AUX_STATE_PASS_THROUGH; memset_value = 0; aux_surf_ok = - isl_surf_get_ccs_surf(&brw->isl_dev, &mt->surf, &aux_surf, 0); + isl_surf_get_ccs_surf(&brw->isl_dev, &mt->surf, &aux_surf, NULL, 0); break; default: diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 45779b06195..6040161d8f9 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -764,9 +764,9 @@ intel_create_image_common(__DRIscreen *dri_screen, return NULL; } - struct isl_surf aux_surf; + struct isl_surf aux_surf = {0,}; if (mod_info->aux_usage == ISL_AUX_USAGE_CCS_E) { - ok = isl_surf_get_ccs_surf(&screen->isl_dev, &surf, &aux_surf, 0); + ok = isl_surf_get_ccs_surf(&screen->isl_dev, &surf, &aux_surf, NULL, 0); if (!ok) { free(image); return NULL; @@ -1185,8 +1185,8 @@ intel_create_image_from_fds_common(__DRIscreen *dri_screen, return NULL; } - struct isl_surf aux_surf; - ok = isl_surf_get_ccs_surf(&screen->isl_dev, &surf, &aux_surf, + struct isl_surf aux_surf = {0,}; + ok = isl_surf_get_ccs_surf(&screen->isl_dev, &surf, &aux_surf, NULL, image->aux_pitch); if (!ok) { brw_bo_unreference(image->bo); -- 2.30.2