1/* 2 * Copyright (c) 2018 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#include "isl_gfx9.h" 25#include "isl_gfx12.h" 26#include "isl_priv.h" 27 28/** 29 * @brief Filter out tiling flags that are incompatible with the surface. 30 * 31 * The resultant outgoing @a flags is a subset of the incoming @a flags. The 32 * outgoing flags may be empty (0x0) if the incoming flags were too 33 * restrictive. 34 * 35 * For example, if the surface will be used for a display 36 * (ISL_SURF_USAGE_DISPLAY_BIT), then this function filters out all tiling 37 * flags except ISL_TILING_4_BIT, ISL_TILING_X_BIT, and ISL_TILING_LINEAR_BIT. 38 */ 39void 40isl_gfx125_filter_tiling(const struct isl_device *dev, 41 const struct isl_surf_init_info *restrict info, 42 isl_tiling_flags_t *flags) 43{ 44 /* Clear flags unsupported on this hardware */ 45 assert(ISL_GFX_VERX10(dev) >= 125); 46 *flags &= ISL_TILING_LINEAR_BIT | 47 ISL_TILING_X_BIT | 48 ISL_TILING_4_BIT | 49 ISL_TILING_64_BIT; 50 51 if (isl_surf_usage_is_depth_or_stencil(info->usage)) 52 *flags &= ISL_TILING_4_BIT | ISL_TILING_64_BIT; 53 54 if (info->usage & ISL_SURF_USAGE_DISPLAY_BIT) 55 *flags &= ~ISL_TILING_64_BIT; 56 57 /* From RENDER_SURFACE_STATE::TileMode, 58 * 59 * TILEMODE_XMAJOR is only allowed if Surface Type is SURFTYPE_2D. 60 * 61 * X-tiling is only allowed for 2D surfaces. 62 */ 63 if (info->dim != ISL_SURF_DIM_2D) 64 *flags &= ~ISL_TILING_X_BIT; 65 66 /* ISL only implements Tile64 support for 2D surfaces. */ 67 if (info->dim != ISL_SURF_DIM_2D) 68 *flags &= ~ISL_TILING_64_BIT; 69 70 /* From RENDER_SURFACE_STATE::NumberofMultisamples, 71 * 72 * This field must not be programmed to anything other than 73 * [MULTISAMPLECOUNT_1] unless the Tile Mode field is programmed to 74 * Tile64. 75 * 76 * Tile64 is required for multisampling. 77 */ 78 if (info->samples > 1) 79 *flags &= ISL_TILING_64_BIT; 80 81 /* Tile64 is not defined for format sizes that are 24, 48, and 96 bpb. */ 82 if (isl_format_get_layout(info->format)->bpb % 3 == 0) 83 *flags &= ~ISL_TILING_64_BIT; 84} 85 86void 87isl_gfx125_choose_image_alignment_el(const struct isl_device *dev, 88 const struct isl_surf_init_info *restrict info, 89 enum isl_tiling tiling, 90 enum isl_dim_layout dim_layout, 91 enum isl_msaa_layout msaa_layout, 92 struct isl_extent3d *image_align_el) 93{ 94 const struct isl_format_layout *fmtl = isl_format_get_layout(info->format); 95 96 if (tiling == ISL_TILING_64) { 97 /* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment, 98 * 99 * This field is ignored for Tile64 surface formats because horizontal 100 * alignment is always to the start of the next tile in that case. 101 * 102 * From RENDER_SURFACE_STATE::SurfaceQPitch, 103 * 104 * Because MSAA is only supported for Tile64, QPitch must also be 105 * programmed to an aligned tile boundary for MSAA surfaces. 106 * 107 * Images in this surface must be tile-aligned. The table on the Bspec 108 * page, "2D/CUBE Alignment Requirement", shows that the vertical 109 * alignment is also a tile height for non-MSAA as well. 110 */ 111 struct isl_tile_info tile_info; 112 isl_tiling_get_info(tiling, info->dim, msaa_layout, fmtl->bpb, 113 info->samples, &tile_info); 114 115 *image_align_el = isl_extent3d(tile_info.logical_extent_el.w, 116 tile_info.logical_extent_el.h, 117 1); 118 } else if (isl_surf_usage_is_depth(info->usage)) { 119 /* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment, 120 * 121 * - 16b Depth Surfaces Must Be HALIGN=16Bytes (8texels) 122 * - 32b Depth Surfaces Must Be HALIGN=32Bytes (8texels) 123 * 124 * From RENDER_SURFACE_STATE::SurfaceVerticalAlignment, 125 * 126 * This field is intended to be set to VALIGN_4 if the surface 127 * was rendered as a depth buffer [...] 128 * 129 * and 130 * 131 * This field should also be set to VALIGN_8 if the surface was 132 * rendered as a D16_UNORM depth buffer [...] 133 */ 134 *image_align_el = 135 info->format != ISL_FORMAT_R16_UNORM ? 136 isl_extent3d(8, 4, 1) : 137 isl_extent3d(8, 8, 1); 138 } else if (isl_surf_usage_is_stencil(info->usage)) { 139 /* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment, 140 * 141 * - Stencil Surfaces (8b) Must be HALIGN=16Bytes (16texels) 142 * 143 * From RENDER_SURFACE_STATE::SurfaceVerticalAlignment, 144 * 145 * This field is intended to be set to VALIGN_8 only if 146 * the surface was rendered as a stencil buffer, since stencil buffer 147 * surfaces support only alignment of 8. 148 */ 149 *image_align_el = isl_extent3d(16, 8, 1); 150 } else if (!isl_is_pow2(fmtl->bpb)) { 151 /* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment, 152 * 153 * - Linear Surfaces surfaces must use HALIGN=128, including 1D which 154 * is always Linear. For 24,48 and 96bpp this means 128texels. 155 * - Tiled 24bpp, 48bpp and 96bpp surfaces must use HALIGN=16 156 */ 157 *image_align_el = tiling == ISL_TILING_LINEAR ? 158 isl_extent3d(128, 4, 1) : 159 isl_extent3d(16, 4, 1); 160 } else { 161 /* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment, 162 * 163 * - Losslessly Compressed Surfaces Must be HALIGN=128 for all 164 * supported Bpp 165 * - 64bpe and 128bpe Surfaces Must Be HALIGN=64Bytes or 128Bytes (4, 166 * 8 texels or 16 texels) 167 * - Linear Surfaces surfaces must use HALIGN=128, including 1D which 168 * is always Linear. 169 * 170 * Even though we could choose a horizontal alignment of 64B for certain 171 * 64 and 128-bit formats, we want to be able to enable CCS whenever 172 * possible and CCS requires 128B horizontal alignment. 173 */ 174 *image_align_el = isl_extent3d(128 * 8 / fmtl->bpb, 4, 1); 175 } 176} 177 178void 179isl_gfx12_choose_image_alignment_el(const struct isl_device *dev, 180 const struct isl_surf_init_info *restrict info, 181 enum isl_tiling tiling, 182 enum isl_dim_layout dim_layout, 183 enum isl_msaa_layout msaa_layout, 184 struct isl_extent3d *image_align_el) 185{ 186 /* Handled by isl_choose_image_alignment_el */ 187 assert(info->format != ISL_FORMAT_HIZ); 188 189 const struct isl_format_layout *fmtl = isl_format_get_layout(info->format); 190 if (fmtl->txc == ISL_TXC_CCS) { 191 /* This CCS compresses a 2D-view of the entire surface. */ 192 assert(info->levels == 1 && info->array_len == 1 && info->depth == 1); 193 *image_align_el = isl_extent3d(1, 1, 1); 194 return; 195 } 196 197 if (isl_surf_usage_is_depth(info->usage)) { 198 /* The alignment parameters for depth buffers are summarized in the 199 * following table: 200 * 201 * Surface Format | MSAA | Align Width | Align Height 202 * -----------------+-------------+-------------+-------------- 203 * D16_UNORM | 1x, 4x, 16x | 8 | 8 204 * ----------------+-------------+-------------+-------------- 205 * D16_UNORM | 2x, 8x | 16 | 4 206 * ----------------+-------------+-------------+-------------- 207 * other | any | 8 | 4 208 * -----------------+-------------+-------------+-------------- 209 */ 210 assert(isl_is_pow2(info->samples)); 211 *image_align_el = 212 info->format != ISL_FORMAT_R16_UNORM ? 213 isl_extent3d(8, 4, 1) : 214 (info->samples == 2 || info->samples == 8 ? 215 isl_extent3d(16, 4, 1) : isl_extent3d(8, 8, 1)); 216 } else if (isl_surf_usage_is_stencil(info->usage)) { 217 *image_align_el = isl_extent3d(16, 8, 1); 218 } else { 219 isl_gfx9_choose_image_alignment_el(dev, info, tiling, dim_layout, 220 msaa_layout, image_align_el); 221 } 222} 223