1 /* 2 * Copyright 2011 Red Hat All Rights Reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 * "Software"), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sub license, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 13 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 14 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS 16 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 18 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 19 * USE OR OTHER DEALINGS IN THE SOFTWARE. 20 * 21 * The above copyright notice and this permission notice (including the 22 * next paragraph) shall be included in all copies or substantial portions 23 * of the Software. 24 */ 25 /* 26 * Authors: 27 * Jrme Glisse <jglisse (at) redhat.com> 28 */ 29 #include <stdbool.h> 30 #include <assert.h> 31 #include <errno.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include <sys/ioctl.h> 36 #include "drm.h" 37 #include "libdrm_macros.h" 38 #include "xf86drm.h" 39 #include "radeon_drm.h" 40 #include "radeon_surface.h" 41 42 #define CIK_TILE_MODE_COLOR_2D 14 43 #define CIK_TILE_MODE_COLOR_2D_SCANOUT 10 44 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64 0 45 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128 1 46 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256 2 47 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512 3 48 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE 4 49 50 #define ALIGN(value, alignment) (((value) + alignment - 1) & ~(alignment - 1)) 51 #define MAX2(A, B) ((A) > (B) ? (A) : (B)) 52 #define MIN2(A, B) ((A) < (B) ? (A) : (B)) 53 54 /* keep this private */ 55 enum radeon_family { 56 CHIP_UNKNOWN, 57 CHIP_R600, 58 CHIP_RV610, 59 CHIP_RV630, 60 CHIP_RV670, 61 CHIP_RV620, 62 CHIP_RV635, 63 CHIP_RS780, 64 CHIP_RS880, 65 CHIP_RV770, 66 CHIP_RV730, 67 CHIP_RV710, 68 CHIP_RV740, 69 CHIP_CEDAR, 70 CHIP_REDWOOD, 71 CHIP_JUNIPER, 72 CHIP_CYPRESS, 73 CHIP_HEMLOCK, 74 CHIP_PALM, 75 CHIP_SUMO, 76 CHIP_SUMO2, 77 CHIP_BARTS, 78 CHIP_TURKS, 79 CHIP_CAICOS, 80 CHIP_CAYMAN, 81 CHIP_ARUBA, 82 CHIP_TAHITI, 83 CHIP_PITCAIRN, 84 CHIP_VERDE, 85 CHIP_OLAND, 86 CHIP_HAINAN, 87 CHIP_BONAIRE, 88 CHIP_KAVERI, 89 CHIP_KABINI, 90 CHIP_HAWAII, 91 CHIP_MULLINS, 92 CHIP_LAST, 93 }; 94 95 typedef int (*hw_init_surface_t)(struct radeon_surface_manager *surf_man, 96 struct radeon_surface *surf); 97 typedef int (*hw_best_surface_t)(struct radeon_surface_manager *surf_man, 98 struct radeon_surface *surf); 99 100 struct radeon_hw_info { 101 /* apply to r6, eg */ 102 uint32_t group_bytes; 103 uint32_t num_banks; 104 uint32_t num_pipes; 105 /* apply to eg */ 106 uint32_t row_size; 107 unsigned allow_2d; 108 /* apply to si */ 109 uint32_t tile_mode_array[32]; 110 /* apply to cik */ 111 uint32_t macrotile_mode_array[16]; 112 }; 113 114 struct radeon_surface_manager { 115 int fd; 116 uint32_t device_id; 117 struct radeon_hw_info hw_info; 118 unsigned family; 119 hw_init_surface_t surface_init; 120 hw_best_surface_t surface_best; 121 }; 122 123 /* helper */ 124 static int radeon_get_value(int fd, unsigned req, uint32_t *value) 125 { 126 struct drm_radeon_info info = {}; 127 int r; 128 129 *value = 0; 130 info.request = req; 131 info.value = (uintptr_t)value; 132 r = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, 133 sizeof(struct drm_radeon_info)); 134 return r; 135 } 136 137 static int radeon_get_family(struct radeon_surface_manager *surf_man) 138 { 139 switch (surf_man->device_id) { 140 #define CHIPSET(pci_id, name, fam) case pci_id: surf_man->family = CHIP_##fam; break; 141 #include "r600_pci_ids.h" 142 #undef CHIPSET 143 default: 144 return -EINVAL; 145 } 146 return 0; 147 } 148 149 static unsigned next_power_of_two(unsigned x) 150 { 151 if (x <= 1) 152 return 1; 153 154 return (1 << ((sizeof(unsigned) * 8) - __builtin_clz(x - 1))); 155 } 156 157 static unsigned mip_minify(unsigned size, unsigned level) 158 { 159 unsigned val; 160 161 val = MAX2(1, size >> level); 162 if (level > 0) 163 val = next_power_of_two(val); 164 return val; 165 } 166 167 static void surf_minify(struct radeon_surface *surf, 168 struct radeon_surface_level *surflevel, 169 unsigned bpe, unsigned level, 170 uint32_t xalign, uint32_t yalign, uint32_t zalign, 171 uint64_t offset) 172 { 173 surflevel->npix_x = mip_minify(surf->npix_x, level); 174 surflevel->npix_y = mip_minify(surf->npix_y, level); 175 surflevel->npix_z = mip_minify(surf->npix_z, level); 176 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w; 177 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h; 178 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d; 179 if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D && 180 !(surf->flags & RADEON_SURF_FMASK)) { 181 if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) { 182 surflevel->mode = RADEON_SURF_MODE_1D; 183 return; 184 } 185 } 186 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign); 187 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign); 188 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign); 189 190 surflevel->offset = offset; 191 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples; 192 surflevel->slice_size = (uint64_t)surflevel->pitch_bytes * surflevel->nblk_y; 193 194 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size; 195 } 196 197 /* =========================================================================== 198 * r600/r700 family 199 */ 200 static int r6_init_hw_info(struct radeon_surface_manager *surf_man) 201 { 202 uint32_t tiling_config; 203 drmVersionPtr version; 204 int r; 205 206 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG, 207 &tiling_config); 208 if (r) { 209 return r; 210 } 211 212 surf_man->hw_info.allow_2d = 0; 213 version = drmGetVersion(surf_man->fd); 214 if (version && version->version_minor >= 14) { 215 surf_man->hw_info.allow_2d = 1; 216 } 217 drmFreeVersion(version); 218 219 switch ((tiling_config & 0xe) >> 1) { 220 case 0: 221 surf_man->hw_info.num_pipes = 1; 222 break; 223 case 1: 224 surf_man->hw_info.num_pipes = 2; 225 break; 226 case 2: 227 surf_man->hw_info.num_pipes = 4; 228 break; 229 case 3: 230 surf_man->hw_info.num_pipes = 8; 231 break; 232 default: 233 surf_man->hw_info.num_pipes = 8; 234 surf_man->hw_info.allow_2d = 0; 235 break; 236 } 237 238 switch ((tiling_config & 0x30) >> 4) { 239 case 0: 240 surf_man->hw_info.num_banks = 4; 241 break; 242 case 1: 243 surf_man->hw_info.num_banks = 8; 244 break; 245 default: 246 surf_man->hw_info.num_banks = 8; 247 surf_man->hw_info.allow_2d = 0; 248 break; 249 } 250 251 switch ((tiling_config & 0xc0) >> 6) { 252 case 0: 253 surf_man->hw_info.group_bytes = 256; 254 break; 255 case 1: 256 surf_man->hw_info.group_bytes = 512; 257 break; 258 default: 259 surf_man->hw_info.group_bytes = 256; 260 surf_man->hw_info.allow_2d = 0; 261 break; 262 } 263 return 0; 264 } 265 266 static int r6_surface_init_linear(struct radeon_surface_manager *surf_man, 267 struct radeon_surface *surf, 268 uint64_t offset, unsigned start_level) 269 { 270 uint32_t xalign, yalign, zalign; 271 unsigned i; 272 273 /* compute alignment */ 274 if (!start_level) { 275 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes); 276 } 277 /* the 32 alignment is for scanout, cb or db but to allow texture to be 278 * easily bound as such we force this alignment to all surface 279 */ 280 xalign = MAX2(1, surf_man->hw_info.group_bytes / surf->bpe); 281 yalign = 1; 282 zalign = 1; 283 if (surf->flags & RADEON_SURF_SCANOUT) { 284 xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign); 285 } 286 287 /* build mipmap tree */ 288 for (i = start_level; i <= surf->last_level; i++) { 289 surf->level[i].mode = RADEON_SURF_MODE_LINEAR; 290 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset); 291 /* level0 and first mipmap need to have alignment */ 292 offset = surf->bo_size; 293 if (i == 0) { 294 offset = ALIGN(offset, surf->bo_alignment); 295 } 296 } 297 return 0; 298 } 299 300 static int r6_surface_init_linear_aligned(struct radeon_surface_manager *surf_man, 301 struct radeon_surface *surf, 302 uint64_t offset, unsigned start_level) 303 { 304 uint32_t xalign, yalign, zalign; 305 unsigned i; 306 307 /* compute alignment */ 308 if (!start_level) { 309 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes); 310 } 311 xalign = MAX2(64, surf_man->hw_info.group_bytes / surf->bpe); 312 yalign = 1; 313 zalign = 1; 314 315 /* build mipmap tree */ 316 for (i = start_level; i <= surf->last_level; i++) { 317 surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED; 318 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset); 319 /* level0 and first mipmap need to have alignment */ 320 offset = surf->bo_size; 321 if (i == 0) { 322 offset = ALIGN(offset, surf->bo_alignment); 323 } 324 } 325 return 0; 326 } 327 328 static int r6_surface_init_1d(struct radeon_surface_manager *surf_man, 329 struct radeon_surface *surf, 330 uint64_t offset, unsigned start_level) 331 { 332 uint32_t xalign, yalign, zalign, tilew; 333 unsigned i; 334 335 /* compute alignment */ 336 tilew = 8; 337 xalign = surf_man->hw_info.group_bytes / (tilew * surf->bpe * surf->nsamples); 338 xalign = MAX2(tilew, xalign); 339 yalign = tilew; 340 zalign = 1; 341 if (surf->flags & RADEON_SURF_SCANOUT) { 342 xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign); 343 } 344 if (!start_level) { 345 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes); 346 } 347 348 /* build mipmap tree */ 349 for (i = start_level; i <= surf->last_level; i++) { 350 surf->level[i].mode = RADEON_SURF_MODE_1D; 351 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset); 352 /* level0 and first mipmap need to have alignment */ 353 offset = surf->bo_size; 354 if (i == 0) { 355 offset = ALIGN(offset, surf->bo_alignment); 356 } 357 } 358 return 0; 359 } 360 361 static int r6_surface_init_2d(struct radeon_surface_manager *surf_man, 362 struct radeon_surface *surf, 363 uint64_t offset, unsigned start_level) 364 { 365 uint32_t xalign, yalign, zalign, tilew; 366 unsigned i; 367 368 /* compute alignment */ 369 tilew = 8; 370 zalign = 1; 371 xalign = (surf_man->hw_info.group_bytes * surf_man->hw_info.num_banks) / 372 (tilew * surf->bpe * surf->nsamples); 373 xalign = MAX2(tilew * surf_man->hw_info.num_banks, xalign); 374 if (surf->flags & RADEON_SURF_FMASK) 375 xalign = MAX2(128, xalign); 376 yalign = tilew * surf_man->hw_info.num_pipes; 377 if (surf->flags & RADEON_SURF_SCANOUT) { 378 xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign); 379 } 380 if (!start_level) { 381 surf->bo_alignment = 382 MAX2(surf_man->hw_info.num_pipes * 383 surf_man->hw_info.num_banks * 384 surf->nsamples * surf->bpe * 64, 385 xalign * yalign * surf->nsamples * surf->bpe); 386 } 387 388 /* build mipmap tree */ 389 for (i = start_level; i <= surf->last_level; i++) { 390 surf->level[i].mode = RADEON_SURF_MODE_2D; 391 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset); 392 if (surf->level[i].mode == RADEON_SURF_MODE_1D) { 393 return r6_surface_init_1d(surf_man, surf, offset, i); 394 } 395 /* level0 and first mipmap need to have alignment */ 396 offset = surf->bo_size; 397 if (i == 0) { 398 offset = ALIGN(offset, surf->bo_alignment); 399 } 400 } 401 return 0; 402 } 403 404 static int r6_surface_init(struct radeon_surface_manager *surf_man, 405 struct radeon_surface *surf) 406 { 407 unsigned mode; 408 int r; 409 410 /* MSAA surfaces support the 2D mode only. */ 411 if (surf->nsamples > 1) { 412 surf->flags = RADEON_SURF_CLR(surf->flags, MODE); 413 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); 414 } 415 416 /* tiling mode */ 417 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK; 418 419 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) { 420 /* zbuffer only support 1D or 2D tiled surface */ 421 switch (mode) { 422 case RADEON_SURF_MODE_1D: 423 case RADEON_SURF_MODE_2D: 424 break; 425 default: 426 mode = RADEON_SURF_MODE_1D; 427 surf->flags = RADEON_SURF_CLR(surf->flags, MODE); 428 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); 429 break; 430 } 431 } 432 433 /* force 1d on kernel that can't do 2d */ 434 if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) { 435 if (surf->nsamples > 1) { 436 fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__); 437 return -EFAULT; 438 } 439 mode = RADEON_SURF_MODE_1D; 440 surf->flags = RADEON_SURF_CLR(surf->flags, MODE); 441 surf->flags |= RADEON_SURF_SET(mode, MODE); 442 } 443 444 /* check surface dimension */ 445 if (surf->npix_x > 8192 || surf->npix_y > 8192 || surf->npix_z > 8192) { 446 return -EINVAL; 447 } 448 449 /* check mipmap last_level */ 450 if (surf->last_level > 14) { 451 return -EINVAL; 452 } 453 454 /* check tiling mode */ 455 switch (mode) { 456 case RADEON_SURF_MODE_LINEAR: 457 r = r6_surface_init_linear(surf_man, surf, 0, 0); 458 break; 459 case RADEON_SURF_MODE_LINEAR_ALIGNED: 460 r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0); 461 break; 462 case RADEON_SURF_MODE_1D: 463 r = r6_surface_init_1d(surf_man, surf, 0, 0); 464 break; 465 case RADEON_SURF_MODE_2D: 466 r = r6_surface_init_2d(surf_man, surf, 0, 0); 467 break; 468 default: 469 return -EINVAL; 470 } 471 return r; 472 } 473 474 static int r6_surface_best(struct radeon_surface_manager *surf_man, 475 struct radeon_surface *surf) 476 { 477 /* no value to optimize for r6xx/r7xx */ 478 return 0; 479 } 480 481 482 /* =========================================================================== 483 * evergreen family 484 */ 485 static int eg_init_hw_info(struct radeon_surface_manager *surf_man) 486 { 487 uint32_t tiling_config; 488 drmVersionPtr version; 489 int r; 490 491 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG, 492 &tiling_config); 493 if (r) { 494 return r; 495 } 496 497 surf_man->hw_info.allow_2d = 0; 498 version = drmGetVersion(surf_man->fd); 499 if (version && version->version_minor >= 16) { 500 surf_man->hw_info.allow_2d = 1; 501 } 502 drmFreeVersion(version); 503 504 switch (tiling_config & 0xf) { 505 case 0: 506 surf_man->hw_info.num_pipes = 1; 507 break; 508 case 1: 509 surf_man->hw_info.num_pipes = 2; 510 break; 511 case 2: 512 surf_man->hw_info.num_pipes = 4; 513 break; 514 case 3: 515 surf_man->hw_info.num_pipes = 8; 516 break; 517 default: 518 surf_man->hw_info.num_pipes = 8; 519 surf_man->hw_info.allow_2d = 0; 520 break; 521 } 522 523 switch ((tiling_config & 0xf0) >> 4) { 524 case 0: 525 surf_man->hw_info.num_banks = 4; 526 break; 527 case 1: 528 surf_man->hw_info.num_banks = 8; 529 break; 530 case 2: 531 surf_man->hw_info.num_banks = 16; 532 break; 533 default: 534 surf_man->hw_info.num_banks = 8; 535 surf_man->hw_info.allow_2d = 0; 536 break; 537 } 538 539 switch ((tiling_config & 0xf00) >> 8) { 540 case 0: 541 surf_man->hw_info.group_bytes = 256; 542 break; 543 case 1: 544 surf_man->hw_info.group_bytes = 512; 545 break; 546 default: 547 surf_man->hw_info.group_bytes = 256; 548 surf_man->hw_info.allow_2d = 0; 549 break; 550 } 551 552 switch ((tiling_config & 0xf000) >> 12) { 553 case 0: 554 surf_man->hw_info.row_size = 1024; 555 break; 556 case 1: 557 surf_man->hw_info.row_size = 2048; 558 break; 559 case 2: 560 surf_man->hw_info.row_size = 4096; 561 break; 562 default: 563 surf_man->hw_info.row_size = 4096; 564 surf_man->hw_info.allow_2d = 0; 565 break; 566 } 567 return 0; 568 } 569 570 static void eg_surf_minify(struct radeon_surface *surf, 571 struct radeon_surface_level *surflevel, 572 unsigned bpe, 573 unsigned level, 574 unsigned slice_pt, 575 unsigned mtilew, 576 unsigned mtileh, 577 unsigned mtileb, 578 uint64_t offset) 579 { 580 unsigned mtile_pr, mtile_ps; 581 582 surflevel->npix_x = mip_minify(surf->npix_x, level); 583 surflevel->npix_y = mip_minify(surf->npix_y, level); 584 surflevel->npix_z = mip_minify(surf->npix_z, level); 585 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w; 586 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h; 587 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d; 588 if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D && 589 !(surf->flags & RADEON_SURF_FMASK)) { 590 if (surflevel->nblk_x < mtilew || surflevel->nblk_y < mtileh) { 591 surflevel->mode = RADEON_SURF_MODE_1D; 592 return; 593 } 594 } 595 surflevel->nblk_x = ALIGN(surflevel->nblk_x, mtilew); 596 surflevel->nblk_y = ALIGN(surflevel->nblk_y, mtileh); 597 surflevel->nblk_z = ALIGN(surflevel->nblk_z, 1); 598 599 /* macro tile per row */ 600 mtile_pr = surflevel->nblk_x / mtilew; 601 /* macro tile per slice */ 602 mtile_ps = (mtile_pr * surflevel->nblk_y) / mtileh; 603 604 surflevel->offset = offset; 605 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples; 606 surflevel->slice_size = (uint64_t)mtile_ps * mtileb * slice_pt; 607 608 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size; 609 } 610 611 static int eg_surface_init_1d(struct radeon_surface_manager *surf_man, 612 struct radeon_surface *surf, 613 struct radeon_surface_level *level, 614 unsigned bpe, 615 uint64_t offset, unsigned start_level) 616 { 617 uint32_t xalign, yalign, zalign, tilew; 618 unsigned i; 619 620 /* compute alignment */ 621 tilew = 8; 622 xalign = surf_man->hw_info.group_bytes / (tilew * bpe * surf->nsamples); 623 xalign = MAX2(tilew, xalign); 624 yalign = tilew; 625 zalign = 1; 626 if (surf->flags & RADEON_SURF_SCANOUT) { 627 xalign = MAX2((bpe == 1) ? 64 : 32, xalign); 628 } 629 630 if (!start_level) { 631 unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes); 632 surf->bo_alignment = MAX2(surf->bo_alignment, alignment); 633 634 if (offset) { 635 offset = ALIGN(offset, alignment); 636 } 637 } 638 639 /* build mipmap tree */ 640 for (i = start_level; i <= surf->last_level; i++) { 641 level[i].mode = RADEON_SURF_MODE_1D; 642 surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, offset); 643 /* level0 and first mipmap need to have alignment */ 644 offset = surf->bo_size; 645 if (i == 0) { 646 offset = ALIGN(offset, surf->bo_alignment); 647 } 648 } 649 return 0; 650 } 651 652 static int eg_surface_init_2d(struct radeon_surface_manager *surf_man, 653 struct radeon_surface *surf, 654 struct radeon_surface_level *level, 655 unsigned bpe, unsigned tile_split, 656 uint64_t offset, unsigned start_level) 657 { 658 unsigned tilew, tileh, tileb; 659 unsigned mtilew, mtileh, mtileb; 660 unsigned slice_pt; 661 unsigned i; 662 663 /* compute tile values */ 664 tilew = 8; 665 tileh = 8; 666 tileb = tilew * tileh * bpe * surf->nsamples; 667 /* slices per tile */ 668 slice_pt = 1; 669 if (tileb > tile_split && tile_split) { 670 slice_pt = tileb / tile_split; 671 } 672 tileb = tileb / slice_pt; 673 674 /* macro tile width & height */ 675 mtilew = (tilew * surf->bankw * surf_man->hw_info.num_pipes) * surf->mtilea; 676 mtileh = (tileh * surf->bankh * surf_man->hw_info.num_banks) / surf->mtilea; 677 /* macro tile bytes */ 678 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb; 679 680 if (!start_level) { 681 unsigned alignment = MAX2(256, mtileb); 682 surf->bo_alignment = MAX2(surf->bo_alignment, alignment); 683 684 if (offset) { 685 offset = ALIGN(offset, alignment); 686 } 687 } 688 689 /* build mipmap tree */ 690 for (i = start_level; i <= surf->last_level; i++) { 691 level[i].mode = RADEON_SURF_MODE_2D; 692 eg_surf_minify(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, mtileb, offset); 693 if (level[i].mode == RADEON_SURF_MODE_1D) { 694 return eg_surface_init_1d(surf_man, surf, level, bpe, offset, i); 695 } 696 /* level0 and first mipmap need to have alignment */ 697 offset = surf->bo_size; 698 if (i == 0) { 699 offset = ALIGN(offset, surf->bo_alignment); 700 } 701 } 702 return 0; 703 } 704 705 static int eg_surface_sanity(struct radeon_surface_manager *surf_man, 706 struct radeon_surface *surf, 707 unsigned mode) 708 { 709 unsigned tileb; 710 711 /* check surface dimension */ 712 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) { 713 return -EINVAL; 714 } 715 716 /* check mipmap last_level */ 717 if (surf->last_level > 15) { 718 return -EINVAL; 719 } 720 721 /* force 1d on kernel that can't do 2d */ 722 if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) { 723 if (surf->nsamples > 1) { 724 fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__); 725 return -EFAULT; 726 } 727 mode = RADEON_SURF_MODE_1D; 728 surf->flags = RADEON_SURF_CLR(surf->flags, MODE); 729 surf->flags |= RADEON_SURF_SET(mode, MODE); 730 } 731 732 /* check tile split */ 733 if (mode == RADEON_SURF_MODE_2D) { 734 switch (surf->tile_split) { 735 case 64: 736 case 128: 737 case 256: 738 case 512: 739 case 1024: 740 case 2048: 741 case 4096: 742 break; 743 default: 744 return -EINVAL; 745 } 746 switch (surf->mtilea) { 747 case 1: 748 case 2: 749 case 4: 750 case 8: 751 break; 752 default: 753 return -EINVAL; 754 } 755 /* check aspect ratio */ 756 if (surf_man->hw_info.num_banks < surf->mtilea) { 757 return -EINVAL; 758 } 759 /* check bank width */ 760 switch (surf->bankw) { 761 case 1: 762 case 2: 763 case 4: 764 case 8: 765 break; 766 default: 767 return -EINVAL; 768 } 769 /* check bank height */ 770 switch (surf->bankh) { 771 case 1: 772 case 2: 773 case 4: 774 case 8: 775 break; 776 default: 777 return -EINVAL; 778 } 779 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples); 780 if ((tileb * surf->bankh * surf->bankw) < surf_man->hw_info.group_bytes) { 781 return -EINVAL; 782 } 783 } 784 785 return 0; 786 } 787 788 static int eg_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man, 789 struct radeon_surface *surf) 790 { 791 unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER; 792 int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags; 793 /* Old libdrm_macros.headers didn't have stencil_level in it. This prevents crashes. */ 794 struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL]; 795 struct radeon_surface_level *stencil_level = 796 (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp; 797 798 r = eg_surface_init_1d(surf_man, surf, surf->level, surf->bpe, 0, 0); 799 if (r) 800 return r; 801 802 if (is_depth_stencil) { 803 r = eg_surface_init_1d(surf_man, surf, stencil_level, 1, 804 surf->bo_size, 0); 805 surf->stencil_offset = stencil_level[0].offset; 806 } 807 return r; 808 } 809 810 static int eg_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man, 811 struct radeon_surface *surf) 812 { 813 unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER; 814 int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags; 815 /* Old libdrm_macros.headers didn't have stencil_level in it. This prevents crashes. */ 816 struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL]; 817 struct radeon_surface_level *stencil_level = 818 (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp; 819 820 r = eg_surface_init_2d(surf_man, surf, surf->level, surf->bpe, 821 surf->tile_split, 0, 0); 822 if (r) 823 return r; 824 825 if (is_depth_stencil) { 826 r = eg_surface_init_2d(surf_man, surf, stencil_level, 1, 827 surf->stencil_tile_split, surf->bo_size, 0); 828 surf->stencil_offset = stencil_level[0].offset; 829 } 830 return r; 831 } 832 833 static int eg_surface_init(struct radeon_surface_manager *surf_man, 834 struct radeon_surface *surf) 835 { 836 unsigned mode; 837 int r; 838 839 /* MSAA surfaces support the 2D mode only. */ 840 if (surf->nsamples > 1) { 841 surf->flags = RADEON_SURF_CLR(surf->flags, MODE); 842 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); 843 } 844 845 /* tiling mode */ 846 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK; 847 848 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) { 849 /* zbuffer only support 1D or 2D tiled surface */ 850 switch (mode) { 851 case RADEON_SURF_MODE_1D: 852 case RADEON_SURF_MODE_2D: 853 break; 854 default: 855 mode = RADEON_SURF_MODE_1D; 856 surf->flags = RADEON_SURF_CLR(surf->flags, MODE); 857 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); 858 break; 859 } 860 } 861 862 r = eg_surface_sanity(surf_man, surf, mode); 863 if (r) { 864 return r; 865 } 866 867 surf->stencil_offset = 0; 868 surf->bo_alignment = 0; 869 870 /* check tiling mode */ 871 switch (mode) { 872 case RADEON_SURF_MODE_LINEAR: 873 r = r6_surface_init_linear(surf_man, surf, 0, 0); 874 break; 875 case RADEON_SURF_MODE_LINEAR_ALIGNED: 876 r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0); 877 break; 878 case RADEON_SURF_MODE_1D: 879 r = eg_surface_init_1d_miptrees(surf_man, surf); 880 break; 881 case RADEON_SURF_MODE_2D: 882 r = eg_surface_init_2d_miptrees(surf_man, surf); 883 break; 884 default: 885 return -EINVAL; 886 } 887 return r; 888 } 889 890 static unsigned log2_int(unsigned x) 891 { 892 unsigned l; 893 894 if (x < 2) { 895 return 0; 896 } 897 for (l = 2; ; l++) { 898 if ((unsigned)(1 << l) > x) { 899 return l - 1; 900 } 901 } 902 return 0; 903 } 904 905 /* compute best tile_split, bankw, bankh, mtilea 906 * depending on surface 907 */ 908 static int eg_surface_best(struct radeon_surface_manager *surf_man, 909 struct radeon_surface *surf) 910 { 911 unsigned mode, tileb, h_over_w; 912 int r; 913 914 /* tiling mode */ 915 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK; 916 917 /* set some default value to avoid sanity check choking on them */ 918 surf->tile_split = 1024; 919 surf->bankw = 1; 920 surf->bankh = 1; 921 surf->mtilea = surf_man->hw_info.num_banks; 922 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples); 923 for (; surf->bankh <= 8; surf->bankh *= 2) { 924 if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) { 925 break; 926 } 927 } 928 if (surf->mtilea > 8) { 929 surf->mtilea = 8; 930 } 931 932 r = eg_surface_sanity(surf_man, surf, mode); 933 if (r) { 934 return r; 935 } 936 937 if (mode != RADEON_SURF_MODE_2D) { 938 /* nothing to do for non 2D tiled surface */ 939 return 0; 940 } 941 942 /* Tweak TILE_SPLIT for performance here. */ 943 if (surf->nsamples > 1) { 944 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) { 945 switch (surf->nsamples) { 946 case 2: 947 surf->tile_split = 128; 948 break; 949 case 4: 950 surf->tile_split = 128; 951 break; 952 case 8: 953 surf->tile_split = 256; 954 break; 955 case 16: /* cayman only */ 956 surf->tile_split = 512; 957 break; 958 default: 959 fprintf(stderr, "radeon: Wrong number of samples %i (%i)\n", 960 surf->nsamples, __LINE__); 961 return -EINVAL; 962 } 963 surf->stencil_tile_split = 64; 964 } else { 965 /* tile split must be >= 256 for colorbuffer surfaces, 966 * SAMPLE_SPLIT = tile_split / (bpe * 64), the optimal value is 2 967 */ 968 surf->tile_split = MAX2(2 * surf->bpe * 64, 256); 969 if (surf->tile_split > 4096) 970 surf->tile_split = 4096; 971 } 972 } else { 973 /* set tile split to row size */ 974 surf->tile_split = surf_man->hw_info.row_size; 975 surf->stencil_tile_split = surf_man->hw_info.row_size / 2; 976 } 977 978 /* bankw or bankh greater than 1 increase alignment requirement, not 979 * sure if it's worth using smaller bankw & bankh to stick with 2D 980 * tiling on small surface rather than falling back to 1D tiling. 981 * Use recommended value based on tile size for now. 982 * 983 * fmask buffer has different optimal value figure them out once we 984 * use it. 985 */ 986 if (surf->flags & RADEON_SURF_SBUFFER) { 987 /* assume 1 bytes for stencil, we optimize for stencil as stencil 988 * and depth shares surface values 989 */ 990 tileb = MIN2(surf->tile_split, 64 * surf->nsamples); 991 } else { 992 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples); 993 } 994 995 /* use bankw of 1 to minimize width alignment, might be interesting to 996 * increase it for large surface 997 */ 998 surf->bankw = 1; 999 switch (tileb) { 1000 case 64: 1001 surf->bankh = 4; 1002 break; 1003 case 128: 1004 case 256: 1005 surf->bankh = 2; 1006 break; 1007 default: 1008 surf->bankh = 1; 1009 break; 1010 } 1011 /* double check the constraint */ 1012 for (; surf->bankh <= 8; surf->bankh *= 2) { 1013 if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) { 1014 break; 1015 } 1016 } 1017 1018 h_over_w = (((surf->bankh * surf_man->hw_info.num_banks) << 16) / 1019 (surf->bankw * surf_man->hw_info.num_pipes)) >> 16; 1020 surf->mtilea = 1 << (log2_int(h_over_w) >> 1); 1021 1022 return 0; 1023 } 1024 1025 1026 /* =========================================================================== 1027 * Southern Islands family 1028 */ 1029 #define SI__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f) 1030 #define SI__PIPE_CONFIG__ADDR_SURF_P2 0 1031 #define SI__PIPE_CONFIG__ADDR_SURF_P4_8x16 4 1032 #define SI__PIPE_CONFIG__ADDR_SURF_P4_16x16 5 1033 #define SI__PIPE_CONFIG__ADDR_SURF_P4_16x32 6 1034 #define SI__PIPE_CONFIG__ADDR_SURF_P4_32x32 7 1035 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8 1036 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9 1037 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10 1038 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11 1039 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12 1040 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13 1041 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14 1042 #define SI__GB_TILE_MODE__TILE_SPLIT(x) (((x) >> 11) & 0x7) 1043 #define SI__TILE_SPLIT__64B 0 1044 #define SI__TILE_SPLIT__128B 1 1045 #define SI__TILE_SPLIT__256B 2 1046 #define SI__TILE_SPLIT__512B 3 1047 #define SI__TILE_SPLIT__1024B 4 1048 #define SI__TILE_SPLIT__2048B 5 1049 #define SI__TILE_SPLIT__4096B 6 1050 #define SI__GB_TILE_MODE__BANK_WIDTH(x) (((x) >> 14) & 0x3) 1051 #define SI__BANK_WIDTH__1 0 1052 #define SI__BANK_WIDTH__2 1 1053 #define SI__BANK_WIDTH__4 2 1054 #define SI__BANK_WIDTH__8 3 1055 #define SI__GB_TILE_MODE__BANK_HEIGHT(x) (((x) >> 16) & 0x3) 1056 #define SI__BANK_HEIGHT__1 0 1057 #define SI__BANK_HEIGHT__2 1 1058 #define SI__BANK_HEIGHT__4 2 1059 #define SI__BANK_HEIGHT__8 3 1060 #define SI__GB_TILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 18) & 0x3) 1061 #define SI__MACRO_TILE_ASPECT__1 0 1062 #define SI__MACRO_TILE_ASPECT__2 1 1063 #define SI__MACRO_TILE_ASPECT__4 2 1064 #define SI__MACRO_TILE_ASPECT__8 3 1065 #define SI__GB_TILE_MODE__NUM_BANKS(x) (((x) >> 20) & 0x3) 1066 #define SI__NUM_BANKS__2_BANK 0 1067 #define SI__NUM_BANKS__4_BANK 1 1068 #define SI__NUM_BANKS__8_BANK 2 1069 #define SI__NUM_BANKS__16_BANK 3 1070 1071 1072 static void si_gb_tile_mode(uint32_t gb_tile_mode, 1073 unsigned *num_pipes, 1074 unsigned *num_banks, 1075 uint32_t *macro_tile_aspect, 1076 uint32_t *bank_w, 1077 uint32_t *bank_h, 1078 uint32_t *tile_split) 1079 { 1080 if (num_pipes) { 1081 switch (SI__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) { 1082 case SI__PIPE_CONFIG__ADDR_SURF_P2: 1083 default: 1084 *num_pipes = 2; 1085 break; 1086 case SI__PIPE_CONFIG__ADDR_SURF_P4_8x16: 1087 case SI__PIPE_CONFIG__ADDR_SURF_P4_16x16: 1088 case SI__PIPE_CONFIG__ADDR_SURF_P4_16x32: 1089 case SI__PIPE_CONFIG__ADDR_SURF_P4_32x32: 1090 *num_pipes = 4; 1091 break; 1092 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16: 1093 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16: 1094 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16: 1095 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16: 1096 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16: 1097 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32: 1098 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32: 1099 *num_pipes = 8; 1100 break; 1101 } 1102 } 1103 if (num_banks) { 1104 switch (SI__GB_TILE_MODE__NUM_BANKS(gb_tile_mode)) { 1105 default: 1106 case SI__NUM_BANKS__2_BANK: 1107 *num_banks = 2; 1108 break; 1109 case SI__NUM_BANKS__4_BANK: 1110 *num_banks = 4; 1111 break; 1112 case SI__NUM_BANKS__8_BANK: 1113 *num_banks = 8; 1114 break; 1115 case SI__NUM_BANKS__16_BANK: 1116 *num_banks = 16; 1117 break; 1118 } 1119 } 1120 if (macro_tile_aspect) { 1121 switch (SI__GB_TILE_MODE__MACRO_TILE_ASPECT(gb_tile_mode)) { 1122 default: 1123 case SI__MACRO_TILE_ASPECT__1: 1124 *macro_tile_aspect = 1; 1125 break; 1126 case SI__MACRO_TILE_ASPECT__2: 1127 *macro_tile_aspect = 2; 1128 break; 1129 case SI__MACRO_TILE_ASPECT__4: 1130 *macro_tile_aspect = 4; 1131 break; 1132 case SI__MACRO_TILE_ASPECT__8: 1133 *macro_tile_aspect = 8; 1134 break; 1135 } 1136 } 1137 if (bank_w) { 1138 switch (SI__GB_TILE_MODE__BANK_WIDTH(gb_tile_mode)) { 1139 default: 1140 case SI__BANK_WIDTH__1: 1141 *bank_w = 1; 1142 break; 1143 case SI__BANK_WIDTH__2: 1144 *bank_w = 2; 1145 break; 1146 case SI__BANK_WIDTH__4: 1147 *bank_w = 4; 1148 break; 1149 case SI__BANK_WIDTH__8: 1150 *bank_w = 8; 1151 break; 1152 } 1153 } 1154 if (bank_h) { 1155 switch (SI__GB_TILE_MODE__BANK_HEIGHT(gb_tile_mode)) { 1156 default: 1157 case SI__BANK_HEIGHT__1: 1158 *bank_h = 1; 1159 break; 1160 case SI__BANK_HEIGHT__2: 1161 *bank_h = 2; 1162 break; 1163 case SI__BANK_HEIGHT__4: 1164 *bank_h = 4; 1165 break; 1166 case SI__BANK_HEIGHT__8: 1167 *bank_h = 8; 1168 break; 1169 } 1170 } 1171 if (tile_split) { 1172 switch (SI__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) { 1173 default: 1174 case SI__TILE_SPLIT__64B: 1175 *tile_split = 64; 1176 break; 1177 case SI__TILE_SPLIT__128B: 1178 *tile_split = 128; 1179 break; 1180 case SI__TILE_SPLIT__256B: 1181 *tile_split = 256; 1182 break; 1183 case SI__TILE_SPLIT__512B: 1184 *tile_split = 512; 1185 break; 1186 case SI__TILE_SPLIT__1024B: 1187 *tile_split = 1024; 1188 break; 1189 case SI__TILE_SPLIT__2048B: 1190 *tile_split = 2048; 1191 break; 1192 case SI__TILE_SPLIT__4096B: 1193 *tile_split = 4096; 1194 break; 1195 } 1196 } 1197 } 1198 1199 static int si_init_hw_info(struct radeon_surface_manager *surf_man) 1200 { 1201 uint32_t tiling_config; 1202 drmVersionPtr version; 1203 int r; 1204 1205 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG, 1206 &tiling_config); 1207 if (r) { 1208 return r; 1209 } 1210 1211 surf_man->hw_info.allow_2d = 0; 1212 version = drmGetVersion(surf_man->fd); 1213 if (version && version->version_minor >= 33) { 1214 if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array)) { 1215 surf_man->hw_info.allow_2d = 1; 1216 } 1217 } 1218 drmFreeVersion(version); 1219 1220 switch (tiling_config & 0xf) { 1221 case 0: 1222 surf_man->hw_info.num_pipes = 1; 1223 break; 1224 case 1: 1225 surf_man->hw_info.num_pipes = 2; 1226 break; 1227 case 2: 1228 surf_man->hw_info.num_pipes = 4; 1229 break; 1230 case 3: 1231 surf_man->hw_info.num_pipes = 8; 1232 break; 1233 default: 1234 surf_man->hw_info.num_pipes = 8; 1235 surf_man->hw_info.allow_2d = 0; 1236 break; 1237 } 1238 1239 switch ((tiling_config & 0xf0) >> 4) { 1240 case 0: 1241 surf_man->hw_info.num_banks = 4; 1242 break; 1243 case 1: 1244 surf_man->hw_info.num_banks = 8; 1245 break; 1246 case 2: 1247 surf_man->hw_info.num_banks = 16; 1248 break; 1249 default: 1250 surf_man->hw_info.num_banks = 8; 1251 surf_man->hw_info.allow_2d = 0; 1252 break; 1253 } 1254 1255 switch ((tiling_config & 0xf00) >> 8) { 1256 case 0: 1257 surf_man->hw_info.group_bytes = 256; 1258 break; 1259 case 1: 1260 surf_man->hw_info.group_bytes = 512; 1261 break; 1262 default: 1263 surf_man->hw_info.group_bytes = 256; 1264 surf_man->hw_info.allow_2d = 0; 1265 break; 1266 } 1267 1268 switch ((tiling_config & 0xf000) >> 12) { 1269 case 0: 1270 surf_man->hw_info.row_size = 1024; 1271 break; 1272 case 1: 1273 surf_man->hw_info.row_size = 2048; 1274 break; 1275 case 2: 1276 surf_man->hw_info.row_size = 4096; 1277 break; 1278 default: 1279 surf_man->hw_info.row_size = 4096; 1280 surf_man->hw_info.allow_2d = 0; 1281 break; 1282 } 1283 return 0; 1284 } 1285 1286 static int si_surface_sanity(struct radeon_surface_manager *surf_man, 1287 struct radeon_surface *surf, 1288 unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode) 1289 { 1290 uint32_t gb_tile_mode; 1291 1292 /* check surface dimension */ 1293 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) { 1294 return -EINVAL; 1295 } 1296 1297 /* check mipmap last_level */ 1298 if (surf->last_level > 15) { 1299 return -EINVAL; 1300 } 1301 1302 /* force 1d on kernel that can't do 2d */ 1303 if (mode > RADEON_SURF_MODE_1D && 1304 (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) { 1305 if (surf->nsamples > 1) { 1306 fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__); 1307 return -EFAULT; 1308 } 1309 mode = RADEON_SURF_MODE_1D; 1310 surf->flags = RADEON_SURF_CLR(surf->flags, MODE); 1311 surf->flags |= RADEON_SURF_SET(mode, MODE); 1312 } 1313 1314 if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) { 1315 return -EINVAL; 1316 } 1317 1318 if (!surf->tile_split) { 1319 /* default value */ 1320 surf->mtilea = 1; 1321 surf->bankw = 1; 1322 surf->bankh = 1; 1323 surf->tile_split = 64; 1324 surf->stencil_tile_split = 64; 1325 } 1326 1327 switch (mode) { 1328 case RADEON_SURF_MODE_2D: 1329 if (surf->flags & RADEON_SURF_SBUFFER) { 1330 switch (surf->nsamples) { 1331 case 1: 1332 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D; 1333 break; 1334 case 2: 1335 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA; 1336 break; 1337 case 4: 1338 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA; 1339 break; 1340 case 8: 1341 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA; 1342 break; 1343 default: 1344 return -EINVAL; 1345 } 1346 /* retrieve tiling mode value */ 1347 gb_tile_mode = surf_man->hw_info.tile_mode_array[*stencil_tile_mode]; 1348 si_gb_tile_mode(gb_tile_mode, NULL, NULL, NULL, NULL, NULL, &surf->stencil_tile_split); 1349 } 1350 if (surf->flags & RADEON_SURF_ZBUFFER) { 1351 switch (surf->nsamples) { 1352 case 1: 1353 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D; 1354 break; 1355 case 2: 1356 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA; 1357 break; 1358 case 4: 1359 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA; 1360 break; 1361 case 8: 1362 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA; 1363 break; 1364 default: 1365 return -EINVAL; 1366 } 1367 } else if (surf->flags & RADEON_SURF_SCANOUT) { 1368 switch (surf->bpe) { 1369 case 2: 1370 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP; 1371 break; 1372 case 4: 1373 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP; 1374 break; 1375 default: 1376 return -EINVAL; 1377 } 1378 } else { 1379 switch (surf->bpe) { 1380 case 1: 1381 *tile_mode = SI_TILE_MODE_COLOR_2D_8BPP; 1382 break; 1383 case 2: 1384 *tile_mode = SI_TILE_MODE_COLOR_2D_16BPP; 1385 break; 1386 case 4: 1387 *tile_mode = SI_TILE_MODE_COLOR_2D_32BPP; 1388 break; 1389 case 8: 1390 case 16: 1391 *tile_mode = SI_TILE_MODE_COLOR_2D_64BPP; 1392 break; 1393 default: 1394 return -EINVAL; 1395 } 1396 } 1397 /* retrieve tiling mode value */ 1398 gb_tile_mode = surf_man->hw_info.tile_mode_array[*tile_mode]; 1399 si_gb_tile_mode(gb_tile_mode, NULL, NULL, &surf->mtilea, &surf->bankw, &surf->bankh, &surf->tile_split); 1400 break; 1401 case RADEON_SURF_MODE_1D: 1402 if (surf->flags & RADEON_SURF_SBUFFER) { 1403 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D; 1404 } 1405 if (surf->flags & RADEON_SURF_ZBUFFER) { 1406 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D; 1407 } else if (surf->flags & RADEON_SURF_SCANOUT) { 1408 *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT; 1409 } else { 1410 *tile_mode = SI_TILE_MODE_COLOR_1D; 1411 } 1412 break; 1413 case RADEON_SURF_MODE_LINEAR_ALIGNED: 1414 default: 1415 *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED; 1416 } 1417 1418 return 0; 1419 } 1420 1421 static void si_surf_minify(struct radeon_surface *surf, 1422 struct radeon_surface_level *surflevel, 1423 unsigned bpe, unsigned level, 1424 uint32_t xalign, uint32_t yalign, uint32_t zalign, 1425 uint32_t slice_align, uint64_t offset) 1426 { 1427 if (level == 0) { 1428 surflevel->npix_x = surf->npix_x; 1429 } else { 1430 surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level); 1431 } 1432 surflevel->npix_y = mip_minify(surf->npix_y, level); 1433 surflevel->npix_z = mip_minify(surf->npix_z, level); 1434 1435 if (level == 0 && surf->last_level > 0) { 1436 surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w; 1437 surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h; 1438 surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d; 1439 } else { 1440 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w; 1441 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h; 1442 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d; 1443 } 1444 1445 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign); 1446 1447 /* XXX: Texture sampling uses unexpectedly large pitches in some cases, 1448 * these are just guesses for the rules behind those 1449 */ 1450 if (level == 0 && surf->last_level == 0) 1451 /* Non-mipmap pitch padded to slice alignment */ 1452 /* Using just bpe here breaks stencil blitting; surf->bpe works. */ 1453 xalign = MAX2(xalign, slice_align / surf->bpe); 1454 else if (surflevel->mode == RADEON_SURF_MODE_LINEAR_ALIGNED) 1455 /* Small rows evenly distributed across slice */ 1456 xalign = MAX2(xalign, slice_align / bpe / surflevel->nblk_y); 1457 1458 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign); 1459 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign); 1460 1461 surflevel->offset = offset; 1462 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples; 1463 surflevel->slice_size = ALIGN((uint64_t)surflevel->pitch_bytes * surflevel->nblk_y, 1464 (uint64_t)slice_align); 1465 1466 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size; 1467 } 1468 1469 static void si_surf_minify_2d(struct radeon_surface *surf, 1470 struct radeon_surface_level *surflevel, 1471 unsigned bpe, unsigned level, unsigned slice_pt, 1472 uint32_t xalign, uint32_t yalign, uint32_t zalign, 1473 unsigned mtileb, uint64_t offset) 1474 { 1475 unsigned mtile_pr, mtile_ps; 1476 1477 if (level == 0) { 1478 surflevel->npix_x = surf->npix_x; 1479 } else { 1480 surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level); 1481 } 1482 surflevel->npix_y = mip_minify(surf->npix_y, level); 1483 surflevel->npix_z = mip_minify(surf->npix_z, level); 1484 1485 if (level == 0 && surf->last_level > 0) { 1486 surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w; 1487 surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h; 1488 surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d; 1489 } else { 1490 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w; 1491 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h; 1492 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d; 1493 } 1494 1495 if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D && 1496 !(surf->flags & RADEON_SURF_FMASK)) { 1497 if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) { 1498 surflevel->mode = RADEON_SURF_MODE_1D; 1499 return; 1500 } 1501 } 1502 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign); 1503 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign); 1504 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign); 1505 1506 /* macro tile per row */ 1507 mtile_pr = surflevel->nblk_x / xalign; 1508 /* macro tile per slice */ 1509 mtile_ps = (mtile_pr * surflevel->nblk_y) / yalign; 1510 surflevel->offset = offset; 1511 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples; 1512 surflevel->slice_size = (uint64_t)mtile_ps * mtileb * slice_pt; 1513 1514 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size; 1515 } 1516 1517 static int si_surface_init_linear_aligned(struct radeon_surface_manager *surf_man, 1518 struct radeon_surface *surf, 1519 unsigned tile_mode, 1520 uint64_t offset, unsigned start_level) 1521 { 1522 uint32_t xalign, yalign, zalign, slice_align; 1523 unsigned i; 1524 1525 /* compute alignment */ 1526 if (!start_level) { 1527 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes); 1528 } 1529 xalign = MAX2(8, 64 / surf->bpe); 1530 yalign = 1; 1531 zalign = 1; 1532 slice_align = MAX2(64 * surf->bpe, surf_man->hw_info.group_bytes); 1533 1534 /* build mipmap tree */ 1535 for (i = start_level; i <= surf->last_level; i++) { 1536 surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED; 1537 si_surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, slice_align, offset); 1538 /* level0 and first mipmap need to have alignment */ 1539 offset = surf->bo_size; 1540 if (i == 0) { 1541 offset = ALIGN(offset, surf->bo_alignment); 1542 } 1543 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) { 1544 surf->tiling_index[i] = tile_mode; 1545 } 1546 } 1547 return 0; 1548 } 1549 1550 static int si_surface_init_1d(struct radeon_surface_manager *surf_man, 1551 struct radeon_surface *surf, 1552 struct radeon_surface_level *level, 1553 unsigned bpe, unsigned tile_mode, 1554 uint64_t offset, unsigned start_level) 1555 { 1556 uint32_t xalign, yalign, zalign, slice_align; 1557 unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes); 1558 unsigned i; 1559 1560 /* compute alignment */ 1561 xalign = 8; 1562 yalign = 8; 1563 zalign = 1; 1564 slice_align = surf_man->hw_info.group_bytes; 1565 if (surf->flags & RADEON_SURF_SCANOUT) { 1566 xalign = MAX2((bpe == 1) ? 64 : 32, xalign); 1567 } 1568 1569 if (start_level <= 1) { 1570 surf->bo_alignment = MAX2(surf->bo_alignment, alignment); 1571 1572 if (offset) { 1573 offset = ALIGN(offset, alignment); 1574 } 1575 } 1576 1577 /* build mipmap tree */ 1578 for (i = start_level; i <= surf->last_level; i++) { 1579 level[i].mode = RADEON_SURF_MODE_1D; 1580 si_surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, slice_align, offset); 1581 /* level0 and first mipmap need to have alignment */ 1582 offset = surf->bo_size; 1583 if (i == 0) { 1584 offset = ALIGN(offset, alignment); 1585 } 1586 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) { 1587 if (surf->level == level) { 1588 surf->tiling_index[i] = tile_mode; 1589 /* it's ok because stencil is done after */ 1590 surf->stencil_tiling_index[i] = tile_mode; 1591 } else { 1592 surf->stencil_tiling_index[i] = tile_mode; 1593 } 1594 } 1595 } 1596 return 0; 1597 } 1598 1599 static int si_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man, 1600 struct radeon_surface *surf, 1601 unsigned tile_mode, unsigned stencil_tile_mode) 1602 { 1603 int r; 1604 1605 r = si_surface_init_1d(surf_man, surf, surf->level, surf->bpe, tile_mode, 0, 0); 1606 if (r) { 1607 return r; 1608 } 1609 1610 if (surf->flags & RADEON_SURF_SBUFFER) { 1611 r = si_surface_init_1d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode, surf->bo_size, 0); 1612 surf->stencil_offset = surf->stencil_level[0].offset; 1613 } 1614 return r; 1615 } 1616 1617 static int si_surface_init_2d(struct radeon_surface_manager *surf_man, 1618 struct radeon_surface *surf, 1619 struct radeon_surface_level *level, 1620 unsigned bpe, unsigned tile_mode, 1621 unsigned num_pipes, unsigned num_banks, 1622 unsigned tile_split, 1623 uint64_t offset, 1624 unsigned start_level) 1625 { 1626 uint64_t aligned_offset = offset; 1627 unsigned tilew, tileh, tileb; 1628 unsigned mtilew, mtileh, mtileb; 1629 unsigned slice_pt; 1630 unsigned i; 1631 1632 /* compute tile values */ 1633 tilew = 8; 1634 tileh = 8; 1635 tileb = tilew * tileh * bpe * surf->nsamples; 1636 /* slices per tile */ 1637 slice_pt = 1; 1638 if (tileb > tile_split && tile_split) { 1639 slice_pt = tileb / tile_split; 1640 } 1641 tileb = tileb / slice_pt; 1642 1643 /* macro tile width & height */ 1644 mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea; 1645 mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea; 1646 1647 /* macro tile bytes */ 1648 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb; 1649 1650 if (start_level <= 1) { 1651 unsigned alignment = MAX2(256, mtileb); 1652 surf->bo_alignment = MAX2(surf->bo_alignment, alignment); 1653 1654 if (aligned_offset) { 1655 aligned_offset = ALIGN(aligned_offset, alignment); 1656 } 1657 } 1658 1659 /* build mipmap tree */ 1660 for (i = start_level; i <= surf->last_level; i++) { 1661 level[i].mode = RADEON_SURF_MODE_2D; 1662 si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset); 1663 if (level[i].mode == RADEON_SURF_MODE_1D) { 1664 switch (tile_mode) { 1665 case SI_TILE_MODE_COLOR_2D_8BPP: 1666 case SI_TILE_MODE_COLOR_2D_16BPP: 1667 case SI_TILE_MODE_COLOR_2D_32BPP: 1668 case SI_TILE_MODE_COLOR_2D_64BPP: 1669 tile_mode = SI_TILE_MODE_COLOR_1D; 1670 break; 1671 case SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP: 1672 case SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP: 1673 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT; 1674 break; 1675 case SI_TILE_MODE_DEPTH_STENCIL_2D: 1676 tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D; 1677 break; 1678 default: 1679 return -EINVAL; 1680 } 1681 return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i); 1682 } 1683 /* level0 and first mipmap need to have alignment */ 1684 aligned_offset = offset = surf->bo_size; 1685 if (i == 0) { 1686 aligned_offset = ALIGN(aligned_offset, surf->bo_alignment); 1687 } 1688 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) { 1689 if (surf->level == level) { 1690 surf->tiling_index[i] = tile_mode; 1691 /* it's ok because stencil is done after */ 1692 surf->stencil_tiling_index[i] = tile_mode; 1693 } else { 1694 surf->stencil_tiling_index[i] = tile_mode; 1695 } 1696 } 1697 } 1698 return 0; 1699 } 1700 1701 static int si_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man, 1702 struct radeon_surface *surf, 1703 unsigned tile_mode, unsigned stencil_tile_mode) 1704 { 1705 unsigned num_pipes, num_banks; 1706 uint32_t gb_tile_mode; 1707 int r; 1708 1709 /* retrieve tiling mode value */ 1710 gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode]; 1711 si_gb_tile_mode(gb_tile_mode, &num_pipes, &num_banks, NULL, NULL, NULL, NULL); 1712 1713 r = si_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode, num_pipes, num_banks, surf->tile_split, 0, 0); 1714 if (r) { 1715 return r; 1716 } 1717 1718 if (surf->flags & RADEON_SURF_SBUFFER) { 1719 r = si_surface_init_2d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode, num_pipes, num_banks, surf->stencil_tile_split, surf->bo_size, 0); 1720 surf->stencil_offset = surf->stencil_level[0].offset; 1721 } 1722 return r; 1723 } 1724 1725 static int si_surface_init(struct radeon_surface_manager *surf_man, 1726 struct radeon_surface *surf) 1727 { 1728 unsigned mode, tile_mode, stencil_tile_mode; 1729 int r; 1730 1731 /* MSAA surfaces support the 2D mode only. */ 1732 if (surf->nsamples > 1) { 1733 surf->flags = RADEON_SURF_CLR(surf->flags, MODE); 1734 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); 1735 } 1736 1737 /* tiling mode */ 1738 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK; 1739 1740 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) { 1741 /* zbuffer only support 1D or 2D tiled surface */ 1742 switch (mode) { 1743 case RADEON_SURF_MODE_1D: 1744 case RADEON_SURF_MODE_2D: 1745 break; 1746 default: 1747 mode = RADEON_SURF_MODE_1D; 1748 surf->flags = RADEON_SURF_CLR(surf->flags, MODE); 1749 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); 1750 break; 1751 } 1752 } 1753 1754 r = si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode); 1755 if (r) { 1756 return r; 1757 } 1758 1759 surf->stencil_offset = 0; 1760 surf->bo_alignment = 0; 1761 1762 /* check tiling mode */ 1763 switch (mode) { 1764 case RADEON_SURF_MODE_LINEAR: 1765 r = r6_surface_init_linear(surf_man, surf, 0, 0); 1766 break; 1767 case RADEON_SURF_MODE_LINEAR_ALIGNED: 1768 r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0); 1769 break; 1770 case RADEON_SURF_MODE_1D: 1771 r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode); 1772 break; 1773 case RADEON_SURF_MODE_2D: 1774 r = si_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode); 1775 break; 1776 default: 1777 return -EINVAL; 1778 } 1779 return r; 1780 } 1781 1782 /* 1783 * depending on surface 1784 */ 1785 static int si_surface_best(struct radeon_surface_manager *surf_man, 1786 struct radeon_surface *surf) 1787 { 1788 unsigned mode, tile_mode, stencil_tile_mode; 1789 1790 /* tiling mode */ 1791 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK; 1792 1793 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) && 1794 !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) { 1795 /* depth/stencil force 1d tiling for old mesa */ 1796 surf->flags = RADEON_SURF_CLR(surf->flags, MODE); 1797 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); 1798 } 1799 1800 return si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode); 1801 } 1802 1803 1804 /* =========================================================================== 1805 * Sea Islands family 1806 */ 1807 #define CIK__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f) 1808 #define CIK__PIPE_CONFIG__ADDR_SURF_P2 0 1809 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16 4 1810 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16 5 1811 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32 6 1812 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32 7 1813 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8 1814 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9 1815 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10 1816 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11 1817 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12 1818 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13 1819 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14 1820 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16 16 1821 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16 17 1822 #define CIK__GB_TILE_MODE__TILE_SPLIT(x) (((x) >> 11) & 0x7) 1823 #define CIK__TILE_SPLIT__64B 0 1824 #define CIK__TILE_SPLIT__128B 1 1825 #define CIK__TILE_SPLIT__256B 2 1826 #define CIK__TILE_SPLIT__512B 3 1827 #define CIK__TILE_SPLIT__1024B 4 1828 #define CIK__TILE_SPLIT__2048B 5 1829 #define CIK__TILE_SPLIT__4096B 6 1830 #define CIK__GB_TILE_MODE__SAMPLE_SPLIT(x) (((x) >> 25) & 0x3) 1831 #define CIK__SAMPLE_SPLIT__1 0 1832 #define CIK__SAMPLE_SPLIT__2 1 1833 #define CIK__SAMPLE_SPLIT__4 2 1834 #define CIK__SAMPLE_SPLIT__8 3 1835 #define CIK__GB_MACROTILE_MODE__BANK_WIDTH(x) ((x) & 0x3) 1836 #define CIK__BANK_WIDTH__1 0 1837 #define CIK__BANK_WIDTH__2 1 1838 #define CIK__BANK_WIDTH__4 2 1839 #define CIK__BANK_WIDTH__8 3 1840 #define CIK__GB_MACROTILE_MODE__BANK_HEIGHT(x) (((x) >> 2) & 0x3) 1841 #define CIK__BANK_HEIGHT__1 0 1842 #define CIK__BANK_HEIGHT__2 1 1843 #define CIK__BANK_HEIGHT__4 2 1844 #define CIK__BANK_HEIGHT__8 3 1845 #define CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 4) & 0x3) 1846 #define CIK__MACRO_TILE_ASPECT__1 0 1847 #define CIK__MACRO_TILE_ASPECT__2 1 1848 #define CIK__MACRO_TILE_ASPECT__4 2 1849 #define CIK__MACRO_TILE_ASPECT__8 3 1850 #define CIK__GB_MACROTILE_MODE__NUM_BANKS(x) (((x) >> 6) & 0x3) 1851 #define CIK__NUM_BANKS__2_BANK 0 1852 #define CIK__NUM_BANKS__4_BANK 1 1853 #define CIK__NUM_BANKS__8_BANK 2 1854 #define CIK__NUM_BANKS__16_BANK 3 1855 1856 1857 static void cik_get_2d_params(struct radeon_surface_manager *surf_man, 1858 unsigned bpe, unsigned nsamples, bool is_color, 1859 unsigned tile_mode, 1860 uint32_t *num_pipes, 1861 uint32_t *tile_split_ptr, 1862 uint32_t *num_banks, 1863 uint32_t *macro_tile_aspect, 1864 uint32_t *bank_w, 1865 uint32_t *bank_h) 1866 { 1867 uint32_t gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode]; 1868 unsigned tileb_1x, tileb; 1869 unsigned gb_macrotile_mode; 1870 unsigned macrotile_index; 1871 unsigned tile_split, sample_split; 1872 1873 if (num_pipes) { 1874 switch (CIK__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) { 1875 case CIK__PIPE_CONFIG__ADDR_SURF_P2: 1876 default: 1877 *num_pipes = 2; 1878 break; 1879 case CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16: 1880 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16: 1881 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32: 1882 case CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32: 1883 *num_pipes = 4; 1884 break; 1885 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16: 1886 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16: 1887 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16: 1888 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16: 1889 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16: 1890 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32: 1891 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32: 1892 *num_pipes = 8; 1893 break; 1894 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16: 1895 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16: 1896 *num_pipes = 16; 1897 break; 1898 } 1899 } 1900 switch (CIK__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) { 1901 default: 1902 case CIK__TILE_SPLIT__64B: 1903 tile_split = 64; 1904 break; 1905 case CIK__TILE_SPLIT__128B: 1906 tile_split = 128; 1907 break; 1908 case CIK__TILE_SPLIT__256B: 1909 tile_split = 256; 1910 break; 1911 case CIK__TILE_SPLIT__512B: 1912 tile_split = 512; 1913 break; 1914 case CIK__TILE_SPLIT__1024B: 1915 tile_split = 1024; 1916 break; 1917 case CIK__TILE_SPLIT__2048B: 1918 tile_split = 2048; 1919 break; 1920 case CIK__TILE_SPLIT__4096B: 1921 tile_split = 4096; 1922 break; 1923 } 1924 switch (CIK__GB_TILE_MODE__SAMPLE_SPLIT(gb_tile_mode)) { 1925 default: 1926 case CIK__SAMPLE_SPLIT__1: 1927 sample_split = 1; 1928 break; 1929 case CIK__SAMPLE_SPLIT__2: 1930 sample_split = 2; 1931 break; 1932 case CIK__SAMPLE_SPLIT__4: 1933 sample_split = 4; 1934 break; 1935 case CIK__SAMPLE_SPLIT__8: 1936 sample_split = 8; 1937 break; 1938 } 1939 1940 /* Adjust the tile split. */ 1941 tileb_1x = 8 * 8 * bpe; 1942 if (is_color) { 1943 tile_split = MAX2(256, sample_split * tileb_1x); 1944 } 1945 tile_split = MIN2(surf_man->hw_info.row_size, tile_split); 1946 1947 /* Determine the macrotile index. */ 1948 tileb = MIN2(tile_split, nsamples * tileb_1x); 1949 1950 for (macrotile_index = 0; tileb > 64; macrotile_index++) { 1951 tileb >>= 1; 1952 } 1953 gb_macrotile_mode = surf_man->hw_info.macrotile_mode_array[macrotile_index]; 1954 1955 if (tile_split_ptr) { 1956 *tile_split_ptr = tile_split; 1957 } 1958 if (num_banks) { 1959 switch (CIK__GB_MACROTILE_MODE__NUM_BANKS(gb_macrotile_mode)) { 1960 default: 1961 case CIK__NUM_BANKS__2_BANK: 1962 *num_banks = 2; 1963 break; 1964 case CIK__NUM_BANKS__4_BANK: 1965 *num_banks = 4; 1966 break; 1967 case CIK__NUM_BANKS__8_BANK: 1968 *num_banks = 8; 1969 break; 1970 case CIK__NUM_BANKS__16_BANK: 1971 *num_banks = 16; 1972 break; 1973 } 1974 } 1975 if (macro_tile_aspect) { 1976 switch (CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(gb_macrotile_mode)) { 1977 default: 1978 case CIK__MACRO_TILE_ASPECT__1: 1979 *macro_tile_aspect = 1; 1980 break; 1981 case CIK__MACRO_TILE_ASPECT__2: 1982 *macro_tile_aspect = 2; 1983 break; 1984 case CIK__MACRO_TILE_ASPECT__4: 1985 *macro_tile_aspect = 4; 1986 break; 1987 case CIK__MACRO_TILE_ASPECT__8: 1988 *macro_tile_aspect = 8; 1989 break; 1990 } 1991 } 1992 if (bank_w) { 1993 switch (CIK__GB_MACROTILE_MODE__BANK_WIDTH(gb_macrotile_mode)) { 1994 default: 1995 case CIK__BANK_WIDTH__1: 1996 *bank_w = 1; 1997 break; 1998 case CIK__BANK_WIDTH__2: 1999 *bank_w = 2; 2000 break; 2001 case CIK__BANK_WIDTH__4: 2002 *bank_w = 4; 2003 break; 2004 case CIK__BANK_WIDTH__8: 2005 *bank_w = 8; 2006 break; 2007 } 2008 } 2009 if (bank_h) { 2010 switch (CIK__GB_MACROTILE_MODE__BANK_HEIGHT(gb_macrotile_mode)) { 2011 default: 2012 case CIK__BANK_HEIGHT__1: 2013 *bank_h = 1; 2014 break; 2015 case CIK__BANK_HEIGHT__2: 2016 *bank_h = 2; 2017 break; 2018 case CIK__BANK_HEIGHT__4: 2019 *bank_h = 4; 2020 break; 2021 case CIK__BANK_HEIGHT__8: 2022 *bank_h = 8; 2023 break; 2024 } 2025 } 2026 } 2027 2028 static int cik_init_hw_info(struct radeon_surface_manager *surf_man) 2029 { 2030 uint32_t tiling_config; 2031 drmVersionPtr version; 2032 int r; 2033 2034 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG, 2035 &tiling_config); 2036 if (r) { 2037 return r; 2038 } 2039 2040 surf_man->hw_info.allow_2d = 0; 2041 version = drmGetVersion(surf_man->fd); 2042 if (version && version->version_minor >= 35) { 2043 if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array) && 2044 !radeon_get_value(surf_man->fd, RADEON_INFO_CIK_MACROTILE_MODE_ARRAY, surf_man->hw_info.macrotile_mode_array)) { 2045 surf_man->hw_info.allow_2d = 1; 2046 } 2047 } 2048 drmFreeVersion(version); 2049 2050 switch (tiling_config & 0xf) { 2051 case 0: 2052 surf_man->hw_info.num_pipes = 1; 2053 break; 2054 case 1: 2055 surf_man->hw_info.num_pipes = 2; 2056 break; 2057 case 2: 2058 surf_man->hw_info.num_pipes = 4; 2059 break; 2060 case 3: 2061 surf_man->hw_info.num_pipes = 8; 2062 break; 2063 default: 2064 surf_man->hw_info.num_pipes = 8; 2065 surf_man->hw_info.allow_2d = 0; 2066 break; 2067 } 2068 2069 switch ((tiling_config & 0xf0) >> 4) { 2070 case 0: 2071 surf_man->hw_info.num_banks = 4; 2072 break; 2073 case 1: 2074 surf_man->hw_info.num_banks = 8; 2075 break; 2076 case 2: 2077 surf_man->hw_info.num_banks = 16; 2078 break; 2079 default: 2080 surf_man->hw_info.num_banks = 8; 2081 surf_man->hw_info.allow_2d = 0; 2082 break; 2083 } 2084 2085 switch ((tiling_config & 0xf00) >> 8) { 2086 case 0: 2087 surf_man->hw_info.group_bytes = 256; 2088 break; 2089 case 1: 2090 surf_man->hw_info.group_bytes = 512; 2091 break; 2092 default: 2093 surf_man->hw_info.group_bytes = 256; 2094 surf_man->hw_info.allow_2d = 0; 2095 break; 2096 } 2097 2098 switch ((tiling_config & 0xf000) >> 12) { 2099 case 0: 2100 surf_man->hw_info.row_size = 1024; 2101 break; 2102 case 1: 2103 surf_man->hw_info.row_size = 2048; 2104 break; 2105 case 2: 2106 surf_man->hw_info.row_size = 4096; 2107 break; 2108 default: 2109 surf_man->hw_info.row_size = 4096; 2110 surf_man->hw_info.allow_2d = 0; 2111 break; 2112 } 2113 return 0; 2114 } 2115 2116 static int cik_surface_sanity(struct radeon_surface_manager *surf_man, 2117 struct radeon_surface *surf, 2118 unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode) 2119 { 2120 /* check surface dimension */ 2121 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) { 2122 return -EINVAL; 2123 } 2124 2125 /* check mipmap last_level */ 2126 if (surf->last_level > 15) { 2127 return -EINVAL; 2128 } 2129 2130 /* force 1d on kernel that can't do 2d */ 2131 if (mode > RADEON_SURF_MODE_1D && 2132 (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) { 2133 if (surf->nsamples > 1) { 2134 fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__); 2135 return -EFAULT; 2136 } 2137 mode = RADEON_SURF_MODE_1D; 2138 surf->flags = RADEON_SURF_CLR(surf->flags, MODE); 2139 surf->flags |= RADEON_SURF_SET(mode, MODE); 2140 } 2141 2142 if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) { 2143 return -EINVAL; 2144 } 2145 2146 if (!surf->tile_split) { 2147 /* default value */ 2148 surf->mtilea = 1; 2149 surf->bankw = 1; 2150 surf->bankh = 1; 2151 surf->tile_split = 64; 2152 surf->stencil_tile_split = 64; 2153 } 2154 2155 switch (mode) { 2156 case RADEON_SURF_MODE_2D: { 2157 if (surf->flags & RADEON_SURF_Z_OR_SBUFFER) { 2158 switch (surf->nsamples) { 2159 case 1: 2160 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64; 2161 break; 2162 case 2: 2163 case 4: 2164 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128; 2165 break; 2166 case 8: 2167 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256; 2168 break; 2169 default: 2170 return -EINVAL; 2171 } 2172 2173 if (surf->flags & RADEON_SURF_SBUFFER) { 2174 *stencil_tile_mode = *tile_mode; 2175 2176 cik_get_2d_params(surf_man, 1, surf->nsamples, false, 2177 *stencil_tile_mode, NULL, 2178 &surf->stencil_tile_split, 2179 NULL, NULL, NULL, NULL); 2180 } 2181 } else if (surf->flags & RADEON_SURF_SCANOUT) { 2182 *tile_mode = CIK_TILE_MODE_COLOR_2D_SCANOUT; 2183 } else { 2184 *tile_mode = CIK_TILE_MODE_COLOR_2D; 2185 } 2186 2187 /* retrieve tiling mode values */ 2188 cik_get_2d_params(surf_man, surf->bpe, surf->nsamples, 2189 !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), *tile_mode, 2190 NULL, &surf->tile_split, NULL, &surf->mtilea, 2191 &surf->bankw, &surf->bankh); 2192 break; 2193 } 2194 case RADEON_SURF_MODE_1D: 2195 if (surf->flags & RADEON_SURF_SBUFFER) { 2196 *stencil_tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D; 2197 } 2198 if (surf->flags & RADEON_SURF_ZBUFFER) { 2199 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D; 2200 } else if (surf->flags & RADEON_SURF_SCANOUT) { 2201 *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT; 2202 } else { 2203 *tile_mode = SI_TILE_MODE_COLOR_1D; 2204 } 2205 break; 2206 case RADEON_SURF_MODE_LINEAR_ALIGNED: 2207 default: 2208 *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED; 2209 } 2210 2211 return 0; 2212 } 2213 2214 static int cik_surface_init_2d(struct radeon_surface_manager *surf_man, 2215 struct radeon_surface *surf, 2216 struct radeon_surface_level *level, 2217 unsigned bpe, unsigned tile_mode, 2218 unsigned tile_split, 2219 unsigned num_pipes, unsigned num_banks, 2220 uint64_t offset, 2221 unsigned start_level) 2222 { 2223 uint64_t aligned_offset = offset; 2224 unsigned tilew, tileh, tileb_1x, tileb; 2225 unsigned mtilew, mtileh, mtileb; 2226 unsigned slice_pt; 2227 unsigned i; 2228 2229 /* compute tile values */ 2230 tilew = 8; 2231 tileh = 8; 2232 tileb_1x = tilew * tileh * bpe; 2233 2234 tile_split = MIN2(surf_man->hw_info.row_size, tile_split); 2235 2236 tileb = surf->nsamples * tileb_1x; 2237 2238 /* slices per tile */ 2239 slice_pt = 1; 2240 if (tileb > tile_split && tile_split) { 2241 slice_pt = tileb / tile_split; 2242 tileb = tileb / slice_pt; 2243 } 2244 2245 /* macro tile width & height */ 2246 mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea; 2247 mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea; 2248 2249 /* macro tile bytes */ 2250 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb; 2251 2252 if (start_level <= 1) { 2253 unsigned alignment = MAX2(256, mtileb); 2254 surf->bo_alignment = MAX2(surf->bo_alignment, alignment); 2255 2256 if (aligned_offset) { 2257 aligned_offset = ALIGN(aligned_offset, alignment); 2258 } 2259 } 2260 2261 /* build mipmap tree */ 2262 for (i = start_level; i <= surf->last_level; i++) { 2263 level[i].mode = RADEON_SURF_MODE_2D; 2264 si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset); 2265 if (level[i].mode == RADEON_SURF_MODE_1D) { 2266 switch (tile_mode) { 2267 case CIK_TILE_MODE_COLOR_2D: 2268 tile_mode = SI_TILE_MODE_COLOR_1D; 2269 break; 2270 case CIK_TILE_MODE_COLOR_2D_SCANOUT: 2271 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT; 2272 break; 2273 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64: 2274 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128: 2275 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256: 2276 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512: 2277 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE: 2278 tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D; 2279 break; 2280 default: 2281 return -EINVAL; 2282 } 2283 return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i); 2284 } 2285 /* level0 and first mipmap need to have alignment */ 2286 aligned_offset = offset = surf->bo_size; 2287 if (i == 0) { 2288 aligned_offset = ALIGN(aligned_offset, surf->bo_alignment); 2289 } 2290 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) { 2291 if (surf->level == level) { 2292 surf->tiling_index[i] = tile_mode; 2293 /* it's ok because stencil is done after */ 2294 surf->stencil_tiling_index[i] = tile_mode; 2295 } else { 2296 surf->stencil_tiling_index[i] = tile_mode; 2297 } 2298 } 2299 } 2300 return 0; 2301 } 2302 2303 static int cik_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man, 2304 struct radeon_surface *surf, 2305 unsigned tile_mode, unsigned stencil_tile_mode) 2306 { 2307 int r; 2308 uint32_t num_pipes, num_banks; 2309 2310 cik_get_2d_params(surf_man, surf->bpe, surf->nsamples, 2311 !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), tile_mode, 2312 &num_pipes, NULL, &num_banks, NULL, NULL, NULL); 2313 2314 r = cik_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode, 2315 surf->tile_split, num_pipes, num_banks, 0, 0); 2316 if (r) { 2317 return r; 2318 } 2319 2320 if (surf->flags & RADEON_SURF_SBUFFER) { 2321 r = cik_surface_init_2d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode, 2322 surf->stencil_tile_split, num_pipes, num_banks, 2323 surf->bo_size, 0); 2324 surf->stencil_offset = surf->stencil_level[0].offset; 2325 } 2326 return r; 2327 } 2328 2329 static int cik_surface_init(struct radeon_surface_manager *surf_man, 2330 struct radeon_surface *surf) 2331 { 2332 unsigned mode, tile_mode, stencil_tile_mode; 2333 int r; 2334 2335 /* MSAA surfaces support the 2D mode only. */ 2336 if (surf->nsamples > 1) { 2337 surf->flags = RADEON_SURF_CLR(surf->flags, MODE); 2338 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); 2339 } 2340 2341 /* tiling mode */ 2342 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK; 2343 2344 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) { 2345 /* zbuffer only support 1D or 2D tiled surface */ 2346 switch (mode) { 2347 case RADEON_SURF_MODE_1D: 2348 case RADEON_SURF_MODE_2D: 2349 break; 2350 default: 2351 mode = RADEON_SURF_MODE_1D; 2352 surf->flags = RADEON_SURF_CLR(surf->flags, MODE); 2353 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); 2354 break; 2355 } 2356 } 2357 2358 r = cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode); 2359 if (r) { 2360 return r; 2361 } 2362 2363 surf->stencil_offset = 0; 2364 surf->bo_alignment = 0; 2365 2366 /* check tiling mode */ 2367 switch (mode) { 2368 case RADEON_SURF_MODE_LINEAR: 2369 r = r6_surface_init_linear(surf_man, surf, 0, 0); 2370 break; 2371 case RADEON_SURF_MODE_LINEAR_ALIGNED: 2372 r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0); 2373 break; 2374 case RADEON_SURF_MODE_1D: 2375 r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode); 2376 break; 2377 case RADEON_SURF_MODE_2D: 2378 r = cik_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode); 2379 break; 2380 default: 2381 return -EINVAL; 2382 } 2383 return r; 2384 } 2385 2386 /* 2387 * depending on surface 2388 */ 2389 static int cik_surface_best(struct radeon_surface_manager *surf_man, 2390 struct radeon_surface *surf) 2391 { 2392 unsigned mode, tile_mode, stencil_tile_mode; 2393 2394 /* tiling mode */ 2395 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK; 2396 2397 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) && 2398 !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) { 2399 /* depth/stencil force 1d tiling for old mesa */ 2400 surf->flags = RADEON_SURF_CLR(surf->flags, MODE); 2401 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); 2402 } 2403 2404 return cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode); 2405 } 2406 2407 2408 /* =========================================================================== 2409 * public API 2410 */ 2411 struct radeon_surface_manager * 2412 radeon_surface_manager_new(int fd) 2413 { 2414 struct radeon_surface_manager *surf_man; 2415 2416 surf_man = calloc(1, sizeof(struct radeon_surface_manager)); 2417 if (surf_man == NULL) { 2418 return NULL; 2419 } 2420 surf_man->fd = fd; 2421 if (radeon_get_value(fd, RADEON_INFO_DEVICE_ID, &surf_man->device_id)) { 2422 goto out_err; 2423 } 2424 if (radeon_get_family(surf_man)) { 2425 goto out_err; 2426 } 2427 2428 if (surf_man->family <= CHIP_RV740) { 2429 if (r6_init_hw_info(surf_man)) { 2430 goto out_err; 2431 } 2432 surf_man->surface_init = &r6_surface_init; 2433 surf_man->surface_best = &r6_surface_best; 2434 } else if (surf_man->family <= CHIP_ARUBA) { 2435 if (eg_init_hw_info(surf_man)) { 2436 goto out_err; 2437 } 2438 surf_man->surface_init = &eg_surface_init; 2439 surf_man->surface_best = &eg_surface_best; 2440 } else if (surf_man->family < CHIP_BONAIRE) { 2441 if (si_init_hw_info(surf_man)) { 2442 goto out_err; 2443 } 2444 surf_man->surface_init = &si_surface_init; 2445 surf_man->surface_best = &si_surface_best; 2446 } else { 2447 if (cik_init_hw_info(surf_man)) { 2448 goto out_err; 2449 } 2450 surf_man->surface_init = &cik_surface_init; 2451 surf_man->surface_best = &cik_surface_best; 2452 } 2453 2454 return surf_man; 2455 out_err: 2456 free(surf_man); 2457 return NULL; 2458 } 2459 2460 void 2461 radeon_surface_manager_free(struct radeon_surface_manager *surf_man) 2462 { 2463 free(surf_man); 2464 } 2465 2466 static int radeon_surface_sanity(struct radeon_surface_manager *surf_man, 2467 struct radeon_surface *surf, 2468 unsigned type, 2469 unsigned mode) 2470 { 2471 if (surf_man == NULL || surf_man->surface_init == NULL || surf == NULL) { 2472 return -EINVAL; 2473 } 2474 2475 /* all dimension must be at least 1 ! */ 2476 if (!surf->npix_x || !surf->npix_y || !surf->npix_z) { 2477 return -EINVAL; 2478 } 2479 if (!surf->blk_w || !surf->blk_h || !surf->blk_d) { 2480 return -EINVAL; 2481 } 2482 if (!surf->array_size) { 2483 return -EINVAL; 2484 } 2485 /* array size must be a power of 2 */ 2486 surf->array_size = next_power_of_two(surf->array_size); 2487 2488 switch (surf->nsamples) { 2489 case 1: 2490 case 2: 2491 case 4: 2492 case 8: 2493 break; 2494 default: 2495 return -EINVAL; 2496 } 2497 /* check type */ 2498 switch (type) { 2499 case RADEON_SURF_TYPE_1D: 2500 if (surf->npix_y > 1) { 2501 return -EINVAL; 2502 } 2503 /* fallthrough */ 2504 case RADEON_SURF_TYPE_2D: 2505 if (surf->npix_z > 1) { 2506 return -EINVAL; 2507 } 2508 break; 2509 case RADEON_SURF_TYPE_CUBEMAP: 2510 if (surf->npix_z > 1) { 2511 return -EINVAL; 2512 } 2513 /* deal with cubemap as they were texture array */ 2514 if (surf_man->family >= CHIP_RV770) { 2515 surf->array_size = 8; 2516 } else { 2517 surf->array_size = 6; 2518 } 2519 break; 2520 case RADEON_SURF_TYPE_3D: 2521 break; 2522 case RADEON_SURF_TYPE_1D_ARRAY: 2523 if (surf->npix_y > 1) { 2524 return -EINVAL; 2525 } 2526 case RADEON_SURF_TYPE_2D_ARRAY: 2527 break; 2528 default: 2529 return -EINVAL; 2530 } 2531 return 0; 2532 } 2533 2534 int 2535 radeon_surface_init(struct radeon_surface_manager *surf_man, 2536 struct radeon_surface *surf) 2537 { 2538 unsigned mode, type; 2539 int r; 2540 2541 type = RADEON_SURF_GET(surf->flags, TYPE); 2542 mode = RADEON_SURF_GET(surf->flags, MODE); 2543 2544 r = radeon_surface_sanity(surf_man, surf, type, mode); 2545 if (r) { 2546 return r; 2547 } 2548 return surf_man->surface_init(surf_man, surf); 2549 } 2550 2551 int 2552 radeon_surface_best(struct radeon_surface_manager *surf_man, 2553 struct radeon_surface *surf) 2554 { 2555 unsigned mode, type; 2556 int r; 2557 2558 type = RADEON_SURF_GET(surf->flags, TYPE); 2559 mode = RADEON_SURF_GET(surf->flags, MODE); 2560 2561 r = radeon_surface_sanity(surf_man, surf, type, mode); 2562 if (r) { 2563 return r; 2564 } 2565 return surf_man->surface_best(surf_man, surf); 2566 } 2567