1 /* 2 * Copyright 2011 Red Hat All Rights Reserved. 3 * Copyright 2014 Advanced Micro Devices, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 16 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS 18 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. 22 * 23 * The above copyright notice and this permission notice (including the 24 * next paragraph) shall be included in all copies or substantial portions 25 * of the Software. 26 */ 27 28 /* Contact: 29 * Marek Olk <maraeo (at) gmail.com> 30 */ 31 32 #include "amdgpu_winsys.h" 33 #include "util/u_format.h" 34 35 #ifndef CIASICIDGFXENGINE_SOUTHERNISLAND 36 #define CIASICIDGFXENGINE_SOUTHERNISLAND 0x0000000A 37 #endif 38 39 40 static int amdgpu_surface_sanity(const struct pipe_resource *tex) 41 { 42 /* all dimension must be at least 1 ! */ 43 if (!tex->width0 || !tex->height0 || !tex->depth0 || 44 !tex->array_size) 45 return -EINVAL; 46 47 switch (tex->nr_samples) { 48 case 0: 49 case 1: 50 case 2: 51 case 4: 52 case 8: 53 break; 54 default: 55 return -EINVAL; 56 } 57 58 switch (tex->target) { 59 case PIPE_TEXTURE_1D: 60 if (tex->height0 > 1) 61 return -EINVAL; 62 /* fall through */ 63 case PIPE_TEXTURE_2D: 64 case PIPE_TEXTURE_RECT: 65 if (tex->depth0 > 1 || tex->array_size > 1) 66 return -EINVAL; 67 break; 68 case PIPE_TEXTURE_3D: 69 if (tex->array_size > 1) 70 return -EINVAL; 71 break; 72 case PIPE_TEXTURE_1D_ARRAY: 73 if (tex->height0 > 1) 74 return -EINVAL; 75 /* fall through */ 76 case PIPE_TEXTURE_CUBE: 77 case PIPE_TEXTURE_2D_ARRAY: 78 case PIPE_TEXTURE_CUBE_ARRAY: 79 if (tex->depth0 > 1) 80 return -EINVAL; 81 break; 82 default: 83 return -EINVAL; 84 } 85 return 0; 86 } 87 88 static void *ADDR_API allocSysMem(const ADDR_ALLOCSYSMEM_INPUT * pInput) 89 { 90 return malloc(pInput->sizeInBytes); 91 } 92 93 static ADDR_E_RETURNCODE ADDR_API freeSysMem(const ADDR_FREESYSMEM_INPUT * pInput) 94 { 95 free(pInput->pVirtAddr); 96 return ADDR_OK; 97 } 98 99 ADDR_HANDLE amdgpu_addr_create(struct amdgpu_winsys *ws) 100 { 101 ADDR_CREATE_INPUT addrCreateInput = {0}; 102 ADDR_CREATE_OUTPUT addrCreateOutput = {0}; 103 ADDR_REGISTER_VALUE regValue = {0}; 104 ADDR_CREATE_FLAGS createFlags = {{0}}; 105 ADDR_E_RETURNCODE addrRet; 106 107 addrCreateInput.size = sizeof(ADDR_CREATE_INPUT); 108 addrCreateOutput.size = sizeof(ADDR_CREATE_OUTPUT); 109 110 regValue.noOfBanks = ws->amdinfo.mc_arb_ramcfg & 0x3; 111 regValue.gbAddrConfig = ws->amdinfo.gb_addr_cfg; 112 regValue.noOfRanks = (ws->amdinfo.mc_arb_ramcfg & 0x4) >> 2; 113 114 regValue.backendDisables = ws->amdinfo.backend_disable[0]; 115 regValue.pTileConfig = ws->amdinfo.gb_tile_mode; 116 regValue.noOfEntries = ARRAY_SIZE(ws->amdinfo.gb_tile_mode); 117 if (ws->info.chip_class == SI) { 118 regValue.pMacroTileConfig = NULL; 119 regValue.noOfMacroEntries = 0; 120 } else { 121 regValue.pMacroTileConfig = ws->amdinfo.gb_macro_tile_mode; 122 regValue.noOfMacroEntries = ARRAY_SIZE(ws->amdinfo.gb_macro_tile_mode); 123 } 124 125 createFlags.value = 0; 126 createFlags.useTileIndex = 1; 127 createFlags.degradeBaseLevel = 1; 128 createFlags.useHtileSliceAlign = 1; 129 130 addrCreateInput.chipEngine = CIASICIDGFXENGINE_SOUTHERNISLAND; 131 addrCreateInput.chipFamily = ws->family; 132 addrCreateInput.chipRevision = ws->rev_id; 133 addrCreateInput.createFlags = createFlags; 134 addrCreateInput.callbacks.allocSysMem = allocSysMem; 135 addrCreateInput.callbacks.freeSysMem = freeSysMem; 136 addrCreateInput.callbacks.debugPrint = 0; 137 addrCreateInput.regValue = regValue; 138 139 addrRet = AddrCreate(&addrCreateInput, &addrCreateOutput); 140 if (addrRet != ADDR_OK) 141 return NULL; 142 143 return addrCreateOutput.hLib; 144 } 145 146 static int compute_level(struct amdgpu_winsys *ws, 147 const struct pipe_resource *tex, 148 struct radeon_surf *surf, bool is_stencil, 149 unsigned level, bool compressed, 150 ADDR_COMPUTE_SURFACE_INFO_INPUT *AddrSurfInfoIn, 151 ADDR_COMPUTE_SURFACE_INFO_OUTPUT *AddrSurfInfoOut, 152 ADDR_COMPUTE_DCCINFO_INPUT *AddrDccIn, 153 ADDR_COMPUTE_DCCINFO_OUTPUT *AddrDccOut, 154 ADDR_COMPUTE_HTILE_INFO_INPUT *AddrHtileIn, 155 ADDR_COMPUTE_HTILE_INFO_OUTPUT *AddrHtileOut) 156 { 157 struct radeon_surf_level *surf_level; 158 ADDR_E_RETURNCODE ret; 159 160 AddrSurfInfoIn->mipLevel = level; 161 AddrSurfInfoIn->width = u_minify(tex->width0, level); 162 AddrSurfInfoIn->height = u_minify(tex->height0, level); 163 164 if (tex->target == PIPE_TEXTURE_3D) 165 AddrSurfInfoIn->numSlices = u_minify(tex->depth0, level); 166 else if (tex->target == PIPE_TEXTURE_CUBE) 167 AddrSurfInfoIn->numSlices = 6; 168 else 169 AddrSurfInfoIn->numSlices = tex->array_size; 170 171 if (level > 0) { 172 /* Set the base level pitch. This is needed for calculation 173 * of non-zero levels. */ 174 if (is_stencil) 175 AddrSurfInfoIn->basePitch = surf->stencil_level[0].nblk_x; 176 else 177 AddrSurfInfoIn->basePitch = surf->level[0].nblk_x; 178 179 /* Convert blocks to pixels for compressed formats. */ 180 if (compressed) 181 AddrSurfInfoIn->basePitch *= surf->blk_w; 182 } 183 184 ret = AddrComputeSurfaceInfo(ws->addrlib, 185 AddrSurfInfoIn, 186 AddrSurfInfoOut); 187 if (ret != ADDR_OK) { 188 return ret; 189 } 190 191 surf_level = is_stencil ? &surf->stencil_level[level] : &surf->level[level]; 192 surf_level->offset = align64(surf->surf_size, AddrSurfInfoOut->baseAlign); 193 surf_level->slice_size = AddrSurfInfoOut->sliceSize; 194 surf_level->nblk_x = AddrSurfInfoOut->pitch; 195 surf_level->nblk_y = AddrSurfInfoOut->height; 196 197 switch (AddrSurfInfoOut->tileMode) { 198 case ADDR_TM_LINEAR_ALIGNED: 199 surf_level->mode = RADEON_SURF_MODE_LINEAR_ALIGNED; 200 break; 201 case ADDR_TM_1D_TILED_THIN1: 202 surf_level->mode = RADEON_SURF_MODE_1D; 203 break; 204 case ADDR_TM_2D_TILED_THIN1: 205 surf_level->mode = RADEON_SURF_MODE_2D; 206 break; 207 default: 208 assert(0); 209 } 210 211 if (is_stencil) 212 surf->stencil_tiling_index[level] = AddrSurfInfoOut->tileIndex; 213 else 214 surf->tiling_index[level] = AddrSurfInfoOut->tileIndex; 215 216 surf->surf_size = surf_level->offset + AddrSurfInfoOut->surfSize; 217 218 /* Clear DCC fields at the beginning. */ 219 surf_level->dcc_offset = 0; 220 221 /* The previous level's flag tells us if we can use DCC for this level. */ 222 if (AddrSurfInfoIn->flags.dccCompatible && 223 (level == 0 || AddrDccOut->subLvlCompressible)) { 224 AddrDccIn->colorSurfSize = AddrSurfInfoOut->surfSize; 225 AddrDccIn->tileMode = AddrSurfInfoOut->tileMode; 226 AddrDccIn->tileInfo = *AddrSurfInfoOut->pTileInfo; 227 AddrDccIn->tileIndex = AddrSurfInfoOut->tileIndex; 228 AddrDccIn->macroModeIndex = AddrSurfInfoOut->macroModeIndex; 229 230 ret = AddrComputeDccInfo(ws->addrlib, 231 AddrDccIn, 232 AddrDccOut); 233 234 if (ret == ADDR_OK) { 235 surf_level->dcc_offset = surf->dcc_size; 236 surf_level->dcc_fast_clear_size = AddrDccOut->dccFastClearSize; 237 surf->num_dcc_levels = level + 1; 238 surf->dcc_size = surf_level->dcc_offset + AddrDccOut->dccRamSize; 239 surf->dcc_alignment = MAX2(surf->dcc_alignment, AddrDccOut->dccRamBaseAlign); 240 } 241 } 242 243 /* TC-compatible HTILE. */ 244 if (!is_stencil && 245 AddrSurfInfoIn->flags.depth && 246 AddrSurfInfoIn->flags.tcCompatible && 247 surf_level->mode == RADEON_SURF_MODE_2D && 248 level == 0) { 249 AddrHtileIn->flags.tcCompatible = 1; 250 AddrHtileIn->pitch = AddrSurfInfoOut->pitch; 251 AddrHtileIn->height = AddrSurfInfoOut->height; 252 AddrHtileIn->numSlices = AddrSurfInfoOut->depth; 253 AddrHtileIn->blockWidth = ADDR_HTILE_BLOCKSIZE_8; 254 AddrHtileIn->blockHeight = ADDR_HTILE_BLOCKSIZE_8; 255 AddrHtileIn->pTileInfo = AddrSurfInfoOut->pTileInfo; 256 AddrHtileIn->tileIndex = AddrSurfInfoOut->tileIndex; 257 AddrHtileIn->macroModeIndex = AddrSurfInfoOut->macroModeIndex; 258 259 ret = AddrComputeHtileInfo(ws->addrlib, 260 AddrHtileIn, 261 AddrHtileOut); 262 263 if (ret == ADDR_OK) { 264 surf->htile_size = AddrHtileOut->htileBytes; 265 surf->htile_alignment = AddrHtileOut->baseAlign; 266 } 267 } 268 269 return 0; 270 } 271 272 #define G_009910_MICRO_TILE_MODE(x) (((x) >> 0) & 0x03) 273 #define G_009910_MICRO_TILE_MODE_NEW(x) (((x) >> 22) & 0x07) 274 275 static void set_micro_tile_mode(struct radeon_surf *surf, 276 struct radeon_info *info) 277 { 278 uint32_t tile_mode = info->si_tile_mode_array[surf->tiling_index[0]]; 279 280 if (info->chip_class >= CIK) 281 surf->micro_tile_mode = G_009910_MICRO_TILE_MODE_NEW(tile_mode); 282 else 283 surf->micro_tile_mode = G_009910_MICRO_TILE_MODE(tile_mode); 284 } 285 286 static unsigned cik_get_macro_tile_index(struct radeon_surf *surf) 287 { 288 unsigned index, tileb; 289 290 tileb = 8 * 8 * surf->bpe; 291 tileb = MIN2(surf->tile_split, tileb); 292 293 for (index = 0; tileb > 64; index++) 294 tileb >>= 1; 295 296 assert(index < 16); 297 return index; 298 } 299 300 static int amdgpu_surface_init(struct radeon_winsys *rws, 301 const struct pipe_resource *tex, 302 unsigned flags, unsigned bpe, 303 enum radeon_surf_mode mode, 304 struct radeon_surf *surf) 305 { 306 struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws; 307 unsigned level; 308 bool compressed; 309 ADDR_COMPUTE_SURFACE_INFO_INPUT AddrSurfInfoIn = {0}; 310 ADDR_COMPUTE_SURFACE_INFO_OUTPUT AddrSurfInfoOut = {0}; 311 ADDR_COMPUTE_DCCINFO_INPUT AddrDccIn = {0}; 312 ADDR_COMPUTE_DCCINFO_OUTPUT AddrDccOut = {0}; 313 ADDR_COMPUTE_HTILE_INFO_INPUT AddrHtileIn = {0}; 314 ADDR_COMPUTE_HTILE_INFO_OUTPUT AddrHtileOut = {0}; 315 ADDR_TILEINFO AddrTileInfoIn = {0}; 316 ADDR_TILEINFO AddrTileInfoOut = {0}; 317 int r; 318 319 r = amdgpu_surface_sanity(tex); 320 if (r) 321 return r; 322 323 AddrSurfInfoIn.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT); 324 AddrSurfInfoOut.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT); 325 AddrDccIn.size = sizeof(ADDR_COMPUTE_DCCINFO_INPUT); 326 AddrDccOut.size = sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT); 327 AddrHtileIn.size = sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT); 328 AddrHtileOut.size = sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT); 329 AddrSurfInfoOut.pTileInfo = &AddrTileInfoOut; 330 331 surf->blk_w = util_format_get_blockwidth(tex->format); 332 surf->blk_h = util_format_get_blockheight(tex->format); 333 surf->bpe = bpe; 334 surf->flags = flags; 335 336 compressed = surf->blk_w == 4 && surf->blk_h == 4; 337 338 /* MSAA and FMASK require 2D tiling. */ 339 if (tex->nr_samples > 1 || 340 (flags & RADEON_SURF_FMASK)) 341 mode = RADEON_SURF_MODE_2D; 342 343 /* DB doesn't support linear layouts. */ 344 if (flags & (RADEON_SURF_Z_OR_SBUFFER) && 345 mode < RADEON_SURF_MODE_1D) 346 mode = RADEON_SURF_MODE_1D; 347 348 /* Set the requested tiling mode. */ 349 switch (mode) { 350 case RADEON_SURF_MODE_LINEAR_ALIGNED: 351 AddrSurfInfoIn.tileMode = ADDR_TM_LINEAR_ALIGNED; 352 break; 353 case RADEON_SURF_MODE_1D: 354 AddrSurfInfoIn.tileMode = ADDR_TM_1D_TILED_THIN1; 355 break; 356 case RADEON_SURF_MODE_2D: 357 AddrSurfInfoIn.tileMode = ADDR_TM_2D_TILED_THIN1; 358 break; 359 default: 360 assert(0); 361 } 362 363 /* The format must be set correctly for the allocation of compressed 364 * textures to work. In other cases, setting the bpp is sufficient. */ 365 if (compressed) { 366 switch (bpe) { 367 case 8: 368 AddrSurfInfoIn.format = ADDR_FMT_BC1; 369 break; 370 case 16: 371 AddrSurfInfoIn.format = ADDR_FMT_BC3; 372 break; 373 default: 374 assert(0); 375 } 376 } 377 else { 378 AddrDccIn.bpp = AddrSurfInfoIn.bpp = bpe * 8; 379 } 380 381 AddrDccIn.numSamples = AddrSurfInfoIn.numSamples = 382 tex->nr_samples ? tex->nr_samples : 1; 383 AddrSurfInfoIn.tileIndex = -1; 384 385 /* Set the micro tile type. */ 386 if (flags & RADEON_SURF_SCANOUT) 387 AddrSurfInfoIn.tileType = ADDR_DISPLAYABLE; 388 else if (flags & (RADEON_SURF_Z_OR_SBUFFER | RADEON_SURF_FMASK)) 389 AddrSurfInfoIn.tileType = ADDR_DEPTH_SAMPLE_ORDER; 390 else 391 AddrSurfInfoIn.tileType = ADDR_NON_DISPLAYABLE; 392 393 AddrSurfInfoIn.flags.color = !(flags & RADEON_SURF_Z_OR_SBUFFER); 394 AddrSurfInfoIn.flags.depth = (flags & RADEON_SURF_ZBUFFER) != 0; 395 AddrSurfInfoIn.flags.cube = tex->target == PIPE_TEXTURE_CUBE; 396 AddrSurfInfoIn.flags.fmask = (flags & RADEON_SURF_FMASK) != 0; 397 AddrSurfInfoIn.flags.display = (flags & RADEON_SURF_SCANOUT) != 0; 398 AddrSurfInfoIn.flags.pow2Pad = tex->last_level > 0; 399 AddrSurfInfoIn.flags.tcCompatible = (flags & RADEON_SURF_TC_COMPATIBLE_HTILE) != 0; 400 401 /* Only degrade the tile mode for space if TC-compatible HTILE hasn't been 402 * requested, because TC-compatible HTILE requires 2D tiling. 403 */ 404 AddrSurfInfoIn.flags.degrade4Space = !AddrSurfInfoIn.flags.tcCompatible && 405 !AddrSurfInfoIn.flags.fmask && 406 tex->nr_samples <= 1 && 407 (flags & RADEON_SURF_OPTIMIZE_FOR_SPACE); 408 AddrSurfInfoIn.flags.opt4Space = AddrSurfInfoIn.flags.degrade4Space; 409 410 /* DCC notes: 411 * - If we add MSAA support, keep in mind that CB can't decompress 8bpp 412 * with samples >= 4. 413 * - Mipmapped array textures have low performance (discovered by a closed 414 * driver team). 415 */ 416 AddrSurfInfoIn.flags.dccCompatible = ws->info.chip_class >= VI && 417 !(flags & RADEON_SURF_Z_OR_SBUFFER) && 418 !(flags & RADEON_SURF_DISABLE_DCC) && 419 !compressed && AddrDccIn.numSamples <= 1 && 420 ((tex->array_size == 1 && tex->depth0 == 1) || 421 tex->last_level == 0); 422 423 AddrSurfInfoIn.flags.noStencil = (flags & RADEON_SURF_SBUFFER) == 0; 424 AddrSurfInfoIn.flags.compressZ = AddrSurfInfoIn.flags.depth; 425 426 /* noStencil = 0 can result in a depth part that is incompatible with 427 * mipmapped texturing. So set noStencil = 1 when mipmaps are requested (in 428 * this case, we may end up setting stencil_adjusted). 429 * 430 * TODO: update addrlib to a newer version, remove this, and 431 * use flags.matchStencilTileCfg = 1 as an alternative fix. 432 */ 433 if (tex->last_level > 0) 434 AddrSurfInfoIn.flags.noStencil = 1; 435 436 /* Set preferred macrotile parameters. This is usually required 437 * for shared resources. This is for 2D tiling only. */ 438 if (AddrSurfInfoIn.tileMode >= ADDR_TM_2D_TILED_THIN1 && 439 surf->bankw && surf->bankh && surf->mtilea && surf->tile_split) { 440 assert(!(flags & RADEON_SURF_FMASK)); 441 442 /* If any of these parameters are incorrect, the calculation 443 * will fail. */ 444 AddrTileInfoIn.banks = surf->num_banks; 445 AddrTileInfoIn.bankWidth = surf->bankw; 446 AddrTileInfoIn.bankHeight = surf->bankh; 447 AddrTileInfoIn.macroAspectRatio = surf->mtilea; 448 AddrTileInfoIn.tileSplitBytes = surf->tile_split; 449 AddrTileInfoIn.pipeConfig = surf->pipe_config + 1; /* +1 compared to GB_TILE_MODE */ 450 AddrSurfInfoIn.flags.degrade4Space = 0; 451 AddrSurfInfoIn.pTileInfo = &AddrTileInfoIn; 452 453 /* If AddrSurfInfoIn.pTileInfo is set, Addrlib doesn't set 454 * the tile index, because we are expected to know it if 455 * we know the other parameters. 456 * 457 * This is something that can easily be fixed in Addrlib. 458 * For now, just figure it out here. 459 * Note that only 2D_TILE_THIN1 is handled here. 460 */ 461 assert(!(flags & RADEON_SURF_Z_OR_SBUFFER)); 462 assert(AddrSurfInfoIn.tileMode == ADDR_TM_2D_TILED_THIN1); 463 464 if (ws->info.chip_class == SI) { 465 if (AddrSurfInfoIn.tileType == ADDR_DISPLAYABLE) { 466 if (bpe == 2) 467 AddrSurfInfoIn.tileIndex = 11; /* 16bpp */ 468 else 469 AddrSurfInfoIn.tileIndex = 12; /* 32bpp */ 470 } else { 471 if (bpe == 1) 472 AddrSurfInfoIn.tileIndex = 14; /* 8bpp */ 473 else if (bpe == 2) 474 AddrSurfInfoIn.tileIndex = 15; /* 16bpp */ 475 else if (bpe == 4) 476 AddrSurfInfoIn.tileIndex = 16; /* 32bpp */ 477 else 478 AddrSurfInfoIn.tileIndex = 17; /* 64bpp (and 128bpp) */ 479 } 480 } else { 481 /* CIK - VI */ 482 if (AddrSurfInfoIn.tileType == ADDR_DISPLAYABLE) 483 AddrSurfInfoIn.tileIndex = 10; /* 2D displayable */ 484 else 485 AddrSurfInfoIn.tileIndex = 14; /* 2D non-displayable */ 486 487 /* Addrlib doesn't set this if tileIndex is forced like above. */ 488 AddrSurfInfoOut.macroModeIndex = cik_get_macro_tile_index(surf); 489 } 490 } 491 492 surf->num_dcc_levels = 0; 493 surf->surf_size = 0; 494 surf->dcc_size = 0; 495 surf->dcc_alignment = 1; 496 surf->htile_size = 0; 497 surf->htile_alignment = 1; 498 499 /* Calculate texture layout information. */ 500 for (level = 0; level <= tex->last_level; level++) { 501 r = compute_level(ws, tex, surf, false, level, compressed, 502 &AddrSurfInfoIn, &AddrSurfInfoOut, 503 &AddrDccIn, &AddrDccOut, &AddrHtileIn, &AddrHtileOut); 504 if (r) 505 return r; 506 507 if (level == 0) { 508 surf->surf_alignment = AddrSurfInfoOut.baseAlign; 509 surf->pipe_config = AddrSurfInfoOut.pTileInfo->pipeConfig - 1; 510 set_micro_tile_mode(surf, &ws->info); 511 512 /* For 2D modes only. */ 513 if (AddrSurfInfoOut.tileMode >= ADDR_TM_2D_TILED_THIN1) { 514 surf->bankw = AddrSurfInfoOut.pTileInfo->bankWidth; 515 surf->bankh = AddrSurfInfoOut.pTileInfo->bankHeight; 516 surf->mtilea = AddrSurfInfoOut.pTileInfo->macroAspectRatio; 517 surf->tile_split = AddrSurfInfoOut.pTileInfo->tileSplitBytes; 518 surf->num_banks = AddrSurfInfoOut.pTileInfo->banks; 519 surf->macro_tile_index = AddrSurfInfoOut.macroModeIndex; 520 } else { 521 surf->macro_tile_index = 0; 522 } 523 } 524 } 525 526 /* Calculate texture layout information for stencil. */ 527 if (flags & RADEON_SURF_SBUFFER) { 528 AddrSurfInfoIn.bpp = 8; 529 AddrSurfInfoIn.flags.depth = 0; 530 AddrSurfInfoIn.flags.stencil = 1; 531 AddrSurfInfoIn.flags.tcCompatible = 0; 532 /* This will be ignored if AddrSurfInfoIn.pTileInfo is NULL. */ 533 AddrTileInfoIn.tileSplitBytes = surf->stencil_tile_split; 534 535 for (level = 0; level <= tex->last_level; level++) { 536 r = compute_level(ws, tex, surf, true, level, compressed, 537 &AddrSurfInfoIn, &AddrSurfInfoOut, &AddrDccIn, &AddrDccOut, 538 NULL, NULL); 539 if (r) 540 return r; 541 542 /* DB uses the depth pitch for both stencil and depth. */ 543 if (surf->stencil_level[level].nblk_x != surf->level[level].nblk_x) 544 surf->stencil_adjusted = true; 545 546 if (level == 0) { 547 /* For 2D modes only. */ 548 if (AddrSurfInfoOut.tileMode >= ADDR_TM_2D_TILED_THIN1) { 549 surf->stencil_tile_split = 550 AddrSurfInfoOut.pTileInfo->tileSplitBytes; 551 } 552 } 553 } 554 } 555 556 /* Recalculate the whole DCC miptree size including disabled levels. 557 * This is what addrlib does, but calling addrlib would be a lot more 558 * complicated. 559 */ 560 if (surf->dcc_size && tex->last_level > 0) { 561 surf->dcc_size = align64(surf->surf_size >> 8, 562 ws->info.pipe_interleave_bytes * 563 ws->info.num_tile_pipes); 564 } 565 566 /* Make sure HTILE covers the whole miptree, because the shader reads 567 * TC-compatible HTILE even for levels where it's disabled by DB. 568 */ 569 if (surf->htile_size && tex->last_level) 570 surf->htile_size *= 2; 571 572 surf->is_linear = surf->level[0].mode == RADEON_SURF_MODE_LINEAR_ALIGNED; 573 return 0; 574 } 575 576 void amdgpu_surface_init_functions(struct amdgpu_winsys *ws) 577 { 578 ws->base.surface_init = amdgpu_surface_init; 579 } 580