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