From 33dc8549fb9b227a57a84aac53f17bd099da38f4 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Fri, 8 Jul 2016 19:36:33 -0700 Subject: [PATCH] isl: Add support for HiZ surfaces Reviewed-by: Chad Versace --- src/intel/isl/isl.c | 23 ++++++++++++++++++++++- src/intel/isl/isl.h | 17 +++++++++++++++++ src/intel/isl/isl_format_layout.csv | 1 + src/intel/isl/isl_gen6.c | 3 +++ src/intel/isl/isl_gen7.c | 13 ++++++++++++- src/intel/isl/isl_gen8.c | 6 +++++- src/intel/isl/isl_gen9.c | 3 +++ 7 files changed, 63 insertions(+), 3 deletions(-) diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c index aaf4d1c8c77..7df649eff0a 100644 --- a/src/intel/isl/isl.c +++ b/src/intel/isl/isl.c @@ -167,6 +167,16 @@ isl_tiling_get_info(const struct isl_device *dev, break; } + case ISL_TILING_HIZ: + /* HiZ buffers are required to have ISL_FORMAT_HIZ which is an 8x4 + * 128bpb format. The tiling has the same physical dimensions as + * Y-tiling but actually has two HiZ columns per Y-tiled column. + */ + assert(bs == 16); + logical_el = isl_extent2d(16, 16); + phys_B = isl_extent2d(128, 32); + break; + default: unreachable("not reached"); } /* end switch */ @@ -221,6 +231,7 @@ isl_surf_choose_tiling(const struct isl_device *dev, CHOOSE(ISL_TILING_LINEAR); } + CHOOSE(ISL_TILING_HIZ); CHOOSE(ISL_TILING_Ys); CHOOSE(ISL_TILING_Yf); CHOOSE(ISL_TILING_Y0); @@ -314,7 +325,8 @@ isl_choose_array_pitch_span(const struct isl_device *dev, return ISL_ARRAY_PITCH_SPAN_COMPACT; } - if (isl_surf_usage_is_depth_or_stencil(info->usage)) { + if (isl_surf_usage_is_depth_or_stencil(info->usage) || + (info->usage & ISL_SURF_USAGE_HIZ_BIT)) { /* From the Ivybridge PRM >> Volume 1 Part 1: Graphics Core >> * Section 6.18.4.7: Surface Arrays (p112): * @@ -388,6 +400,15 @@ isl_choose_image_alignment_el(const struct isl_device *dev, enum isl_msaa_layout msaa_layout, struct isl_extent3d *image_align_el) { + if (info->format == ISL_FORMAT_HIZ) { + assert(ISL_DEV_GEN(dev) >= 6); + /* HiZ surfaces are always aligned to 16x8 pixels in the primary surface + * which works out to 2x2 HiZ elments. + */ + *image_align_el = isl_extent3d(2, 2, 1); + return; + } + if (ISL_DEV_GEN(dev) >= 9) { gen9_choose_image_alignment_el(dev, info, tiling, msaa_layout, image_align_el); diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h index a86688c91bc..8c01d6edb89 100644 --- a/src/intel/isl/isl.h +++ b/src/intel/isl/isl.h @@ -345,6 +345,14 @@ enum isl_format { ISL_FORMAT_ASTC_LDR_2D_12X10_FLT16 = 638, ISL_FORMAT_ASTC_LDR_2D_12X12_FLT16 = 639, + /* The formats that follow are internal to ISL and as such don't have an + * explicit number. We'll just let the C compiler assign it for us. Any + * actual hardware formats *must* come before these in the list. + */ + + /* Formats for color compression surfaces */ + ISL_FORMAT_HIZ, + /* Hardware doesn't understand this out-of-band value */ ISL_FORMAT_UNSUPPORTED = UINT16_MAX, }; @@ -392,6 +400,9 @@ enum isl_txc { ISL_TXC_ETC1, ISL_TXC_ETC2, ISL_TXC_ASTC, + + /* Used for auxiliary surface formats */ + ISL_TXC_HIZ, }; /** @@ -410,6 +421,7 @@ enum isl_tiling { ISL_TILING_Y0, /**< Legacy Y tiling */ ISL_TILING_Yf, /**< Standard 4K tiling. The 'f' means "four". */ ISL_TILING_Ys, /**< Standard 64K tiling. The 's' means "sixty-four". */ + ISL_TILING_HIZ, /**< Tiling format for HiZ surfaces */ }; /** @@ -423,6 +435,7 @@ typedef uint32_t isl_tiling_flags_t; #define ISL_TILING_Y0_BIT (1u << ISL_TILING_Y0) #define ISL_TILING_Yf_BIT (1u << ISL_TILING_Yf) #define ISL_TILING_Ys_BIT (1u << ISL_TILING_Ys) +#define ISL_TILING_HIZ_BIT (1u << ISL_TILING_HIZ) #define ISL_TILING_ANY_MASK (~0u) #define ISL_TILING_NON_LINEAR_MASK (~ISL_TILING_LINEAR_BIT) @@ -505,6 +518,7 @@ typedef uint64_t isl_surf_usage_flags_t; #define ISL_SURF_USAGE_DISPLAY_FLIP_X_BIT (1u << 10) #define ISL_SURF_USAGE_DISPLAY_FLIP_Y_BIT (1u << 11) #define ISL_SURF_USAGE_STORAGE_BIT (1u << 12) +#define ISL_SURF_USAGE_HIZ_BIT (1u << 13) /** @} */ /** @@ -968,6 +982,9 @@ isl_format_has_bc_compression(enum isl_format fmt) case ISL_TXC_ETC2: case ISL_TXC_ASTC: return false; + + case ISL_TXC_HIZ: + unreachable("Should not be called on an aux surface"); } unreachable("bad texture compression mode"); diff --git a/src/intel/isl/isl_format_layout.csv b/src/intel/isl/isl_format_layout.csv index f90fbe063b5..3e681e8a4a4 100644 --- a/src/intel/isl/isl_format_layout.csv +++ b/src/intel/isl/isl_format_layout.csv @@ -314,3 +314,4 @@ ASTC_LDR_2D_10X8_FLT16 , 128, 10, 8, 1, sf16, sf16, sf16, sf16, , ASTC_LDR_2D_10X10_FLT16 , 128, 10, 10, 1, sf16, sf16, sf16, sf16, , , , linear, astc ASTC_LDR_2D_12X10_FLT16 , 128, 12, 10, 1, sf16, sf16, sf16, sf16, , , , linear, astc ASTC_LDR_2D_12X12_FLT16 , 128, 12, 12, 1, sf16, sf16, sf16, sf16, , , , linear, astc +HIZ , 128, 8, 4, 1, , , , , , , , , hiz diff --git a/src/intel/isl/isl_gen6.c b/src/intel/isl/isl_gen6.c index 699aa41d7ba..de95a8fb280 100644 --- a/src/intel/isl/isl_gen6.c +++ b/src/intel/isl/isl_gen6.c @@ -89,6 +89,9 @@ gen6_choose_image_alignment_el(const struct isl_device *dev, enum isl_msaa_layout msaa_layout, struct isl_extent3d *image_align_el) { + /* Handled by isl_choose_image_alignment_el */ + assert(info->format != ISL_FORMAT_HIZ); + /* Note that the surface's horizontal image alignment is not programmable * on Sandybridge. * diff --git a/src/intel/isl/isl_gen7.c b/src/intel/isl/isl_gen7.c index d9b0c080a4c..1cdb52d3c4e 100644 --- a/src/intel/isl/isl_gen7.c +++ b/src/intel/isl/isl_gen7.c @@ -111,7 +111,8 @@ gen7_choose_msaa_layout(const struct isl_device *dev, * In the table above, MSFMT_MSS refers to ISL_MSAA_LAYOUT_ARRAY, and * MSFMT_DEPTH_STENCIL refers to ISL_MSAA_LAYOUT_INTERLEAVED. */ - if (isl_surf_usage_is_depth_or_stencil(info->usage)) + if (isl_surf_usage_is_depth_or_stencil(info->usage) || + (info->usage & ISL_SURF_USAGE_HIZ_BIT)) require_interleaved = true; /* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled @@ -230,6 +231,13 @@ gen7_filter_tiling(const struct isl_device *dev, *flags &= ~ISL_TILING_W_BIT; } + /* The HiZ format and tiling always go together */ + if (info->format == ISL_FORMAT_HIZ) { + *flags &= ISL_TILING_HIZ_BIT; + } else { + *flags &= ~ISL_TILING_HIZ_BIT; + } + if (info->usage & (ISL_SURF_USAGE_DISPLAY_ROTATE_90_BIT | ISL_SURF_USAGE_DISPLAY_ROTATE_180_BIT | ISL_SURF_USAGE_DISPLAY_ROTATE_270_BIT)) { @@ -384,6 +392,9 @@ gen7_choose_image_alignment_el(const struct isl_device *dev, enum isl_msaa_layout msaa_layout, struct isl_extent3d *image_align_el) { + /* Handled by isl_choose_image_alignment_el */ + assert(info->format != ISL_FORMAT_HIZ); + /* IVB+ does not support combined depthstencil. */ assert(!isl_surf_usage_is_depth_and_stencil(info->usage)); diff --git a/src/intel/isl/isl_gen8.c b/src/intel/isl/isl_gen8.c index a46427aacc8..ff35d5f868f 100644 --- a/src/intel/isl/isl_gen8.c +++ b/src/intel/isl/isl_gen8.c @@ -84,7 +84,8 @@ gen8_choose_msaa_layout(const struct isl_device *dev, if (isl_format_is_yuv(info->format)) return false; - if (isl_surf_usage_is_depth_or_stencil(info->usage)) + if (isl_surf_usage_is_depth_or_stencil(info->usage) || + (info->usage & ISL_SURF_USAGE_HIZ_BIT)) require_interleaved = true; if (require_array && require_interleaved) @@ -198,6 +199,9 @@ gen8_choose_image_alignment_el(const struct isl_device *dev, enum isl_msaa_layout msaa_layout, struct isl_extent3d *image_align_el) { + /* Handled by isl_choose_image_alignment_el */ + assert(info->format != ISL_FORMAT_HIZ); + assert(!isl_tiling_is_std_y(tiling)); /* The below text from the Broadwell PRM provides some insight into the diff --git a/src/intel/isl/isl_gen9.c b/src/intel/isl/isl_gen9.c index 39f409245cd..ff0dec955a5 100644 --- a/src/intel/isl/isl_gen9.c +++ b/src/intel/isl/isl_gen9.c @@ -103,6 +103,9 @@ gen9_choose_image_alignment_el(const struct isl_device *dev, enum isl_msaa_layout msaa_layout, struct isl_extent3d *image_align_el) { + /* Handled by isl_choose_image_alignment_el */ + assert(info->format != ISL_FORMAT_HIZ); + /* This BSpec text provides some insight into the hardware's alignment * requirements [Skylake BSpec > Memory Views > Common Surface Formats > * Surface Layout and Tiling > 2D Surfaces]: -- 2.30.2