1 /* 2 * Copyright 2015 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 <assert.h> 25 #include <stdarg.h> 26 #include <stdio.h> 27 28 #include "genxml/genX_bits.h" 29 30 #include "isl.h" 31 #include "isl_gen4.h" 32 #include "isl_gen6.h" 33 #include "isl_gen7.h" 34 #include "isl_gen8.h" 35 #include "isl_gen9.h" 36 #include "isl_priv.h" 37 38 void PRINTFLIKE(3, 4) UNUSED 39 __isl_finishme(const char *file, int line, const char *fmt, ...) 40 { 41 va_list ap; 42 char buf[512]; 43 44 va_start(ap, fmt); 45 vsnprintf(buf, sizeof(buf), fmt, ap); 46 va_end(ap); 47 48 fprintf(stderr, "%s:%d: FINISHME: %s\n", file, line, buf); 49 } 50 51 void 52 isl_device_init(struct isl_device *dev, 53 const struct gen_device_info *info, 54 bool has_bit6_swizzling) 55 { 56 dev->info = info; 57 dev->use_separate_stencil = ISL_DEV_GEN(dev) >= 6; 58 dev->has_bit6_swizzling = has_bit6_swizzling; 59 60 /* The ISL_DEV macros may be defined in the CFLAGS, thus hardcoding some 61 * device properties at buildtime. Verify that the macros with the device 62 * properties chosen during runtime. 63 */ 64 ISL_DEV_GEN_SANITIZE(dev); 65 ISL_DEV_USE_SEPARATE_STENCIL_SANITIZE(dev); 66 67 /* Did we break hiz or stencil? */ 68 if (ISL_DEV_USE_SEPARATE_STENCIL(dev)) 69 assert(info->has_hiz_and_separate_stencil); 70 if (info->must_use_separate_stencil) 71 assert(ISL_DEV_USE_SEPARATE_STENCIL(dev)); 72 73 dev->ss.size = RENDER_SURFACE_STATE_length(info) * 4; 74 dev->ss.align = isl_align(dev->ss.size, 32); 75 76 dev->ss.clear_value_size = 77 isl_align(RENDER_SURFACE_STATE_RedClearColor_bits(info) + 78 RENDER_SURFACE_STATE_GreenClearColor_bits(info) + 79 RENDER_SURFACE_STATE_BlueClearColor_bits(info) + 80 RENDER_SURFACE_STATE_AlphaClearColor_bits(info), 32) / 8; 81 82 dev->ss.clear_value_offset = 83 RENDER_SURFACE_STATE_RedClearColor_start(info) / 32 * 4; 84 85 assert(RENDER_SURFACE_STATE_SurfaceBaseAddress_start(info) % 8 == 0); 86 dev->ss.addr_offset = 87 RENDER_SURFACE_STATE_SurfaceBaseAddress_start(info) / 8; 88 89 /* The "Auxiliary Surface Base Address" field starts a bit higher up 90 * because the bottom 12 bits are used for other things. Round down to 91 * the nearest dword before. 92 */ 93 dev->ss.aux_addr_offset = 94 (RENDER_SURFACE_STATE_AuxiliarySurfaceBaseAddress_start(info) & ~31) / 8; 95 96 dev->ds.size = _3DSTATE_DEPTH_BUFFER_length(info) * 4; 97 assert(_3DSTATE_DEPTH_BUFFER_SurfaceBaseAddress_start(info) % 8 == 0); 98 dev->ds.depth_offset = 99 _3DSTATE_DEPTH_BUFFER_SurfaceBaseAddress_start(info) / 8; 100 101 if (dev->use_separate_stencil) { 102 dev->ds.size += _3DSTATE_STENCIL_BUFFER_length(info) * 4 + 103 _3DSTATE_HIER_DEPTH_BUFFER_length(info) * 4 + 104 _3DSTATE_CLEAR_PARAMS_length(info) * 4; 105 106 assert(_3DSTATE_STENCIL_BUFFER_SurfaceBaseAddress_start(info) % 8 == 0); 107 dev->ds.stencil_offset = 108 _3DSTATE_DEPTH_BUFFER_length(info) * 4 + 109 _3DSTATE_STENCIL_BUFFER_SurfaceBaseAddress_start(info) / 8; 110 111 assert(_3DSTATE_HIER_DEPTH_BUFFER_SurfaceBaseAddress_start(info) % 8 == 0); 112 dev->ds.hiz_offset = 113 _3DSTATE_DEPTH_BUFFER_length(info) * 4 + 114 _3DSTATE_STENCIL_BUFFER_length(info) * 4 + 115 _3DSTATE_HIER_DEPTH_BUFFER_SurfaceBaseAddress_start(info) / 8; 116 } else { 117 dev->ds.stencil_offset = 0; 118 dev->ds.hiz_offset = 0; 119 } 120 } 121 122 /** 123 * @brief Query the set of multisamples supported by the device. 124 * 125 * This function always returns non-zero, as ISL_SAMPLE_COUNT_1_BIT is always 126 * supported. 127 */ 128 isl_sample_count_mask_t ATTRIBUTE_CONST 129 isl_device_get_sample_counts(struct isl_device *dev) 130 { 131 if (ISL_DEV_GEN(dev) >= 9) { 132 return ISL_SAMPLE_COUNT_1_BIT | 133 ISL_SAMPLE_COUNT_2_BIT | 134 ISL_SAMPLE_COUNT_4_BIT | 135 ISL_SAMPLE_COUNT_8_BIT | 136 ISL_SAMPLE_COUNT_16_BIT; 137 } else if (ISL_DEV_GEN(dev) >= 8) { 138 return ISL_SAMPLE_COUNT_1_BIT | 139 ISL_SAMPLE_COUNT_2_BIT | 140 ISL_SAMPLE_COUNT_4_BIT | 141 ISL_SAMPLE_COUNT_8_BIT; 142 } else if (ISL_DEV_GEN(dev) >= 7) { 143 return ISL_SAMPLE_COUNT_1_BIT | 144 ISL_SAMPLE_COUNT_4_BIT | 145 ISL_SAMPLE_COUNT_8_BIT; 146 } else if (ISL_DEV_GEN(dev) >= 6) { 147 return ISL_SAMPLE_COUNT_1_BIT | 148 ISL_SAMPLE_COUNT_4_BIT; 149 } else { 150 return ISL_SAMPLE_COUNT_1_BIT; 151 } 152 } 153 154 /** 155 * @param[out] info is written only on success 156 */ 157 static void 158 isl_tiling_get_info(enum isl_tiling tiling, 159 uint32_t format_bpb, 160 struct isl_tile_info *tile_info) 161 { 162 const uint32_t bs = format_bpb / 8; 163 struct isl_extent2d logical_el, phys_B; 164 165 if (tiling != ISL_TILING_LINEAR && !isl_is_pow2(format_bpb)) { 166 /* It is possible to have non-power-of-two formats in a tiled buffer. 167 * The easiest way to handle this is to treat the tile as if it is three 168 * times as wide. This way no pixel will ever cross a tile boundary. 169 * This really only works on legacy X and Y tiling formats. 170 */ 171 assert(tiling == ISL_TILING_X || tiling == ISL_TILING_Y0); 172 assert(bs % 3 == 0 && isl_is_pow2(format_bpb / 3)); 173 isl_tiling_get_info(tiling, format_bpb / 3, tile_info); 174 return; 175 } 176 177 switch (tiling) { 178 case ISL_TILING_LINEAR: 179 assert(bs > 0); 180 logical_el = isl_extent2d(1, 1); 181 phys_B = isl_extent2d(bs, 1); 182 break; 183 184 case ISL_TILING_X: 185 assert(bs > 0); 186 logical_el = isl_extent2d(512 / bs, 8); 187 phys_B = isl_extent2d(512, 8); 188 break; 189 190 case ISL_TILING_Y0: 191 assert(bs > 0); 192 logical_el = isl_extent2d(128 / bs, 32); 193 phys_B = isl_extent2d(128, 32); 194 break; 195 196 case ISL_TILING_W: 197 assert(bs == 1); 198 logical_el = isl_extent2d(64, 64); 199 /* From the Broadwell PRM Vol 2d, RENDER_SURFACE_STATE::SurfacePitch: 200 * 201 * "If the surface is a stencil buffer (and thus has Tile Mode set 202 * to TILEMODE_WMAJOR), the pitch must be set to 2x the value 203 * computed based on width, as the stencil buffer is stored with two 204 * rows interleaved." 205 * 206 * This, together with the fact that stencil buffers are referred to as 207 * being Y-tiled in the PRMs for older hardware implies that the 208 * physical size of a W-tile is actually the same as for a Y-tile. 209 */ 210 phys_B = isl_extent2d(128, 32); 211 break; 212 213 case ISL_TILING_Yf: 214 case ISL_TILING_Ys: { 215 bool is_Ys = tiling == ISL_TILING_Ys; 216 217 assert(bs > 0); 218 unsigned width = 1 << (6 + (ffs(bs) / 2) + (2 * is_Ys)); 219 unsigned height = 1 << (6 - (ffs(bs) / 2) + (2 * is_Ys)); 220 221 logical_el = isl_extent2d(width / bs, height); 222 phys_B = isl_extent2d(width, height); 223 break; 224 } 225 226 case ISL_TILING_HIZ: 227 /* HiZ buffers are required to have ISL_FORMAT_HIZ which is an 8x4 228 * 128bpb format. The tiling has the same physical dimensions as 229 * Y-tiling but actually has two HiZ columns per Y-tiled column. 230 */ 231 assert(bs == 16); 232 logical_el = isl_extent2d(16, 16); 233 phys_B = isl_extent2d(128, 32); 234 break; 235 236 case ISL_TILING_CCS: 237 /* CCS surfaces are required to have one of the GENX_CCS_* formats which 238 * have a block size of 1 or 2 bits per block and each CCS element 239 * corresponds to one cache-line pair in the main surface. From the Sky 240 * Lake PRM Vol. 12 in the section on planes: 241 * 242 * "The Color Control Surface (CCS) contains the compression status 243 * of the cache-line pairs. The compression state of the cache-line 244 * pair is specified by 2 bits in the CCS. Each CCS cache-line 245 * represents an area on the main surface of 16x16 sets of 128 byte 246 * Y-tiled cache-line-pairs. CCS is always Y tiled." 247 * 248 * The CCS being Y-tiled implies that it's an 8x8 grid of cache-lines. 249 * Since each cache line corresponds to a 16x16 set of cache-line pairs, 250 * that yields total tile area of 128x128 cache-line pairs or CCS 251 * elements. On older hardware, each CCS element is 1 bit and the tile 252 * is 128x256 elements. 253 */ 254 assert(format_bpb == 1 || format_bpb == 2); 255 logical_el = isl_extent2d(128, 256 / format_bpb); 256 phys_B = isl_extent2d(128, 32); 257 break; 258 259 default: 260 unreachable("not reached"); 261 } /* end switch */ 262 263 *tile_info = (struct isl_tile_info) { 264 .tiling = tiling, 265 .format_bpb = format_bpb, 266 .logical_extent_el = logical_el, 267 .phys_extent_B = phys_B, 268 }; 269 } 270 271 bool 272 isl_color_value_is_zero(union isl_color_value value, 273 enum isl_format format) 274 { 275 const struct isl_format_layout *fmtl = isl_format_get_layout(format); 276 277 #define RETURN_FALSE_IF_NOT_0(c, i) \ 278 if (fmtl->channels.c.bits && value.u32[i] != 0) \ 279 return false 280 281 RETURN_FALSE_IF_NOT_0(r, 0); 282 RETURN_FALSE_IF_NOT_0(g, 1); 283 RETURN_FALSE_IF_NOT_0(b, 2); 284 RETURN_FALSE_IF_NOT_0(a, 3); 285 286 #undef RETURN_FALSE_IF_NOT_0 287 288 return true; 289 } 290 291 bool 292 isl_color_value_is_zero_one(union isl_color_value value, 293 enum isl_format format) 294 { 295 const struct isl_format_layout *fmtl = isl_format_get_layout(format); 296 297 #define RETURN_FALSE_IF_NOT_0_1(c, i, field) \ 298 if (fmtl->channels.c.bits && value.field[i] != 0 && value.field[i] != 1) \ 299 return false 300 301 if (isl_format_has_int_channel(format)) { 302 RETURN_FALSE_IF_NOT_0_1(r, 0, u32); 303 RETURN_FALSE_IF_NOT_0_1(g, 1, u32); 304 RETURN_FALSE_IF_NOT_0_1(b, 2, u32); 305 RETURN_FALSE_IF_NOT_0_1(a, 3, u32); 306 } else { 307 RETURN_FALSE_IF_NOT_0_1(r, 0, f32); 308 RETURN_FALSE_IF_NOT_0_1(g, 1, f32); 309 RETURN_FALSE_IF_NOT_0_1(b, 2, f32); 310 RETURN_FALSE_IF_NOT_0_1(a, 3, f32); 311 } 312 313 #undef RETURN_FALSE_IF_NOT_0_1 314 315 return true; 316 } 317 318 /** 319 * @param[out] tiling is set only on success 320 */ 321 static bool 322 isl_surf_choose_tiling(const struct isl_device *dev, 323 const struct isl_surf_init_info *restrict info, 324 enum isl_tiling *tiling) 325 { 326 isl_tiling_flags_t tiling_flags = info->tiling_flags; 327 328 /* HiZ surfaces always use the HiZ tiling */ 329 if (info->usage & ISL_SURF_USAGE_HIZ_BIT) { 330 assert(info->format == ISL_FORMAT_HIZ); 331 assert(tiling_flags == ISL_TILING_HIZ_BIT); 332 *tiling = ISL_TILING_HIZ; 333 return true; 334 } 335 336 /* CCS surfaces always use the CCS tiling */ 337 if (info->usage & ISL_SURF_USAGE_CCS_BIT) { 338 assert(isl_format_get_layout(info->format)->txc == ISL_TXC_CCS); 339 assert(tiling_flags == ISL_TILING_CCS_BIT); 340 *tiling = ISL_TILING_CCS; 341 return true; 342 } 343 344 if (ISL_DEV_GEN(dev) >= 6) { 345 isl_gen6_filter_tiling(dev, info, &tiling_flags); 346 } else { 347 isl_gen4_filter_tiling(dev, info, &tiling_flags); 348 } 349 350 #define CHOOSE(__tiling) \ 351 do { \ 352 if (tiling_flags & (1u << (__tiling))) { \ 353 *tiling = (__tiling); \ 354 return true; \ 355 } \ 356 } while (0) 357 358 /* Of the tiling modes remaining, choose the one that offers the best 359 * performance. 360 */ 361 362 if (info->dim == ISL_SURF_DIM_1D) { 363 /* Prefer linear for 1D surfaces because they do not benefit from 364 * tiling. To the contrary, tiling leads to wasted memory and poor 365 * memory locality due to the swizzling and alignment restrictions 366 * required in tiled surfaces. 367 */ 368 CHOOSE(ISL_TILING_LINEAR); 369 } 370 371 CHOOSE(ISL_TILING_Ys); 372 CHOOSE(ISL_TILING_Yf); 373 CHOOSE(ISL_TILING_Y0); 374 CHOOSE(ISL_TILING_X); 375 CHOOSE(ISL_TILING_W); 376 CHOOSE(ISL_TILING_LINEAR); 377 378 #undef CHOOSE 379 380 /* No tiling mode accomodates the inputs. */ 381 return false; 382 } 383 384 static bool 385 isl_choose_msaa_layout(const struct isl_device *dev, 386 const struct isl_surf_init_info *info, 387 enum isl_tiling tiling, 388 enum isl_msaa_layout *msaa_layout) 389 { 390 if (ISL_DEV_GEN(dev) >= 8) { 391 return isl_gen8_choose_msaa_layout(dev, info, tiling, msaa_layout); 392 } else if (ISL_DEV_GEN(dev) >= 7) { 393 return isl_gen7_choose_msaa_layout(dev, info, tiling, msaa_layout); 394 } else if (ISL_DEV_GEN(dev) >= 6) { 395 return isl_gen6_choose_msaa_layout(dev, info, tiling, msaa_layout); 396 } else { 397 return isl_gen4_choose_msaa_layout(dev, info, tiling, msaa_layout); 398 } 399 } 400 401 struct isl_extent2d 402 isl_get_interleaved_msaa_px_size_sa(uint32_t samples) 403 { 404 assert(isl_is_pow2(samples)); 405 406 /* From the Broadwell PRM >> Volume 5: Memory Views >> Computing Mip Level 407 * Sizes (p133): 408 * 409 * If the surface is multisampled and it is a depth or stencil surface 410 * or Multisampled Surface StorageFormat in SURFACE_STATE is 411 * MSFMT_DEPTH_STENCIL, W_L and H_L must be adjusted as follows before 412 * proceeding: [...] 413 */ 414 return (struct isl_extent2d) { 415 .width = 1 << ((ffs(samples) - 0) / 2), 416 .height = 1 << ((ffs(samples) - 1) / 2), 417 }; 418 } 419 420 static void 421 isl_msaa_interleaved_scale_px_to_sa(uint32_t samples, 422 uint32_t *width, uint32_t *height) 423 { 424 const struct isl_extent2d px_size_sa = 425 isl_get_interleaved_msaa_px_size_sa(samples); 426 427 if (width) 428 *width = isl_align(*width, 2) * px_size_sa.width; 429 if (height) 430 *height = isl_align(*height, 2) * px_size_sa.height; 431 } 432 433 static enum isl_array_pitch_span 434 isl_choose_array_pitch_span(const struct isl_device *dev, 435 const struct isl_surf_init_info *restrict info, 436 enum isl_dim_layout dim_layout, 437 const struct isl_extent4d *phys_level0_sa) 438 { 439 switch (dim_layout) { 440 case ISL_DIM_LAYOUT_GEN9_1D: 441 case ISL_DIM_LAYOUT_GEN4_2D: 442 if (ISL_DEV_GEN(dev) >= 8) { 443 /* QPitch becomes programmable in Broadwell. So choose the 444 * most compact QPitch possible in order to conserve memory. 445 * 446 * From the Broadwell PRM >> Volume 2d: Command Reference: Structures 447 * >> RENDER_SURFACE_STATE Surface QPitch (p325): 448 * 449 * - Software must ensure that this field is set to a value 450 * sufficiently large such that the array slices in the surface 451 * do not overlap. Refer to the Memory Data Formats section for 452 * information on how surfaces are stored in memory. 453 * 454 * - This field specifies the distance in rows between array 455 * slices. It is used only in the following cases: 456 * 457 * - Surface Array is enabled OR 458 * - Number of Mulitsamples is not NUMSAMPLES_1 and 459 * Multisampled Surface Storage Format set to MSFMT_MSS OR 460 * - Surface Type is SURFTYPE_CUBE 461 */ 462 return ISL_ARRAY_PITCH_SPAN_COMPACT; 463 } else if (ISL_DEV_GEN(dev) >= 7) { 464 /* Note that Ivybridge introduces 465 * RENDER_SURFACE_STATE.SurfaceArraySpacing, which provides the 466 * driver more control over the QPitch. 467 */ 468 469 if (phys_level0_sa->array_len == 1) { 470 /* The hardware will never use the QPitch. So choose the most 471 * compact QPitch possible in order to conserve memory. 472 */ 473 return ISL_ARRAY_PITCH_SPAN_COMPACT; 474 } 475 476 if (isl_surf_usage_is_depth_or_stencil(info->usage) || 477 (info->usage & ISL_SURF_USAGE_HIZ_BIT)) { 478 /* From the Ivybridge PRM >> Volume 1 Part 1: Graphics Core >> 479 * Section 6.18.4.7: Surface Arrays (p112): 480 * 481 * If Surface Array Spacing is set to ARYSPC_FULL (note that 482 * the depth buffer and stencil buffer have an implied value of 483 * ARYSPC_FULL): 484 */ 485 return ISL_ARRAY_PITCH_SPAN_FULL; 486 } 487 488 if (info->levels == 1) { 489 /* We are able to set RENDER_SURFACE_STATE.SurfaceArraySpacing 490 * to ARYSPC_LOD0. 491 */ 492 return ISL_ARRAY_PITCH_SPAN_COMPACT; 493 } 494 495 return ISL_ARRAY_PITCH_SPAN_FULL; 496 } else if ((ISL_DEV_GEN(dev) == 5 || ISL_DEV_GEN(dev) == 6) && 497 ISL_DEV_USE_SEPARATE_STENCIL(dev) && 498 isl_surf_usage_is_stencil(info->usage)) { 499 /* [ILK-SNB] Errata from the Sandy Bridge PRM >> Volume 4 Part 1: 500 * Graphics Core >> Section 7.18.3.7: Surface Arrays: 501 * 502 * The separate stencil buffer does not support mip mapping, thus 503 * the storage for LODs other than LOD 0 is not needed. 504 */ 505 assert(info->levels == 1); 506 return ISL_ARRAY_PITCH_SPAN_COMPACT; 507 } else { 508 if ((ISL_DEV_GEN(dev) == 5 || ISL_DEV_GEN(dev) == 6) && 509 ISL_DEV_USE_SEPARATE_STENCIL(dev) && 510 isl_surf_usage_is_stencil(info->usage)) { 511 /* [ILK-SNB] Errata from the Sandy Bridge PRM >> Volume 4 Part 1: 512 * Graphics Core >> Section 7.18.3.7: Surface Arrays: 513 * 514 * The separate stencil buffer does not support mip mapping, 515 * thus the storage for LODs other than LOD 0 is not needed. 516 */ 517 assert(info->levels == 1); 518 assert(phys_level0_sa->array_len == 1); 519 return ISL_ARRAY_PITCH_SPAN_COMPACT; 520 } 521 522 if (phys_level0_sa->array_len == 1) { 523 /* The hardware will never use the QPitch. So choose the most 524 * compact QPitch possible in order to conserve memory. 525 */ 526 return ISL_ARRAY_PITCH_SPAN_COMPACT; 527 } 528 529 return ISL_ARRAY_PITCH_SPAN_FULL; 530 } 531 532 case ISL_DIM_LAYOUT_GEN4_3D: 533 /* The hardware will never use the QPitch. So choose the most 534 * compact QPitch possible in order to conserve memory. 535 */ 536 return ISL_ARRAY_PITCH_SPAN_COMPACT; 537 538 case ISL_DIM_LAYOUT_GEN6_STENCIL_HIZ: 539 /* Each array image in the gen6 stencil of HiZ surface is compact in the 540 * sense that every LOD is a compact array of the same size as LOD0. 541 */ 542 return ISL_ARRAY_PITCH_SPAN_COMPACT; 543 } 544 545 unreachable("bad isl_dim_layout"); 546 return ISL_ARRAY_PITCH_SPAN_FULL; 547 } 548 549 static void 550 isl_choose_image_alignment_el(const struct isl_device *dev, 551 const struct isl_surf_init_info *restrict info, 552 enum isl_tiling tiling, 553 enum isl_dim_layout dim_layout, 554 enum isl_msaa_layout msaa_layout, 555 struct isl_extent3d *image_align_el) 556 { 557 const struct isl_format_layout *fmtl = isl_format_get_layout(info->format); 558 if (fmtl->txc == ISL_TXC_MCS) { 559 assert(tiling == ISL_TILING_Y0); 560 561 /* 562 * IvyBrigde PRM Vol 2, Part 1, "11.7 MCS Buffer for Render Target(s)": 563 * 564 * Height, width, and layout of MCS buffer in this case must match with 565 * Render Target height, width, and layout. MCS buffer is tiledY. 566 * 567 * To avoid wasting memory, choose the smallest alignment possible: 568 * HALIGN_4 and VALIGN_4. 569 */ 570 *image_align_el = isl_extent3d(4, 4, 1); 571 return; 572 } else if (info->format == ISL_FORMAT_HIZ) { 573 assert(ISL_DEV_GEN(dev) >= 6); 574 if (ISL_DEV_GEN(dev) == 6) { 575 /* HiZ surfaces on Sandy Bridge are packed tightly. */ 576 *image_align_el = isl_extent3d(1, 1, 1); 577 } else { 578 /* On gen7+, HiZ surfaces are always aligned to 16x8 pixels in the 579 * primary surface which works out to 2x2 HiZ elments. 580 */ 581 *image_align_el = isl_extent3d(2, 2, 1); 582 } 583 return; 584 } 585 586 if (ISL_DEV_GEN(dev) >= 9) { 587 isl_gen9_choose_image_alignment_el(dev, info, tiling, dim_layout, 588 msaa_layout, image_align_el); 589 } else if (ISL_DEV_GEN(dev) >= 8) { 590 isl_gen8_choose_image_alignment_el(dev, info, tiling, dim_layout, 591 msaa_layout, image_align_el); 592 } else if (ISL_DEV_GEN(dev) >= 7) { 593 isl_gen7_choose_image_alignment_el(dev, info, tiling, dim_layout, 594 msaa_layout, image_align_el); 595 } else if (ISL_DEV_GEN(dev) >= 6) { 596 isl_gen6_choose_image_alignment_el(dev, info, tiling, dim_layout, 597 msaa_layout, image_align_el); 598 } else { 599 isl_gen4_choose_image_alignment_el(dev, info, tiling, dim_layout, 600 msaa_layout, image_align_el); 601 } 602 } 603 604 static enum isl_dim_layout 605 isl_surf_choose_dim_layout(const struct isl_device *dev, 606 enum isl_surf_dim logical_dim, 607 enum isl_tiling tiling, 608 isl_surf_usage_flags_t usage) 609 { 610 /* Sandy bridge needs a special layout for HiZ and stencil. */ 611 if (ISL_DEV_GEN(dev) == 6 && 612 (tiling == ISL_TILING_W || tiling == ISL_TILING_HIZ)) 613 return ISL_DIM_LAYOUT_GEN6_STENCIL_HIZ; 614 615 if (ISL_DEV_GEN(dev) >= 9) { 616 switch (logical_dim) { 617 case ISL_SURF_DIM_1D: 618 /* From the Sky Lake PRM Vol. 5, "1D Surfaces": 619 * 620 * One-dimensional surfaces use a tiling mode of linear. 621 * Technically, they are not tiled resources, but the Tiled 622 * Resource Mode field in RENDER_SURFACE_STATE is still used to 623 * indicate the alignment requirements for this linear surface 624 * (See 1D Alignment requirements for how 4K and 64KB Tiled 625 * Resource Modes impact alignment). Alternatively, a 1D surface 626 * can be defined as a 2D tiled surface (e.g. TileY or TileX) with 627 * a height of 0. 628 * 629 * In other words, ISL_DIM_LAYOUT_GEN9_1D is only used for linear 630 * surfaces and, for tiled surfaces, ISL_DIM_LAYOUT_GEN4_2D is used. 631 */ 632 if (tiling == ISL_TILING_LINEAR) 633 return ISL_DIM_LAYOUT_GEN9_1D; 634 else 635 return ISL_DIM_LAYOUT_GEN4_2D; 636 case ISL_SURF_DIM_2D: 637 case ISL_SURF_DIM_3D: 638 return ISL_DIM_LAYOUT_GEN4_2D; 639 } 640 } else { 641 switch (logical_dim) { 642 case ISL_SURF_DIM_1D: 643 case ISL_SURF_DIM_2D: 644 /* From the G45 PRM Vol. 1a, "6.17.4.1 Hardware Cube Map Layout": 645 * 646 * The cube face textures are stored in the same way as 3D surfaces 647 * are stored (see section 6.17.5 for details). For cube surfaces, 648 * however, the depth is equal to the number of faces (always 6) and 649 * is not reduced for each MIP. 650 */ 651 if (ISL_DEV_GEN(dev) == 4 && (usage & ISL_SURF_USAGE_CUBE_BIT)) 652 return ISL_DIM_LAYOUT_GEN4_3D; 653 654 return ISL_DIM_LAYOUT_GEN4_2D; 655 case ISL_SURF_DIM_3D: 656 return ISL_DIM_LAYOUT_GEN4_3D; 657 } 658 } 659 660 unreachable("bad isl_surf_dim"); 661 return ISL_DIM_LAYOUT_GEN4_2D; 662 } 663 664 /** 665 * Calculate the physical extent of the surface's first level, in units of 666 * surface samples. The result is aligned to the format's compression block. 667 */ 668 static void 669 isl_calc_phys_level0_extent_sa(const struct isl_device *dev, 670 const struct isl_surf_init_info *restrict info, 671 enum isl_dim_layout dim_layout, 672 enum isl_tiling tiling, 673 enum isl_msaa_layout msaa_layout, 674 struct isl_extent4d *phys_level0_sa) 675 { 676 const struct isl_format_layout *fmtl = isl_format_get_layout(info->format); 677 678 if (isl_format_is_yuv(info->format)) 679 isl_finishme("%s:%s: YUV format", __FILE__, __func__); 680 681 switch (info->dim) { 682 case ISL_SURF_DIM_1D: 683 assert(info->height == 1); 684 assert(info->depth == 1); 685 assert(info->samples == 1); 686 687 switch (dim_layout) { 688 case ISL_DIM_LAYOUT_GEN4_3D: 689 unreachable("bad isl_dim_layout"); 690 691 case ISL_DIM_LAYOUT_GEN9_1D: 692 case ISL_DIM_LAYOUT_GEN4_2D: 693 case ISL_DIM_LAYOUT_GEN6_STENCIL_HIZ: 694 *phys_level0_sa = (struct isl_extent4d) { 695 .w = isl_align_npot(info->width, fmtl->bw), 696 .h = fmtl->bh, 697 .d = 1, 698 .a = info->array_len, 699 }; 700 break; 701 } 702 break; 703 704 case ISL_SURF_DIM_2D: 705 if (ISL_DEV_GEN(dev) == 4 && (info->usage & ISL_SURF_USAGE_CUBE_BIT)) 706 assert(dim_layout == ISL_DIM_LAYOUT_GEN4_3D); 707 else 708 assert(dim_layout == ISL_DIM_LAYOUT_GEN4_2D || 709 dim_layout == ISL_DIM_LAYOUT_GEN6_STENCIL_HIZ); 710 711 if (tiling == ISL_TILING_Ys && info->samples > 1) 712 isl_finishme("%s:%s: multisample TileYs layout", __FILE__, __func__); 713 714 switch (msaa_layout) { 715 case ISL_MSAA_LAYOUT_NONE: 716 assert(info->depth == 1); 717 assert(info->samples == 1); 718 719 *phys_level0_sa = (struct isl_extent4d) { 720 .w = isl_align_npot(info->width, fmtl->bw), 721 .h = isl_align_npot(info->height, fmtl->bh), 722 .d = 1, 723 .a = info->array_len, 724 }; 725 break; 726 727 case ISL_MSAA_LAYOUT_ARRAY: 728 assert(info->depth == 1); 729 assert(info->levels == 1); 730 assert(isl_format_supports_multisampling(dev->info, info->format)); 731 assert(fmtl->bw == 1 && fmtl->bh == 1); 732 733 *phys_level0_sa = (struct isl_extent4d) { 734 .w = info->width, 735 .h = info->height, 736 .d = 1, 737 .a = info->array_len * info->samples, 738 }; 739 break; 740 741 case ISL_MSAA_LAYOUT_INTERLEAVED: 742 assert(info->depth == 1); 743 assert(info->levels == 1); 744 assert(isl_format_supports_multisampling(dev->info, info->format)); 745 746 *phys_level0_sa = (struct isl_extent4d) { 747 .w = info->width, 748 .h = info->height, 749 .d = 1, 750 .a = info->array_len, 751 }; 752 753 isl_msaa_interleaved_scale_px_to_sa(info->samples, 754 &phys_level0_sa->w, 755 &phys_level0_sa->h); 756 757 phys_level0_sa->w = isl_align(phys_level0_sa->w, fmtl->bw); 758 phys_level0_sa->h = isl_align(phys_level0_sa->h, fmtl->bh); 759 break; 760 } 761 break; 762 763 case ISL_SURF_DIM_3D: 764 assert(info->array_len == 1); 765 assert(info->samples == 1); 766 767 if (fmtl->bd > 1) { 768 isl_finishme("%s:%s: compression block with depth > 1", 769 __FILE__, __func__); 770 } 771 772 switch (dim_layout) { 773 case ISL_DIM_LAYOUT_GEN9_1D: 774 case ISL_DIM_LAYOUT_GEN6_STENCIL_HIZ: 775 unreachable("bad isl_dim_layout"); 776 777 case ISL_DIM_LAYOUT_GEN4_2D: 778 assert(ISL_DEV_GEN(dev) >= 9); 779 780 *phys_level0_sa = (struct isl_extent4d) { 781 .w = isl_align_npot(info->width, fmtl->bw), 782 .h = isl_align_npot(info->height, fmtl->bh), 783 .d = 1, 784 .a = info->depth, 785 }; 786 break; 787 788 case ISL_DIM_LAYOUT_GEN4_3D: 789 assert(ISL_DEV_GEN(dev) < 9); 790 *phys_level0_sa = (struct isl_extent4d) { 791 .w = isl_align(info->width, fmtl->bw), 792 .h = isl_align(info->height, fmtl->bh), 793 .d = info->depth, 794 .a = 1, 795 }; 796 break; 797 } 798 break; 799 } 800 } 801 802 /** 803 * Calculate the pitch between physical array slices, in units of rows of 804 * surface elements. 805 */ 806 static uint32_t 807 isl_calc_array_pitch_el_rows_gen4_2d( 808 const struct isl_device *dev, 809 const struct isl_surf_init_info *restrict info, 810 const struct isl_tile_info *tile_info, 811 const struct isl_extent3d *image_align_sa, 812 const struct isl_extent4d *phys_level0_sa, 813 enum isl_array_pitch_span array_pitch_span, 814 const struct isl_extent2d *phys_slice0_sa) 815 { 816 const struct isl_format_layout *fmtl = isl_format_get_layout(info->format); 817 uint32_t pitch_sa_rows = 0; 818 819 switch (array_pitch_span) { 820 case ISL_ARRAY_PITCH_SPAN_COMPACT: 821 pitch_sa_rows = isl_align_npot(phys_slice0_sa->h, image_align_sa->h); 822 break; 823 case ISL_ARRAY_PITCH_SPAN_FULL: { 824 /* The QPitch equation is found in the Broadwell PRM >> Volume 5: 825 * Memory Views >> Common Surface Formats >> Surface Layout >> 2D 826 * Surfaces >> Surface Arrays. 827 */ 828 uint32_t H0_sa = phys_level0_sa->h; 829 uint32_t H1_sa = isl_minify(H0_sa, 1); 830 831 uint32_t h0_sa = isl_align_npot(H0_sa, image_align_sa->h); 832 uint32_t h1_sa = isl_align_npot(H1_sa, image_align_sa->h); 833 834 uint32_t m; 835 if (ISL_DEV_GEN(dev) >= 7) { 836 /* The QPitch equation changed slightly in Ivybridge. */ 837 m = 12; 838 } else { 839 m = 11; 840 } 841 842 pitch_sa_rows = h0_sa + h1_sa + (m * image_align_sa->h); 843 844 if (ISL_DEV_GEN(dev) == 6 && info->samples > 1 && 845 (info->height % 4 == 1)) { 846 /* [SNB] Errata from the Sandy Bridge PRM >> Volume 4 Part 1: 847 * Graphics Core >> Section 7.18.3.7: Surface Arrays: 848 * 849 * [SNB] Errata: Sampler MSAA Qpitch will be 4 greater than 850 * the value calculated in the equation above , for every 851 * other odd Surface Height starting from 1 i.e. 1,5,9,13. 852 * 853 * XXX(chadv): Is the errata natural corollary of the physical 854 * layout of interleaved samples? 855 */ 856 pitch_sa_rows += 4; 857 } 858 859 pitch_sa_rows = isl_align_npot(pitch_sa_rows, fmtl->bh); 860 } /* end case */ 861 break; 862 } 863 864 assert(pitch_sa_rows % fmtl->bh == 0); 865 uint32_t pitch_el_rows = pitch_sa_rows / fmtl->bh; 866 867 if (ISL_DEV_GEN(dev) >= 9 && fmtl->txc == ISL_TXC_CCS) { 868 /* 869 * From the Sky Lake PRM Vol 7, "MCS Buffer for Render Target(s)" (p. 632): 870 * 871 * "Mip-mapped and arrayed surfaces are supported with MCS buffer 872 * layout with these alignments in the RT space: Horizontal 873 * Alignment = 128 and Vertical Alignment = 64." 874 * 875 * From the Sky Lake PRM Vol. 2d, "RENDER_SURFACE_STATE" (p. 435): 876 * 877 * "For non-multisampled render target's CCS auxiliary surface, 878 * QPitch must be computed with Horizontal Alignment = 128 and 879 * Surface Vertical Alignment = 256. These alignments are only for 880 * CCS buffer and not for associated render target." 881 * 882 * The first restriction is already handled by isl_choose_image_alignment_el 883 * but the second restriction, which is an extension of the first, only 884 * applies to qpitch and must be applied here. 885 */ 886 assert(fmtl->bh == 4); 887 pitch_el_rows = isl_align(pitch_el_rows, 256 / 4); 888 } 889 890 if (ISL_DEV_GEN(dev) >= 9 && 891 info->dim == ISL_SURF_DIM_3D && 892 tile_info->tiling != ISL_TILING_LINEAR) { 893 /* From the Skylake BSpec >> RENDER_SURFACE_STATE >> Surface QPitch: 894 * 895 * Tile Mode != Linear: This field must be set to an integer multiple 896 * of the tile height 897 */ 898 pitch_el_rows = isl_align(pitch_el_rows, tile_info->logical_extent_el.height); 899 } 900 901 return pitch_el_rows; 902 } 903 904 /** 905 * A variant of isl_calc_phys_slice0_extent_sa() specific to 906 * ISL_DIM_LAYOUT_GEN4_2D. 907 */ 908 static void 909 isl_calc_phys_slice0_extent_sa_gen4_2d( 910 const struct isl_device *dev, 911 const struct isl_surf_init_info *restrict info, 912 enum isl_msaa_layout msaa_layout, 913 const struct isl_extent3d *image_align_sa, 914 const struct isl_extent4d *phys_level0_sa, 915 struct isl_extent2d *phys_slice0_sa) 916 { 917 const struct isl_format_layout *fmtl = isl_format_get_layout(info->format); 918 919 assert(phys_level0_sa->depth == 1); 920 921 if (info->levels == 1) { 922 /* Do not pad the surface to the image alignment. Instead, pad it only 923 * to the pixel format's block alignment. 924 * 925 * For tiled surfaces, using a reduced alignment here avoids wasting CPU 926 * cycles on the below mipmap layout caluclations. Reducing the 927 * alignment here is safe because we later align the row pitch and array 928 * pitch to the tile boundary. It is safe even for 929 * ISL_MSAA_LAYOUT_INTERLEAVED, because phys_level0_sa is already scaled 930 * to accomodate the interleaved samples. 931 * 932 * For linear surfaces, reducing the alignment here permits us to later 933 * choose an arbitrary, non-aligned row pitch. If the surface backs 934 * a VkBuffer, then an arbitrary pitch may be needed to accomodate 935 * VkBufferImageCopy::bufferRowLength. 936 */ 937 *phys_slice0_sa = (struct isl_extent2d) { 938 .w = isl_align_npot(phys_level0_sa->w, fmtl->bw), 939 .h = isl_align_npot(phys_level0_sa->h, fmtl->bh), 940 }; 941 return; 942 } 943 944 uint32_t slice_top_w = 0; 945 uint32_t slice_bottom_w = 0; 946 uint32_t slice_left_h = 0; 947 uint32_t slice_right_h = 0; 948 949 uint32_t W0 = phys_level0_sa->w; 950 uint32_t H0 = phys_level0_sa->h; 951 952 for (uint32_t l = 0; l < info->levels; ++l) { 953 uint32_t W = isl_minify(W0, l); 954 uint32_t H = isl_minify(H0, l); 955 956 uint32_t w = isl_align_npot(W, image_align_sa->w); 957 uint32_t h = isl_align_npot(H, image_align_sa->h); 958 959 if (l == 0) { 960 slice_top_w = w; 961 slice_left_h = h; 962 slice_right_h = h; 963 } else if (l == 1) { 964 slice_bottom_w = w; 965 slice_left_h += h; 966 } else if (l == 2) { 967 slice_bottom_w += w; 968 slice_right_h += h; 969 } else { 970 slice_right_h += h; 971 } 972 } 973 974 *phys_slice0_sa = (struct isl_extent2d) { 975 .w = MAX(slice_top_w, slice_bottom_w), 976 .h = MAX(slice_left_h, slice_right_h), 977 }; 978 } 979 980 static void 981 isl_calc_phys_total_extent_el_gen4_2d( 982 const struct isl_device *dev, 983 const struct isl_surf_init_info *restrict info, 984 const struct isl_tile_info *tile_info, 985 enum isl_msaa_layout msaa_layout, 986 const struct isl_extent3d *image_align_sa, 987 const struct isl_extent4d *phys_level0_sa, 988 enum isl_array_pitch_span array_pitch_span, 989 uint32_t *array_pitch_el_rows, 990 struct isl_extent2d *total_extent_el) 991 { 992 const struct isl_format_layout *fmtl = isl_format_get_layout(info->format); 993 994 struct isl_extent2d phys_slice0_sa; 995 isl_calc_phys_slice0_extent_sa_gen4_2d(dev, info, msaa_layout, 996 image_align_sa, phys_level0_sa, 997 &phys_slice0_sa); 998 *array_pitch_el_rows = 999 isl_calc_array_pitch_el_rows_gen4_2d(dev, info, tile_info, 1000 image_align_sa, phys_level0_sa, 1001 array_pitch_span, 1002 &phys_slice0_sa); 1003 *total_extent_el = (struct isl_extent2d) { 1004 .w = isl_assert_div(phys_slice0_sa.w, fmtl->bw), 1005 .h = *array_pitch_el_rows * (phys_level0_sa->array_len - 1) + 1006 isl_assert_div(phys_slice0_sa.h, fmtl->bh), 1007 }; 1008 } 1009 1010 /** 1011 * A variant of isl_calc_phys_slice0_extent_sa() specific to 1012 * ISL_DIM_LAYOUT_GEN4_3D. 1013 */ 1014 static void 1015 isl_calc_phys_total_extent_el_gen4_3d( 1016 const struct isl_device *dev, 1017 const struct isl_surf_init_info *restrict info, 1018 const struct isl_extent3d *image_align_sa, 1019 const struct isl_extent4d *phys_level0_sa, 1020 uint32_t *array_pitch_el_rows, 1021 struct isl_extent2d *phys_total_el) 1022 { 1023 const struct isl_format_layout *fmtl = isl_format_get_layout(info->format); 1024 1025 assert(info->samples == 1); 1026 1027 if (info->dim != ISL_SURF_DIM_3D) { 1028 /* From the G45 PRM Vol. 1a, "6.17.4.1 Hardware Cube Map Layout": 1029 * 1030 * The cube face textures are stored in the same way as 3D surfaces 1031 * are stored (see section 6.17.5 for details). For cube surfaces, 1032 * however, the depth is equal to the number of faces (always 6) and 1033 * is not reduced for each MIP. 1034 */ 1035 assert(ISL_DEV_GEN(dev) == 4); 1036 assert(info->usage & ISL_SURF_USAGE_CUBE_BIT); 1037 assert(phys_level0_sa->array_len == 6); 1038 } else { 1039 assert(phys_level0_sa->array_len == 1); 1040 } 1041 1042 uint32_t total_w = 0; 1043 uint32_t total_h = 0; 1044 1045 uint32_t W0 = phys_level0_sa->w; 1046 uint32_t H0 = phys_level0_sa->h; 1047 uint32_t D0 = phys_level0_sa->d; 1048 uint32_t A0 = phys_level0_sa->a; 1049 1050 for (uint32_t l = 0; l < info->levels; ++l) { 1051 uint32_t level_w = isl_align_npot(isl_minify(W0, l), image_align_sa->w); 1052 uint32_t level_h = isl_align_npot(isl_minify(H0, l), image_align_sa->h); 1053 uint32_t level_d = info->dim == ISL_SURF_DIM_3D ? isl_minify(D0, l) : A0; 1054 1055 uint32_t max_layers_horiz = MIN(level_d, 1u << l); 1056 uint32_t max_layers_vert = isl_align(level_d, 1u << l) / (1u << l); 1057 1058 total_w = MAX(total_w, level_w * max_layers_horiz); 1059 total_h += level_h * max_layers_vert; 1060 } 1061 1062 /* GEN4_3D layouts don't really have an array pitch since each LOD has a 1063 * different number of horizontal and vertical layers. We have to set it 1064 * to something, so at least make it true for LOD0. 1065 */ 1066 *array_pitch_el_rows = 1067 isl_align_npot(phys_level0_sa->h, image_align_sa->h) / fmtl->bw; 1068 *phys_total_el = (struct isl_extent2d) { 1069 .w = isl_assert_div(total_w, fmtl->bw), 1070 .h = isl_assert_div(total_h, fmtl->bh), 1071 }; 1072 } 1073 1074 /** 1075 * A variant of isl_calc_phys_slice0_extent_sa() specific to 1076 * ISL_DIM_LAYOUT_GEN6_STENCIL_HIZ. 1077 */ 1078 static void 1079 isl_calc_phys_total_extent_el_gen6_stencil_hiz( 1080 const struct isl_device *dev, 1081 const struct isl_surf_init_info *restrict info, 1082 const struct isl_tile_info *tile_info, 1083 const struct isl_extent3d *image_align_sa, 1084 const struct isl_extent4d *phys_level0_sa, 1085 uint32_t *array_pitch_el_rows, 1086 struct isl_extent2d *phys_total_el) 1087 { 1088 const struct isl_format_layout *fmtl = isl_format_get_layout(info->format); 1089 1090 const struct isl_extent2d tile_extent_sa = { 1091 .w = tile_info->logical_extent_el.w * fmtl->bw, 1092 .h = tile_info->logical_extent_el.h * fmtl->bh, 1093 }; 1094 /* Tile size is a multiple of image alignment */ 1095 assert(tile_extent_sa.w % image_align_sa->w == 0); 1096 assert(tile_extent_sa.h % image_align_sa->h == 0); 1097 1098 const uint32_t W0 = phys_level0_sa->w; 1099 const uint32_t H0 = phys_level0_sa->h; 1100 1101 /* Each image has the same height as LOD0 because the hardware thinks 1102 * everything is LOD0 1103 */ 1104 const uint32_t H = isl_align(H0, image_align_sa->h) * phys_level0_sa->a; 1105 1106 uint32_t total_top_w = 0; 1107 uint32_t total_bottom_w = 0; 1108 uint32_t total_h = 0; 1109 1110 for (uint32_t l = 0; l < info->levels; ++l) { 1111 const uint32_t W = isl_minify(W0, l); 1112 1113 const uint32_t w = isl_align(W, tile_extent_sa.w); 1114 const uint32_t h = isl_align(H, tile_extent_sa.h); 1115 1116 if (l == 0) { 1117 total_top_w = w; 1118 total_h = h; 1119 } else if (l == 1) { 1120 total_bottom_w = w; 1121 total_h += h; 1122 } else { 1123 total_bottom_w += w; 1124 } 1125 } 1126 1127 *array_pitch_el_rows = 1128 isl_assert_div(isl_align(H0, image_align_sa->h), fmtl->bh); 1129 *phys_total_el = (struct isl_extent2d) { 1130 .w = isl_assert_div(MAX(total_top_w, total_bottom_w), fmtl->bw), 1131 .h = isl_assert_div(total_h, fmtl->bh), 1132 }; 1133 } 1134 1135 /** 1136 * A variant of isl_calc_phys_slice0_extent_sa() specific to 1137 * ISL_DIM_LAYOUT_GEN9_1D. 1138 */ 1139 static void 1140 isl_calc_phys_total_extent_el_gen9_1d( 1141 const struct isl_device *dev, 1142 const struct isl_surf_init_info *restrict info, 1143 const struct isl_extent3d *image_align_sa, 1144 const struct isl_extent4d *phys_level0_sa, 1145 uint32_t *array_pitch_el_rows, 1146 struct isl_extent2d *phys_total_el) 1147 { 1148 MAYBE_UNUSED const struct isl_format_layout *fmtl = isl_format_get_layout(info->format); 1149 1150 assert(phys_level0_sa->height / fmtl->bh == 1); 1151 assert(phys_level0_sa->depth == 1); 1152 assert(info->samples == 1); 1153 assert(image_align_sa->w >= fmtl->bw); 1154 1155 uint32_t slice_w = 0; 1156 const uint32_t W0 = phys_level0_sa->w; 1157 1158 for (uint32_t l = 0; l < info->levels; ++l) { 1159 uint32_t W = isl_minify(W0, l); 1160 uint32_t w = isl_align_npot(W, image_align_sa->w); 1161 1162 slice_w += w; 1163 } 1164 1165 *array_pitch_el_rows = 1; 1166 *phys_total_el = (struct isl_extent2d) { 1167 .w = isl_assert_div(slice_w, fmtl->bw), 1168 .h = phys_level0_sa->array_len, 1169 }; 1170 } 1171 1172 /** 1173 * Calculate the two-dimensional total physical extent of the surface, in 1174 * units of surface elements. 1175 */ 1176 static void 1177 isl_calc_phys_total_extent_el(const struct isl_device *dev, 1178 const struct isl_surf_init_info *restrict info, 1179 const struct isl_tile_info *tile_info, 1180 enum isl_dim_layout dim_layout, 1181 enum isl_msaa_layout msaa_layout, 1182 const struct isl_extent3d *image_align_sa, 1183 const struct isl_extent4d *phys_level0_sa, 1184 enum isl_array_pitch_span array_pitch_span, 1185 uint32_t *array_pitch_el_rows, 1186 struct isl_extent2d *total_extent_el) 1187 { 1188 switch (dim_layout) { 1189 case ISL_DIM_LAYOUT_GEN9_1D: 1190 assert(array_pitch_span == ISL_ARRAY_PITCH_SPAN_COMPACT); 1191 isl_calc_phys_total_extent_el_gen9_1d(dev, info, 1192 image_align_sa, phys_level0_sa, 1193 array_pitch_el_rows, 1194 total_extent_el); 1195 return; 1196 case ISL_DIM_LAYOUT_GEN4_2D: 1197 isl_calc_phys_total_extent_el_gen4_2d(dev, info, tile_info, msaa_layout, 1198 image_align_sa, phys_level0_sa, 1199 array_pitch_span, 1200 array_pitch_el_rows, 1201 total_extent_el); 1202 return; 1203 case ISL_DIM_LAYOUT_GEN6_STENCIL_HIZ: 1204 assert(array_pitch_span == ISL_ARRAY_PITCH_SPAN_COMPACT); 1205 isl_calc_phys_total_extent_el_gen6_stencil_hiz(dev, info, tile_info, 1206 image_align_sa, 1207 phys_level0_sa, 1208 array_pitch_el_rows, 1209 total_extent_el); 1210 return; 1211 case ISL_DIM_LAYOUT_GEN4_3D: 1212 assert(array_pitch_span == ISL_ARRAY_PITCH_SPAN_COMPACT); 1213 isl_calc_phys_total_extent_el_gen4_3d(dev, info, 1214 image_align_sa, phys_level0_sa, 1215 array_pitch_el_rows, 1216 total_extent_el); 1217 return; 1218 } 1219 } 1220 1221 static uint32_t 1222 isl_calc_row_pitch_alignment(const struct isl_surf_init_info *surf_info, 1223 const struct isl_tile_info *tile_info) 1224 { 1225 if (tile_info->tiling != ISL_TILING_LINEAR) 1226 return tile_info->phys_extent_B.width; 1227 1228 /* From the Broadwel PRM >> Volume 2d: Command Reference: Structures >> 1229 * RENDER_SURFACE_STATE Surface Pitch (p349): 1230 * 1231 * - For linear render target surfaces and surfaces accessed with the 1232 * typed data port messages, the pitch must be a multiple of the 1233 * element size for non-YUV surface formats. Pitch must be 1234 * a multiple of 2 * element size for YUV surface formats. 1235 * 1236 * - [Requirements for SURFTYPE_BUFFER and SURFTYPE_STRBUF, which we 1237 * ignore because isl doesn't do buffers.] 1238 * 1239 * - For other linear surfaces, the pitch can be any multiple of 1240 * bytes. 1241 */ 1242 const struct isl_format_layout *fmtl = isl_format_get_layout(surf_info->format); 1243 const uint32_t bs = fmtl->bpb / 8; 1244 1245 if (surf_info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) { 1246 if (isl_format_is_yuv(surf_info->format)) { 1247 return 2 * bs; 1248 } else { 1249 return bs; 1250 } 1251 } 1252 1253 return 1; 1254 } 1255 1256 static uint32_t 1257 isl_calc_linear_min_row_pitch(const struct isl_device *dev, 1258 const struct isl_surf_init_info *info, 1259 const struct isl_extent2d *phys_total_el, 1260 uint32_t alignment) 1261 { 1262 const struct isl_format_layout *fmtl = isl_format_get_layout(info->format); 1263 const uint32_t bs = fmtl->bpb / 8; 1264 1265 return isl_align_npot(bs * phys_total_el->w, alignment); 1266 } 1267 1268 static uint32_t 1269 isl_calc_tiled_min_row_pitch(const struct isl_device *dev, 1270 const struct isl_surf_init_info *surf_info, 1271 const struct isl_tile_info *tile_info, 1272 const struct isl_extent2d *phys_total_el, 1273 uint32_t alignment) 1274 { 1275 const struct isl_format_layout *fmtl = isl_format_get_layout(surf_info->format); 1276 1277 assert(fmtl->bpb % tile_info->format_bpb == 0); 1278 1279 const uint32_t tile_el_scale = fmtl->bpb / tile_info->format_bpb; 1280 const uint32_t total_w_tl = 1281 isl_align_div(phys_total_el->w * tile_el_scale, 1282 tile_info->logical_extent_el.width); 1283 1284 assert(alignment == tile_info->phys_extent_B.width); 1285 return total_w_tl * tile_info->phys_extent_B.width; 1286 } 1287 1288 static uint32_t 1289 isl_calc_min_row_pitch(const struct isl_device *dev, 1290 const struct isl_surf_init_info *surf_info, 1291 const struct isl_tile_info *tile_info, 1292 const struct isl_extent2d *phys_total_el, 1293 uint32_t alignment) 1294 { 1295 if (tile_info->tiling == ISL_TILING_LINEAR) { 1296 return isl_calc_linear_min_row_pitch(dev, surf_info, phys_total_el, 1297 alignment); 1298 } else { 1299 return isl_calc_tiled_min_row_pitch(dev, surf_info, tile_info, 1300 phys_total_el, alignment); 1301 } 1302 } 1303 1304 /** 1305 * Is `pitch` in the valid range for a hardware bitfield, if the bitfield's 1306 * size is `bits` bits? 1307 * 1308 * Hardware pitch fields are offset by 1. For example, if the size of 1309 * RENDER_SURFACE_STATE::SurfacePitch is B bits, then the range of valid 1310 * pitches is [1, 2^b] inclusive. If the surface pitch is N, then 1311 * RENDER_SURFACE_STATE::SurfacePitch must be set to N-1. 1312 */ 1313 static bool 1314 pitch_in_range(uint32_t n, uint32_t bits) 1315 { 1316 assert(n != 0); 1317 return likely(bits != 0 && 1 <= n && n <= (1 << bits)); 1318 } 1319 1320 static bool 1321 isl_calc_row_pitch(const struct isl_device *dev, 1322 const struct isl_surf_init_info *surf_info, 1323 const struct isl_tile_info *tile_info, 1324 enum isl_dim_layout dim_layout, 1325 const struct isl_extent2d *phys_total_el, 1326 uint32_t *out_row_pitch) 1327 { 1328 uint32_t alignment = 1329 isl_calc_row_pitch_alignment(surf_info, tile_info); 1330 1331 /* If pitch isn't given and it can be chosen freely, align it by cache line 1332 * allowing one to use blit engine on the surface. 1333 */ 1334 if (surf_info->row_pitch == 0 && tile_info->tiling == ISL_TILING_LINEAR) { 1335 /* From the Broadwell PRM docs for XY_SRC_COPY_BLT::SourceBaseAddress: 1336 * 1337 * "Base address of the destination surface: X=0, Y=0. Lower 32bits 1338 * of the 48bit addressing. When Src Tiling is enabled (Bit_15 1339 * enabled), this address must be 4KB-aligned. When Tiling is not 1340 * enabled, this address should be CL (64byte) aligned." 1341 */ 1342 alignment = MAX2(alignment, 64); 1343 } 1344 1345 const uint32_t min_row_pitch = 1346 isl_calc_min_row_pitch(dev, surf_info, tile_info, phys_total_el, 1347 alignment); 1348 1349 uint32_t row_pitch = min_row_pitch; 1350 1351 if (surf_info->row_pitch != 0) { 1352 row_pitch = surf_info->row_pitch; 1353 1354 if (row_pitch < min_row_pitch) 1355 return false; 1356 1357 if (row_pitch % alignment != 0) 1358 return false; 1359 } 1360 1361 const uint32_t row_pitch_tiles = row_pitch / tile_info->phys_extent_B.width; 1362 1363 if (row_pitch == 0) 1364 return false; 1365 1366 if (dim_layout == ISL_DIM_LAYOUT_GEN9_1D) { 1367 /* SurfacePitch is ignored for this layout. */ 1368 goto done; 1369 } 1370 1371 if ((surf_info->usage & (ISL_SURF_USAGE_RENDER_TARGET_BIT | 1372 ISL_SURF_USAGE_TEXTURE_BIT | 1373 ISL_SURF_USAGE_STORAGE_BIT)) && 1374 !pitch_in_range(row_pitch, RENDER_SURFACE_STATE_SurfacePitch_bits(dev->info))) 1375 return false; 1376 1377 if ((surf_info->usage & (ISL_SURF_USAGE_CCS_BIT | 1378 ISL_SURF_USAGE_MCS_BIT)) && 1379 !pitch_in_range(row_pitch_tiles, RENDER_SURFACE_STATE_AuxiliarySurfacePitch_bits(dev->info))) 1380 return false; 1381 1382 if ((surf_info->usage & ISL_SURF_USAGE_DEPTH_BIT) && 1383 !pitch_in_range(row_pitch, _3DSTATE_DEPTH_BUFFER_SurfacePitch_bits(dev->info))) 1384 return false; 1385 1386 if ((surf_info->usage & ISL_SURF_USAGE_HIZ_BIT) && 1387 !pitch_in_range(row_pitch, _3DSTATE_HIER_DEPTH_BUFFER_SurfacePitch_bits(dev->info))) 1388 return false; 1389 1390 const uint32_t stencil_pitch_bits = dev->use_separate_stencil ? 1391 _3DSTATE_STENCIL_BUFFER_SurfacePitch_bits(dev->info) : 1392 _3DSTATE_DEPTH_BUFFER_SurfacePitch_bits(dev->info); 1393 1394 if ((surf_info->usage & ISL_SURF_USAGE_STENCIL_BIT) && 1395 !pitch_in_range(row_pitch, stencil_pitch_bits)) 1396 return false; 1397 1398 done: 1399 *out_row_pitch = row_pitch; 1400 return true; 1401 } 1402 1403 bool 1404 isl_surf_init_s(const struct isl_device *dev, 1405 struct isl_surf *surf, 1406 const struct isl_surf_init_info *restrict info) 1407 { 1408 const struct isl_format_layout *fmtl = isl_format_get_layout(info->format); 1409 1410 const struct isl_extent4d logical_level0_px = { 1411 .w = info->width, 1412 .h = info->height, 1413 .d = info->depth, 1414 .a = info->array_len, 1415 }; 1416 1417 enum isl_tiling tiling; 1418 if (!isl_surf_choose_tiling(dev, info, &tiling)) 1419 return false; 1420 1421 struct isl_tile_info tile_info; 1422 isl_tiling_get_info(tiling, fmtl->bpb, &tile_info); 1423 1424 const enum isl_dim_layout dim_layout = 1425 isl_surf_choose_dim_layout(dev, info->dim, tiling, info->usage); 1426 1427 enum isl_msaa_layout msaa_layout; 1428 if (!isl_choose_msaa_layout(dev, info, tiling, &msaa_layout)) 1429 return false; 1430 1431 struct isl_extent3d image_align_el; 1432 isl_choose_image_alignment_el(dev, info, tiling, dim_layout, msaa_layout, 1433 &image_align_el); 1434 1435 struct isl_extent3d image_align_sa = 1436 isl_extent3d_el_to_sa(info->format, image_align_el); 1437 1438 struct isl_extent4d phys_level0_sa; 1439 isl_calc_phys_level0_extent_sa(dev, info, dim_layout, tiling, msaa_layout, 1440 &phys_level0_sa); 1441 assert(phys_level0_sa.w % fmtl->bw == 0); 1442 assert(phys_level0_sa.h % fmtl->bh == 0); 1443 1444 enum isl_array_pitch_span array_pitch_span = 1445 isl_choose_array_pitch_span(dev, info, dim_layout, &phys_level0_sa); 1446 1447 uint32_t array_pitch_el_rows; 1448 struct isl_extent2d phys_total_el; 1449 isl_calc_phys_total_extent_el(dev, info, &tile_info, 1450 dim_layout, msaa_layout, 1451 &image_align_sa, &phys_level0_sa, 1452 array_pitch_span, &array_pitch_el_rows, 1453 &phys_total_el); 1454 1455 uint32_t row_pitch; 1456 if (!isl_calc_row_pitch(dev, info, &tile_info, dim_layout, 1457 &phys_total_el, &row_pitch)) 1458 return false; 1459 1460 uint32_t base_alignment; 1461 uint64_t size; 1462 if (tiling == ISL_TILING_LINEAR) { 1463 size = (uint64_t) row_pitch * phys_total_el.h; 1464 1465 /* From the Broadwell PRM Vol 2d, RENDER_SURFACE_STATE::SurfaceBaseAddress: 1466 * 1467 * "The Base Address for linear render target surfaces and surfaces 1468 * accessed with the typed surface read/write data port messages must 1469 * be element-size aligned, for non-YUV surface formats, or a 1470 * multiple of 2 element-sizes for YUV surface formats. Other linear 1471 * surfaces have no alignment requirements (byte alignment is 1472 * sufficient.)" 1473 */ 1474 base_alignment = MAX(1, info->min_alignment); 1475 if (info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) { 1476 if (isl_format_is_yuv(info->format)) { 1477 base_alignment = MAX(base_alignment, fmtl->bpb / 4); 1478 } else { 1479 base_alignment = MAX(base_alignment, fmtl->bpb / 8); 1480 } 1481 } 1482 base_alignment = isl_round_up_to_power_of_two(base_alignment); 1483 } else { 1484 const uint32_t total_h_tl = 1485 isl_align_div(phys_total_el.h, tile_info.logical_extent_el.height); 1486 1487 size = (uint64_t) total_h_tl * tile_info.phys_extent_B.height * row_pitch; 1488 1489 const uint32_t tile_size = tile_info.phys_extent_B.width * 1490 tile_info.phys_extent_B.height; 1491 assert(isl_is_pow2(info->min_alignment) && isl_is_pow2(tile_size)); 1492 base_alignment = MAX(info->min_alignment, tile_size); 1493 } 1494 1495 if (ISL_DEV_GEN(dev) < 9) { 1496 /* From the Broadwell PRM Vol 5, Surface Layout: 1497 * 1498 * "In addition to restrictions on maximum height, width, and depth, 1499 * surfaces are also restricted to a maximum size in bytes. This 1500 * maximum is 2 GB for all products and all surface types." 1501 * 1502 * This comment is applicable to all Pre-gen9 platforms. 1503 */ 1504 if (size > (uint64_t) 1 << 31) 1505 return false; 1506 } else { 1507 /* From the Skylake PRM Vol 5, Maximum Surface Size in Bytes: 1508 * "In addition to restrictions on maximum height, width, and depth, 1509 * surfaces are also restricted to a maximum size of 2^38 bytes. 1510 * All pixels within the surface must be contained within 2^38 bytes 1511 * of the base address." 1512 */ 1513 if (size > (uint64_t) 1 << 38) 1514 return false; 1515 } 1516 1517 *surf = (struct isl_surf) { 1518 .dim = info->dim, 1519 .dim_layout = dim_layout, 1520 .msaa_layout = msaa_layout, 1521 .tiling = tiling, 1522 .format = info->format, 1523 1524 .levels = info->levels, 1525 .samples = info->samples, 1526 1527 .image_alignment_el = image_align_el, 1528 .logical_level0_px = logical_level0_px, 1529 .phys_level0_sa = phys_level0_sa, 1530 1531 .size = size, 1532 .alignment = base_alignment, 1533 .row_pitch = row_pitch, 1534 .array_pitch_el_rows = array_pitch_el_rows, 1535 .array_pitch_span = array_pitch_span, 1536 1537 .usage = info->usage, 1538 }; 1539 1540 return true; 1541 } 1542 1543 void 1544 isl_surf_get_tile_info(const struct isl_surf *surf, 1545 struct isl_tile_info *tile_info) 1546 { 1547 const struct isl_format_layout *fmtl = isl_format_get_layout(surf->format); 1548 isl_tiling_get_info(surf->tiling, fmtl->bpb, tile_info); 1549 } 1550 1551 bool 1552 isl_surf_get_hiz_surf(const struct isl_device *dev, 1553 const struct isl_surf *surf, 1554 struct isl_surf *hiz_surf) 1555 { 1556 assert(ISL_DEV_GEN(dev) >= 5 && ISL_DEV_USE_SEPARATE_STENCIL(dev)); 1557 1558 /* Multisampled depth is always interleaved */ 1559 assert(surf->msaa_layout == ISL_MSAA_LAYOUT_NONE || 1560 surf->msaa_layout == ISL_MSAA_LAYOUT_INTERLEAVED); 1561 1562 /* From the Broadwell PRM Vol. 7, "Hierarchical Depth Buffer": 1563 * 1564 * "The Surface Type, Height, Width, Depth, Minimum Array Element, Render 1565 * Target View Extent, and Depth Coordinate Offset X/Y of the 1566 * hierarchical depth buffer are inherited from the depth buffer. The 1567 * height and width of the hierarchical depth buffer that must be 1568 * allocated are computed by the following formulas, where HZ is the 1569 * hierarchical depth buffer and Z is the depth buffer. The Z_Height, 1570 * Z_Width, and Z_Depth values given in these formulas are those present 1571 * in 3DSTATE_DEPTH_BUFFER incremented by one. 1572 * 1573 * "The value of Z_Height and Z_Width must each be multiplied by 2 before 1574 * being applied to the table below if Number of Multisamples is set to 1575 * NUMSAMPLES_4. The value of Z_Height must be multiplied by 2 and 1576 * Z_Width must be multiplied by 4 before being applied to the table 1577 * below if Number of Multisamples is set to NUMSAMPLES_8." 1578 * 1579 * In the Sky Lake PRM, the second paragraph is replaced with this: 1580 * 1581 * "The Z_Height and Z_Width values must equal those present in 1582 * 3DSTATE_DEPTH_BUFFER incremented by one." 1583 * 1584 * In other words, on Sandy Bridge through Broadwell, each 128-bit HiZ 1585 * block corresponds to a region of 8x4 samples in the primary depth 1586 * surface. On Sky Lake, on the other hand, each HiZ block corresponds to 1587 * a region of 8x4 pixels in the primary depth surface regardless of the 1588 * number of samples. The dimensions of a HiZ block in both pixels and 1589 * samples are given in the table below: 1590 * 1591 * | SNB - BDW | SKL+ 1592 * ------+-----------+------------- 1593 * 1x | 8 x 4 sa | 8 x 4 sa 1594 * MSAA | 8 x 4 px | 8 x 4 px 1595 * ------+-----------+------------- 1596 * 2x | 8 x 4 sa | 16 x 4 sa 1597 * MSAA | 4 x 4 px | 8 x 4 px 1598 * ------+-----------+------------- 1599 * 4x | 8 x 4 sa | 16 x 8 sa 1600 * MSAA | 4 x 2 px | 8 x 4 px 1601 * ------+-----------+------------- 1602 * 8x | 8 x 4 sa | 32 x 8 sa 1603 * MSAA | 2 x 2 px | 8 x 4 px 1604 * ------+-----------+------------- 1605 * 16x | N/A | 32 x 16 sa 1606 * MSAA | N/A | 8 x 4 px 1607 * ------+-----------+------------- 1608 * 1609 * There are a number of different ways that this discrepency could be 1610 * handled. The way we have chosen is to simply make MSAA HiZ have the 1611 * same number of samples as the parent surface pre-Sky Lake and always be 1612 * single-sampled on Sky Lake and above. Since the block sizes of 1613 * compressed formats are given in samples, this neatly handles everything 1614 * without the need for additional HiZ formats with different block sizes 1615 * on SKL+. 1616 */ 1617 const unsigned samples = ISL_DEV_GEN(dev) >= 9 ? 1 : surf->samples; 1618 1619 return isl_surf_init(dev, hiz_surf, 1620 .dim = surf->dim, 1621 .format = ISL_FORMAT_HIZ, 1622 .width = surf->logical_level0_px.width, 1623 .height = surf->logical_level0_px.height, 1624 .depth = surf->logical_level0_px.depth, 1625 .levels = surf->levels, 1626 .array_len = surf->logical_level0_px.array_len, 1627 .samples = samples, 1628 .usage = ISL_SURF_USAGE_HIZ_BIT, 1629 .tiling_flags = ISL_TILING_HIZ_BIT); 1630 } 1631 1632 bool 1633 isl_surf_get_mcs_surf(const struct isl_device *dev, 1634 const struct isl_surf *surf, 1635 struct isl_surf *mcs_surf) 1636 { 1637 /* It must be multisampled with an array layout */ 1638 assert(surf->samples > 1 && surf->msaa_layout == ISL_MSAA_LAYOUT_ARRAY); 1639 1640 /* The following are true of all multisampled surfaces */ 1641 assert(surf->dim == ISL_SURF_DIM_2D); 1642 assert(surf->levels == 1); 1643 assert(surf->logical_level0_px.depth == 1); 1644 1645 /* The "Auxiliary Surface Pitch" field in RENDER_SURFACE_STATE is only 9 1646 * bits which means the maximum pitch of a compression surface is 512 1647 * tiles or 64KB (since MCS is always Y-tiled). Since a 16x MCS buffer is 1648 * 64bpp, this gives us a maximum width of 8192 pixels. We can create 1649 * larger multisampled surfaces, we just can't compress them. For 2x, 4x, 1650 * and 8x, we have enough room for the full 16k supported by the hardware. 1651 */ 1652 if (surf->samples == 16 && surf->logical_level0_px.width > 8192) 1653 return false; 1654 1655 enum isl_format mcs_format; 1656 switch (surf->samples) { 1657 case 2: mcs_format = ISL_FORMAT_MCS_2X; break; 1658 case 4: mcs_format = ISL_FORMAT_MCS_4X; break; 1659 case 8: mcs_format = ISL_FORMAT_MCS_8X; break; 1660 case 16: mcs_format = ISL_FORMAT_MCS_16X; break; 1661 default: 1662 unreachable("Invalid sample count"); 1663 } 1664 1665 return isl_surf_init(dev, mcs_surf, 1666 .dim = ISL_SURF_DIM_2D, 1667 .format = mcs_format, 1668 .width = surf->logical_level0_px.width, 1669 .height = surf->logical_level0_px.height, 1670 .depth = 1, 1671 .levels = 1, 1672 .array_len = surf->logical_level0_px.array_len, 1673 .samples = 1, /* MCS surfaces are really single-sampled */ 1674 .usage = ISL_SURF_USAGE_MCS_BIT, 1675 .tiling_flags = ISL_TILING_Y0_BIT); 1676 } 1677 1678 bool 1679 isl_surf_get_ccs_surf(const struct isl_device *dev, 1680 const struct isl_surf *surf, 1681 struct isl_surf *ccs_surf, 1682 uint32_t row_pitch) 1683 { 1684 assert(surf->samples == 1 && surf->msaa_layout == ISL_MSAA_LAYOUT_NONE); 1685 assert(ISL_DEV_GEN(dev) >= 7); 1686 1687 if (surf->usage & ISL_SURF_USAGE_DISABLE_AUX_BIT) 1688 return false; 1689 1690 /* The PRM doesn't say this explicitly, but fast-clears don't appear to 1691 * work for 3D textures until gen9 where the layout of 3D textures changes 1692 * to match 2D array textures. 1693 */ 1694 if (ISL_DEV_GEN(dev) <= 8 && surf->dim != ISL_SURF_DIM_2D) 1695 return false; 1696 1697 /* From the HSW PRM Volume 7: 3D-Media-GPGPU, page 652 (Color Clear of 1698 * Non-MultiSampler Render Target Restrictions): 1699 * 1700 * "Support is for non-mip-mapped and non-array surface types only." 1701 * 1702 * This restriction is lifted on gen8+. Technically, it may be possible to 1703 * create a CCS for an arrayed or mipmapped image and only enable CCS_D 1704 * when rendering to the base slice. However, there is no documentation 1705 * tell us what the hardware would do in that case or what it does if you 1706 * walk off the bases slice. (Does it ignore CCS or does it start 1707 * scribbling over random memory?) We play it safe and just follow the 1708 * docs and don't allow CCS_D for arrayed or mip-mapped surfaces. 1709 */ 1710 if (ISL_DEV_GEN(dev) <= 7 && 1711 (surf->levels > 1 || surf->logical_level0_px.array_len > 1)) 1712 return false; 1713 1714 if (isl_format_is_compressed(surf->format)) 1715 return false; 1716 1717 /* TODO: More conditions where it can fail. */ 1718 1719 enum isl_format ccs_format; 1720 if (ISL_DEV_GEN(dev) >= 9) { 1721 if (!isl_tiling_is_any_y(surf->tiling)) 1722 return false; 1723 1724 switch (isl_format_get_layout(surf->format)->bpb) { 1725 case 32: ccs_format = ISL_FORMAT_GEN9_CCS_32BPP; break; 1726 case 64: ccs_format = ISL_FORMAT_GEN9_CCS_64BPP; break; 1727 case 128: ccs_format = ISL_FORMAT_GEN9_CCS_128BPP; break; 1728 default: 1729 return false; 1730 } 1731 } else if (surf->tiling == ISL_TILING_Y0) { 1732 switch (isl_format_get_layout(surf->format)->bpb) { 1733 case 32: ccs_format = ISL_FORMAT_GEN7_CCS_32BPP_Y; break; 1734 case 64: ccs_format = ISL_FORMAT_GEN7_CCS_64BPP_Y; break; 1735 case 128: ccs_format = ISL_FORMAT_GEN7_CCS_128BPP_Y; break; 1736 default: 1737 return false; 1738 } 1739 } else if (surf->tiling == ISL_TILING_X) { 1740 switch (isl_format_get_layout(surf->format)->bpb) { 1741 case 32: ccs_format = ISL_FORMAT_GEN7_CCS_32BPP_X; break; 1742 case 64: ccs_format = ISL_FORMAT_GEN7_CCS_64BPP_X; break; 1743 case 128: ccs_format = ISL_FORMAT_GEN7_CCS_128BPP_X; break; 1744 default: 1745 return false; 1746 } 1747 } else { 1748 return false; 1749 } 1750 1751 return isl_surf_init(dev, ccs_surf, 1752 .dim = surf->dim, 1753 .format = ccs_format, 1754 .width = surf->logical_level0_px.width, 1755 .height = surf->logical_level0_px.height, 1756 .depth = surf->logical_level0_px.depth, 1757 .levels = surf->levels, 1758 .array_len = surf->logical_level0_px.array_len, 1759 .samples = 1, 1760 .row_pitch = row_pitch, 1761 .usage = ISL_SURF_USAGE_CCS_BIT, 1762 .tiling_flags = ISL_TILING_CCS_BIT); 1763 } 1764 1765 #define isl_genX_call(dev, func, ...) \ 1766 switch (ISL_DEV_GEN(dev)) { \ 1767 case 4: \ 1768 /* G45 surface state is the same as gen5 */ \ 1769 if (ISL_DEV_IS_G4X(dev)) { \ 1770 isl_gen5_##func(__VA_ARGS__); \ 1771 } else { \ 1772 isl_gen4_##func(__VA_ARGS__); \ 1773 } \ 1774 break; \ 1775 case 5: \ 1776 isl_gen5_##func(__VA_ARGS__); \ 1777 break; \ 1778 case 6: \ 1779 isl_gen6_##func(__VA_ARGS__); \ 1780 break; \ 1781 case 7: \ 1782 if (ISL_DEV_IS_HASWELL(dev)) { \ 1783 isl_gen75_##func(__VA_ARGS__); \ 1784 } else { \ 1785 isl_gen7_##func(__VA_ARGS__); \ 1786 } \ 1787 break; \ 1788 case 8: \ 1789 isl_gen8_##func(__VA_ARGS__); \ 1790 break; \ 1791 case 9: \ 1792 isl_gen9_##func(__VA_ARGS__); \ 1793 break; \ 1794 case 10: \ 1795 isl_gen10_##func(__VA_ARGS__); \ 1796 break; \ 1797 default: \ 1798 assert(!"Unknown hardware generation"); \ 1799 } 1800 1801 void 1802 isl_surf_fill_state_s(const struct isl_device *dev, void *state, 1803 const struct isl_surf_fill_state_info *restrict info) 1804 { 1805 #ifndef NDEBUG 1806 isl_surf_usage_flags_t _base_usage = 1807 info->view->usage & (ISL_SURF_USAGE_RENDER_TARGET_BIT | 1808 ISL_SURF_USAGE_TEXTURE_BIT | 1809 ISL_SURF_USAGE_STORAGE_BIT); 1810 /* They may only specify one of the above bits at a time */ 1811 assert(__builtin_popcount(_base_usage) == 1); 1812 /* The only other allowed bit is ISL_SURF_USAGE_CUBE_BIT */ 1813 assert((info->view->usage & ~ISL_SURF_USAGE_CUBE_BIT) == _base_usage); 1814 #endif 1815 1816 if (info->surf->dim == ISL_SURF_DIM_3D) { 1817 assert(info->view->base_array_layer + info->view->array_len <= 1818 info->surf->logical_level0_px.depth); 1819 } else { 1820 assert(info->view->base_array_layer + info->view->array_len <= 1821 info->surf->logical_level0_px.array_len); 1822 } 1823 1824 isl_genX_call(dev, surf_fill_state_s, dev, state, info); 1825 } 1826 1827 void 1828 isl_buffer_fill_state_s(const struct isl_device *dev, void *state, 1829 const struct isl_buffer_fill_state_info *restrict info) 1830 { 1831 isl_genX_call(dev, buffer_fill_state_s, state, info); 1832 } 1833 1834 void 1835 isl_null_fill_state(const struct isl_device *dev, void *state, 1836 struct isl_extent3d size) 1837 { 1838 isl_genX_call(dev, null_fill_state, state, size); 1839 } 1840 1841 void 1842 isl_emit_depth_stencil_hiz_s(const struct isl_device *dev, void *batch, 1843 const struct isl_depth_stencil_hiz_emit_info *restrict info) 1844 { 1845 if (info->depth_surf && info->stencil_surf) { 1846 if (!dev->info->has_hiz_and_separate_stencil) { 1847 assert(info->depth_surf == info->stencil_surf); 1848 assert(info->depth_address == info->stencil_address); 1849 } 1850 assert(info->depth_surf->dim == info->stencil_surf->dim); 1851 } 1852 1853 if (info->depth_surf) { 1854 assert((info->depth_surf->usage & ISL_SURF_USAGE_DEPTH_BIT)); 1855 if (info->depth_surf->dim == ISL_SURF_DIM_3D) { 1856 assert(info->view->base_array_layer + info->view->array_len <= 1857 info->depth_surf->logical_level0_px.depth); 1858 } else { 1859 assert(info->view->base_array_layer + info->view->array_len <= 1860 info->depth_surf->logical_level0_px.array_len); 1861 } 1862 } 1863 1864 if (info->stencil_surf) { 1865 assert((info->stencil_surf->usage & ISL_SURF_USAGE_STENCIL_BIT)); 1866 if (info->stencil_surf->dim == ISL_SURF_DIM_3D) { 1867 assert(info->view->base_array_layer + info->view->array_len <= 1868 info->stencil_surf->logical_level0_px.depth); 1869 } else { 1870 assert(info->view->base_array_layer + info->view->array_len <= 1871 info->stencil_surf->logical_level0_px.array_len); 1872 } 1873 } 1874 1875 isl_genX_call(dev, emit_depth_stencil_hiz_s, dev, batch, info); 1876 } 1877 1878 /** 1879 * A variant of isl_surf_get_image_offset_sa() specific to 1880 * ISL_DIM_LAYOUT_GEN4_2D. 1881 */ 1882 static void 1883 get_image_offset_sa_gen4_2d(const struct isl_surf *surf, 1884 uint32_t level, uint32_t logical_array_layer, 1885 uint32_t *x_offset_sa, 1886 uint32_t *y_offset_sa) 1887 { 1888 assert(level < surf->levels); 1889 if (surf->dim == ISL_SURF_DIM_3D) 1890 assert(logical_array_layer < surf->logical_level0_px.depth); 1891 else 1892 assert(logical_array_layer < surf->logical_level0_px.array_len); 1893 1894 const struct isl_extent3d image_align_sa = 1895 isl_surf_get_image_alignment_sa(surf); 1896 1897 const uint32_t W0 = surf->phys_level0_sa.width; 1898 const uint32_t H0 = surf->phys_level0_sa.height; 1899 1900 const uint32_t phys_layer = logical_array_layer * 1901 (surf->msaa_layout == ISL_MSAA_LAYOUT_ARRAY ? surf->samples : 1); 1902 1903 uint32_t x = 0; 1904 uint32_t y = phys_layer * isl_surf_get_array_pitch_sa_rows(surf); 1905 1906 for (uint32_t l = 0; l < level; ++l) { 1907 if (l == 1) { 1908 uint32_t W = isl_minify(W0, l); 1909 x += isl_align_npot(W, image_align_sa.w); 1910 } else { 1911 uint32_t H = isl_minify(H0, l); 1912 y += isl_align_npot(H, image_align_sa.h); 1913 } 1914 } 1915 1916 *x_offset_sa = x; 1917 *y_offset_sa = y; 1918 } 1919 1920 /** 1921 * A variant of isl_surf_get_image_offset_sa() specific to 1922 * ISL_DIM_LAYOUT_GEN4_3D. 1923 */ 1924 static void 1925 get_image_offset_sa_gen4_3d(const struct isl_surf *surf, 1926 uint32_t level, uint32_t logical_z_offset_px, 1927 uint32_t *x_offset_sa, 1928 uint32_t *y_offset_sa) 1929 { 1930 assert(level < surf->levels); 1931 if (surf->dim == ISL_SURF_DIM_3D) { 1932 assert(surf->phys_level0_sa.array_len == 1); 1933 assert(logical_z_offset_px < isl_minify(surf->phys_level0_sa.depth, level)); 1934 } else { 1935 assert(surf->dim == ISL_SURF_DIM_2D); 1936 assert(surf->usage & ISL_SURF_USAGE_CUBE_BIT); 1937 assert(surf->phys_level0_sa.array_len == 6); 1938 assert(logical_z_offset_px < surf->phys_level0_sa.array_len); 1939 } 1940 1941 const struct isl_extent3d image_align_sa = 1942 isl_surf_get_image_alignment_sa(surf); 1943 1944 const uint32_t W0 = surf->phys_level0_sa.width; 1945 const uint32_t H0 = surf->phys_level0_sa.height; 1946 const uint32_t D0 = surf->phys_level0_sa.depth; 1947 const uint32_t AL = surf->phys_level0_sa.array_len; 1948 1949 uint32_t x = 0; 1950 uint32_t y = 0; 1951 1952 for (uint32_t l = 0; l < level; ++l) { 1953 const uint32_t level_h = isl_align_npot(isl_minify(H0, l), image_align_sa.h); 1954 const uint32_t level_d = 1955 isl_align_npot(surf->dim == ISL_SURF_DIM_3D ? isl_minify(D0, l) : AL, 1956 image_align_sa.d); 1957 const uint32_t max_layers_vert = isl_align(level_d, 1u << l) / (1u << l); 1958 1959 y += level_h * max_layers_vert; 1960 } 1961 1962 const uint32_t level_w = isl_align_npot(isl_minify(W0, level), image_align_sa.w); 1963 const uint32_t level_h = isl_align_npot(isl_minify(H0, level), image_align_sa.h); 1964 const uint32_t level_d = 1965 isl_align_npot(surf->dim == ISL_SURF_DIM_3D ? isl_minify(D0, level) : AL, 1966 image_align_sa.d); 1967 1968 const uint32_t max_layers_horiz = MIN(level_d, 1u << level); 1969 1970 x += level_w * (logical_z_offset_px % max_layers_horiz); 1971 y += level_h * (logical_z_offset_px / max_layers_horiz); 1972 1973 *x_offset_sa = x; 1974 *y_offset_sa = y; 1975 } 1976 1977 static void 1978 get_image_offset_sa_gen6_stencil_hiz(const struct isl_surf *surf, 1979 uint32_t level, 1980 uint32_t logical_array_layer, 1981 uint32_t *x_offset_sa, 1982 uint32_t *y_offset_sa) 1983 { 1984 assert(level < surf->levels); 1985 assert(surf->logical_level0_px.depth == 1); 1986 assert(logical_array_layer < surf->logical_level0_px.array_len); 1987 1988 const struct isl_format_layout *fmtl = isl_format_get_layout(surf->format); 1989 1990 const struct isl_extent3d image_align_sa = 1991 isl_surf_get_image_alignment_sa(surf); 1992 1993 struct isl_tile_info tile_info; 1994 isl_tiling_get_info(surf->tiling, fmtl->bpb, &tile_info); 1995 const struct isl_extent2d tile_extent_sa = { 1996 .w = tile_info.logical_extent_el.w * fmtl->bw, 1997 .h = tile_info.logical_extent_el.h * fmtl->bh, 1998 }; 1999 /* Tile size is a multiple of image alignment */ 2000 assert(tile_extent_sa.w % image_align_sa.w == 0); 2001 assert(tile_extent_sa.h % image_align_sa.h == 0); 2002 2003 const uint32_t W0 = surf->phys_level0_sa.w; 2004 const uint32_t H0 = surf->phys_level0_sa.h; 2005 2006 /* Each image has the same height as LOD0 because the hardware thinks 2007 * everything is LOD0 2008 */ 2009 const uint32_t H = isl_align(H0, image_align_sa.h); 2010 2011 /* Quick sanity check for consistency */ 2012 if (surf->phys_level0_sa.array_len > 1) 2013 assert(surf->array_pitch_el_rows == isl_assert_div(H, fmtl->bh)); 2014 2015 uint32_t x = 0, y = 0; 2016 for (uint32_t l = 0; l < level; ++l) { 2017 const uint32_t W = isl_minify(W0, l); 2018 2019 const uint32_t w = isl_align(W, tile_extent_sa.w); 2020 const uint32_t h = isl_align(H * surf->phys_level0_sa.a, 2021 tile_extent_sa.h); 2022 2023 if (l == 0) { 2024 y += h; 2025 } else { 2026 x += w; 2027 } 2028 } 2029 2030 y += H * logical_array_layer; 2031 2032 *x_offset_sa = x; 2033 *y_offset_sa = y; 2034 } 2035 2036 /** 2037 * A variant of isl_surf_get_image_offset_sa() specific to 2038 * ISL_DIM_LAYOUT_GEN9_1D. 2039 */ 2040 static void 2041 get_image_offset_sa_gen9_1d(const struct isl_surf *surf, 2042 uint32_t level, uint32_t layer, 2043 uint32_t *x_offset_sa, 2044 uint32_t *y_offset_sa) 2045 { 2046 assert(level < surf->levels); 2047 assert(layer < surf->phys_level0_sa.array_len); 2048 assert(surf->phys_level0_sa.height == 1); 2049 assert(surf->phys_level0_sa.depth == 1); 2050 assert(surf->samples == 1); 2051 2052 const uint32_t W0 = surf->phys_level0_sa.width; 2053 const struct isl_extent3d image_align_sa = 2054 isl_surf_get_image_alignment_sa(surf); 2055 2056 uint32_t x = 0; 2057 2058 for (uint32_t l = 0; l < level; ++l) { 2059 uint32_t W = isl_minify(W0, l); 2060 uint32_t w = isl_align_npot(W, image_align_sa.w); 2061 2062 x += w; 2063 } 2064 2065 *x_offset_sa = x; 2066 *y_offset_sa = layer * isl_surf_get_array_pitch_sa_rows(surf); 2067 } 2068 2069 /** 2070 * Calculate the offset, in units of surface samples, to a subimage in the 2071 * surface. 2072 * 2073 * @invariant level < surface levels 2074 * @invariant logical_array_layer < logical array length of surface 2075 * @invariant logical_z_offset_px < logical depth of surface at level 2076 */ 2077 void 2078 isl_surf_get_image_offset_sa(const struct isl_surf *surf, 2079 uint32_t level, 2080 uint32_t logical_array_layer, 2081 uint32_t logical_z_offset_px, 2082 uint32_t *x_offset_sa, 2083 uint32_t *y_offset_sa) 2084 { 2085 assert(level < surf->levels); 2086 assert(logical_array_layer < surf->logical_level0_px.array_len); 2087 assert(logical_z_offset_px 2088 < isl_minify(surf->logical_level0_px.depth, level)); 2089 2090 switch (surf->dim_layout) { 2091 case ISL_DIM_LAYOUT_GEN9_1D: 2092 get_image_offset_sa_gen9_1d(surf, level, logical_array_layer, 2093 x_offset_sa, y_offset_sa); 2094 break; 2095 case ISL_DIM_LAYOUT_GEN4_2D: 2096 get_image_offset_sa_gen4_2d(surf, level, logical_array_layer 2097 + logical_z_offset_px, 2098 x_offset_sa, y_offset_sa); 2099 break; 2100 case ISL_DIM_LAYOUT_GEN4_3D: 2101 get_image_offset_sa_gen4_3d(surf, level, logical_array_layer + 2102 logical_z_offset_px, 2103 x_offset_sa, y_offset_sa); 2104 break; 2105 case ISL_DIM_LAYOUT_GEN6_STENCIL_HIZ: 2106 get_image_offset_sa_gen6_stencil_hiz(surf, level, logical_array_layer + 2107 logical_z_offset_px, 2108 x_offset_sa, y_offset_sa); 2109 break; 2110 2111 default: 2112 unreachable("not reached"); 2113 } 2114 } 2115 2116 void 2117 isl_surf_get_image_offset_el(const struct isl_surf *surf, 2118 uint32_t level, 2119 uint32_t logical_array_layer, 2120 uint32_t logical_z_offset_px, 2121 uint32_t *x_offset_el, 2122 uint32_t *y_offset_el) 2123 { 2124 const struct isl_format_layout *fmtl = isl_format_get_layout(surf->format); 2125 2126 assert(level < surf->levels); 2127 assert(logical_array_layer < surf->logical_level0_px.array_len); 2128 assert(logical_z_offset_px 2129 < isl_minify(surf->logical_level0_px.depth, level)); 2130 2131 uint32_t x_offset_sa, y_offset_sa; 2132 isl_surf_get_image_offset_sa(surf, level, 2133 logical_array_layer, 2134 logical_z_offset_px, 2135 &x_offset_sa, 2136 &y_offset_sa); 2137 2138 *x_offset_el = x_offset_sa / fmtl->bw; 2139 *y_offset_el = y_offset_sa / fmtl->bh; 2140 } 2141 2142 void 2143 isl_surf_get_image_offset_B_tile_sa(const struct isl_surf *surf, 2144 uint32_t level, 2145 uint32_t logical_array_layer, 2146 uint32_t logical_z_offset_px, 2147 uint32_t *offset_B, 2148 uint32_t *x_offset_sa, 2149 uint32_t *y_offset_sa) 2150 { 2151 const struct isl_format_layout *fmtl = isl_format_get_layout(surf->format); 2152 2153 uint32_t total_x_offset_el, total_y_offset_el; 2154 isl_surf_get_image_offset_el(surf, level, logical_array_layer, 2155 logical_z_offset_px, 2156 &total_x_offset_el, 2157 &total_y_offset_el); 2158 2159 uint32_t x_offset_el, y_offset_el; 2160 isl_tiling_get_intratile_offset_el(surf->tiling, fmtl->bpb, 2161 surf->row_pitch, 2162 total_x_offset_el, 2163 total_y_offset_el, 2164 offset_B, 2165 &x_offset_el, 2166 &y_offset_el); 2167 2168 if (x_offset_sa) { 2169 *x_offset_sa = x_offset_el * fmtl->bw; 2170 } else { 2171 assert(x_offset_el == 0); 2172 } 2173 2174 if (y_offset_sa) { 2175 *y_offset_sa = y_offset_el * fmtl->bh; 2176 } else { 2177 assert(y_offset_el == 0); 2178 } 2179 } 2180 2181 void 2182 isl_surf_get_image_surf(const struct isl_device *dev, 2183 const struct isl_surf *surf, 2184 uint32_t level, 2185 uint32_t logical_array_layer, 2186 uint32_t logical_z_offset_px, 2187 struct isl_surf *image_surf, 2188 uint32_t *offset_B, 2189 uint32_t *x_offset_sa, 2190 uint32_t *y_offset_sa) 2191 { 2192 isl_surf_get_image_offset_B_tile_sa(surf, 2193 level, 2194 logical_array_layer, 2195 logical_z_offset_px, 2196 offset_B, 2197 x_offset_sa, 2198 y_offset_sa); 2199 2200 /* Even for cube maps there will be only single face, therefore drop the 2201 * corresponding flag if present. 2202 */ 2203 const isl_surf_usage_flags_t usage = 2204 surf->usage & (~ISL_SURF_USAGE_CUBE_BIT); 2205 2206 bool ok UNUSED; 2207 ok = isl_surf_init(dev, image_surf, 2208 .dim = ISL_SURF_DIM_2D, 2209 .format = surf->format, 2210 .width = isl_minify(surf->logical_level0_px.w, level), 2211 .height = isl_minify(surf->logical_level0_px.h, level), 2212 .depth = 1, 2213 .levels = 1, 2214 .array_len = 1, 2215 .samples = surf->samples, 2216 .row_pitch = surf->row_pitch, 2217 .usage = usage, 2218 .tiling_flags = (1 << surf->tiling)); 2219 assert(ok); 2220 } 2221 2222 void 2223 isl_tiling_get_intratile_offset_el(enum isl_tiling tiling, 2224 uint32_t bpb, 2225 uint32_t row_pitch, 2226 uint32_t total_x_offset_el, 2227 uint32_t total_y_offset_el, 2228 uint32_t *base_address_offset, 2229 uint32_t *x_offset_el, 2230 uint32_t *y_offset_el) 2231 { 2232 if (tiling == ISL_TILING_LINEAR) { 2233 assert(bpb % 8 == 0); 2234 *base_address_offset = total_y_offset_el * row_pitch + 2235 total_x_offset_el * (bpb / 8); 2236 *x_offset_el = 0; 2237 *y_offset_el = 0; 2238 return; 2239 } 2240 2241 struct isl_tile_info tile_info; 2242 isl_tiling_get_info(tiling, bpb, &tile_info); 2243 2244 assert(row_pitch % tile_info.phys_extent_B.width == 0); 2245 2246 /* For non-power-of-two formats, we need the address to be both tile and 2247 * element-aligned. The easiest way to achieve this is to work with a tile 2248 * that is three times as wide as the regular tile. 2249 * 2250 * The tile info returned by get_tile_info has a logical size that is an 2251 * integer number of tile_info.format_bpb size elements. To scale the 2252 * tile, we scale up the physical width and then treat the logical tile 2253 * size as if it has bpb size elements. 2254 */ 2255 const uint32_t tile_el_scale = bpb / tile_info.format_bpb; 2256 tile_info.phys_extent_B.width *= tile_el_scale; 2257 2258 /* Compute the offset into the tile */ 2259 *x_offset_el = total_x_offset_el % tile_info.logical_extent_el.w; 2260 *y_offset_el = total_y_offset_el % tile_info.logical_extent_el.h; 2261 2262 /* Compute the offset of the tile in units of whole tiles */ 2263 uint32_t x_offset_tl = total_x_offset_el / tile_info.logical_extent_el.w; 2264 uint32_t y_offset_tl = total_y_offset_el / tile_info.logical_extent_el.h; 2265 2266 *base_address_offset = 2267 y_offset_tl * tile_info.phys_extent_B.h * row_pitch + 2268 x_offset_tl * tile_info.phys_extent_B.h * tile_info.phys_extent_B.w; 2269 } 2270 2271 uint32_t 2272 isl_surf_get_depth_format(const struct isl_device *dev, 2273 const struct isl_surf *surf) 2274 { 2275 /* Support for separate stencil buffers began in gen5. Support for 2276 * interleaved depthstencil buffers ceased in gen7. The intermediate gens, 2277 * those that supported separate and interleaved stencil, were gen5 and 2278 * gen6. 2279 * 2280 * For a list of all available formats, see the Sandybridge PRM >> Volume 2281 * 2 Part 1: 3D/Media - 3D Pipeline >> 3DSTATE_DEPTH_BUFFER >> Surface 2282 * Format (p321). 2283 */ 2284 2285 bool has_stencil = surf->usage & ISL_SURF_USAGE_STENCIL_BIT; 2286 2287 assert(surf->usage & ISL_SURF_USAGE_DEPTH_BIT); 2288 2289 if (has_stencil) 2290 assert(ISL_DEV_GEN(dev) < 7); 2291 2292 switch (surf->format) { 2293 default: 2294 unreachable("bad isl depth format"); 2295 case ISL_FORMAT_R32_FLOAT_X8X24_TYPELESS: 2296 assert(ISL_DEV_GEN(dev) < 7); 2297 return 0; /* D32_FLOAT_S8X24_UINT */ 2298 case ISL_FORMAT_R32_FLOAT: 2299 assert(!has_stencil); 2300 return 1; /* D32_FLOAT */ 2301 case ISL_FORMAT_R24_UNORM_X8_TYPELESS: 2302 if (has_stencil) { 2303 assert(ISL_DEV_GEN(dev) < 7); 2304 return 2; /* D24_UNORM_S8_UINT */ 2305 } else { 2306 assert(ISL_DEV_GEN(dev) >= 5); 2307 return 3; /* D24_UNORM_X8_UINT */ 2308 } 2309 case ISL_FORMAT_R16_UNORM: 2310 assert(!has_stencil); 2311 return 5; /* D16_UNORM */ 2312 } 2313 } 2314