isl: Take a hiz_or_mcs_surf in isl_surf_supports_ccs

Whether or not a surface supports CCS on Tigerlake and later is
dependent not only on the main surface but also on the MCS or HiZ
surface, if any.  We were doing some of these checks in
isl_get_ccs_surf based on the extra_aux parameter but not as many as we
probably should.  In particular, we were really only checking HiZ
conditions and nothing for MCS.  It also meant that, in spite of the
symmetry in names, the checks in isl_surf_get_ccs_surf were more
complete than in isl_surf_supports_ccs.

Reviewed-by: Nanley Chery <nanley.g.chery@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11479>
This commit is contained in:
Jason Ekstrand 2021-06-18 17:12:32 -05:00 committed by Marge Bot
parent 2d2590a879
commit 37f76aab1c
3 changed files with 57 additions and 15 deletions

View file

@ -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,

View file

@ -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,

View file

@ -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;