1 /* 2 * Copyright 2014 Advanced Micro Devices, Inc. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 15 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 16 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS 17 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 * USE OR OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * The above copyright notice and this permission notice (including the 23 * next paragraph) shall be included in all copies or substantial portions 24 * of the Software. 25 */ 26 27 /** 28 *************************************************************************************************** 29 * @file egbaddrlib.cpp 30 * @brief Contains the EgBasedAddrLib class implementation 31 *************************************************************************************************** 32 */ 33 34 #include "egbaddrlib.h" 35 36 /** 37 *************************************************************************************************** 38 * EgBasedAddrLib::EgBasedAddrLib 39 * 40 * @brief 41 * Constructor 42 * 43 * @note 44 * 45 *************************************************************************************************** 46 */ 47 EgBasedAddrLib::EgBasedAddrLib(const AddrClient* pClient) : 48 AddrLib(pClient), 49 m_ranks(0), 50 m_logicalBanks(0), 51 m_bankInterleave(1) 52 { 53 } 54 55 /** 56 *************************************************************************************************** 57 * EgBasedAddrLib::~EgBasedAddrLib 58 * 59 * @brief 60 * Destructor 61 *************************************************************************************************** 62 */ 63 EgBasedAddrLib::~EgBasedAddrLib() 64 { 65 } 66 67 /** 68 *************************************************************************************************** 69 * EgBasedAddrLib::DispatchComputeSurfaceInfo 70 * 71 * @brief 72 * Compute surface sizes include padded pitch,height,slices,total size in bytes, 73 * meanwhile output suitable tile mode and base alignment might be changed in this 74 * call as well. Results are returned through output parameters. 75 * 76 * @return 77 * TRUE if no error occurs 78 *************************************************************************************************** 79 */ 80 BOOL_32 EgBasedAddrLib::DispatchComputeSurfaceInfo( 81 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure 82 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure 83 ) const 84 { 85 AddrTileMode tileMode = pIn->tileMode; 86 UINT_32 bpp = pIn->bpp; 87 UINT_32 numSamples = pIn->numSamples; 88 UINT_32 numFrags = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags); 89 UINT_32 pitch = pIn->width; 90 UINT_32 height = pIn->height; 91 UINT_32 numSlices = pIn->numSlices; 92 UINT_32 mipLevel = pIn->mipLevel; 93 ADDR_SURFACE_FLAGS flags = pIn->flags; 94 95 ADDR_TILEINFO tileInfoDef = {0}; 96 ADDR_TILEINFO* pTileInfo = &tileInfoDef; 97 98 UINT_32 padDims = 0; 99 BOOL_32 valid; 100 101 tileMode = DegradeLargeThickTile(tileMode, bpp); 102 103 // Only override numSamples for NI above 104 if (m_chipFamily >= ADDR_CHIP_FAMILY_NI) 105 { 106 if (numFrags != numSamples) // This means EQAA 107 { 108 // The real surface size needed is determined by number of fragments 109 numSamples = numFrags; 110 } 111 112 // Save altered numSamples in pOut 113 pOut->numSamples = numSamples; 114 } 115 116 // Caller makes sure pOut->pTileInfo is not NULL, see HwlComputeSurfaceInfo 117 ADDR_ASSERT(pOut->pTileInfo); 118 119 if (pOut->pTileInfo != NULL) 120 { 121 pTileInfo = pOut->pTileInfo; 122 } 123 124 // Set default values 125 if (pIn->pTileInfo != NULL) 126 { 127 if (pTileInfo != pIn->pTileInfo) 128 { 129 *pTileInfo = *pIn->pTileInfo; 130 } 131 } 132 else 133 { 134 memset(pTileInfo, 0, sizeof(ADDR_TILEINFO)); 135 } 136 137 // For macro tile mode, we should calculate default tiling parameters 138 HwlSetupTileInfo(tileMode, 139 flags, 140 bpp, 141 pitch, 142 height, 143 numSamples, 144 pIn->pTileInfo, 145 pTileInfo, 146 pIn->tileType, 147 pOut); 148 149 if (flags.cube) 150 { 151 if (mipLevel == 0) 152 { 153 padDims = 2; 154 } 155 156 if (numSlices == 1) 157 { 158 // This is calculating one face, remove cube flag 159 flags.cube = 0; 160 } 161 } 162 163 switch (tileMode) 164 { 165 case ADDR_TM_LINEAR_GENERAL://fall through 166 case ADDR_TM_LINEAR_ALIGNED: 167 valid = ComputeSurfaceInfoLinear(pIn, pOut, padDims); 168 break; 169 170 case ADDR_TM_1D_TILED_THIN1://fall through 171 case ADDR_TM_1D_TILED_THICK: 172 valid = ComputeSurfaceInfoMicroTiled(pIn, pOut, padDims, tileMode); 173 break; 174 175 case ADDR_TM_2D_TILED_THIN1: //fall through 176 case ADDR_TM_2D_TILED_THICK: //fall through 177 case ADDR_TM_3D_TILED_THIN1: //fall through 178 case ADDR_TM_3D_TILED_THICK: //fall through 179 case ADDR_TM_2D_TILED_XTHICK: //fall through 180 case ADDR_TM_3D_TILED_XTHICK: //fall through 181 case ADDR_TM_PRT_TILED_THIN1: //fall through 182 case ADDR_TM_PRT_2D_TILED_THIN1://fall through 183 case ADDR_TM_PRT_3D_TILED_THIN1://fall through 184 case ADDR_TM_PRT_TILED_THICK: //fall through 185 case ADDR_TM_PRT_2D_TILED_THICK://fall through 186 case ADDR_TM_PRT_3D_TILED_THICK: 187 valid = ComputeSurfaceInfoMacroTiled(pIn, pOut, padDims, tileMode); 188 break; 189 190 default: 191 valid = FALSE; 192 ADDR_ASSERT_ALWAYS(); 193 break; 194 } 195 196 return valid; 197 } 198 199 /** 200 *************************************************************************************************** 201 * EgBasedAddrLib::ComputeSurfaceInfoLinear 202 * 203 * @brief 204 * Compute linear surface sizes include padded pitch, height, slices, total size in 205 * bytes, meanwhile alignments as well. Since it is linear mode, so output tile mode 206 * will not be changed here. Results are returned through output parameters. 207 * 208 * @return 209 * TRUE if no error occurs 210 *************************************************************************************************** 211 */ 212 BOOL_32 EgBasedAddrLib::ComputeSurfaceInfoLinear( 213 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure 214 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut, ///< [out] Output structure 215 UINT_32 padDims ///< [in] Dimensions to padd 216 ) const 217 { 218 UINT_32 expPitch = pIn->width; 219 UINT_32 expHeight = pIn->height; 220 UINT_32 expNumSlices = pIn->numSlices; 221 222 // No linear MSAA on real H/W, keep this for TGL 223 UINT_32 numSamples = pOut->numSamples; 224 225 const UINT_32 microTileThickness = 1; 226 227 // 228 // Compute the surface alignments. 229 // 230 ComputeSurfaceAlignmentsLinear(pIn->tileMode, 231 pIn->bpp, 232 pIn->flags, 233 &pOut->baseAlign, 234 &pOut->pitchAlign, 235 &pOut->heightAlign); 236 237 if ((pIn->tileMode == ADDR_TM_LINEAR_GENERAL) && pIn->flags.color && (pIn->height > 1)) 238 { 239 #if !ALT_TEST 240 // When linear_general surface is accessed in multiple lines, it requires 8 pixels in pitch 241 // alignment since PITCH_TILE_MAX is in unit of 8 pixels. 242 // It is OK if it is accessed per line. 243 ADDR_ASSERT((pIn->width % 8) == 0); 244 #endif 245 } 246 247 pOut->depthAlign = microTileThickness; 248 249 expPitch = HwlPreHandleBaseLvl3xPitch(pIn, expPitch); 250 251 // 252 // Pad pitch and height to the required granularities. 253 // 254 PadDimensions(pIn->tileMode, 255 pIn->bpp, 256 pIn->flags, 257 numSamples, 258 pOut->pTileInfo, 259 padDims, 260 pIn->mipLevel, 261 &expPitch, pOut->pitchAlign, 262 &expHeight, pOut->heightAlign, 263 &expNumSlices, microTileThickness); 264 265 expPitch = HwlPostHandleBaseLvl3xPitch(pIn, expPitch); 266 267 // 268 // Adjust per HWL 269 // 270 271 UINT_64 logicalSliceSize; 272 273 logicalSliceSize = HwlGetSizeAdjustmentLinear(pIn->tileMode, 274 pIn->bpp, 275 numSamples, 276 pOut->baseAlign, 277 pOut->pitchAlign, 278 &expPitch, 279 &expHeight, 280 &pOut->heightAlign); 281 282 283 pOut->pitch = expPitch; 284 pOut->height = expHeight; 285 pOut->depth = expNumSlices; 286 287 pOut->surfSize = logicalSliceSize * expNumSlices; 288 289 pOut->tileMode = pIn->tileMode; 290 291 return TRUE; 292 } 293 294 /** 295 *************************************************************************************************** 296 * EgBasedAddrLib::ComputeSurfaceInfoMicroTiled 297 * 298 * @brief 299 * Compute 1D/Micro Tiled surface sizes include padded pitch, height, slices, total 300 * size in bytes, meanwhile alignments as well. Results are returned through output 301 * parameters. 302 * 303 * @return 304 * TRUE if no error occurs 305 *************************************************************************************************** 306 */ 307 BOOL_32 EgBasedAddrLib::ComputeSurfaceInfoMicroTiled( 308 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure 309 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut, ///< [out] Output structure 310 UINT_32 padDims, ///< [in] Dimensions to padd 311 AddrTileMode expTileMode ///< [in] Expected tile mode 312 ) const 313 { 314 BOOL_32 valid = TRUE; 315 316 UINT_32 microTileThickness; 317 UINT_32 expPitch = pIn->width; 318 UINT_32 expHeight = pIn->height; 319 UINT_32 expNumSlices = pIn->numSlices; 320 321 // No 1D MSAA on real H/W, keep this for TGL 322 UINT_32 numSamples = pOut->numSamples; 323 324 // 325 // Compute the micro tile thickness. 326 // 327 microTileThickness = ComputeSurfaceThickness(expTileMode); 328 329 // 330 // Extra override for mip levels 331 // 332 if (pIn->mipLevel > 0) 333 { 334 // 335 // Reduce tiling mode from thick to thin if the number of slices is less than the 336 // micro tile thickness. 337 // 338 if ((expTileMode == ADDR_TM_1D_TILED_THICK) && 339 (expNumSlices < ThickTileThickness)) 340 { 341 expTileMode = HwlDegradeThickTileMode(ADDR_TM_1D_TILED_THICK, expNumSlices, NULL); 342 if (expTileMode != ADDR_TM_1D_TILED_THICK) 343 { 344 microTileThickness = 1; 345 } 346 } 347 } 348 349 // 350 // Compute the surface restrictions. 351 // 352 ComputeSurfaceAlignmentsMicroTiled(expTileMode, 353 pIn->bpp, 354 pIn->flags, 355 pIn->mipLevel, 356 numSamples, 357 &pOut->baseAlign, 358 &pOut->pitchAlign, 359 &pOut->heightAlign); 360 361 pOut->depthAlign = microTileThickness; 362 363 // 364 // Pad pitch and height to the required granularities. 365 // Compute surface size. 366 // Return parameters. 367 // 368 PadDimensions(expTileMode, 369 pIn->bpp, 370 pIn->flags, 371 numSamples, 372 pOut->pTileInfo, 373 padDims, 374 pIn->mipLevel, 375 &expPitch, pOut->pitchAlign, 376 &expHeight, pOut->heightAlign, 377 &expNumSlices, microTileThickness); 378 379 // 380 // Get HWL specific pitch adjustment 381 // 382 UINT_64 logicalSliceSize = HwlGetSizeAdjustmentMicroTiled(microTileThickness, 383 pIn->bpp, 384 pIn->flags, 385 numSamples, 386 pOut->baseAlign, 387 pOut->pitchAlign, 388 &expPitch, 389 &expHeight); 390 391 392 pOut->pitch = expPitch; 393 pOut->height = expHeight; 394 pOut->depth = expNumSlices; 395 396 pOut->surfSize = logicalSliceSize * expNumSlices; 397 398 pOut->tileMode = expTileMode; 399 400 return valid; 401 } 402 403 404 /** 405 *************************************************************************************************** 406 * EgBasedAddrLib::ComputeSurfaceInfoMacroTiled 407 * 408 * @brief 409 * Compute 2D/macro tiled surface sizes include padded pitch, height, slices, total 410 * size in bytes, meanwhile output suitable tile mode and alignments might be changed 411 * in this call as well. Results are returned through output parameters. 412 * 413 * @return 414 * TRUE if no error occurs 415 *************************************************************************************************** 416 */ 417 BOOL_32 EgBasedAddrLib::ComputeSurfaceInfoMacroTiled( 418 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure 419 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut, ///< [out] Output structure 420 UINT_32 padDims, ///< [in] Dimensions to padd 421 AddrTileMode expTileMode ///< [in] Expected tile mode 422 ) const 423 { 424 BOOL_32 valid = TRUE; 425 426 AddrTileMode origTileMode = expTileMode; 427 UINT_32 microTileThickness; 428 429 UINT_32 paddedPitch; 430 UINT_32 paddedHeight; 431 UINT_64 bytesPerSlice; 432 433 UINT_32 expPitch = pIn->width; 434 UINT_32 expHeight = pIn->height; 435 UINT_32 expNumSlices = pIn->numSlices; 436 437 UINT_32 numSamples = pOut->numSamples; 438 439 // 440 // Compute the surface restrictions as base 441 // SanityCheckMacroTiled is called in ComputeSurfaceAlignmentsMacroTiled 442 // 443 valid = ComputeSurfaceAlignmentsMacroTiled(expTileMode, 444 pIn->bpp, 445 pIn->flags, 446 pIn->mipLevel, 447 numSamples, 448 pOut->pTileInfo, 449 &pOut->baseAlign, 450 &pOut->pitchAlign, 451 &pOut->heightAlign); 452 453 if (valid) 454 { 455 // 456 // Compute the micro tile thickness. 457 // 458 microTileThickness = ComputeSurfaceThickness(expTileMode); 459 460 // 461 // Find the correct tiling mode for mip levels 462 // 463 if (pIn->mipLevel > 0) 464 { 465 // 466 // Try valid tile mode 467 // 468 expTileMode = ComputeSurfaceMipLevelTileMode(expTileMode, 469 pIn->bpp, 470 expPitch, 471 expHeight, 472 expNumSlices, 473 numSamples, 474 pOut->pitchAlign, 475 pOut->heightAlign, 476 pOut->pTileInfo); 477 478 if (!IsMacroTiled(expTileMode)) // Downgraded to micro-tiled 479 { 480 return ComputeSurfaceInfoMicroTiled(pIn, pOut, padDims, expTileMode); 481 } 482 else 483 { 484 if (microTileThickness != ComputeSurfaceThickness(expTileMode)) 485 { 486 // 487 // Re-compute if thickness changed since bank-height may be changed! 488 // 489 return ComputeSurfaceInfoMacroTiled(pIn, pOut, padDims, expTileMode); 490 } 491 } 492 } 493 494 paddedPitch = expPitch; 495 paddedHeight = expHeight; 496 497 // 498 // Re-cal alignment 499 // 500 if (expTileMode != origTileMode) // Tile mode is changed but still macro-tiled 501 { 502 valid = ComputeSurfaceAlignmentsMacroTiled(expTileMode, 503 pIn->bpp, 504 pIn->flags, 505 pIn->mipLevel, 506 numSamples, 507 pOut->pTileInfo, 508 &pOut->baseAlign, 509 &pOut->pitchAlign, 510 &pOut->heightAlign); 511 } 512 513 // 514 // Do padding 515 // 516 PadDimensions(expTileMode, 517 pIn->bpp, 518 pIn->flags, 519 numSamples, 520 pOut->pTileInfo, 521 padDims, 522 pIn->mipLevel, 523 &paddedPitch, pOut->pitchAlign, 524 &paddedHeight, pOut->heightAlign, 525 &expNumSlices, microTileThickness); 526 527 if (pIn->flags.qbStereo && 528 (pOut->pStereoInfo != NULL) && 529 HwlStereoCheckRightOffsetPadding()) 530 { 531 // Eye height's bank bits are different from y == 0? 532 // Since 3D rendering treats right eye buffer starting from y == "eye height" while 533 // display engine treats it to be 0, so the bank bits may be different, we pad 534 // more in height to make sure y == "eye height" has the same bank bits as y == 0. 535 UINT_32 checkMask = pOut->pTileInfo->banks - 1; 536 UINT_32 bankBits = 0; 537 do 538 { 539 bankBits = (paddedHeight / 8 / pOut->pTileInfo->bankHeight) & checkMask; 540 541 if (bankBits) 542 { 543 paddedHeight += pOut->heightAlign; 544 } 545 } while (bankBits); 546 } 547 548 // 549 // Compute the size of a slice. 550 // 551 bytesPerSlice = BITS_TO_BYTES(static_cast<UINT_64>(paddedPitch) * 552 paddedHeight * NextPow2(pIn->bpp) * numSamples); 553 554 pOut->pitch = paddedPitch; 555 // Put this check right here to workaround special mipmap cases which the original height 556 // is needed. 557 // The original height is pre-stored in pOut->height in PostComputeMipLevel and 558 // pOut->pitch is needed in HwlCheckLastMacroTiledLvl, too. 559 if (m_configFlags.checkLast2DLevel && numSamples == 1) // Don't check MSAA 560 { 561 // Set a TRUE in pOut if next Level is the first 1D sub level 562 HwlCheckLastMacroTiledLvl(pIn, pOut); 563 } 564 pOut->height = paddedHeight; 565 566 pOut->depth = expNumSlices; 567 568 pOut->surfSize = bytesPerSlice * expNumSlices; 569 570 pOut->tileMode = expTileMode; 571 572 pOut->depthAlign = microTileThickness; 573 574 } // if (valid) 575 576 return valid; 577 } 578 579 /** 580 *************************************************************************************************** 581 * EgBasedAddrLib::ComputeSurfaceAlignmentsLinear 582 * 583 * @brief 584 * Compute linear surface alignment, calculation results are returned through 585 * output parameters. 586 * 587 * @return 588 * TRUE if no error occurs 589 *************************************************************************************************** 590 */ 591 BOOL_32 EgBasedAddrLib::ComputeSurfaceAlignmentsLinear( 592 AddrTileMode tileMode, ///< [in] tile mode 593 UINT_32 bpp, ///< [in] bits per pixel 594 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags 595 UINT_32* pBaseAlign, ///< [out] base address alignment in bytes 596 UINT_32* pPitchAlign, ///< [out] pitch alignment in pixels 597 UINT_32* pHeightAlign ///< [out] height alignment in pixels 598 ) const 599 { 600 BOOL_32 valid = TRUE; 601 602 switch (tileMode) 603 { 604 case ADDR_TM_LINEAR_GENERAL: 605 // 606 // The required base alignment and pitch and height granularities is to 1 element. 607 // 608 *pBaseAlign = (bpp > 8) ? bpp / 8 : 1; 609 *pPitchAlign = 1; 610 *pHeightAlign = 1; 611 break; 612 case ADDR_TM_LINEAR_ALIGNED: 613 // 614 // The required alignment for base is the pipe interleave size. 615 // The required granularity for pitch is hwl dependent. 616 // The required granularity for height is one row. 617 // 618 *pBaseAlign = m_pipeInterleaveBytes; 619 *pPitchAlign = HwlGetPitchAlignmentLinear(bpp, flags); 620 *pHeightAlign = 1; 621 break; 622 default: 623 *pBaseAlign = 1; 624 *pPitchAlign = 1; 625 *pHeightAlign = 1; 626 ADDR_UNHANDLED_CASE(); 627 break; 628 } 629 630 AdjustPitchAlignment(flags, pPitchAlign); 631 632 return valid; 633 } 634 635 /** 636 *************************************************************************************************** 637 * EgBasedAddrLib::ComputeSurfaceAlignmentsMicroTiled 638 * 639 * @brief 640 * Compute 1D tiled surface alignment, calculation results are returned through 641 * output parameters. 642 * 643 * @return 644 * TRUE if no error occurs 645 *************************************************************************************************** 646 */ 647 BOOL_32 EgBasedAddrLib::ComputeSurfaceAlignmentsMicroTiled( 648 AddrTileMode tileMode, ///< [in] tile mode 649 UINT_32 bpp, ///< [in] bits per pixel 650 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags 651 UINT_32 mipLevel, ///< [in] mip level 652 UINT_32 numSamples, ///< [in] number of samples 653 UINT_32* pBaseAlign, ///< [out] base address alignment in bytes 654 UINT_32* pPitchAlign, ///< [out] pitch alignment in pixels 655 UINT_32* pHeightAlign ///< [out] height alignment in pixels 656 ) const 657 { 658 BOOL_32 valid = TRUE; 659 660 // 661 // The required alignment for base is the pipe interleave size. 662 // 663 *pBaseAlign = m_pipeInterleaveBytes; 664 665 *pPitchAlign = HwlGetPitchAlignmentMicroTiled(tileMode, bpp, flags, numSamples); 666 667 *pHeightAlign = MicroTileHeight; 668 669 AdjustPitchAlignment(flags, pPitchAlign); 670 671 // ECR#393489 672 // Workaround 2 for 1D tiling - There is HW bug for Carrizo 673 // where it requires the following alignments for 1D tiling. 674 if (flags.czDispCompatible && (mipLevel == 0)) 675 { 676 *pBaseAlign = PowTwoAlign(*pBaseAlign, 4096); //Base address MOD 4096 = 0 677 *pPitchAlign = PowTwoAlign(*pPitchAlign, 512 / (BITS_TO_BYTES(bpp))); //(8 lines * pitch * bytes per pixel) MOD 4096 = 0 678 } 679 // end Carrizo workaround for 1D tilling 680 681 return valid; 682 } 683 684 685 /** 686 *************************************************************************************************** 687 * EgBasedAddrLib::HwlReduceBankWidthHeight 688 * 689 * @brief 690 * Additional checks, reduce bankHeight/bankWidth if needed and possible 691 * tileSize*BANK_WIDTH*BANK_HEIGHT <= ROW_SIZE 692 * 693 * @return 694 * TRUE if no error occurs 695 *************************************************************************************************** 696 */ 697 BOOL_32 EgBasedAddrLib::HwlReduceBankWidthHeight( 698 UINT_32 tileSize, ///< [in] tile size 699 UINT_32 bpp, ///< [in] bits per pixel 700 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags 701 UINT_32 numSamples, ///< [in] number of samples 702 UINT_32 bankHeightAlign, ///< [in] bank height alignment 703 UINT_32 pipes, ///< [in] pipes 704 ADDR_TILEINFO* pTileInfo ///< [in/out] bank structure. 705 ) const 706 { 707 UINT_32 macroAspectAlign; 708 BOOL_32 valid = TRUE; 709 710 if (tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize) 711 { 712 BOOL_32 stillGreater = TRUE; 713 714 // Try reducing bankWidth first 715 if (stillGreater && pTileInfo->bankWidth > 1) 716 { 717 while (stillGreater && pTileInfo->bankWidth > 0) 718 { 719 pTileInfo->bankWidth >>= 1; 720 721 if (pTileInfo->bankWidth == 0) 722 { 723 pTileInfo->bankWidth = 1; 724 break; 725 } 726 727 stillGreater = 728 tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize; 729 } 730 731 // bankWidth is reduced above, so we need to recalculate bankHeight and ratio 732 bankHeightAlign = Max(1u, 733 m_pipeInterleaveBytes * m_bankInterleave / 734 (tileSize * pTileInfo->bankWidth) 735 ); 736 737 // We cannot increase bankHeight so just assert this case. 738 ADDR_ASSERT((pTileInfo->bankHeight % bankHeightAlign) == 0); 739 740 if (numSamples == 1) 741 { 742 macroAspectAlign = Max(1u, 743 m_pipeInterleaveBytes * m_bankInterleave / 744 (tileSize * pipes * pTileInfo->bankWidth) 745 ); 746 pTileInfo->macroAspectRatio = PowTwoAlign(pTileInfo->macroAspectRatio, 747 macroAspectAlign); 748 } 749 } 750 751 // Early quit bank_height degradation for "64" bit z buffer 752 if (flags.depth && bpp >= 64) 753 { 754 stillGreater = FALSE; 755 } 756 757 // Then try reducing bankHeight 758 if (stillGreater && pTileInfo->bankHeight > bankHeightAlign) 759 { 760 while (stillGreater && pTileInfo->bankHeight > bankHeightAlign) 761 { 762 pTileInfo->bankHeight >>= 1; 763 764 if (pTileInfo->bankHeight < bankHeightAlign) 765 { 766 pTileInfo->bankHeight = bankHeightAlign; 767 break; 768 } 769 770 stillGreater = 771 tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize; 772 } 773 } 774 775 valid = !stillGreater; 776 777 // Generate a warning if we still fail to meet this constraint 778 if (!valid) 779 { 780 ADDR_WARN( 781 0, ("TILE_SIZE(%d)*BANK_WIDTH(%d)*BANK_HEIGHT(%d) <= ROW_SIZE(%d)", 782 tileSize, pTileInfo->bankWidth, pTileInfo->bankHeight, m_rowSize)); 783 } 784 } 785 786 return valid; 787 } 788 789 /** 790 *************************************************************************************************** 791 * EgBasedAddrLib::ComputeSurfaceAlignmentsMacroTiled 792 * 793 * @brief 794 * Compute 2D tiled surface alignment, calculation results are returned through 795 * output parameters. 796 * 797 * @return 798 * TRUE if no error occurs 799 *************************************************************************************************** 800 */ 801 BOOL_32 EgBasedAddrLib::ComputeSurfaceAlignmentsMacroTiled( 802 AddrTileMode tileMode, ///< [in] tile mode 803 UINT_32 bpp, ///< [in] bits per pixel 804 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags 805 UINT_32 mipLevel, ///< [in] mip level 806 UINT_32 numSamples, ///< [in] number of samples 807 ADDR_TILEINFO* pTileInfo, ///< [in/out] bank structure. 808 UINT_32* pBaseAlign, ///< [out] base address alignment in bytes 809 UINT_32* pPitchAlign, ///< [out] pitch alignment in pixels 810 UINT_32* pHeightAlign ///< [out] height alignment in pixels 811 ) const 812 { 813 BOOL_32 valid = SanityCheckMacroTiled(pTileInfo); 814 815 if (valid) 816 { 817 UINT_32 macroTileWidth; 818 UINT_32 macroTileHeight; 819 820 UINT_32 tileSize; 821 UINT_32 bankHeightAlign; 822 UINT_32 macroAspectAlign; 823 824 UINT_32 thickness = ComputeSurfaceThickness(tileMode); 825 UINT_32 pipes = HwlGetPipes(pTileInfo); 826 827 // 828 // Align bank height first according to latest h/w spec 829 // 830 831 // tile_size = MIN(tile_split, 64 * tile_thickness * element_bytes * num_samples) 832 tileSize = Min(pTileInfo->tileSplitBytes, 833 BITS_TO_BYTES(64 * thickness * bpp * numSamples)); 834 835 // bank_height_align = 836 // MAX(1, (pipe_interleave_bytes * bank_interleave)/(tile_size*bank_width)) 837 bankHeightAlign = Max(1u, 838 m_pipeInterleaveBytes * m_bankInterleave / 839 (tileSize * pTileInfo->bankWidth) 840 ); 841 842 pTileInfo->bankHeight = PowTwoAlign(pTileInfo->bankHeight, bankHeightAlign); 843 844 // num_pipes * bank_width * macro_tile_aspect >= 845 // (pipe_interleave_size * bank_interleave) / tile_size 846 if (numSamples == 1) 847 { 848 // this restriction is only for mipmap (mipmap's numSamples must be 1) 849 macroAspectAlign = Max(1u, 850 m_pipeInterleaveBytes * m_bankInterleave / 851 (tileSize * pipes * pTileInfo->bankWidth) 852 ); 853 pTileInfo->macroAspectRatio = PowTwoAlign(pTileInfo->macroAspectRatio, macroAspectAlign); 854 } 855 856 valid = HwlReduceBankWidthHeight(tileSize, 857 bpp, 858 flags, 859 numSamples, 860 bankHeightAlign, 861 pipes, 862 pTileInfo); 863 864 // 865 // The required granularity for pitch is the macro tile width. 866 // 867 macroTileWidth = MicroTileWidth * pTileInfo->bankWidth * pipes * 868 pTileInfo->macroAspectRatio; 869 870 *pPitchAlign = macroTileWidth; 871 872 AdjustPitchAlignment(flags, pPitchAlign); 873 874 // 875 // The required granularity for height is the macro tile height. 876 // 877 macroTileHeight = MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks / 878 pTileInfo->macroAspectRatio; 879 880 *pHeightAlign = macroTileHeight; 881 882 // 883 // Compute base alignment 884 // 885 *pBaseAlign = pipes * 886 pTileInfo->bankWidth * pTileInfo->banks * pTileInfo->bankHeight * tileSize; 887 888 if ((mipLevel == 0) && (flags.prt) && (m_chipFamily == ADDR_CHIP_FAMILY_SI)) 889 { 890 static const UINT_32 PrtTileSize = 0x10000; 891 892 UINT_32 macroTileSize = macroTileWidth * macroTileHeight * numSamples * bpp / 8; 893 894 if (macroTileSize < PrtTileSize) 895 { 896 UINT_32 numMacroTiles = PrtTileSize / macroTileSize; 897 898 ADDR_ASSERT((PrtTileSize % macroTileSize) == 0); 899 900 *pPitchAlign *= numMacroTiles; 901 *pBaseAlign *= numMacroTiles; 902 } 903 } 904 } 905 906 return valid; 907 } 908 909 /** 910 *************************************************************************************************** 911 * EgBasedAddrLib::SanityCheckMacroTiled 912 * 913 * @brief 914 * Check if macro-tiled parameters are valid 915 * @return 916 * TRUE if valid 917 *************************************************************************************************** 918 */ 919 BOOL_32 EgBasedAddrLib::SanityCheckMacroTiled( 920 ADDR_TILEINFO* pTileInfo ///< [in] macro-tiled parameters 921 ) const 922 { 923 BOOL_32 valid = TRUE; 924 UINT_32 numPipes = HwlGetPipes(pTileInfo); 925 926 switch (pTileInfo->banks) 927 { 928 case 2: //fall through 929 case 4: //fall through 930 case 8: //fall through 931 case 16: 932 break; 933 default: 934 valid = FALSE; 935 break; 936 937 } 938 939 if (valid) 940 { 941 switch (pTileInfo->bankWidth) 942 { 943 case 1: //fall through 944 case 2: //fall through 945 case 4: //fall through 946 case 8: 947 break; 948 default: 949 valid = FALSE; 950 break; 951 } 952 } 953 954 if (valid) 955 { 956 switch (pTileInfo->bankHeight) 957 { 958 case 1: //fall through 959 case 2: //fall through 960 case 4: //fall through 961 case 8: 962 break; 963 default: 964 valid = FALSE; 965 break; 966 } 967 } 968 969 if (valid) 970 { 971 switch (pTileInfo->macroAspectRatio) 972 { 973 case 1: //fall through 974 case 2: //fall through 975 case 4: //fall through 976 case 8: 977 break; 978 default: 979 valid = FALSE; 980 break; 981 } 982 } 983 984 if (valid) 985 { 986 if (pTileInfo->banks < pTileInfo->macroAspectRatio) 987 { 988 // This will generate macro tile height <= 1 989 valid = FALSE; 990 } 991 } 992 993 if (valid) 994 { 995 if (pTileInfo->tileSplitBytes > m_rowSize) 996 { 997 valid = FALSE; 998 } 999 } 1000 1001 if (valid) 1002 { 1003 valid = HwlSanityCheckMacroTiled(pTileInfo); 1004 } 1005 1006 ADDR_ASSERT(valid == TRUE); 1007 1008 // Add this assert for guidance 1009 ADDR_ASSERT(numPipes * pTileInfo->banks >= 4); 1010 1011 return valid; 1012 } 1013 1014 /** 1015 *************************************************************************************************** 1016 * EgBasedAddrLib::ComputeSurfaceMipLevelTileMode 1017 * 1018 * @brief 1019 * Compute valid tile mode for surface mipmap sub-levels 1020 * 1021 * @return 1022 * Suitable tile mode 1023 *************************************************************************************************** 1024 */ 1025 AddrTileMode EgBasedAddrLib::ComputeSurfaceMipLevelTileMode( 1026 AddrTileMode baseTileMode, ///< [in] base tile mode 1027 UINT_32 bpp, ///< [in] bits per pixels 1028 UINT_32 pitch, ///< [in] current level pitch 1029 UINT_32 height, ///< [in] current level height 1030 UINT_32 numSlices, ///< [in] current number of slices 1031 UINT_32 numSamples, ///< [in] number of samples 1032 UINT_32 pitchAlign, ///< [in] pitch alignment 1033 UINT_32 heightAlign, ///< [in] height alignment 1034 ADDR_TILEINFO* pTileInfo ///< [in] ptr to bank structure 1035 ) const 1036 { 1037 UINT_32 bytesPerTile; 1038 1039 AddrTileMode expTileMode = baseTileMode; 1040 UINT_32 microTileThickness = ComputeSurfaceThickness(expTileMode); 1041 UINT_32 interleaveSize = m_pipeInterleaveBytes * m_bankInterleave; 1042 1043 // 1044 // Compute the size of a slice. 1045 // 1046 bytesPerTile = BITS_TO_BYTES(MicroTilePixels * microTileThickness * NextPow2(bpp) * numSamples); 1047 1048 // 1049 // Reduce tiling mode from thick to thin if the number of slices is less than the 1050 // micro tile thickness. 1051 // 1052 if (numSlices < microTileThickness) 1053 { 1054 expTileMode = HwlDegradeThickTileMode(expTileMode, numSlices, &bytesPerTile); 1055 } 1056 1057 if (bytesPerTile > pTileInfo->tileSplitBytes) 1058 { 1059 bytesPerTile = pTileInfo->tileSplitBytes; 1060 } 1061 1062 UINT_32 threshold1 = 1063 bytesPerTile * HwlGetPipes(pTileInfo) * pTileInfo->bankWidth * pTileInfo->macroAspectRatio; 1064 1065 UINT_32 threshold2 = 1066 bytesPerTile * pTileInfo->bankWidth * pTileInfo->bankHeight; 1067 1068 // 1069 // Reduce the tile mode from 2D/3D to 1D in following conditions 1070 // 1071 switch (expTileMode) 1072 { 1073 case ADDR_TM_2D_TILED_THIN1: //fall through 1074 case ADDR_TM_3D_TILED_THIN1: 1075 case ADDR_TM_PRT_TILED_THIN1: 1076 case ADDR_TM_PRT_2D_TILED_THIN1: 1077 case ADDR_TM_PRT_3D_TILED_THIN1: 1078 if ((pitch < pitchAlign) || 1079 (height < heightAlign) || 1080 (interleaveSize > threshold1) || 1081 (interleaveSize > threshold2)) 1082 { 1083 expTileMode = ADDR_TM_1D_TILED_THIN1; 1084 } 1085 break; 1086 case ADDR_TM_2D_TILED_THICK: //fall through 1087 case ADDR_TM_3D_TILED_THICK: 1088 case ADDR_TM_2D_TILED_XTHICK: 1089 case ADDR_TM_3D_TILED_XTHICK: 1090 case ADDR_TM_PRT_TILED_THICK: 1091 case ADDR_TM_PRT_2D_TILED_THICK: 1092 case ADDR_TM_PRT_3D_TILED_THICK: 1093 if ((pitch < pitchAlign) || 1094 (height < heightAlign)) 1095 { 1096 expTileMode = ADDR_TM_1D_TILED_THICK; 1097 } 1098 break; 1099 default: 1100 break; 1101 } 1102 1103 return expTileMode; 1104 } 1105 1106 /** 1107 *************************************************************************************************** 1108 * EgBasedAddrLib::HwlDegradeBaseLevel 1109 * @brief 1110 * Check if degrade is needed for base level 1111 * @return 1112 * TRUE if degrade is suggested 1113 *************************************************************************************************** 1114 */ 1115 BOOL_32 EgBasedAddrLib::HwlDegradeBaseLevel( 1116 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn) const 1117 { 1118 BOOL_32 degrade = FALSE; 1119 BOOL_32 valid = TRUE; 1120 1121 ADDR_ASSERT(IsMacroTiled(pIn->tileMode)); 1122 1123 UINT_32 baseAlign; 1124 UINT_32 pitchAlign; 1125 UINT_32 heightAlign; 1126 1127 ADDR_ASSERT(pIn->pTileInfo); 1128 ADDR_TILEINFO tileInfo = *pIn->pTileInfo; 1129 ADDR_COMPUTE_SURFACE_INFO_OUTPUT out = {0}; 1130 1131 if (UseTileIndex(pIn->tileIndex)) 1132 { 1133 out.tileIndex = pIn->tileIndex; 1134 out.macroModeIndex = TileIndexInvalid; 1135 } 1136 1137 HwlSetupTileInfo(pIn->tileMode, 1138 pIn->flags, 1139 pIn->bpp, 1140 pIn->width, 1141 pIn->height, 1142 pIn->numSamples, 1143 &tileInfo, 1144 &tileInfo, 1145 pIn->tileType, 1146 &out); 1147 1148 valid = ComputeSurfaceAlignmentsMacroTiled(pIn->tileMode, 1149 pIn->bpp, 1150 pIn->flags, 1151 pIn->mipLevel, 1152 pIn->numSamples, 1153 &tileInfo, 1154 &baseAlign, 1155 &pitchAlign, 1156 &heightAlign); 1157 1158 if (valid) 1159 { 1160 degrade = (pIn->width < pitchAlign || pIn->height < heightAlign); 1161 } 1162 else 1163 { 1164 degrade = TRUE; 1165 } 1166 1167 return degrade; 1168 } 1169 1170 /** 1171 *************************************************************************************************** 1172 * EgBasedAddrLib::HwlDegradeThickTileMode 1173 * 1174 * @brief 1175 * Degrades valid tile mode for thick modes if needed 1176 * 1177 * @return 1178 * Suitable tile mode 1179 *************************************************************************************************** 1180 */ 1181 AddrTileMode EgBasedAddrLib::HwlDegradeThickTileMode( 1182 AddrTileMode baseTileMode, ///< [in] base tile mode 1183 UINT_32 numSlices, ///< [in] current number of slices 1184 UINT_32* pBytesPerTile ///< [in/out] pointer to bytes per slice 1185 ) const 1186 { 1187 ADDR_ASSERT(numSlices < ComputeSurfaceThickness(baseTileMode)); 1188 // if pBytesPerTile is NULL, this is a don't-care.... 1189 UINT_32 bytesPerTile = pBytesPerTile != NULL ? *pBytesPerTile : 64; 1190 1191 AddrTileMode expTileMode = baseTileMode; 1192 switch (baseTileMode) 1193 { 1194 case ADDR_TM_1D_TILED_THICK: 1195 expTileMode = ADDR_TM_1D_TILED_THIN1; 1196 bytesPerTile >>= 2; 1197 break; 1198 case ADDR_TM_2D_TILED_THICK: 1199 expTileMode = ADDR_TM_2D_TILED_THIN1; 1200 bytesPerTile >>= 2; 1201 break; 1202 case ADDR_TM_3D_TILED_THICK: 1203 expTileMode = ADDR_TM_3D_TILED_THIN1; 1204 bytesPerTile >>= 2; 1205 break; 1206 case ADDR_TM_2D_TILED_XTHICK: 1207 if (numSlices < ThickTileThickness) 1208 { 1209 expTileMode = ADDR_TM_2D_TILED_THIN1; 1210 bytesPerTile >>= 3; 1211 } 1212 else 1213 { 1214 expTileMode = ADDR_TM_2D_TILED_THICK; 1215 bytesPerTile >>= 1; 1216 } 1217 break; 1218 case ADDR_TM_3D_TILED_XTHICK: 1219 if (numSlices < ThickTileThickness) 1220 { 1221 expTileMode = ADDR_TM_3D_TILED_THIN1; 1222 bytesPerTile >>= 3; 1223 } 1224 else 1225 { 1226 expTileMode = ADDR_TM_3D_TILED_THICK; 1227 bytesPerTile >>= 1; 1228 } 1229 break; 1230 default: 1231 ADDR_ASSERT_ALWAYS(); 1232 break; 1233 } 1234 1235 if (pBytesPerTile != NULL) 1236 { 1237 *pBytesPerTile = bytesPerTile; 1238 } 1239 1240 return expTileMode; 1241 } 1242 1243 /** 1244 *************************************************************************************************** 1245 * EgBasedAddrLib::DispatchComputeSurfaceAddrFromCoord 1246 * 1247 * @brief 1248 * Compute surface address from given coord (x, y, slice,sample) 1249 * 1250 * @return 1251 * Address in bytes 1252 *************************************************************************************************** 1253 */ 1254 UINT_64 EgBasedAddrLib::DispatchComputeSurfaceAddrFromCoord( 1255 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure 1256 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure 1257 ) const 1258 { 1259 UINT_32 x = pIn->x; 1260 UINT_32 y = pIn->y; 1261 UINT_32 slice = pIn->slice; 1262 UINT_32 sample = pIn->sample; 1263 UINT_32 bpp = pIn->bpp; 1264 UINT_32 pitch = pIn->pitch; 1265 UINT_32 height = pIn->height; 1266 UINT_32 numSlices = pIn->numSlices; 1267 UINT_32 numSamples = ((pIn->numSamples == 0) ? 1 : pIn->numSamples); 1268 UINT_32 numFrags = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags); 1269 AddrTileMode tileMode = pIn->tileMode; 1270 AddrTileType microTileType = pIn->tileType; 1271 BOOL_32 ignoreSE = pIn->ignoreSE; 1272 BOOL_32 isDepthSampleOrder = pIn->isDepth; 1273 ADDR_TILEINFO* pTileInfo = pIn->pTileInfo; 1274 1275 UINT_32* pBitPosition = &pOut->bitPosition; 1276 UINT_64 addr; 1277 1278 #if ADDR_AM_BUILD 1279 UINT_32 addr5Bit = 0; 1280 UINT_32 addr5Swizzle = pIn->addr5Swizzle; 1281 BOOL_32 is32ByteTile = pIn->is32ByteTile; 1282 #endif 1283 1284 // ADDR_DEPTH_SAMPLE_ORDER = non-disp + depth-sample-order 1285 if (microTileType == ADDR_DEPTH_SAMPLE_ORDER) 1286 { 1287 isDepthSampleOrder = TRUE; 1288 } 1289 1290 if (m_chipFamily >= ADDR_CHIP_FAMILY_NI) 1291 { 1292 if (numFrags != numSamples) 1293 { 1294 numSamples = numFrags; 1295 ADDR_ASSERT(sample < numSamples); 1296 } 1297 1298 /// @note 1299 /// 128 bit/thick tiled surface doesn't support display tiling and 1300 /// mipmap chain must have the same tileType, so please fill tileType correctly 1301 if (!IsLinear(pIn->tileMode)) 1302 { 1303 if (bpp >= 128 || ComputeSurfaceThickness(tileMode) > 1) 1304 { 1305 ADDR_ASSERT(microTileType != ADDR_DISPLAYABLE); 1306 } 1307 } 1308 } 1309 1310 switch (tileMode) 1311 { 1312 case ADDR_TM_LINEAR_GENERAL://fall through 1313 case ADDR_TM_LINEAR_ALIGNED: 1314 addr = ComputeSurfaceAddrFromCoordLinear(x, 1315 y, 1316 slice, 1317 sample, 1318 bpp, 1319 pitch, 1320 height, 1321 numSlices, 1322 pBitPosition); 1323 break; 1324 case ADDR_TM_1D_TILED_THIN1://fall through 1325 case ADDR_TM_1D_TILED_THICK: 1326 addr = ComputeSurfaceAddrFromCoordMicroTiled(x, 1327 y, 1328 slice, 1329 sample, 1330 bpp, 1331 pitch, 1332 height, 1333 numSamples, 1334 tileMode, 1335 microTileType, 1336 isDepthSampleOrder, 1337 pBitPosition); 1338 break; 1339 case ADDR_TM_2D_TILED_THIN1: //fall through 1340 case ADDR_TM_2D_TILED_THICK: //fall through 1341 case ADDR_TM_3D_TILED_THIN1: //fall through 1342 case ADDR_TM_3D_TILED_THICK: //fall through 1343 case ADDR_TM_2D_TILED_XTHICK: //fall through 1344 case ADDR_TM_3D_TILED_XTHICK: //fall through 1345 case ADDR_TM_PRT_TILED_THIN1: //fall through 1346 case ADDR_TM_PRT_2D_TILED_THIN1://fall through 1347 case ADDR_TM_PRT_3D_TILED_THIN1://fall through 1348 case ADDR_TM_PRT_TILED_THICK: //fall through 1349 case ADDR_TM_PRT_2D_TILED_THICK://fall through 1350 case ADDR_TM_PRT_3D_TILED_THICK: 1351 UINT_32 pipeSwizzle; 1352 UINT_32 bankSwizzle; 1353 1354 if (m_configFlags.useCombinedSwizzle) 1355 { 1356 ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo, 1357 &bankSwizzle, &pipeSwizzle); 1358 } 1359 else 1360 { 1361 pipeSwizzle = pIn->pipeSwizzle; 1362 bankSwizzle = pIn->bankSwizzle; 1363 } 1364 1365 addr = ComputeSurfaceAddrFromCoordMacroTiled(x, 1366 y, 1367 slice, 1368 sample, 1369 bpp, 1370 pitch, 1371 height, 1372 numSamples, 1373 tileMode, 1374 microTileType, 1375 ignoreSE, 1376 isDepthSampleOrder, 1377 pipeSwizzle, 1378 bankSwizzle, 1379 pTileInfo, 1380 pBitPosition); 1381 break; 1382 default: 1383 addr = 0; 1384 ADDR_ASSERT_ALWAYS(); 1385 break; 1386 } 1387 1388 #if ADDR_AM_BUILD 1389 if (m_chipFamily >= ADDR_CHIP_FAMILY_NI) 1390 { 1391 if (addr5Swizzle && isDepthSampleOrder && is32ByteTile) 1392 { 1393 UINT_32 tx = x >> 3; 1394 UINT_32 ty = y >> 3; 1395 UINT_32 tileBits = ((ty&0x3) << 2) | (tx&0x3); 1396 1397 tileBits = tileBits & addr5Swizzle; 1398 addr5Bit = XorReduce(tileBits, 4); 1399 1400 addr = addr | static_cast<UINT_64>(addr5Bit << 5); 1401 } 1402 } 1403 #endif 1404 1405 return addr; 1406 } 1407 1408 /** 1409 *************************************************************************************************** 1410 * EgBasedAddrLib::ComputeSurfaceAddrFromCoordMicroTiled 1411 * 1412 * @brief 1413 * Computes the surface address and bit position from a 1414 * coordinate for 2D tilied (macro tiled) 1415 * @return 1416 * The byte address 1417 *************************************************************************************************** 1418 */ 1419 UINT_64 EgBasedAddrLib::ComputeSurfaceAddrFromCoordMacroTiled( 1420 UINT_32 x, ///< [in] x coordinate 1421 UINT_32 y, ///< [in] y coordinate 1422 UINT_32 slice, ///< [in] slice index 1423 UINT_32 sample, ///< [in] sample index 1424 UINT_32 bpp, ///< [in] bits per pixel 1425 UINT_32 pitch, ///< [in] surface pitch, in pixels 1426 UINT_32 height, ///< [in] surface height, in pixels 1427 UINT_32 numSamples, ///< [in] number of samples 1428 AddrTileMode tileMode, ///< [in] tile mode 1429 AddrTileType microTileType, ///< [in] micro tiling type 1430 BOOL_32 ignoreSE, ///< [in] TRUE if shader enginers can be ignored 1431 BOOL_32 isDepthSampleOrder, ///< [in] TRUE if it depth sample ordering is used 1432 UINT_32 pipeSwizzle, ///< [in] pipe swizzle 1433 UINT_32 bankSwizzle, ///< [in] bank swizzle 1434 ADDR_TILEINFO* pTileInfo, ///< [in] bank structure 1435 /// **All fields to be valid on entry** 1436 UINT_32* pBitPosition ///< [out] bit position, e.g. FMT_1 will use this 1437 ) const 1438 { 1439 UINT_64 addr; 1440 1441 UINT_32 microTileBytes; 1442 UINT_32 microTileBits; 1443 UINT_32 sampleOffset; 1444 UINT_32 pixelIndex; 1445 UINT_32 pixelOffset; 1446 UINT_32 elementOffset; 1447 UINT_32 tileSplitSlice; 1448 UINT_32 pipe; 1449 UINT_32 bank; 1450 UINT_64 sliceBytes; 1451 UINT_64 sliceOffset; 1452 UINT_32 macroTilePitch; 1453 UINT_32 macroTileHeight; 1454 UINT_32 macroTilesPerRow; 1455 UINT_32 macroTilesPerSlice; 1456 UINT_64 macroTileBytes; 1457 UINT_32 macroTileIndexX; 1458 UINT_32 macroTileIndexY; 1459 UINT_64 macroTileOffset; 1460 UINT_64 totalOffset; 1461 UINT_64 pipeInterleaveMask; 1462 UINT_64 bankInterleaveMask; 1463 UINT_64 pipeInterleaveOffset; 1464 UINT_32 bankInterleaveOffset; 1465 UINT_64 offset; 1466 UINT_32 tileRowIndex; 1467 UINT_32 tileColumnIndex; 1468 UINT_32 tileIndex; 1469 UINT_32 tileOffset; 1470 1471 UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode); 1472 1473 // 1474 // Compute the number of group, pipe, and bank bits. 1475 // 1476 UINT_32 numPipes = HwlGetPipes(pTileInfo); 1477 UINT_32 numPipeInterleaveBits = Log2(m_pipeInterleaveBytes); 1478 UINT_32 numPipeBits = Log2(numPipes); 1479 UINT_32 numBankInterleaveBits = Log2(m_bankInterleave); 1480 UINT_32 numBankBits = Log2(pTileInfo->banks); 1481 1482 // 1483 // Compute the micro tile size. 1484 // 1485 microTileBits = MicroTilePixels * microTileThickness * bpp * numSamples; 1486 1487 microTileBytes = microTileBits / 8; 1488 // 1489 // Compute the pixel index within the micro tile. 1490 // 1491 pixelIndex = ComputePixelIndexWithinMicroTile(x, 1492 y, 1493 slice, 1494 bpp, 1495 tileMode, 1496 microTileType); 1497 1498 // 1499 // Compute the sample offset and pixel offset. 1500 // 1501 if (isDepthSampleOrder) 1502 { 1503 // 1504 // For depth surfaces, samples are stored contiguously for each element, so the sample 1505 // offset is the sample number times the element size. 1506 // 1507 sampleOffset = sample * bpp; 1508 pixelOffset = pixelIndex * bpp * numSamples; 1509 } 1510 else 1511 { 1512 // 1513 // For color surfaces, all elements for a particular sample are stored contiguously, so 1514 // the sample offset is the sample number times the micro tile size divided yBit the number 1515 // of samples. 1516 // 1517 sampleOffset = sample * (microTileBits / numSamples); 1518 pixelOffset = pixelIndex * bpp; 1519 } 1520 1521 // 1522 // Compute the element offset. 1523 // 1524 elementOffset = pixelOffset + sampleOffset; 1525 1526 *pBitPosition = static_cast<UINT_32>(elementOffset % 8); 1527 1528 elementOffset /= 8; //bit-to-byte 1529 1530 // 1531 // Determine if tiles need to be split across slices. 1532 // 1533 // If the size of the micro tile is larger than the tile split size, then the tile will be 1534 // split across multiple slices. 1535 // 1536 UINT_32 slicesPerTile = 1; 1537 1538 if ((microTileBytes > pTileInfo->tileSplitBytes) && (microTileThickness == 1)) 1539 { //don't support for thick mode 1540 1541 // 1542 // Compute the number of slices per tile. 1543 // 1544 slicesPerTile = microTileBytes / pTileInfo->tileSplitBytes; 1545 1546 // 1547 // Compute the tile split slice number for use in rotating the bank. 1548 // 1549 tileSplitSlice = elementOffset / pTileInfo->tileSplitBytes; 1550 1551 // 1552 // Adjust the element offset to account for the portion of the tile that is being moved to 1553 // a new slice.. 1554 // 1555 elementOffset %= pTileInfo->tileSplitBytes; 1556 1557 // 1558 // Adjust the microTileBytes size to tileSplitBytes size since 1559 // a new slice.. 1560 // 1561 microTileBytes = pTileInfo->tileSplitBytes; 1562 } 1563 else 1564 { 1565 tileSplitSlice = 0; 1566 } 1567 1568 // 1569 // Compute macro tile pitch and height. 1570 // 1571 macroTilePitch = 1572 (MicroTileWidth * pTileInfo->bankWidth * numPipes) * pTileInfo->macroAspectRatio; 1573 macroTileHeight = 1574 (MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks) / pTileInfo->macroAspectRatio; 1575 1576 // 1577 // Compute the number of bytes per macro tile. Note: bytes of the same bank/pipe actually 1578 // 1579 macroTileBytes = 1580 static_cast<UINT_64>(microTileBytes) * 1581 (macroTilePitch / MicroTileWidth) * (macroTileHeight / MicroTileHeight) / 1582 (numPipes * pTileInfo->banks); 1583 1584 // 1585 // Compute the number of macro tiles per row. 1586 // 1587 macroTilesPerRow = pitch / macroTilePitch; 1588 1589 // 1590 // Compute the offset to the macro tile containing the specified coordinate. 1591 // 1592 macroTileIndexX = x / macroTilePitch; 1593 macroTileIndexY = y / macroTileHeight; 1594 macroTileOffset = ((macroTileIndexY * macroTilesPerRow) + macroTileIndexX) * macroTileBytes; 1595 1596 // 1597 // Compute the number of macro tiles per slice. 1598 // 1599 macroTilesPerSlice = macroTilesPerRow * (height / macroTileHeight); 1600 1601 // 1602 // Compute the slice size. 1603 // 1604 sliceBytes = macroTilesPerSlice * macroTileBytes; 1605 1606 // 1607 // Compute the slice offset. 1608 // 1609 sliceOffset = sliceBytes * (tileSplitSlice + slicesPerTile * (slice / microTileThickness)); 1610 1611 // 1612 // Compute tile offest 1613 // 1614 tileRowIndex = (y / MicroTileHeight) % pTileInfo->bankHeight; 1615 tileColumnIndex = ((x / MicroTileWidth) / numPipes) % pTileInfo->bankWidth; 1616 tileIndex = (tileRowIndex * pTileInfo->bankWidth) + tileColumnIndex; 1617 tileOffset = tileIndex * microTileBytes; 1618 1619 // 1620 // Combine the slice offset and macro tile offset with the pixel and sample offsets, accounting 1621 // for the pipe and bank bits in the middle of the address. 1622 // 1623 totalOffset = sliceOffset + macroTileOffset + elementOffset + tileOffset; 1624 1625 // 1626 // Get the pipe and bank. 1627 // 1628 1629 // when the tileMode is PRT type, then adjust x and y coordinates 1630 if (IsPrtNoRotationTileMode(tileMode)) 1631 { 1632 x = x % macroTilePitch; 1633 y = y % macroTileHeight; 1634 } 1635 1636 pipe = ComputePipeFromCoord(x, 1637 y, 1638 slice, 1639 tileMode, 1640 pipeSwizzle, 1641 ignoreSE, 1642 pTileInfo); 1643 1644 bank = ComputeBankFromCoord(x, 1645 y, 1646 slice, 1647 tileMode, 1648 bankSwizzle, 1649 tileSplitSlice, 1650 pTileInfo); 1651 1652 1653 // 1654 // Split the offset to put some bits below the pipe+bank bits and some above. 1655 // 1656 pipeInterleaveMask = (1 << numPipeInterleaveBits) - 1; 1657 bankInterleaveMask = (1 << numBankInterleaveBits) - 1; 1658 pipeInterleaveOffset = totalOffset & pipeInterleaveMask; 1659 bankInterleaveOffset = static_cast<UINT_32>((totalOffset >> numPipeInterleaveBits) & 1660 bankInterleaveMask); 1661 offset = totalOffset >> (numPipeInterleaveBits + numBankInterleaveBits); 1662 1663 // 1664 // Assemble the address from its components. 1665 // 1666 addr = pipeInterleaveOffset; 1667 // This is to remove /analyze warnings 1668 UINT_32 pipeBits = pipe << numPipeInterleaveBits; 1669 UINT_32 bankInterleaveBits = bankInterleaveOffset << (numPipeInterleaveBits + numPipeBits); 1670 UINT_32 bankBits = bank << (numPipeInterleaveBits + numPipeBits + 1671 numBankInterleaveBits); 1672 UINT_64 offsetBits = offset << (numPipeInterleaveBits + numPipeBits + 1673 numBankInterleaveBits + numBankBits); 1674 1675 addr |= pipeBits; 1676 addr |= bankInterleaveBits; 1677 addr |= bankBits; 1678 addr |= offsetBits; 1679 1680 return addr; 1681 } 1682 1683 /** 1684 *************************************************************************************************** 1685 * EgBasedAddrLib::ComputeSurfaceAddrFromCoordMicroTiled 1686 * 1687 * @brief 1688 * Computes the surface address and bit position from a coordinate for 1D tilied 1689 * (micro tiled) 1690 * @return 1691 * The byte address 1692 *************************************************************************************************** 1693 */ 1694 UINT_64 EgBasedAddrLib::ComputeSurfaceAddrFromCoordMicroTiled( 1695 UINT_32 x, ///< [in] x coordinate 1696 UINT_32 y, ///< [in] y coordinate 1697 UINT_32 slice, ///< [in] slice index 1698 UINT_32 sample, ///< [in] sample index 1699 UINT_32 bpp, ///< [in] bits per pixel 1700 UINT_32 pitch, ///< [in] pitch, in pixels 1701 UINT_32 height, ///< [in] height, in pixels 1702 UINT_32 numSamples, ///< [in] number of samples 1703 AddrTileMode tileMode, ///< [in] tile mode 1704 AddrTileType microTileType, ///< [in] micro tiling type 1705 BOOL_32 isDepthSampleOrder, ///< [in] TRUE if depth sample ordering is used 1706 UINT_32* pBitPosition ///< [out] bit position, e.g. FMT_1 will use this 1707 ) const 1708 { 1709 UINT_64 addr = 0; 1710 1711 UINT_32 microTileBytes; 1712 UINT_64 sliceBytes; 1713 UINT_32 microTilesPerRow; 1714 UINT_32 microTileIndexX; 1715 UINT_32 microTileIndexY; 1716 UINT_32 microTileIndexZ; 1717 UINT_64 sliceOffset; 1718 UINT_64 microTileOffset; 1719 UINT_32 sampleOffset; 1720 UINT_32 pixelIndex; 1721 UINT_32 pixelOffset; 1722 1723 UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode); 1724 1725 // 1726 // Compute the micro tile size. 1727 // 1728 microTileBytes = BITS_TO_BYTES(MicroTilePixels * microTileThickness * bpp * numSamples); 1729 1730 // 1731 // Compute the slice size. 1732 // 1733 sliceBytes = 1734 BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * microTileThickness * bpp * numSamples); 1735 1736 // 1737 // Compute the number of micro tiles per row. 1738 // 1739 microTilesPerRow = pitch / MicroTileWidth; 1740 1741 // 1742 // Compute the micro tile index. 1743 // 1744 microTileIndexX = x / MicroTileWidth; 1745 microTileIndexY = y / MicroTileHeight; 1746 microTileIndexZ = slice / microTileThickness; 1747 1748 // 1749 // Compute the slice offset. 1750 // 1751 sliceOffset = static_cast<UINT_64>(microTileIndexZ) * sliceBytes; 1752 1753 // 1754 // Compute the offset to the micro tile containing the specified coordinate. 1755 // 1756 microTileOffset = (static_cast<UINT_64>(microTileIndexY) * microTilesPerRow + microTileIndexX) * 1757 microTileBytes; 1758 1759 // 1760 // Compute the pixel index within the micro tile. 1761 // 1762 pixelIndex = ComputePixelIndexWithinMicroTile(x, 1763 y, 1764 slice, 1765 bpp, 1766 tileMode, 1767 microTileType); 1768 1769 // Compute the sample offset. 1770 // 1771 if (isDepthSampleOrder) 1772 { 1773 // 1774 // For depth surfaces, samples are stored contiguously for each element, so the sample 1775 // offset is the sample number times the element size. 1776 // 1777 sampleOffset = sample * bpp; 1778 pixelOffset = pixelIndex * bpp * numSamples; 1779 } 1780 else 1781 { 1782 // 1783 // For color surfaces, all elements for a particular sample are stored contiguously, so 1784 // the sample offset is the sample number times the micro tile size divided yBit the number 1785 // of samples. 1786 // 1787 sampleOffset = sample * (microTileBytes*8 / numSamples); 1788 pixelOffset = pixelIndex * bpp; 1789 } 1790 1791 // 1792 // Compute the bit position of the pixel. Each element is stored with one bit per sample. 1793 // 1794 1795 UINT_32 elemOffset = sampleOffset + pixelOffset; 1796 1797 *pBitPosition = elemOffset % 8; 1798 elemOffset /= 8; 1799 1800 // 1801 // Combine the slice offset, micro tile offset, sample offset, and pixel offsets. 1802 // 1803 addr = sliceOffset + microTileOffset + elemOffset; 1804 1805 return addr; 1806 } 1807 1808 /** 1809 *************************************************************************************************** 1810 * EgBasedAddrLib::HwlComputePixelCoordFromOffset 1811 * 1812 * @brief 1813 * Compute pixel coordinate from offset inside a micro tile 1814 * @return 1815 * N/A 1816 *************************************************************************************************** 1817 */ 1818 VOID EgBasedAddrLib::HwlComputePixelCoordFromOffset( 1819 UINT_32 offset, ///< [in] offset inside micro tile in bits 1820 UINT_32 bpp, ///< [in] bits per pixel 1821 UINT_32 numSamples, ///< [in] number of samples 1822 AddrTileMode tileMode, ///< [in] tile mode 1823 UINT_32 tileBase, ///< [in] base offset within a tile 1824 UINT_32 compBits, ///< [in] component bits actually needed(for planar surface) 1825 UINT_32* pX, ///< [out] x coordinate 1826 UINT_32* pY, ///< [out] y coordinate 1827 UINT_32* pSlice, ///< [out] slice index 1828 UINT_32* pSample, ///< [out] sample index 1829 AddrTileType microTileType, ///< [in] micro tiling type 1830 BOOL_32 isDepthSampleOrder ///< [in] TRUE if depth sample order in microtile is used 1831 ) const 1832 { 1833 UINT_32 x = 0; 1834 UINT_32 y = 0; 1835 UINT_32 z = 0; 1836 UINT_32 thickness = ComputeSurfaceThickness(tileMode); 1837 1838 // For planar surface, we adjust offset acoording to tile base 1839 if ((bpp != compBits) && (compBits != 0) && isDepthSampleOrder) 1840 { 1841 offset -= tileBase; 1842 1843 ADDR_ASSERT(microTileType == ADDR_NON_DISPLAYABLE || 1844 microTileType == ADDR_DEPTH_SAMPLE_ORDER); 1845 1846 bpp = compBits; 1847 } 1848 1849 UINT_32 sampleTileBits; 1850 UINT_32 samplePixelBits; 1851 UINT_32 pixelIndex; 1852 1853 if (isDepthSampleOrder) 1854 { 1855 samplePixelBits = bpp * numSamples; 1856 pixelIndex = offset / samplePixelBits; 1857 *pSample = (offset % samplePixelBits) / bpp; 1858 } 1859 else 1860 { 1861 sampleTileBits = MicroTilePixels * bpp * thickness; 1862 *pSample = offset / sampleTileBits; 1863 pixelIndex = (offset % sampleTileBits) / bpp; 1864 } 1865 1866 if (microTileType != ADDR_THICK) 1867 { 1868 if (microTileType == ADDR_DISPLAYABLE) // displayable 1869 { 1870 switch (bpp) 1871 { 1872 case 8: 1873 x = pixelIndex & 0x7; 1874 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,4)); 1875 break; 1876 case 16: 1877 x = pixelIndex & 0x7; 1878 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,3)); 1879 break; 1880 case 32: 1881 x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,1),_BIT(pixelIndex,0)); 1882 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,2)); 1883 break; 1884 case 64: 1885 x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,2),_BIT(pixelIndex,0)); 1886 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,1)); 1887 break; 1888 case 128: 1889 x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,2),_BIT(pixelIndex,1)); 1890 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,0)); 1891 break; 1892 default: 1893 break; 1894 } 1895 } 1896 else if (microTileType == ADDR_NON_DISPLAYABLE || microTileType == ADDR_DEPTH_SAMPLE_ORDER) 1897 { 1898 x = Bits2Number(3, _BIT(pixelIndex,4),_BIT(pixelIndex,2),_BIT(pixelIndex,0)); 1899 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,1)); 1900 } 1901 else if (microTileType == ADDR_ROTATED) 1902 { 1903 /* 1904 8-Bit Elements 1905 element_index[5:0] = { x[2], x[0], x[1], y[2], y[1], y[0] } 1906 1907 16-Bit Elements 1908 element_index[5:0] = { x[2], x[1], x[0], y[2], y[1], y[0] } 1909 1910 32-Bit Elements 1911 element_index[5:0] = { x[2], x[1], y[2], x[0], y[1], y[0] } 1912 1913 64-Bit Elements 1914 element_index[5:0] = { y[2], x[2], x[1], y[1], x[0], y[0] } 1915 */ 1916 switch(bpp) 1917 { 1918 case 8: 1919 x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,4)); 1920 y = pixelIndex & 0x7; 1921 break; 1922 case 16: 1923 x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,3)); 1924 y = pixelIndex & 0x7; 1925 break; 1926 case 32: 1927 x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,2)); 1928 y = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,1),_BIT(pixelIndex,0)); 1929 break; 1930 case 64: 1931 x = Bits2Number(3, _BIT(pixelIndex,4),_BIT(pixelIndex,3),_BIT(pixelIndex,1)); 1932 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,2),_BIT(pixelIndex,0)); 1933 break; 1934 default: 1935 ADDR_ASSERT_ALWAYS(); 1936 break; 1937 } 1938 } 1939 1940 if (thickness > 1) // thick 1941 { 1942 z = Bits2Number(3, _BIT(pixelIndex,8),_BIT(pixelIndex,7),_BIT(pixelIndex,6)); 1943 } 1944 } 1945 else 1946 { 1947 ADDR_ASSERT((m_chipFamily >= ADDR_CHIP_FAMILY_CI) && (thickness > 1)); 1948 /* 1949 8-Bit Elements and 16-Bit Elements 1950 element_index[7:0] = { y[2], x[2], z[1], z[0], y[1], x[1], y[0], x[0] } 1951 1952 32-Bit Elements 1953 element_index[7:0] = { y[2], x[2], z[1], y[1], z[0], x[1], y[0], x[0] } 1954 1955 64-Bit Elements and 128-Bit Elements 1956 element_index[7:0] = { y[2], x[2], z[1], y[1], x[1], z[0], y[0], x[0] } 1957 1958 The equation to compute the element index for the extra thick tile: 1959 element_index[8] = z[2] 1960 */ 1961 switch (bpp) 1962 { 1963 case 8: 1964 case 16: // fall-through 1965 x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,2),_BIT(pixelIndex,0)); 1966 y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,3),_BIT(pixelIndex,1)); 1967 z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,4)); 1968 break; 1969 case 32: 1970 x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,2),_BIT(pixelIndex,0)); 1971 y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,4),_BIT(pixelIndex,1)); 1972 z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,3)); 1973 break; 1974 case 64: 1975 case 128: // fall-through 1976 x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,3),_BIT(pixelIndex,0)); 1977 y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,4),_BIT(pixelIndex,1)); 1978 z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,2)); 1979 break; 1980 default: 1981 ADDR_ASSERT_ALWAYS(); 1982 break; 1983 } 1984 1985 if (thickness == 8) 1986 { 1987 z += Bits2Number(3,_BIT(pixelIndex,8),0,0); 1988 } 1989 } 1990 1991 *pX = x; 1992 *pY = y; 1993 *pSlice += z; 1994 } 1995 1996 1997 /** 1998 *************************************************************************************************** 1999 * EgBasedAddrLib::DispatchComputeSurfaceCoordFromAddrDispatch 2000 * 2001 * @brief 2002 * Compute (x,y,slice,sample) coordinates from surface address 2003 * @return 2004 * N/A 2005 *************************************************************************************************** 2006 */ 2007 VOID EgBasedAddrLib::DispatchComputeSurfaceCoordFromAddr( 2008 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure 2009 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure 2010 ) const 2011 { 2012 UINT_64 addr = pIn->addr; 2013 UINT_32 bitPosition = pIn->bitPosition; 2014 UINT_32 bpp = pIn->bpp; 2015 UINT_32 pitch = pIn->pitch; 2016 UINT_32 height = pIn->height; 2017 UINT_32 numSlices = pIn->numSlices; 2018 UINT_32 numSamples = ((pIn->numSamples == 0) ? 1 : pIn->numSamples); 2019 UINT_32 numFrags = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags); 2020 AddrTileMode tileMode = pIn->tileMode; 2021 UINT_32 tileBase = pIn->tileBase; 2022 UINT_32 compBits = pIn->compBits; 2023 AddrTileType microTileType = pIn->tileType; 2024 BOOL_32 ignoreSE = pIn->ignoreSE; 2025 BOOL_32 isDepthSampleOrder = pIn->isDepth; 2026 ADDR_TILEINFO* pTileInfo = pIn->pTileInfo; 2027 2028 UINT_32* pX = &pOut->x; 2029 UINT_32* pY = &pOut->y; 2030 UINT_32* pSlice = &pOut->slice; 2031 UINT_32* pSample = &pOut->sample; 2032 2033 if (microTileType == ADDR_DEPTH_SAMPLE_ORDER) 2034 { 2035 isDepthSampleOrder = TRUE; 2036 } 2037 2038 if (m_chipFamily >= ADDR_CHIP_FAMILY_NI) 2039 { 2040 if (numFrags != numSamples) 2041 { 2042 numSamples = numFrags; 2043 } 2044 2045 /// @note 2046 /// 128 bit/thick tiled surface doesn't support display tiling and 2047 /// mipmap chain must have the same tileType, so please fill tileType correctly 2048 if (!IsLinear(pIn->tileMode)) 2049 { 2050 if (bpp >= 128 || ComputeSurfaceThickness(tileMode) > 1) 2051 { 2052 ADDR_ASSERT(microTileType != ADDR_DISPLAYABLE); 2053 } 2054 } 2055 } 2056 2057 switch (tileMode) 2058 { 2059 case ADDR_TM_LINEAR_GENERAL://fall through 2060 case ADDR_TM_LINEAR_ALIGNED: 2061 ComputeSurfaceCoordFromAddrLinear(addr, 2062 bitPosition, 2063 bpp, 2064 pitch, 2065 height, 2066 numSlices, 2067 pX, 2068 pY, 2069 pSlice, 2070 pSample); 2071 break; 2072 case ADDR_TM_1D_TILED_THIN1://fall through 2073 case ADDR_TM_1D_TILED_THICK: 2074 ComputeSurfaceCoordFromAddrMicroTiled(addr, 2075 bitPosition, 2076 bpp, 2077 pitch, 2078 height, 2079 numSamples, 2080 tileMode, 2081 tileBase, 2082 compBits, 2083 pX, 2084 pY, 2085 pSlice, 2086 pSample, 2087 microTileType, 2088 isDepthSampleOrder); 2089 break; 2090 case ADDR_TM_2D_TILED_THIN1: //fall through 2091 case ADDR_TM_2D_TILED_THICK: //fall through 2092 case ADDR_TM_3D_TILED_THIN1: //fall through 2093 case ADDR_TM_3D_TILED_THICK: //fall through 2094 case ADDR_TM_2D_TILED_XTHICK: //fall through 2095 case ADDR_TM_3D_TILED_XTHICK: //fall through 2096 case ADDR_TM_PRT_TILED_THIN1: //fall through 2097 case ADDR_TM_PRT_2D_TILED_THIN1://fall through 2098 case ADDR_TM_PRT_3D_TILED_THIN1://fall through 2099 case ADDR_TM_PRT_TILED_THICK: //fall through 2100 case ADDR_TM_PRT_2D_TILED_THICK://fall through 2101 case ADDR_TM_PRT_3D_TILED_THICK: 2102 UINT_32 pipeSwizzle; 2103 UINT_32 bankSwizzle; 2104 2105 if (m_configFlags.useCombinedSwizzle) 2106 { 2107 ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo, 2108 &bankSwizzle, &pipeSwizzle); 2109 } 2110 else 2111 { 2112 pipeSwizzle = pIn->pipeSwizzle; 2113 bankSwizzle = pIn->bankSwizzle; 2114 } 2115 2116 ComputeSurfaceCoordFromAddrMacroTiled(addr, 2117 bitPosition, 2118 bpp, 2119 pitch, 2120 height, 2121 numSamples, 2122 tileMode, 2123 tileBase, 2124 compBits, 2125 microTileType, 2126 ignoreSE, 2127 isDepthSampleOrder, 2128 pipeSwizzle, 2129 bankSwizzle, 2130 pTileInfo, 2131 pX, 2132 pY, 2133 pSlice, 2134 pSample); 2135 break; 2136 default: 2137 ADDR_ASSERT_ALWAYS(); 2138 } 2139 } 2140 2141 2142 /** 2143 *************************************************************************************************** 2144 * EgBasedAddrLib::ComputeSurfaceCoordFromAddrMacroTiled 2145 * 2146 * @brief 2147 * Compute surface coordinates from address for macro tiled surface 2148 * @return 2149 * N/A 2150 *************************************************************************************************** 2151 */ 2152 VOID EgBasedAddrLib::ComputeSurfaceCoordFromAddrMacroTiled( 2153 UINT_64 addr, ///< [in] byte address 2154 UINT_32 bitPosition, ///< [in] bit position 2155 UINT_32 bpp, ///< [in] bits per pixel 2156 UINT_32 pitch, ///< [in] pitch in pixels 2157 UINT_32 height, ///< [in] height in pixels 2158 UINT_32 numSamples, ///< [in] number of samples 2159 AddrTileMode tileMode, ///< [in] tile mode 2160 UINT_32 tileBase, ///< [in] tile base offset 2161 UINT_32 compBits, ///< [in] component bits (for planar surface) 2162 AddrTileType microTileType, ///< [in] micro tiling type 2163 BOOL_32 ignoreSE, ///< [in] TRUE if shader engines can be ignored 2164 BOOL_32 isDepthSampleOrder, ///< [in] TRUE if depth sample order is used 2165 UINT_32 pipeSwizzle, ///< [in] pipe swizzle 2166 UINT_32 bankSwizzle, ///< [in] bank swizzle 2167 ADDR_TILEINFO* pTileInfo, ///< [in] bank structure. 2168 /// **All fields to be valid on entry** 2169 UINT_32* pX, ///< [out] X coord 2170 UINT_32* pY, ///< [out] Y coord 2171 UINT_32* pSlice, ///< [out] slice index 2172 UINT_32* pSample ///< [out] sample index 2173 ) const 2174 { 2175 UINT_32 mx; 2176 UINT_32 my; 2177 UINT_64 tileBits; 2178 UINT_64 macroTileBits; 2179 UINT_32 slices; 2180 UINT_32 tileSlices; 2181 UINT_64 elementOffset; 2182 UINT_64 macroTileIndex; 2183 UINT_32 tileIndex; 2184 UINT_64 totalOffset; 2185 2186 2187 UINT_32 bank; 2188 UINT_32 pipe; 2189 UINT_32 groupBits = m_pipeInterleaveBytes << 3; 2190 UINT_32 pipes = HwlGetPipes(pTileInfo); 2191 UINT_32 banks = pTileInfo->banks; 2192 2193 UINT_32 bankInterleave = m_bankInterleave; 2194 2195 UINT_64 addrBits = BYTES_TO_BITS(addr) + bitPosition; 2196 2197 // 2198 // remove bits for bank and pipe 2199 // 2200 totalOffset = (addrBits % groupBits) + 2201 (((addrBits / groupBits / pipes) % bankInterleave) * groupBits) + 2202 (((addrBits / groupBits / pipes) / bankInterleave) / banks) * groupBits * bankInterleave; 2203 2204 UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode); 2205 2206 UINT_32 microTileBits = bpp * microTileThickness * MicroTilePixels * numSamples; 2207 2208 UINT_32 microTileBytes = BITS_TO_BYTES(microTileBits); 2209 // 2210 // Determine if tiles need to be split across slices. 2211 // 2212 // If the size of the micro tile is larger than the tile split size, then the tile will be 2213 // split across multiple slices. 2214 // 2215 UINT_32 slicesPerTile = 1; //_State->TileSlices 2216 2217 if ((microTileBytes > pTileInfo->tileSplitBytes) && (microTileThickness == 1)) 2218 { //don't support for thick mode 2219 2220 // 2221 // Compute the number of slices per tile. 2222 // 2223 slicesPerTile = microTileBytes / pTileInfo->tileSplitBytes; 2224 } 2225 2226 tileBits = microTileBits / slicesPerTile; // micro tile bits 2227 2228 // in micro tiles because not MicroTileWidth timed. 2229 UINT_32 macroWidth = pTileInfo->bankWidth * pipes * pTileInfo->macroAspectRatio; 2230 // in micro tiles as well 2231 UINT_32 macroHeight = pTileInfo->bankHeight * banks / pTileInfo->macroAspectRatio; 2232 2233 UINT_32 pitchInMacroTiles = pitch / MicroTileWidth / macroWidth; 2234 2235 macroTileBits = (macroWidth * macroHeight) * tileBits / (banks * pipes); 2236 2237 macroTileIndex = totalOffset / macroTileBits; 2238 2239 // pitchMacros * height / heightMacros; macroTilesPerSlice == _State->SliceMacros 2240 UINT_32 macroTilesPerSlice = (pitch / (macroWidth * MicroTileWidth)) * height / 2241 (macroHeight * MicroTileWidth); 2242 2243 slices = static_cast<UINT_32>(macroTileIndex / macroTilesPerSlice); 2244 2245 *pSlice = static_cast<UINT_32>(slices / slicesPerTile * microTileThickness); 2246 2247 // 2248 // calculate element offset and x[2:0], y[2:0], z[1:0] for thick 2249 // 2250 tileSlices = slices % slicesPerTile; 2251 2252 elementOffset = tileSlices * tileBits; 2253 elementOffset += totalOffset % tileBits; 2254 2255 UINT_32 coordZ = 0; 2256 2257 HwlComputePixelCoordFromOffset(static_cast<UINT_32>(elementOffset), 2258 bpp, 2259 numSamples, 2260 tileMode, 2261 tileBase, 2262 compBits, 2263 pX, 2264 pY, 2265 &coordZ, 2266 pSample, 2267 microTileType, 2268 isDepthSampleOrder); 2269 2270 macroTileIndex = macroTileIndex % macroTilesPerSlice; 2271 *pY += static_cast<UINT_32>(macroTileIndex / pitchInMacroTiles * macroHeight * MicroTileHeight); 2272 *pX += static_cast<UINT_32>(macroTileIndex % pitchInMacroTiles * macroWidth * MicroTileWidth); 2273 2274 *pSlice += coordZ; 2275 2276 tileIndex = static_cast<UINT_32>((totalOffset % macroTileBits) / tileBits); 2277 2278 my = (tileIndex / pTileInfo->bankWidth) % pTileInfo->bankHeight * MicroTileHeight; 2279 mx = (tileIndex % pTileInfo->bankWidth) * pipes * MicroTileWidth; 2280 2281 *pY += my; 2282 *pX += mx; 2283 2284 bank = ComputeBankFromAddr(addr, banks, pipes); 2285 pipe = ComputePipeFromAddr(addr, pipes); 2286 2287 HwlComputeSurfaceCoord2DFromBankPipe(tileMode, 2288 pX, 2289 pY, 2290 *pSlice, 2291 bank, 2292 pipe, 2293 bankSwizzle, 2294 pipeSwizzle, 2295 tileSlices, 2296 ignoreSE, 2297 pTileInfo); 2298 } 2299 2300 /** 2301 *************************************************************************************************** 2302 * EgBasedAddrLib::ComputeSurfaceCoord2DFromBankPipe 2303 * 2304 * @brief 2305 * Compute surface x,y coordinates from bank/pipe info 2306 * @return 2307 * N/A 2308 *************************************************************************************************** 2309 */ 2310 VOID EgBasedAddrLib::ComputeSurfaceCoord2DFromBankPipe( 2311 AddrTileMode tileMode, ///< [in] tile mode 2312 UINT_32 x, ///< [in] x coordinate 2313 UINT_32 y, ///< [in] y coordinate 2314 UINT_32 slice, ///< [in] slice index 2315 UINT_32 bank, ///< [in] bank number 2316 UINT_32 pipe, ///< [in] pipe number 2317 UINT_32 bankSwizzle,///< [in] bank swizzle 2318 UINT_32 pipeSwizzle,///< [in] pipe swizzle 2319 UINT_32 tileSlices, ///< [in] slices in a micro tile 2320 ADDR_TILEINFO* pTileInfo, ///< [in] bank structure. **All fields to be valid on entry** 2321 CoordFromBankPipe* pOutput ///< [out] pointer to extracted x/y bits 2322 ) const 2323 { 2324 UINT_32 yBit3 = 0; 2325 UINT_32 yBit4 = 0; 2326 UINT_32 yBit5 = 0; 2327 UINT_32 yBit6 = 0; 2328 2329 UINT_32 xBit3 = 0; 2330 UINT_32 xBit4 = 0; 2331 UINT_32 xBit5 = 0; 2332 2333 UINT_32 tileSplitRotation; 2334 2335 UINT_32 numPipes = HwlGetPipes(pTileInfo); 2336 2337 UINT_32 bankRotation = ComputeBankRotation(tileMode, 2338 pTileInfo->banks, numPipes); 2339 2340 UINT_32 pipeRotation = ComputePipeRotation(tileMode, numPipes); 2341 2342 UINT_32 xBit = x / (MicroTileWidth * pTileInfo->bankWidth * numPipes); 2343 UINT_32 yBit = y / (MicroTileHeight * pTileInfo->bankHeight); 2344 2345 //calculate the bank and pipe before rotation and swizzle 2346 2347 switch (tileMode) 2348 { 2349 case ADDR_TM_2D_TILED_THIN1: //fall through 2350 case ADDR_TM_2D_TILED_THICK: //fall through 2351 case ADDR_TM_2D_TILED_XTHICK: //fall through 2352 case ADDR_TM_3D_TILED_THIN1: //fall through 2353 case ADDR_TM_3D_TILED_THICK: //fall through 2354 case ADDR_TM_3D_TILED_XTHICK: 2355 tileSplitRotation = ((pTileInfo->banks / 2) + 1); 2356 break; 2357 default: 2358 tileSplitRotation = 0; 2359 break; 2360 } 2361 2362 UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode); 2363 2364 bank ^= tileSplitRotation * tileSlices; 2365 if (pipeRotation == 0) 2366 { 2367 bank ^= bankRotation * (slice / microTileThickness) + bankSwizzle; 2368 bank %= pTileInfo->banks; 2369 pipe ^= pipeSwizzle; 2370 } 2371 else 2372 { 2373 bank ^= bankRotation * (slice / microTileThickness) / numPipes + bankSwizzle; 2374 bank %= pTileInfo->banks; 2375 pipe ^= pipeRotation * (slice / microTileThickness) + pipeSwizzle; 2376 } 2377 2378 if (pTileInfo->macroAspectRatio == 1) 2379 { 2380 switch (pTileInfo->banks) 2381 { 2382 case 2: 2383 yBit3 = _BIT(bank, 0) ^ _BIT(xBit,0); 2384 break; 2385 case 4: 2386 yBit4 = _BIT(bank, 0) ^ _BIT(xBit,0); 2387 yBit3 = _BIT(bank, 1) ^ _BIT(xBit,1); 2388 break; 2389 case 8: 2390 yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2); 2391 yBit5 = _BIT(bank, 0) ^ _BIT(xBit,0); 2392 yBit4 = _BIT(bank, 1) ^ _BIT(xBit,1) ^ yBit5; 2393 break; 2394 case 16: 2395 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); 2396 yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2); 2397 yBit6 = _BIT(bank, 0) ^ _BIT(xBit, 0); 2398 yBit5 = _BIT(bank, 1) ^ _BIT(xBit, 1) ^ yBit6; 2399 break; 2400 default: 2401 break; 2402 } 2403 2404 } 2405 else if (pTileInfo->macroAspectRatio == 2) 2406 { 2407 switch (pTileInfo->banks) 2408 { 2409 case 2: //xBit3 = yBit3^b0 2410 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,0); 2411 break; 2412 case 4: //xBit3=yBit4^b0; yBit3=xBit4^b1 2413 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,1); 2414 yBit3 = _BIT(bank, 1) ^ _BIT(xBit,1); 2415 break; 2416 case 8: //xBit4, xBit5, yBit5 are known 2417 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2); 2418 yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2); 2419 yBit4 = _BIT(bank, 1) ^ _BIT(xBit,1) ^ _BIT(yBit, 2); 2420 break; 2421 case 16://x4,x5,x6,y6 are known 2422 xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3); //x3 = y6 ^ b0 2423 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = x6 ^ b3 2424 yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2); //y4 = x5 ^ b2 2425 yBit5 = _BIT(bank, 1) ^ _BIT(xBit, 1) ^ _BIT(yBit, 3); //y5=x4^y6^b1 2426 break; 2427 default: 2428 break; 2429 } 2430 } 2431 else if (pTileInfo->macroAspectRatio == 4) 2432 { 2433 switch (pTileInfo->banks) 2434 { 2435 case 4: //yBit3, yBit4 2436 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,1); 2437 xBit4 = _BIT(bank, 1) ^ _BIT(yBit,0); 2438 break; 2439 case 8: //xBit5, yBit4, yBit5 2440 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2); 2441 yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2); 2442 xBit4 = _BIT(bank, 1) ^ _BIT(yBit,1) ^ _BIT(yBit,2); 2443 break; 2444 case 16: //xBit5, xBit6, yBit5, yBit6 2445 xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3);//x3 = b0 ^ y6 2446 xBit4 = _BIT(bank, 1) ^ _BIT(yBit, 2) ^ _BIT(yBit, 3);//x4 = b1 ^ y5 ^ y6; 2447 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = b3 ^ x6; 2448 yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2); //y4 = b2 ^ x5; 2449 break; 2450 default: 2451 break; 2452 } 2453 } 2454 else if (pTileInfo->macroAspectRatio == 8) 2455 { 2456 switch (pTileInfo->banks) 2457 { 2458 case 8: //yBit3, yBit4, yBit5 2459 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2); //x3 = b0 ^ y5; 2460 xBit4 = _BIT(bank, 1) ^ _BIT(yBit,1) ^ _BIT(yBit, 2);//x4 = b1 ^ y4 ^ y5; 2461 xBit5 = _BIT(bank, 2) ^ _BIT(yBit,0); 2462 break; 2463 case 16: //xBit6, yBit4, yBit5, yBit6 2464 xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3);//x3 = y6 ^ b0 2465 xBit4 = _BIT(bank, 1) ^ _BIT(yBit, 2) ^ _BIT(yBit, 3);//x4 = y5 ^ y6 ^ b1 2466 xBit5 = _BIT(bank, 2) ^ _BIT(yBit, 1);//x5 = y4 ^ b2 2467 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = x6 ^ b3 2468 break; 2469 default: 2470 break; 2471 } 2472 } 2473 2474 pOutput->xBits = xBit; 2475 pOutput->yBits = yBit; 2476 2477 pOutput->xBit3 = xBit3; 2478 pOutput->xBit4 = xBit4; 2479 pOutput->xBit5 = xBit5; 2480 pOutput->yBit3 = yBit3; 2481 pOutput->yBit4 = yBit4; 2482 pOutput->yBit5 = yBit5; 2483 pOutput->yBit6 = yBit6; 2484 } 2485 2486 /** 2487 *************************************************************************************************** 2488 * EgBasedAddrLib::HwlExtractBankPipeSwizzle 2489 * @brief 2490 * Entry of EgBasedAddrLib ExtractBankPipeSwizzle 2491 * @return 2492 * ADDR_E_RETURNCODE 2493 *************************************************************************************************** 2494 */ 2495 ADDR_E_RETURNCODE EgBasedAddrLib::HwlExtractBankPipeSwizzle( 2496 const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT* pIn, ///< [in] input structure 2497 ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT* pOut ///< [out] output structure 2498 ) const 2499 { 2500 ExtractBankPipeSwizzle(pIn->base256b, 2501 pIn->pTileInfo, 2502 &pOut->bankSwizzle, 2503 &pOut->pipeSwizzle); 2504 2505 return ADDR_OK; 2506 } 2507 2508 2509 /** 2510 *************************************************************************************************** 2511 * EgBasedAddrLib::HwlCombineBankPipeSwizzle 2512 * @brief 2513 * Combine bank/pipe swizzle 2514 * @return 2515 * ADDR_E_RETURNCODE 2516 *************************************************************************************************** 2517 */ 2518 ADDR_E_RETURNCODE EgBasedAddrLib::HwlCombineBankPipeSwizzle( 2519 UINT_32 bankSwizzle, ///< [in] bank swizzle 2520 UINT_32 pipeSwizzle, ///< [in] pipe swizzle 2521 ADDR_TILEINFO* pTileInfo, ///< [in] tile info 2522 UINT_64 baseAddr, ///< [in] base address 2523 UINT_32* pTileSwizzle ///< [out] combined swizzle 2524 ) const 2525 { 2526 ADDR_E_RETURNCODE retCode = ADDR_OK; 2527 2528 if (pTileSwizzle) 2529 { 2530 *pTileSwizzle = GetBankPipeSwizzle(bankSwizzle, pipeSwizzle, baseAddr, pTileInfo); 2531 } 2532 else 2533 { 2534 retCode = ADDR_INVALIDPARAMS; 2535 } 2536 2537 return retCode; 2538 } 2539 2540 /** 2541 *************************************************************************************************** 2542 * EgBasedAddrLib::HwlComputeBaseSwizzle 2543 * @brief 2544 * Compute base swizzle 2545 * @return 2546 * ADDR_E_RETURNCODE 2547 *************************************************************************************************** 2548 */ 2549 ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeBaseSwizzle( 2550 const ADDR_COMPUTE_BASE_SWIZZLE_INPUT* pIn, 2551 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT* pOut 2552 ) const 2553 { 2554 UINT_32 bankSwizzle = 0; 2555 UINT_32 pipeSwizzle = 0; 2556 ADDR_TILEINFO* pTileInfo = pIn->pTileInfo; 2557 2558 ADDR_ASSERT(IsMacroTiled(pIn->tileMode)); 2559 ADDR_ASSERT(pIn->pTileInfo); 2560 2561 /// This is a legacy misreading of h/w doc, use it as it doesn't hurt. 2562 static const UINT_8 bankRotationArray[4][16] = { 2563 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_2_BANK 2564 { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_4_BANK 2565 { 0, 3, 6, 1, 4, 7, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_8_BANK 2566 { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }, // ADDR_SURF_16_BANK 2567 }; 2568 2569 UINT_32 banks = pTileInfo ? pTileInfo->banks : 2; 2570 UINT_32 hwNumBanks; 2571 2572 // Uses less bank swizzle bits 2573 if (pIn->option.reduceBankBit && banks > 2) 2574 { 2575 banks >>= 1; 2576 } 2577 2578 switch (banks) 2579 { 2580 case 2: 2581 hwNumBanks = 0; 2582 break; 2583 case 4: 2584 hwNumBanks = 1; 2585 break; 2586 case 8: 2587 hwNumBanks = 2; 2588 break; 2589 case 16: 2590 hwNumBanks = 3; 2591 break; 2592 default: 2593 ADDR_ASSERT_ALWAYS(); 2594 hwNumBanks = 0; 2595 break; 2596 } 2597 2598 if (pIn->option.genOption == ADDR_SWIZZLE_GEN_LINEAR) 2599 { 2600 bankSwizzle = pIn->surfIndex & (banks - 1); 2601 } 2602 else // (pIn->option.genOption == ADDR_SWIZZLE_GEN_DEFAULT) 2603 { 2604 bankSwizzle = bankRotationArray[hwNumBanks][pIn->surfIndex & (banks - 1)]; 2605 } 2606 2607 if (IsMacro3dTiled(pIn->tileMode)) 2608 { 2609 pipeSwizzle = pIn->surfIndex & (HwlGetPipes(pTileInfo) - 1); 2610 } 2611 2612 return HwlCombineBankPipeSwizzle(bankSwizzle, pipeSwizzle, pTileInfo, 0, &pOut->tileSwizzle); 2613 } 2614 2615 /** 2616 *************************************************************************************************** 2617 * EgBasedAddrLib::ExtractBankPipeSwizzle 2618 * @brief 2619 * Extract bank/pipe swizzle from base256b 2620 * @return 2621 * N/A 2622 *************************************************************************************************** 2623 */ 2624 VOID EgBasedAddrLib::ExtractBankPipeSwizzle( 2625 UINT_32 base256b, ///< [in] input base256b register value 2626 ADDR_TILEINFO* pTileInfo, ///< [in] 2D tile parameters. Client must provide all data 2627 UINT_32* pBankSwizzle, ///< [out] bank swizzle 2628 UINT_32* pPipeSwizzle ///< [out] pipe swizzle 2629 ) const 2630 { 2631 UINT_32 bankSwizzle = 0; 2632 UINT_32 pipeSwizzle = 0; 2633 2634 if (base256b != 0) 2635 { 2636 UINT_32 numPipes = HwlGetPipes(pTileInfo); 2637 UINT_32 bankBits = QLog2(pTileInfo->banks); 2638 UINT_32 pipeBits = QLog2(numPipes); 2639 UINT_32 groupBytes = m_pipeInterleaveBytes; 2640 UINT_32 bankInterleave = m_bankInterleave; 2641 2642 pipeSwizzle = 2643 (base256b / (groupBytes >> 8)) & ((1<<pipeBits)-1); 2644 2645 bankSwizzle = 2646 (base256b / (groupBytes >> 8) / numPipes / bankInterleave) & ((1 << bankBits) - 1); 2647 } 2648 2649 *pPipeSwizzle = pipeSwizzle; 2650 *pBankSwizzle = bankSwizzle; 2651 } 2652 2653 /** 2654 *************************************************************************************************** 2655 * EgBasedAddrLib::GetBankPipeSwizzle 2656 * @brief 2657 * Combine bank/pipe swizzle 2658 * @return 2659 * Base256b bits (only filled bank/pipe bits) 2660 *************************************************************************************************** 2661 */ 2662 UINT_32 EgBasedAddrLib::GetBankPipeSwizzle( 2663 UINT_32 bankSwizzle, ///< [in] bank swizzle 2664 UINT_32 pipeSwizzle, ///< [in] pipe swizzle 2665 UINT_64 baseAddr, ///< [in] base address 2666 ADDR_TILEINFO* pTileInfo ///< [in] tile info 2667 ) const 2668 { 2669 UINT_32 pipeBits = QLog2(HwlGetPipes(pTileInfo)); 2670 UINT_32 bankInterleaveBits = QLog2(m_bankInterleave); 2671 UINT_32 tileSwizzle = pipeSwizzle + ((bankSwizzle << bankInterleaveBits) << pipeBits); 2672 2673 baseAddr ^= tileSwizzle * m_pipeInterleaveBytes; 2674 baseAddr >>= 8; 2675 2676 return static_cast<UINT_32>(baseAddr); 2677 } 2678 2679 /** 2680 *************************************************************************************************** 2681 * EgBasedAddrLib::ComputeSliceTileSwizzle 2682 * @brief 2683 * Compute cubemap/3d texture faces/slices tile swizzle 2684 * @return 2685 * Tile swizzle 2686 *************************************************************************************************** 2687 */ 2688 UINT_32 EgBasedAddrLib::ComputeSliceTileSwizzle( 2689 AddrTileMode tileMode, ///< [in] Tile mode 2690 UINT_32 baseSwizzle, ///< [in] Base swizzle 2691 UINT_32 slice, ///< [in] Slice index, Cubemap face index, 0 means +X 2692 UINT_64 baseAddr, ///< [in] Base address 2693 ADDR_TILEINFO* pTileInfo ///< [in] Bank structure 2694 ) const 2695 { 2696 UINT_32 tileSwizzle = 0; 2697 2698 if (IsMacroTiled(tileMode)) // Swizzle only for macro tile mode 2699 { 2700 UINT_32 firstSlice = slice / ComputeSurfaceThickness(tileMode); 2701 2702 UINT_32 numPipes = HwlGetPipes(pTileInfo); 2703 UINT_32 numBanks = pTileInfo->banks; 2704 2705 UINT_32 pipeRotation; 2706 UINT_32 bankRotation; 2707 2708 UINT_32 bankSwizzle = 0; 2709 UINT_32 pipeSwizzle = 0; 2710 2711 pipeRotation = ComputePipeRotation(tileMode, numPipes); 2712 bankRotation = ComputeBankRotation(tileMode, numBanks, numPipes); 2713 2714 if (baseSwizzle != 0) 2715 { 2716 ExtractBankPipeSwizzle(baseSwizzle, 2717 pTileInfo, 2718 &bankSwizzle, 2719 &pipeSwizzle); 2720 } 2721 2722 if (pipeRotation == 0) //2D mode 2723 { 2724 bankSwizzle += firstSlice * bankRotation; 2725 bankSwizzle %= numBanks; 2726 } 2727 else //3D mode 2728 { 2729 pipeSwizzle += firstSlice * pipeRotation; 2730 pipeSwizzle %= numPipes; 2731 bankSwizzle += firstSlice * bankRotation / numPipes; 2732 bankSwizzle %= numBanks; 2733 } 2734 2735 tileSwizzle = GetBankPipeSwizzle(bankSwizzle, 2736 pipeSwizzle, 2737 baseAddr, 2738 pTileInfo); 2739 } 2740 2741 return tileSwizzle; 2742 } 2743 2744 /** 2745 *************************************************************************************************** 2746 * EgBasedAddrLib::HwlComputeQbStereoRightSwizzle 2747 * 2748 * @brief 2749 * Compute right eye swizzle 2750 * @return 2751 * swizzle 2752 *************************************************************************************************** 2753 */ 2754 UINT_32 EgBasedAddrLib::HwlComputeQbStereoRightSwizzle( 2755 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pInfo ///< [in] Surface info, must be valid 2756 ) const 2757 { 2758 UINT_32 bankBits = 0; 2759 UINT_32 swizzle = 0; 2760 2761 // The assumption is default swizzle for left eye is 0 2762 if (IsMacroTiled(pInfo->tileMode) && pInfo->pStereoInfo && pInfo->pTileInfo) 2763 { 2764 bankBits = ComputeBankFromCoord(0, pInfo->height, 0, 2765 pInfo->tileMode, 0, 0, pInfo->pTileInfo); 2766 2767 if (bankBits) 2768 { 2769 HwlCombineBankPipeSwizzle(bankBits, 0, pInfo->pTileInfo, 0, &swizzle); 2770 } 2771 } 2772 2773 return swizzle; 2774 } 2775 2776 /** 2777 *************************************************************************************************** 2778 * EgBasedAddrLib::ComputeBankFromCoord 2779 * 2780 * @brief 2781 * Compute bank number from coordinates 2782 * @return 2783 * Bank number 2784 *************************************************************************************************** 2785 */ 2786 UINT_32 EgBasedAddrLib::ComputeBankFromCoord( 2787 UINT_32 x, ///< [in] x coordinate 2788 UINT_32 y, ///< [in] y coordinate 2789 UINT_32 slice, ///< [in] slice index 2790 AddrTileMode tileMode, ///< [in] tile mode 2791 UINT_32 bankSwizzle, ///< [in] bank swizzle 2792 UINT_32 tileSplitSlice, ///< [in] If the size of the pixel offset is larger than the 2793 /// tile split size, then the pixel will be moved to a separate 2794 /// slice. This value equals pixelOffset / tileSplitBytes 2795 /// in this case. Otherwise this is 0. 2796 ADDR_TILEINFO* pTileInfo ///< [in] tile info 2797 ) const 2798 { 2799 UINT_32 pipes = HwlGetPipes(pTileInfo); 2800 UINT_32 bankBit0 = 0; 2801 UINT_32 bankBit1 = 0; 2802 UINT_32 bankBit2 = 0; 2803 UINT_32 bankBit3 = 0; 2804 UINT_32 sliceRotation; 2805 UINT_32 tileSplitRotation; 2806 UINT_32 bank; 2807 UINT_32 numBanks = pTileInfo->banks; 2808 UINT_32 bankWidth = pTileInfo->bankWidth; 2809 UINT_32 bankHeight = pTileInfo->bankHeight; 2810 2811 UINT_32 tx = x / MicroTileWidth / (bankWidth * pipes); 2812 UINT_32 ty = y / MicroTileHeight / bankHeight; 2813 2814 UINT_32 x3 = _BIT(tx,0); 2815 UINT_32 x4 = _BIT(tx,1); 2816 UINT_32 x5 = _BIT(tx,2); 2817 UINT_32 x6 = _BIT(tx,3); 2818 UINT_32 y3 = _BIT(ty,0); 2819 UINT_32 y4 = _BIT(ty,1); 2820 UINT_32 y5 = _BIT(ty,2); 2821 UINT_32 y6 = _BIT(ty,3); 2822 2823 switch (numBanks) 2824 { 2825 case 16: 2826 bankBit0 = x3 ^ y6; 2827 bankBit1 = x4 ^ y5 ^ y6; 2828 bankBit2 = x5 ^ y4; 2829 bankBit3 = x6 ^ y3; 2830 break; 2831 case 8: 2832 bankBit0 = x3 ^ y5; 2833 bankBit1 = x4 ^ y4 ^ y5; 2834 bankBit2 = x5 ^ y3; 2835 break; 2836 case 4: 2837 bankBit0 = x3 ^ y4; 2838 bankBit1 = x4 ^ y3; 2839 break; 2840 case 2: 2841 bankBit0 = x3 ^ y3; 2842 break; 2843 default: 2844 ADDR_ASSERT_ALWAYS(); 2845 break; 2846 } 2847 2848 bank = bankBit0 | (bankBit1 << 1) | (bankBit2 << 2) | (bankBit3 << 3); 2849 2850 //Bits2Number(4, bankBit3, bankBit2, bankBit1, bankBit0); 2851 2852 bank = HwlPreAdjustBank((x / MicroTileWidth), bank, pTileInfo); 2853 // 2854 // Compute bank rotation for the slice. 2855 // 2856 UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode); 2857 2858 switch (tileMode) 2859 { 2860 case ADDR_TM_2D_TILED_THIN1: // fall through 2861 case ADDR_TM_2D_TILED_THICK: // fall through 2862 case ADDR_TM_2D_TILED_XTHICK: 2863 sliceRotation = ((numBanks / 2) - 1) * (slice / microTileThickness); 2864 break; 2865 case ADDR_TM_3D_TILED_THIN1: // fall through 2866 case ADDR_TM_3D_TILED_THICK: // fall through 2867 case ADDR_TM_3D_TILED_XTHICK: 2868 sliceRotation = 2869 Max(1u, (pipes / 2) - 1) * (slice / microTileThickness) / pipes; 2870 break; 2871 default: 2872 sliceRotation = 0; 2873 break; 2874 } 2875 2876 2877 // 2878 // Compute bank rotation for the tile split slice. 2879 // 2880 // The sample slice will be non-zero if samples must be split across multiple slices. 2881 // This situation arises when the micro tile size multiplied yBit the number of samples exceeds 2882 // the split size (set in GB_ADDR_CONFIG). 2883 // 2884 switch (tileMode) 2885 { 2886 case ADDR_TM_2D_TILED_THIN1: //fall through 2887 case ADDR_TM_3D_TILED_THIN1: //fall through 2888 case ADDR_TM_PRT_2D_TILED_THIN1: //fall through 2889 case ADDR_TM_PRT_3D_TILED_THIN1: //fall through 2890 tileSplitRotation = ((numBanks / 2) + 1) * tileSplitSlice; 2891 break; 2892 default: 2893 tileSplitRotation = 0; 2894 break; 2895 } 2896 2897 // 2898 // Apply bank rotation for the slice and tile split slice. 2899 // 2900 bank ^= bankSwizzle + sliceRotation; 2901 bank ^= tileSplitRotation; 2902 2903 bank &= (numBanks - 1); 2904 2905 return bank; 2906 } 2907 2908 /** 2909 *************************************************************************************************** 2910 * EgBasedAddrLib::ComputeBankFromAddr 2911 * 2912 * @brief 2913 * Compute the bank number from an address 2914 * @return 2915 * Bank number 2916 *************************************************************************************************** 2917 */ 2918 UINT_32 EgBasedAddrLib::ComputeBankFromAddr( 2919 UINT_64 addr, ///< [in] address 2920 UINT_32 numBanks, ///< [in] number of banks 2921 UINT_32 numPipes ///< [in] number of pipes 2922 ) const 2923 { 2924 UINT_32 bank; 2925 2926 // 2927 // The LSBs of the address are arranged as follows: 2928 // bank | bankInterleave | pipe | pipeInterleave 2929 // 2930 // To get the bank number, shift off the pipe interleave, pipe, and bank interlave bits and 2931 // mask the bank bits. 2932 // 2933 bank = static_cast<UINT_32>( 2934 (addr >> Log2(m_pipeInterleaveBytes * numPipes * m_bankInterleave)) & 2935 (numBanks - 1) 2936 ); 2937 2938 return bank; 2939 } 2940 2941 /** 2942 *************************************************************************************************** 2943 * EgBasedAddrLib::ComputePipeRotation 2944 * 2945 * @brief 2946 * Compute pipe rotation value 2947 * @return 2948 * Pipe rotation 2949 *************************************************************************************************** 2950 */ 2951 UINT_32 EgBasedAddrLib::ComputePipeRotation( 2952 AddrTileMode tileMode, ///< [in] tile mode 2953 UINT_32 numPipes ///< [in] number of pipes 2954 ) const 2955 { 2956 UINT_32 rotation; 2957 2958 switch (tileMode) 2959 { 2960 case ADDR_TM_3D_TILED_THIN1: //fall through 2961 case ADDR_TM_3D_TILED_THICK: //fall through 2962 case ADDR_TM_3D_TILED_XTHICK: //fall through 2963 case ADDR_TM_PRT_3D_TILED_THIN1: //fall through 2964 case ADDR_TM_PRT_3D_TILED_THICK: 2965 rotation = (numPipes < 4) ? 1 : (numPipes / 2 - 1); 2966 break; 2967 default: 2968 rotation = 0; 2969 } 2970 2971 return rotation; 2972 } 2973 2974 2975 2976 /** 2977 *************************************************************************************************** 2978 * EgBasedAddrLib::ComputeBankRotation 2979 * 2980 * @brief 2981 * Compute bank rotation value 2982 * @return 2983 * Bank rotation 2984 *************************************************************************************************** 2985 */ 2986 UINT_32 EgBasedAddrLib::ComputeBankRotation( 2987 AddrTileMode tileMode, ///< [in] tile mode 2988 UINT_32 numBanks, ///< [in] number of banks 2989 UINT_32 numPipes ///< [in] number of pipes 2990 ) const 2991 { 2992 UINT_32 rotation; 2993 2994 switch (tileMode) 2995 { 2996 case ADDR_TM_2D_TILED_THIN1: // fall through 2997 case ADDR_TM_2D_TILED_THICK: // fall through 2998 case ADDR_TM_2D_TILED_XTHICK: 2999 case ADDR_TM_PRT_2D_TILED_THIN1: 3000 case ADDR_TM_PRT_2D_TILED_THICK: 3001 // Rotate banks per Z-slice yBit 1 for 4-bank or 3 for 8-bank 3002 rotation = numBanks / 2 - 1; 3003 break; 3004 case ADDR_TM_3D_TILED_THIN1: // fall through 3005 case ADDR_TM_3D_TILED_THICK: // fall through 3006 case ADDR_TM_3D_TILED_XTHICK: 3007 case ADDR_TM_PRT_3D_TILED_THIN1: 3008 case ADDR_TM_PRT_3D_TILED_THICK: 3009 rotation = (numPipes < 4) ? 1 : (numPipes / 2 - 1); // rotate pipes & banks 3010 break; 3011 default: 3012 rotation = 0; 3013 } 3014 3015 return rotation; 3016 } 3017 3018 3019 /** 3020 *************************************************************************************************** 3021 * EgBasedAddrLib::ComputeHtileBytes 3022 * 3023 * @brief 3024 * Compute htile size in bytes 3025 * 3026 * @return 3027 * Htile size in bytes 3028 *************************************************************************************************** 3029 */ 3030 UINT_64 EgBasedAddrLib::ComputeHtileBytes( 3031 UINT_32 pitch, ///< [in] pitch 3032 UINT_32 height, ///< [in] height 3033 UINT_32 bpp, ///< [in] bits per pixel 3034 BOOL_32 isLinear, ///< [in] if it is linear mode 3035 UINT_32 numSlices, ///< [in] number of slices 3036 UINT_64* sliceBytes, ///< [out] bytes per slice 3037 UINT_32 baseAlign ///< [in] base alignments 3038 ) const 3039 { 3040 UINT_64 surfBytes; 3041 3042 const UINT_64 HtileCacheLineSize = BITS_TO_BYTES(HtileCacheBits); 3043 3044 *sliceBytes = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp / 64); 3045 3046 if (m_configFlags.useHtileSliceAlign) 3047 { 3048 // Align the sliceSize to htilecachelinesize * pipes at first 3049 *sliceBytes = PowTwoAlign(*sliceBytes, HtileCacheLineSize * m_pipes); 3050 surfBytes = *sliceBytes * numSlices; 3051 } 3052 else 3053 { 3054 // Align the surfSize to htilecachelinesize * pipes at last 3055 surfBytes = *sliceBytes * numSlices; 3056 surfBytes = PowTwoAlign(surfBytes, HtileCacheLineSize * m_pipes); 3057 } 3058 3059 return surfBytes; 3060 } 3061 3062 /** 3063 *************************************************************************************************** 3064 * EgBasedAddrLib::DispatchComputeFmaskInfo 3065 * 3066 * @brief 3067 * Compute fmask sizes include padded pitch, height, slices, total size in bytes, 3068 * meanwhile output suitable tile mode and alignments as well. Results are returned 3069 * through output parameters. 3070 * 3071 * @return 3072 * ADDR_E_RETURNCODE 3073 *************************************************************************************************** 3074 */ 3075 ADDR_E_RETURNCODE EgBasedAddrLib::DispatchComputeFmaskInfo( 3076 const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure 3077 ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut) ///< [out] output structure 3078 { 3079 ADDR_E_RETURNCODE retCode = ADDR_OK; 3080 3081 ADDR_COMPUTE_SURFACE_INFO_INPUT surfIn = {0}; 3082 ADDR_COMPUTE_SURFACE_INFO_OUTPUT surfOut = {0}; 3083 3084 // Setup input structure 3085 surfIn.tileMode = pIn->tileMode; 3086 surfIn.width = pIn->pitch; 3087 surfIn.height = pIn->height; 3088 surfIn.numSlices = pIn->numSlices; 3089 surfIn.pTileInfo = pIn->pTileInfo; 3090 surfIn.tileType = ADDR_NON_DISPLAYABLE; 3091 surfIn.flags.fmask = 1; 3092 3093 // Setup output structure 3094 surfOut.pTileInfo = pOut->pTileInfo; 3095 3096 // Setup hwl specific fields 3097 HwlFmaskPreThunkSurfInfo(pIn, pOut, &surfIn, &surfOut); 3098 3099 surfIn.bpp = HwlComputeFmaskBits(pIn, &surfIn.numSamples); 3100 3101 // ComputeSurfaceInfo needs numSamples in surfOut as surface routines need adjusted numSamples 3102 surfOut.numSamples = surfIn.numSamples; 3103 3104 retCode = HwlComputeSurfaceInfo(&surfIn, &surfOut); 3105 3106 // Save bpp field for surface dump support 3107 surfOut.bpp = surfIn.bpp; 3108 3109 if (retCode == ADDR_OK) 3110 { 3111 pOut->bpp = surfOut.bpp; 3112 pOut->pitch = surfOut.pitch; 3113 pOut->height = surfOut.height; 3114 pOut->numSlices = surfOut.depth; 3115 pOut->fmaskBytes = surfOut.surfSize; 3116 pOut->baseAlign = surfOut.baseAlign; 3117 pOut->pitchAlign = surfOut.pitchAlign; 3118 pOut->heightAlign = surfOut.heightAlign; 3119 3120 if (surfOut.depth > 1) 3121 { 3122 // For fmask, expNumSlices is stored in depth. 3123 pOut->sliceSize = surfOut.surfSize / surfOut.depth; 3124 } 3125 else 3126 { 3127 pOut->sliceSize = surfOut.surfSize; 3128 } 3129 3130 // Save numSamples field for surface dump support 3131 pOut->numSamples = surfOut.numSamples; 3132 3133 HwlFmaskPostThunkSurfInfo(&surfOut, pOut); 3134 } 3135 3136 return retCode; 3137 } 3138 3139 /** 3140 *************************************************************************************************** 3141 * EgBasedAddrLib::HwlFmaskSurfaceInfo 3142 * @brief 3143 * Entry of EgBasedAddrLib ComputeFmaskInfo 3144 * @return 3145 * ADDR_E_RETURNCODE 3146 *************************************************************************************************** 3147 */ 3148 ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeFmaskInfo( 3149 const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure 3150 ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut ///< [out] output structure 3151 ) 3152 { 3153 ADDR_E_RETURNCODE retCode = ADDR_OK; 3154 3155 ADDR_TILEINFO tileInfo = {0}; 3156 3157 // Use internal tile info if pOut does not have a valid pTileInfo 3158 if (pOut->pTileInfo == NULL) 3159 { 3160 pOut->pTileInfo = &tileInfo; 3161 } 3162 3163 retCode = DispatchComputeFmaskInfo(pIn, pOut); 3164 3165 if (retCode == ADDR_OK) 3166 { 3167 pOut->tileIndex = 3168 HwlPostCheckTileIndex(pOut->pTileInfo, pIn->tileMode, ADDR_NON_DISPLAYABLE, 3169 pOut->tileIndex); 3170 } 3171 3172 // Resets pTileInfo to NULL if the internal tile info is used 3173 if (pOut->pTileInfo == &tileInfo) 3174 { 3175 pOut->pTileInfo = NULL; 3176 } 3177 3178 return retCode; 3179 } 3180 3181 /** 3182 *************************************************************************************************** 3183 * EgBasedAddrLib::HwlComputeFmaskAddrFromCoord 3184 * @brief 3185 * Entry of EgBasedAddrLib ComputeFmaskAddrFromCoord 3186 * @return 3187 * ADDR_E_RETURNCODE 3188 *************************************************************************************************** 3189 */ 3190 ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeFmaskAddrFromCoord( 3191 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure 3192 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure 3193 ) const 3194 { 3195 ADDR_E_RETURNCODE retCode = ADDR_OK; 3196 3197 #if ADDR_AM_BUILD 3198 if ((pIn->x > pIn->pitch) || 3199 (pIn->y > pIn->height) || 3200 (pIn->numSamples > m_maxSamples) || 3201 (pIn->sample >= m_maxSamples)) 3202 { 3203 retCode = ADDR_INVALIDPARAMS; 3204 } 3205 else 3206 { 3207 pOut->addr = DispatchComputeFmaskAddrFromCoord(pIn, pOut); 3208 } 3209 #endif 3210 3211 return retCode; 3212 } 3213 3214 /** 3215 *************************************************************************************************** 3216 * EgBasedAddrLib::HwlComputeFmaskCoordFromAddr 3217 * @brief 3218 * Entry of EgBasedAddrLib ComputeFmaskCoordFromAddr 3219 * @return 3220 * ADDR_E_RETURNCODE 3221 *************************************************************************************************** 3222 */ 3223 ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeFmaskCoordFromAddr( 3224 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure 3225 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure 3226 ) const 3227 { 3228 ADDR_E_RETURNCODE retCode = ADDR_OK; 3229 3230 #if ADDR_AM_BUILD 3231 if ((pIn->bitPosition >= 8) || 3232 (pIn->numSamples > m_maxSamples)) 3233 { 3234 retCode = ADDR_INVALIDPARAMS; 3235 } 3236 else 3237 { 3238 DispatchComputeFmaskCoordFromAddr(pIn, pOut); 3239 } 3240 #endif 3241 3242 return retCode; 3243 } 3244 3245 #if ADDR_AM_BUILD 3246 /** 3247 *************************************************************************************************** 3248 * EgBasedAddrLib::DispatchComputeFmaskAddrFromCoord 3249 * 3250 * @brief 3251 * Computes the FMASK address and bit position from a coordinate. 3252 * @return 3253 * The byte address 3254 *************************************************************************************************** 3255 */ 3256 UINT_64 EgBasedAddrLib::DispatchComputeFmaskAddrFromCoord( 3257 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure 3258 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure 3259 ) const 3260 { 3261 UINT_32 x = pIn->x; 3262 UINT_32 y = pIn->y; 3263 UINT_32 slice = pIn->slice; 3264 UINT_32 sample = pIn->sample; 3265 UINT_32 plane = pIn->plane; 3266 UINT_32 pitch = pIn->pitch; 3267 UINT_32 height = pIn->height; 3268 UINT_32 numSamples = pIn->numSamples; 3269 AddrTileMode tileMode = pIn->tileMode; 3270 BOOL_32 ignoreSE = pIn->ignoreSE; 3271 ADDR_TILEINFO* pTileInfo = pIn->pTileInfo; 3272 BOOL_32 resolved = pIn->resolved; 3273 3274 UINT_32* pBitPosition = &pOut->bitPosition; 3275 UINT_64 addr = 0; 3276 3277 ADDR_ASSERT(numSamples > 1); 3278 ADDR_ASSERT(ComputeSurfaceThickness(tileMode) == 1); 3279 3280 switch (tileMode) 3281 { 3282 case ADDR_TM_1D_TILED_THIN1: 3283 addr = ComputeFmaskAddrFromCoordMicroTiled(x, 3284 y, 3285 slice, 3286 sample, 3287 plane, 3288 pitch, 3289 height, 3290 numSamples, 3291 tileMode, 3292 resolved, 3293 pBitPosition); 3294 break; 3295 case ADDR_TM_2D_TILED_THIN1: //fall through 3296 case ADDR_TM_3D_TILED_THIN1: 3297 UINT_32 pipeSwizzle; 3298 UINT_32 bankSwizzle; 3299 3300 if (m_configFlags.useCombinedSwizzle) 3301 { 3302 ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo, 3303 &bankSwizzle, &pipeSwizzle); 3304 } 3305 else 3306 { 3307 pipeSwizzle = pIn->pipeSwizzle; 3308 bankSwizzle = pIn->bankSwizzle; 3309 } 3310 3311 addr = ComputeFmaskAddrFromCoordMacroTiled(x, 3312 y, 3313 slice, 3314 sample, 3315 plane, 3316 pitch, 3317 height, 3318 numSamples, 3319 tileMode, 3320 pipeSwizzle, 3321 bankSwizzle, 3322 ignoreSE, 3323 pTileInfo, 3324 resolved, 3325 pBitPosition); 3326 break; 3327 default: 3328 *pBitPosition = 0; 3329 break; 3330 } 3331 3332 return addr; 3333 } 3334 3335 /** 3336 *************************************************************************************************** 3337 * EgBasedAddrLib::ComputeFmaskAddrFromCoordMicroTiled 3338 * 3339 * @brief 3340 * Computes the FMASK address and bit position from a coordinate for 1D tilied (micro 3341 * tiled) 3342 * @return 3343 * The byte address 3344 *************************************************************************************************** 3345 */ 3346 UINT_64 EgBasedAddrLib::ComputeFmaskAddrFromCoordMicroTiled( 3347 UINT_32 x, ///< [in] x coordinate 3348 UINT_32 y, ///< [in] y coordinate 3349 UINT_32 slice, ///< [in] slice index 3350 UINT_32 sample, ///< [in] sample number 3351 UINT_32 plane, ///< [in] plane number 3352 UINT_32 pitch, ///< [in] surface pitch in pixels 3353 UINT_32 height, ///< [in] surface height in pixels 3354 UINT_32 numSamples, ///< [in] number of samples 3355 AddrTileMode tileMode, ///< [in] tile mode 3356 BOOL_32 resolved, ///< [in] TRUE if this is for resolved fmask 3357 UINT_32* pBitPosition ///< [out] pointer to returned bit position 3358 ) const 3359 { 3360 UINT_64 addr = 0; 3361 UINT_32 effectiveBpp; 3362 UINT_32 effectiveSamples; 3363 3364 // 3365 // 2xAA use the same layout as 4xAA 3366 // 3367 if (numSamples == 2) 3368 { 3369 numSamples = 4; 3370 } 3371 3372 // 3373 // Compute the number of planes. 3374 // 3375 if (!resolved) 3376 { 3377 effectiveSamples = ComputeFmaskNumPlanesFromNumSamples(numSamples); 3378 effectiveBpp = numSamples; 3379 3380 // 3381 // Compute the address just like a color surface with numSamples bits per element and 3382 // numPlanes samples. 3383 // 3384 addr = ComputeSurfaceAddrFromCoordMicroTiled(x, 3385 y, 3386 slice, 3387 plane, // sample 3388 effectiveBpp, 3389 pitch, 3390 height, 3391 effectiveSamples, 3392 tileMode, 3393 ADDR_NON_DISPLAYABLE, 3394 FALSE, 3395 pBitPosition); 3396 3397 // 3398 // Compute the real bit position. Each (sample, plane) is stored with one bit per sample. 3399 // 3400 3401 // 3402 // Compute the pixel index with in the micro tile 3403 // 3404 UINT_32 pixelIndex = ComputePixelIndexWithinMicroTile(x % 8, 3405 y % 8, 3406 slice, 3407 1, 3408 tileMode, 3409 ADDR_NON_DISPLAYABLE); 3410 3411 *pBitPosition = ((pixelIndex * numSamples) + sample) & (BITS_PER_BYTE-1); 3412 3413 UINT_64 bitAddr = BYTES_TO_BITS(addr) + *pBitPosition; 3414 3415 addr = bitAddr / 8; 3416 } 3417 else 3418 { 3419 effectiveBpp = ComputeFmaskResolvedBppFromNumSamples(numSamples); 3420 effectiveSamples = 1; 3421 3422 // 3423 // Compute the address just like a color surface with numSamples bits per element and 3424 // numPlanes samples. 3425 // 3426 addr = ComputeSurfaceAddrFromCoordMicroTiled(x, 3427 y, 3428 slice, 3429 sample, 3430 effectiveBpp, 3431 pitch, 3432 height, 3433 effectiveSamples, 3434 tileMode, 3435 ADDR_NON_DISPLAYABLE, 3436 TRUE, 3437 pBitPosition); 3438 } 3439 3440 return addr; 3441 } 3442 3443 /** 3444 *************************************************************************************************** 3445 * EgBasedAddrLib::ComputeFmaskAddrFromCoordMacroTiled 3446 * 3447 * @brief 3448 * Computes the FMASK address and bit position from a coordinate for 2D tilied (macro 3449 * tiled) 3450 * @return 3451 * The byte address 3452 *************************************************************************************************** 3453 */ 3454 UINT_64 EgBasedAddrLib::ComputeFmaskAddrFromCoordMacroTiled( 3455 UINT_32 x, ///< [in] x coordinate 3456 UINT_32 y, ///< [in] y coordinate 3457 UINT_32 slice, ///< [in] slice index 3458 UINT_32 sample, ///< [in] sample number 3459 UINT_32 plane, ///< [in] plane number 3460 UINT_32 pitch, ///< [in] surface pitch in pixels 3461 UINT_32 height, ///< [in] surface height in pixels 3462 UINT_32 numSamples, ///< [in] number of samples 3463 AddrTileMode tileMode, ///< [in] tile mode 3464 UINT_32 pipeSwizzle, ///< [in] pipe swizzle 3465 UINT_32 bankSwizzle, ///< [in] bank swizzle 3466 BOOL_32 ignoreSE, ///< [in] TRUE if ignore shader engine 3467 ADDR_TILEINFO* pTileInfo, ///< [in] bank structure.**All fields to be valid on entry** 3468 BOOL_32 resolved, ///< [in] TRUE if this is for resolved fmask 3469 UINT_32* pBitPosition ///< [out] pointer to returned bit position 3470 ) const 3471 { 3472 UINT_64 addr = 0; 3473 UINT_32 effectiveBpp; 3474 UINT_32 effectiveSamples; 3475 3476 // 3477 // 2xAA use the same layout as 4xAA 3478 // 3479 if (numSamples == 2) 3480 { 3481 numSamples = 4; 3482 } 3483 3484 // 3485 // Compute the number of planes. 3486 // 3487 if (!resolved) 3488 { 3489 effectiveSamples = ComputeFmaskNumPlanesFromNumSamples(numSamples); 3490 effectiveBpp = numSamples; 3491 3492 // 3493 // Compute the address just like a color surface with numSamples bits per element and 3494 // numPlanes samples. 3495 // 3496 addr = ComputeSurfaceAddrFromCoordMacroTiled(x, 3497 y, 3498 slice, 3499 plane, // sample 3500 effectiveBpp, 3501 pitch, 3502 height, 3503 effectiveSamples, 3504 tileMode, 3505 ADDR_NON_DISPLAYABLE,// isdisp 3506 ignoreSE,// ignore_shader 3507 FALSE,// depth_sample_order 3508 pipeSwizzle, 3509 bankSwizzle, 3510 pTileInfo, 3511 pBitPosition); 3512 3513 // 3514 // Compute the real bit position. Each (sample, plane) is stored with one bit per sample. 3515 // 3516 3517 3518 // 3519 // Compute the pixel index with in the micro tile 3520 // 3521 UINT_32 pixelIndex = ComputePixelIndexWithinMicroTile(x , 3522 y , 3523 slice, 3524 effectiveBpp, 3525 tileMode, 3526 ADDR_NON_DISPLAYABLE); 3527 3528 *pBitPosition = ((pixelIndex * numSamples) + sample) & (BITS_PER_BYTE-1); 3529 3530 UINT_64 bitAddr = BYTES_TO_BITS(addr) + *pBitPosition; 3531 3532 addr = bitAddr / 8; 3533 3534 } 3535 else 3536 { 3537 effectiveBpp = ComputeFmaskResolvedBppFromNumSamples(numSamples); 3538 effectiveSamples = 1; 3539 3540 // 3541 // Compute the address just like a color surface with numSamples bits per element and 3542 // numPlanes samples. 3543 // 3544 addr = ComputeSurfaceAddrFromCoordMacroTiled(x, 3545 y, 3546 slice, 3547 sample, 3548 effectiveBpp, 3549 pitch, 3550 height, 3551 effectiveSamples, 3552 tileMode, 3553 ADDR_NON_DISPLAYABLE, 3554 ignoreSE, 3555 TRUE, 3556 pipeSwizzle, 3557 bankSwizzle, 3558 pTileInfo, 3559 pBitPosition); 3560 } 3561 3562 return addr; 3563 } 3564 3565 /** 3566 *************************************************************************************************** 3567 * EgBasedAddrLib::ComputeFmaskCoordFromAddrMicroTiled 3568 * 3569 * @brief 3570 * Compute (x,y,slice,sample,plane) coordinates from fmask address 3571 * @return 3572 * N/A 3573 * 3574 *************************************************************************************************** 3575 */ 3576 VOID EgBasedAddrLib::ComputeFmaskCoordFromAddrMicroTiled( 3577 UINT_64 addr, ///< [in] byte address 3578 UINT_32 bitPosition,///< [in] bit position 3579 UINT_32 pitch, ///< [in] pitch in pixels 3580 UINT_32 height, ///< [in] height in pixels 3581 UINT_32 numSamples, ///< [in] number of samples (of color buffer) 3582 AddrTileMode tileMode, ///< [in] tile mode 3583 BOOL_32 resolved, ///< [in] TRUE if it is resolved fmask 3584 UINT_32* pX, ///< [out] X coord 3585 UINT_32* pY, ///< [out] Y coord 3586 UINT_32* pSlice, ///< [out] slice index 3587 UINT_32* pSample, ///< [out] sample index 3588 UINT_32* pPlane ///< [out] plane index 3589 ) const 3590 { 3591 UINT_32 effectiveBpp; 3592 UINT_32 effectiveSamples; 3593 3594 // 2xAA use the same layout as 4xAA 3595 if (numSamples == 2) 3596 { 3597 numSamples = 4; 3598 } 3599 3600 if (!resolved) 3601 { 3602 effectiveSamples = ComputeFmaskNumPlanesFromNumSamples(numSamples); 3603 effectiveBpp = numSamples; 3604 3605 ComputeSurfaceCoordFromAddrMicroTiled(addr, 3606 bitPosition, 3607 effectiveBpp, 3608 pitch, 3609 height, 3610 effectiveSamples, 3611 tileMode, 3612 0, // tileBase 3613 0, // compBits 3614 pX, 3615 pY, 3616 pSlice, 3617 pPlane, 3618 ADDR_NON_DISPLAYABLE, // microTileType 3619 FALSE // isDepthSampleOrder 3620 ); 3621 3622 3623 if ( pSample ) 3624 { 3625 *pSample = bitPosition % numSamples; 3626 } 3627 } 3628 else 3629 { 3630 effectiveBpp = ComputeFmaskResolvedBppFromNumSamples(numSamples); 3631 effectiveSamples = 1; 3632 3633 ComputeSurfaceCoordFromAddrMicroTiled(addr, 3634 bitPosition, 3635 effectiveBpp, 3636 pitch, 3637 height, 3638 effectiveSamples, 3639 tileMode, 3640 0, // tileBase 3641 0, // compBits 3642 pX, 3643 pY, 3644 pSlice, 3645 pSample, 3646 ADDR_NON_DISPLAYABLE, // microTileType 3647 TRUE // isDepthSampleOrder 3648 ); 3649 } 3650 } 3651 3652 /** 3653 *************************************************************************************************** 3654 * EgBasedAddrLib::ComputeFmaskCoordFromAddrMacroTiled 3655 * 3656 * @brief 3657 * Compute (x,y,slice,sample,plane) coordinates from 3658 * fmask address 3659 * @return 3660 * N/A 3661 * 3662 *************************************************************************************************** 3663 */ 3664 VOID EgBasedAddrLib::ComputeFmaskCoordFromAddrMacroTiled( 3665 UINT_64 addr, ///< [in] byte address 3666 UINT_32 bitPosition,///< [in] bit position 3667 UINT_32 pitch, ///< [in] pitch in pixels 3668 UINT_32 height, ///< [in] height in pixels 3669 UINT_32 numSamples, ///< [in] number of samples (of color buffer) 3670 AddrTileMode tileMode, ///< [in] tile mode 3671 UINT_32 pipeSwizzle,///< [in] pipe swizzle 3672 UINT_32 bankSwizzle,///< [in] bank swizzle 3673 BOOL_32 ignoreSE, ///< [in] TRUE if ignore shader engine 3674 ADDR_TILEINFO* pTileInfo, ///< [in] bank structure. **All fields to be valid on entry** 3675 BOOL_32 resolved, ///< [in] TRUE if it is resolved fmask 3676 UINT_32* pX, ///< [out] X coord 3677 UINT_32* pY, ///< [out] Y coord 3678 UINT_32* pSlice, ///< [out] slice index 3679 UINT_32* pSample, ///< [out] sample index 3680 UINT_32* pPlane ///< [out] plane index 3681 ) const 3682 { 3683 UINT_32 effectiveBpp; 3684 UINT_32 effectiveSamples; 3685 3686 // 2xAA use the same layout as 4xAA 3687 if (numSamples == 2) 3688 { 3689 numSamples = 4; 3690 } 3691 3692 // 3693 // Compute the number of planes. 3694 // 3695 if (!resolved) 3696 { 3697 effectiveSamples = ComputeFmaskNumPlanesFromNumSamples(numSamples); 3698 effectiveBpp = numSamples; 3699 3700 ComputeSurfaceCoordFromAddrMacroTiled(addr, 3701 bitPosition, 3702 effectiveBpp, 3703 pitch, 3704 height, 3705 effectiveSamples, 3706 tileMode, 3707 0, // No tileBase 3708 0, // No compBits 3709 ADDR_NON_DISPLAYABLE, 3710 ignoreSE, 3711 FALSE, 3712 pipeSwizzle, 3713 bankSwizzle, 3714 pTileInfo, 3715 pX, 3716 pY, 3717 pSlice, 3718 pPlane); 3719 3720 if (pSample) 3721 { 3722 *pSample = bitPosition % numSamples; 3723 } 3724 } 3725 else 3726 { 3727 effectiveBpp = ComputeFmaskResolvedBppFromNumSamples(numSamples); 3728 effectiveSamples = 1; 3729 3730 ComputeSurfaceCoordFromAddrMacroTiled(addr, 3731 bitPosition, 3732 effectiveBpp, 3733 pitch, 3734 height, 3735 effectiveSamples, 3736 tileMode, 3737 0, // No tileBase 3738 0, // No compBits 3739 ADDR_NON_DISPLAYABLE, 3740 ignoreSE, 3741 TRUE, 3742 pipeSwizzle, 3743 bankSwizzle, 3744 pTileInfo, 3745 pX, 3746 pY, 3747 pSlice, 3748 pSample); 3749 } 3750 } 3751 3752 /** 3753 *************************************************************************************************** 3754 * EgBasedAddrLib::DispatchComputeFmaskCoordFromAddr 3755 * 3756 * @brief 3757 * Compute (x,y,slice,sample,plane) coordinates from 3758 * fmask address 3759 * @return 3760 * N/A 3761 * 3762 *************************************************************************************************** 3763 */ 3764 VOID EgBasedAddrLib::DispatchComputeFmaskCoordFromAddr( 3765 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure 3766 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure 3767 ) const 3768 { 3769 UINT_64 addr = pIn->addr; 3770 UINT_32 bitPosition = pIn->bitPosition; 3771 UINT_32 pitch = pIn->pitch; 3772 UINT_32 height = pIn->height; 3773 UINT_32 numSamples = pIn->numSamples; 3774 AddrTileMode tileMode = pIn->tileMode; 3775 BOOL_32 ignoreSE = pIn->ignoreSE; 3776 ADDR_TILEINFO* pTileInfo = pIn->pTileInfo; 3777 BOOL_32 resolved = pIn->resolved; 3778 3779 UINT_32* pX = &pOut->x; 3780 UINT_32* pY = &pOut->y; 3781 UINT_32* pSlice = &pOut->slice; 3782 UINT_32* pSample = &pOut->sample; 3783 UINT_32* pPlane = &pOut->plane; 3784 3785 switch (tileMode) 3786 { 3787 case ADDR_TM_1D_TILED_THIN1: 3788 ComputeFmaskCoordFromAddrMicroTiled(addr, 3789 bitPosition, 3790 pitch, 3791 height, 3792 numSamples, 3793 tileMode, 3794 resolved, 3795 pX, 3796 pY, 3797 pSlice, 3798 pSample, 3799 pPlane); 3800 break; 3801 case ADDR_TM_2D_TILED_THIN1://fall through 3802 case ADDR_TM_3D_TILED_THIN1: 3803 UINT_32 pipeSwizzle; 3804 UINT_32 bankSwizzle; 3805 3806 if (m_configFlags.useCombinedSwizzle) 3807 { 3808 ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo, 3809 &bankSwizzle, &pipeSwizzle); 3810 } 3811 else 3812 { 3813 pipeSwizzle = pIn->pipeSwizzle; 3814 bankSwizzle = pIn->bankSwizzle; 3815 } 3816 3817 ComputeFmaskCoordFromAddrMacroTiled(addr, 3818 bitPosition, 3819 pitch, 3820 height, 3821 numSamples, 3822 tileMode, 3823 pipeSwizzle, 3824 bankSwizzle, 3825 ignoreSE, 3826 pTileInfo, 3827 resolved, 3828 pX, 3829 pY, 3830 pSlice, 3831 pSample, 3832 pPlane); 3833 break; 3834 default: 3835 ADDR_ASSERT_ALWAYS(); 3836 break; 3837 3838 } 3839 } 3840 #endif 3841 3842 /** 3843 *************************************************************************************************** 3844 * EgBasedAddrLib::ComputeFmaskNumPlanesFromNumSamples 3845 * 3846 * @brief 3847 * Compute fmask number of planes from number of samples 3848 * 3849 * @return 3850 * Number of planes 3851 *************************************************************************************************** 3852 */ 3853 UINT_32 EgBasedAddrLib::ComputeFmaskNumPlanesFromNumSamples( 3854 UINT_32 numSamples) ///< [in] number of samples 3855 { 3856 UINT_32 numPlanes; 3857 3858 // 3859 // FMASK is stored such that each micro tile is composed of elements containing N bits, where 3860 // N is the number of samples. There is a micro tile for each bit in the FMASK address, and 3861 // micro tiles for each address bit, sometimes referred to as a plane, are stored sequentially. 3862 // The FMASK for a 2-sample surface looks like a general surface with 2 bits per element. 3863 // The FMASK for a 4-sample surface looks like a general surface with 4 bits per element and 3864 // 2 samples. The FMASK for an 8-sample surface looks like a general surface with 8 bits per 3865 // element and 4 samples. R6xx and R7xx only stored 3 planes for 8-sample FMASK surfaces. 3866 // This was changed for R8xx to simplify the logic in the CB. 3867 // 3868 switch (numSamples) 3869 { 3870 case 2: 3871 numPlanes = 1; 3872 break; 3873 case 4: 3874 numPlanes = 2; 3875 break; 3876 case 8: 3877 numPlanes = 4; 3878 break; 3879 default: 3880 ADDR_UNHANDLED_CASE(); 3881 numPlanes = 0; 3882 break; 3883 } 3884 return numPlanes; 3885 } 3886 3887 /** 3888 *************************************************************************************************** 3889 * EgBasedAddrLib::ComputeFmaskResolvedBppFromNumSamples 3890 * 3891 * @brief 3892 * Compute resolved fmask effective bpp based on number of samples 3893 * 3894 * @return 3895 * bpp 3896 *************************************************************************************************** 3897 */ 3898 UINT_32 EgBasedAddrLib::ComputeFmaskResolvedBppFromNumSamples( 3899 UINT_32 numSamples) ///< number of samples 3900 { 3901 UINT_32 bpp; 3902 3903 // 3904 // Resolved FMASK surfaces are generated yBit the CB and read yBit the texture unit 3905 // so that the texture unit can read compressed multi-sample color data. 3906 // These surfaces store each index value packed per element. 3907 // Each element contains at least num_samples * log2(num_samples) bits. 3908 // Resolved FMASK surfaces are addressed as follows: 3909 // 2-sample Addressed similarly to a color surface with 8 bits per element and 1 sample. 3910 // 4-sample Addressed similarly to a color surface with 8 bits per element and 1 sample. 3911 // 8-sample Addressed similarly to a color surface with 32 bits per element and 1 sample. 3912 3913 switch (numSamples) 3914 { 3915 case 2: 3916 bpp = 8; 3917 break; 3918 case 4: 3919 bpp = 8; 3920 break; 3921 case 8: 3922 bpp = 32; 3923 break; 3924 default: 3925 ADDR_UNHANDLED_CASE(); 3926 bpp = 0; 3927 break; 3928 } 3929 return bpp; 3930 } 3931 3932 /** 3933 *************************************************************************************************** 3934 * EgBasedAddrLib::IsTileInfoAllZero 3935 * 3936 * @brief 3937 * Return TRUE if all field are zero 3938 * @note 3939 * Since NULL input is consider to be all zero 3940 *************************************************************************************************** 3941 */ 3942 BOOL_32 EgBasedAddrLib::IsTileInfoAllZero( 3943 ADDR_TILEINFO* pTileInfo) 3944 { 3945 BOOL_32 allZero = TRUE; 3946 3947 if (pTileInfo) 3948 { 3949 if ((pTileInfo->banks != 0) || 3950 (pTileInfo->bankWidth != 0) || 3951 (pTileInfo->bankHeight != 0) || 3952 (pTileInfo->macroAspectRatio != 0) || 3953 (pTileInfo->tileSplitBytes != 0) || 3954 (pTileInfo->pipeConfig != 0) 3955 ) 3956 { 3957 allZero = FALSE; 3958 } 3959 } 3960 3961 return allZero; 3962 } 3963 3964 /** 3965 *************************************************************************************************** 3966 * EgBasedAddrLib::HwlTileInfoEqual 3967 * 3968 * @brief 3969 * Return TRUE if all field are equal 3970 * @note 3971 * Only takes care of current HWL's data 3972 *************************************************************************************************** 3973 */ 3974 BOOL_32 EgBasedAddrLib::HwlTileInfoEqual( 3975 const ADDR_TILEINFO* pLeft, ///<[in] Left compare operand 3976 const ADDR_TILEINFO* pRight ///<[in] Right compare operand 3977 ) const 3978 { 3979 BOOL_32 equal = FALSE; 3980 3981 if (pLeft->banks == pRight->banks && 3982 pLeft->bankWidth == pRight->bankWidth && 3983 pLeft->bankHeight == pRight->bankHeight && 3984 pLeft->macroAspectRatio == pRight->macroAspectRatio && 3985 pLeft->tileSplitBytes == pRight->tileSplitBytes) 3986 { 3987 equal = TRUE; 3988 } 3989 3990 return equal; 3991 } 3992 3993 /** 3994 *************************************************************************************************** 3995 * EgBasedAddrLib::HwlConvertTileInfoToHW 3996 * @brief 3997 * Entry of EgBasedAddrLib ConvertTileInfoToHW 3998 * @return 3999 * ADDR_E_RETURNCODE 4000 *************************************************************************************************** 4001 */ 4002 ADDR_E_RETURNCODE EgBasedAddrLib::HwlConvertTileInfoToHW( 4003 const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure 4004 ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut ///< [out] output structure 4005 ) const 4006 { 4007 ADDR_E_RETURNCODE retCode = ADDR_OK; 4008 4009 ADDR_TILEINFO *pTileInfoIn = pIn->pTileInfo; 4010 ADDR_TILEINFO *pTileInfoOut = pOut->pTileInfo; 4011 4012 if ((pTileInfoIn != NULL) && (pTileInfoOut != NULL)) 4013 { 4014 if (pIn->reverse == FALSE) 4015 { 4016 switch (pTileInfoIn->banks) 4017 { 4018 case 2: 4019 pTileInfoOut->banks = 0; 4020 break; 4021 case 4: 4022 pTileInfoOut->banks = 1; 4023 break; 4024 case 8: 4025 pTileInfoOut->banks = 2; 4026 break; 4027 case 16: 4028 pTileInfoOut->banks = 3; 4029 break; 4030 default: 4031 ADDR_ASSERT_ALWAYS(); 4032 retCode = ADDR_INVALIDPARAMS; 4033 pTileInfoOut->banks = 0; 4034 break; 4035 } 4036 4037 switch (pTileInfoIn->bankWidth) 4038 { 4039 case 1: 4040 pTileInfoOut->bankWidth = 0; 4041 break; 4042 case 2: 4043 pTileInfoOut->bankWidth = 1; 4044 break; 4045 case 4: 4046 pTileInfoOut->bankWidth = 2; 4047 break; 4048 case 8: 4049 pTileInfoOut->bankWidth = 3; 4050 break; 4051 default: 4052 ADDR_ASSERT_ALWAYS(); 4053 retCode = ADDR_INVALIDPARAMS; 4054 pTileInfoOut->bankWidth = 0; 4055 break; 4056 } 4057 4058 switch (pTileInfoIn->bankHeight) 4059 { 4060 case 1: 4061 pTileInfoOut->bankHeight = 0; 4062 break; 4063 case 2: 4064 pTileInfoOut->bankHeight = 1; 4065 break; 4066 case 4: 4067 pTileInfoOut->bankHeight = 2; 4068 break; 4069 case 8: 4070 pTileInfoOut->bankHeight = 3; 4071 break; 4072 default: 4073 ADDR_ASSERT_ALWAYS(); 4074 retCode = ADDR_INVALIDPARAMS; 4075 pTileInfoOut->bankHeight = 0; 4076 break; 4077 } 4078 4079 switch (pTileInfoIn->macroAspectRatio) 4080 { 4081 case 1: 4082 pTileInfoOut->macroAspectRatio = 0; 4083 break; 4084 case 2: 4085 pTileInfoOut->macroAspectRatio = 1; 4086 break; 4087 case 4: 4088 pTileInfoOut->macroAspectRatio = 2; 4089 break; 4090 case 8: 4091 pTileInfoOut->macroAspectRatio = 3; 4092 break; 4093 default: 4094 ADDR_ASSERT_ALWAYS(); 4095 retCode = ADDR_INVALIDPARAMS; 4096 pTileInfoOut->macroAspectRatio = 0; 4097 break; 4098 } 4099 4100 switch (pTileInfoIn->tileSplitBytes) 4101 { 4102 case 64: 4103 pTileInfoOut->tileSplitBytes = 0; 4104 break; 4105 case 128: 4106 pTileInfoOut->tileSplitBytes = 1; 4107 break; 4108 case 256: 4109 pTileInfoOut->tileSplitBytes = 2; 4110 break; 4111 case 512: 4112 pTileInfoOut->tileSplitBytes = 3; 4113 break; 4114 case 1024: 4115 pTileInfoOut->tileSplitBytes = 4; 4116 break; 4117 case 2048: 4118 pTileInfoOut->tileSplitBytes = 5; 4119 break; 4120 case 4096: 4121 pTileInfoOut->tileSplitBytes = 6; 4122 break; 4123 default: 4124 ADDR_ASSERT_ALWAYS(); 4125 retCode = ADDR_INVALIDPARAMS; 4126 pTileInfoOut->tileSplitBytes = 0; 4127 break; 4128 } 4129 } 4130 else 4131 { 4132 switch (pTileInfoIn->banks) 4133 { 4134 case 0: 4135 pTileInfoOut->banks = 2; 4136 break; 4137 case 1: 4138 pTileInfoOut->banks = 4; 4139 break; 4140 case 2: 4141 pTileInfoOut->banks = 8; 4142 break; 4143 case 3: 4144 pTileInfoOut->banks = 16; 4145 break; 4146 default: 4147 ADDR_ASSERT_ALWAYS(); 4148 retCode = ADDR_INVALIDPARAMS; 4149 pTileInfoOut->banks = 2; 4150 break; 4151 } 4152 4153 switch (pTileInfoIn->bankWidth) 4154 { 4155 case 0: 4156 pTileInfoOut->bankWidth = 1; 4157 break; 4158 case 1: 4159 pTileInfoOut->bankWidth = 2; 4160 break; 4161 case 2: 4162 pTileInfoOut->bankWidth = 4; 4163 break; 4164 case 3: 4165 pTileInfoOut->bankWidth = 8; 4166 break; 4167 default: 4168 ADDR_ASSERT_ALWAYS(); 4169 retCode = ADDR_INVALIDPARAMS; 4170 pTileInfoOut->bankWidth = 1; 4171 break; 4172 } 4173 4174 switch (pTileInfoIn->bankHeight) 4175 { 4176 case 0: 4177 pTileInfoOut->bankHeight = 1; 4178 break; 4179 case 1: 4180 pTileInfoOut->bankHeight = 2; 4181 break; 4182 case 2: 4183 pTileInfoOut->bankHeight = 4; 4184 break; 4185 case 3: 4186 pTileInfoOut->bankHeight = 8; 4187 break; 4188 default: 4189 ADDR_ASSERT_ALWAYS(); 4190 retCode = ADDR_INVALIDPARAMS; 4191 pTileInfoOut->bankHeight = 1; 4192 break; 4193 } 4194 4195 switch (pTileInfoIn->macroAspectRatio) 4196 { 4197 case 0: 4198 pTileInfoOut->macroAspectRatio = 1; 4199 break; 4200 case 1: 4201 pTileInfoOut->macroAspectRatio = 2; 4202 break; 4203 case 2: 4204 pTileInfoOut->macroAspectRatio = 4; 4205 break; 4206 case 3: 4207 pTileInfoOut->macroAspectRatio = 8; 4208 break; 4209 default: 4210 ADDR_ASSERT_ALWAYS(); 4211 retCode = ADDR_INVALIDPARAMS; 4212 pTileInfoOut->macroAspectRatio = 1; 4213 break; 4214 } 4215 4216 switch (pTileInfoIn->tileSplitBytes) 4217 { 4218 case 0: 4219 pTileInfoOut->tileSplitBytes = 64; 4220 break; 4221 case 1: 4222 pTileInfoOut->tileSplitBytes = 128; 4223 break; 4224 case 2: 4225 pTileInfoOut->tileSplitBytes = 256; 4226 break; 4227 case 3: 4228 pTileInfoOut->tileSplitBytes = 512; 4229 break; 4230 case 4: 4231 pTileInfoOut->tileSplitBytes = 1024; 4232 break; 4233 case 5: 4234 pTileInfoOut->tileSplitBytes = 2048; 4235 break; 4236 case 6: 4237 pTileInfoOut->tileSplitBytes = 4096; 4238 break; 4239 default: 4240 ADDR_ASSERT_ALWAYS(); 4241 retCode = ADDR_INVALIDPARAMS; 4242 pTileInfoOut->tileSplitBytes = 64; 4243 break; 4244 } 4245 } 4246 4247 if (pTileInfoIn != pTileInfoOut) 4248 { 4249 pTileInfoOut->pipeConfig = pTileInfoIn->pipeConfig; 4250 } 4251 } 4252 else 4253 { 4254 ADDR_ASSERT_ALWAYS(); 4255 retCode = ADDR_INVALIDPARAMS; 4256 } 4257 4258 return retCode; 4259 } 4260 4261 /** 4262 *************************************************************************************************** 4263 * EgBasedAddrLib::HwlComputeSurfaceInfo 4264 * @brief 4265 * Entry of EgBasedAddrLib ComputeSurfaceInfo 4266 * @return 4267 * ADDR_E_RETURNCODE 4268 *************************************************************************************************** 4269 */ 4270 ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeSurfaceInfo( 4271 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure 4272 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure 4273 ) const 4274 { 4275 ADDR_E_RETURNCODE retCode = ADDR_OK; 4276 4277 if (pIn->numSamples < pIn->numFrags) 4278 { 4279 retCode = ADDR_INVALIDPARAMS; 4280 } 4281 4282 ADDR_TILEINFO tileInfo = {0}; 4283 4284 if (retCode == ADDR_OK) 4285 { 4286 // Uses internal tile info if pOut does not have a valid pTileInfo 4287 if (pOut->pTileInfo == NULL) 4288 { 4289 pOut->pTileInfo = &tileInfo; 4290 } 4291 4292 if (!DispatchComputeSurfaceInfo(pIn, pOut)) 4293 { 4294 retCode = ADDR_INVALIDPARAMS; 4295 } 4296 4297 // Returns an index 4298 pOut->tileIndex = HwlPostCheckTileIndex(pOut->pTileInfo, 4299 pOut->tileMode, 4300 pOut->tileType, 4301 pOut->tileIndex); 4302 4303 if (IsMacroTiled(pOut->tileMode) && (pOut->macroModeIndex == TileIndexInvalid)) 4304 { 4305 pOut->macroModeIndex = HwlComputeMacroModeIndex(pOut->tileIndex, 4306 pIn->flags, 4307 pIn->bpp, 4308 pIn->numSamples, 4309 pOut->pTileInfo); 4310 } 4311 4312 // Resets pTileInfo to NULL if the internal tile info is used 4313 if (pOut->pTileInfo == &tileInfo) 4314 { 4315 #if DEBUG 4316 // Client does not pass in a valid pTileInfo 4317 if (IsMacroTiled(pOut->tileMode)) 4318 { 4319 // If a valid index is returned, then no pTileInfo is okay 4320 ADDR_ASSERT(!m_configFlags.useTileIndex || pOut->tileIndex != TileIndexInvalid); 4321 4322 if (!IsTileInfoAllZero(pIn->pTileInfo)) 4323 { 4324 // The initial value of pIn->pTileInfo is copied to tileInfo 4325 // We do not expect any of these value to be changed nor any 0 of inputs 4326 ADDR_ASSERT(tileInfo.banks == pIn->pTileInfo->banks); 4327 ADDR_ASSERT(tileInfo.bankWidth == pIn->pTileInfo->bankWidth); 4328 ADDR_ASSERT(tileInfo.bankHeight == pIn->pTileInfo->bankHeight); 4329 ADDR_ASSERT(tileInfo.macroAspectRatio == pIn->pTileInfo->macroAspectRatio); 4330 ADDR_ASSERT(tileInfo.tileSplitBytes == pIn->pTileInfo->tileSplitBytes); 4331 } 4332 } 4333 #endif 4334 pOut->pTileInfo = NULL; 4335 } 4336 } 4337 4338 return retCode; 4339 } 4340 4341 /** 4342 *************************************************************************************************** 4343 * EgBasedAddrLib::HwlComputeSurfaceAddrFromCoord 4344 * @brief 4345 * Entry of EgBasedAddrLib ComputeSurfaceAddrFromCoord 4346 * @return 4347 * ADDR_E_RETURNCODE 4348 *************************************************************************************************** 4349 */ 4350 ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeSurfaceAddrFromCoord( 4351 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure 4352 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure 4353 ) const 4354 { 4355 ADDR_E_RETURNCODE retCode = ADDR_OK; 4356 4357 if ( 4358 #if !ALT_TEST // Overflow test needs this out-of-boundary coord 4359 (pIn->x > pIn->pitch) || 4360 (pIn->y > pIn->height) || 4361 #endif 4362 (pIn->numSamples > m_maxSamples)) 4363 { 4364 retCode = ADDR_INVALIDPARAMS; 4365 } 4366 else 4367 { 4368 pOut->addr = DispatchComputeSurfaceAddrFromCoord(pIn, pOut); 4369 } 4370 4371 return retCode; 4372 } 4373 4374 /** 4375 *************************************************************************************************** 4376 * EgBasedAddrLib::HwlComputeSurfaceCoordFromAddr 4377 * @brief 4378 * Entry of EgBasedAddrLib ComputeSurfaceCoordFromAddr 4379 * @return 4380 * ADDR_E_RETURNCODE 4381 *************************************************************************************************** 4382 */ 4383 ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeSurfaceCoordFromAddr( 4384 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure 4385 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure 4386 ) const 4387 { 4388 ADDR_E_RETURNCODE retCode = ADDR_OK; 4389 4390 if ((pIn->bitPosition >= 8) || 4391 (pIn->numSamples > m_maxSamples)) 4392 { 4393 retCode = ADDR_INVALIDPARAMS; 4394 } 4395 else 4396 { 4397 DispatchComputeSurfaceCoordFromAddr(pIn, pOut); 4398 } 4399 return retCode; 4400 } 4401 4402 /** 4403 *************************************************************************************************** 4404 * EgBasedAddrLib::HwlComputeSliceTileSwizzle 4405 * @brief 4406 * Entry of EgBasedAddrLib ComputeSurfaceCoordFromAddr 4407 * @return 4408 * ADDR_E_RETURNCODE 4409 *************************************************************************************************** 4410 */ 4411 ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeSliceTileSwizzle( 4412 const ADDR_COMPUTE_SLICESWIZZLE_INPUT* pIn, ///< [in] input structure 4413 ADDR_COMPUTE_SLICESWIZZLE_OUTPUT* pOut ///< [out] output structure 4414 ) const 4415 { 4416 ADDR_E_RETURNCODE retCode = ADDR_OK; 4417 4418 if (pIn->pTileInfo && (pIn->pTileInfo->banks > 0)) 4419 { 4420 4421 pOut->tileSwizzle = ComputeSliceTileSwizzle(pIn->tileMode, 4422 pIn->baseSwizzle, 4423 pIn->slice, 4424 pIn->baseAddr, 4425 pIn->pTileInfo); 4426 } 4427 else 4428 { 4429 retCode = ADDR_INVALIDPARAMS; 4430 } 4431 4432 return retCode; 4433 } 4434 4435 /** 4436 *************************************************************************************************** 4437 * EgBasedAddrLib::HwlComputeHtileBpp 4438 * 4439 * @brief 4440 * Compute htile bpp 4441 * 4442 * @return 4443 * Htile bpp 4444 *************************************************************************************************** 4445 */ 4446 UINT_32 EgBasedAddrLib::HwlComputeHtileBpp( 4447 BOOL_32 isWidth8, ///< [in] TRUE if block width is 8 4448 BOOL_32 isHeight8 ///< [in] TRUE if block height is 8 4449 ) const 4450 { 4451 // only support 8x8 mode 4452 ADDR_ASSERT(isWidth8 && isHeight8); 4453 return 32; 4454 } 4455 4456 /** 4457 *************************************************************************************************** 4458 * EgBasedAddrLib::HwlComputeHtileBaseAlign 4459 * 4460 * @brief 4461 * Compute htile base alignment 4462 * 4463 * @return 4464 * Htile base alignment 4465 *************************************************************************************************** 4466 */ 4467 UINT_32 EgBasedAddrLib::HwlComputeHtileBaseAlign( 4468 BOOL_32 isTcCompatible, ///< [in] if TC compatible 4469 BOOL_32 isLinear, ///< [in] if it is linear mode 4470 ADDR_TILEINFO* pTileInfo ///< [in] Tile info 4471 ) const 4472 { 4473 UINT_32 baseAlign = m_pipeInterleaveBytes * HwlGetPipes(pTileInfo); 4474 4475 if (isTcCompatible) 4476 { 4477 ADDR_ASSERT(pTileInfo != NULL); 4478 if (pTileInfo) 4479 { 4480 baseAlign *= pTileInfo->banks; 4481 } 4482 } 4483 4484 return baseAlign; 4485 } 4486 4487 /** 4488 *************************************************************************************************** 4489 * EgBasedAddrLib::HwlGetPitchAlignmentMicroTiled 4490 * 4491 * @brief 4492 * Compute 1D tiled surface pitch alignment, calculation results are returned through 4493 * output parameters. 4494 * 4495 * @return 4496 * pitch alignment 4497 *************************************************************************************************** 4498 */ 4499 UINT_32 EgBasedAddrLib::HwlGetPitchAlignmentMicroTiled( 4500 AddrTileMode tileMode, ///< [in] tile mode 4501 UINT_32 bpp, ///< [in] bits per pixel 4502 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags 4503 UINT_32 numSamples ///< [in] number of samples 4504 ) const 4505 { 4506 UINT_32 pitchAlign; 4507 4508 UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode); 4509 4510 UINT_32 pixelsPerMicroTile; 4511 UINT_32 pixelsPerPipeInterleave; 4512 UINT_32 microTilesPerPipeInterleave; 4513 4514 // 4515 // Special workaround for depth/stencil buffer, use 8 bpp to meet larger requirement for 4516 // stencil buffer since pitch alignment is related to bpp. 4517 // For a depth only buffer do not set this. 4518 // 4519 // Note: this actually does not work for mipmap but mipmap depth texture is not really 4520 // sampled with mipmap. 4521 // 4522 if (flags.depth && !flags.noStencil) 4523 { 4524 bpp = 8; 4525 } 4526 4527 pixelsPerMicroTile = MicroTilePixels * microTileThickness; 4528 pixelsPerPipeInterleave = BYTES_TO_BITS(m_pipeInterleaveBytes) / (bpp * numSamples); 4529 microTilesPerPipeInterleave = pixelsPerPipeInterleave / pixelsPerMicroTile; 4530 4531 pitchAlign = Max(MicroTileWidth, microTilesPerPipeInterleave * MicroTileWidth); 4532 4533 return pitchAlign; 4534 } 4535 4536 /** 4537 *************************************************************************************************** 4538 * EgBasedAddrLib::HwlGetSizeAdjustmentMicroTiled 4539 * 4540 * @brief 4541 * Adjust 1D tiled surface pitch and slice size 4542 * 4543 * @return 4544 * Logical slice size in bytes 4545 *************************************************************************************************** 4546 */ 4547 UINT_64 EgBasedAddrLib::HwlGetSizeAdjustmentMicroTiled( 4548 UINT_32 thickness, ///< [in] thickness 4549 UINT_32 bpp, ///< [in] bits per pixel 4550 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags 4551 UINT_32 numSamples, ///< [in] number of samples 4552 UINT_32 baseAlign, ///< [in] base alignment 4553 UINT_32 pitchAlign, ///< [in] pitch alignment 4554 UINT_32* pPitch, ///< [in/out] pointer to pitch 4555 UINT_32* pHeight ///< [in/out] pointer to height 4556 ) const 4557 { 4558 UINT_64 logicalSliceSize; 4559 UINT_64 physicalSliceSize; 4560 4561 UINT_32 pitch = *pPitch; 4562 UINT_32 height = *pHeight; 4563 4564 // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1) 4565 logicalSliceSize = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples); 4566 4567 // Physical slice: multiplied by thickness 4568 physicalSliceSize = logicalSliceSize * thickness; 4569 4570 // 4571 // R800 will always pad physical slice size to baseAlign which is pipe_interleave_bytes 4572 // 4573 ADDR_ASSERT((physicalSliceSize % baseAlign) == 0) 4574 4575 return logicalSliceSize; 4576 } 4577 4578