diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c index 3390604394b..ed52b37747b 100644 --- a/src/intel/isl/isl.c +++ b/src/intel/isl/isl.c @@ -2007,7 +2007,8 @@ isl_surf_get_mcs_surf(const struct isl_device *dev, bool isl_surf_supports_ccs(const struct isl_device *dev, - const struct isl_surf *surf) + const struct isl_surf *surf, + const struct isl_surf *hiz_or_mcs_surf) { /* CCS support does not exist prior to Gfx7 */ if (ISL_GFX_VER(dev) <= 6) @@ -2050,8 +2051,37 @@ isl_surf_supports_ccs(const struct isl_device *dev, return false; if (ISL_GFX_VER(dev) >= 12) { - if (isl_surf_usage_is_stencil(surf->usage) && surf->samples > 1) - return false; + if (isl_surf_usage_is_stencil(surf->usage)) { + /* HiZ and MCS aren't allowed with stencil */ + assert(hiz_or_mcs_surf == NULL || hiz_or_mcs_surf->size_B == 0); + + /* Multi-sampled stencil cannot have CCS */ + if (surf->samples > 1) + return false; + } else if (isl_surf_usage_is_depth(surf->usage)) { + const struct isl_surf *hiz_surf = hiz_or_mcs_surf; + + /* With depth surfaces, HIZ is required for CCS. */ + if (hiz_surf == NULL || hiz_surf->size_B == 0) + return false; + + assert(hiz_surf->usage & ISL_SURF_USAGE_HIZ_BIT); + assert(hiz_surf->tiling == ISL_TILING_HIZ); + assert(hiz_surf->format == ISL_FORMAT_HIZ); + } else if (surf->samples > 1) { + const struct isl_surf *mcs_surf = hiz_or_mcs_surf; + + /* With multisampled color, CCS requires MCS */ + if (mcs_surf == NULL || mcs_surf->size_B == 0) + return false; + + assert(mcs_surf->usage & ISL_SURF_USAGE_MCS_BIT); + assert(isl_tiling_is_any_y(mcs_surf->tiling)); + assert(isl_format_is_mcs(mcs_surf->format)); + } else { + /* Single-sampled color can't have MCS or HiZ */ + assert(hiz_or_mcs_surf == NULL || hiz_or_mcs_surf->size_B == 0); + } /* On Gfx12, all CCS-compressed surface pitches must be multiples of * 512B. @@ -2093,6 +2123,9 @@ isl_surf_supports_ccs(const struct isl_device *dev, if (isl_surf_usage_is_depth_or_stencil(surf->usage)) return false; + /* We're single-sampled color so having HiZ or MCS makes no sense */ + assert(hiz_or_mcs_surf == NULL || hiz_or_mcs_surf->size_B == 0); + /* The PRM doesn't say this explicitly, but fast-clears don't appear to * work for 3D textures until gfx9 where the layout of 3D textures * changes to match 2D array textures. @@ -2152,15 +2185,15 @@ isl_surf_get_ccs_surf(const struct isl_device *dev, assert(extra_aux_surf); assert(!(aux_surf->usage & ISL_SURF_USAGE_CCS_BIT)); - if (!isl_surf_supports_ccs(dev, surf)) + const struct isl_surf *hiz_or_mcs_surf = + aux_surf->size_B > 0 ? aux_surf : NULL; + struct isl_surf *ccs_surf = + aux_surf->size_B > 0 ? extra_aux_surf : aux_surf; + + if (!isl_surf_supports_ccs(dev, surf, hiz_or_mcs_surf)) return false; if (ISL_GFX_VER(dev) >= 12) { - /* With depth surfaces, HIZ is required for CCS. */ - if (surf->usage & ISL_SURF_USAGE_DEPTH_BIT && - aux_surf->tiling != ISL_TILING_HIZ) - return false; - enum isl_format ccs_format; switch (isl_format_get_layout(surf->format)->bpb) { case 8: ccs_format = ISL_FORMAT_GFX12_CCS_8BPP_Y0; break; @@ -2175,8 +2208,6 @@ isl_surf_get_ccs_surf(const struct isl_device *dev, /* On Gfx12, 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, @@ -2220,7 +2251,7 @@ isl_surf_get_ccs_surf(const struct isl_device *dev, unreachable("Invalid tiling format"); } - return isl_surf_init(dev, aux_surf, + return isl_surf_init(dev, ccs_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 3ae038f1fe0..4b18fbefc89 100644 --- a/src/intel/isl/isl.h +++ b/src/intel/isl/isl.h @@ -1798,6 +1798,14 @@ isl_format_has_bc_compression(enum isl_format fmt) return false; } +static inline bool +isl_format_is_mcs(enum isl_format fmt) +{ + const struct isl_format_layout *fmtl = isl_format_get_layout(fmt); + + return fmtl->txc == ISL_TXC_MCS; +} + static inline bool isl_format_is_planar(enum isl_format fmt) { @@ -2204,7 +2212,8 @@ isl_surf_get_tile_info(const struct isl_surf *surf, bool isl_surf_supports_ccs(const struct isl_device *dev, - const struct isl_surf *surf); + const struct isl_surf *surf, + const struct isl_surf *hiz_or_mcs_surf); bool isl_surf_get_hiz_surf(const struct isl_device *dev, diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index 4f6a6e077a4..9453f3f2141 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -559,7 +559,8 @@ add_aux_surface_if_supported(struct anv_device *device, &image->planes[plane].aux_surface.isl); assert(ok); if (!isl_surf_supports_ccs(&device->isl_dev, - &image->planes[plane].primary_surface.isl)) { + &image->planes[plane].primary_surface.isl, + &image->planes[plane].aux_surface.isl)) { image->planes[plane].aux_usage = ISL_AUX_USAGE_HIZ; } else if (image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) && @@ -593,7 +594,8 @@ add_aux_surface_if_supported(struct anv_device *device, return VK_SUCCESS; if (!isl_surf_supports_ccs(&device->isl_dev, - &image->planes[plane].primary_surface.isl)) + &image->planes[plane].primary_surface.isl, + NULL)) return VK_SUCCESS; image->planes[plane].aux_usage = ISL_AUX_USAGE_STC_CCS;