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 siaddrlib.cpp 30 * @brief Contains the implementation for the SIAddrLib class. 31 *************************************************************************************************** 32 */ 33 34 #include "siaddrlib.h" 35 36 #include "si_gb_reg.h" 37 38 #include "si_ci_vi_merged_enum.h" 39 40 #if BRAHMA_BUILD 41 #include "amdgpu_id.h" 42 #else 43 #include "si_id.h" 44 #endif 45 46 /////////////////////////////////////////////////////////////////////////////////////////////////// 47 /////////////////////////////////////////////////////////////////////////////////////////////////// 48 49 /** 50 *************************************************************************************************** 51 * AddrSIHwlInit 52 * 53 * @brief 54 * Creates an SIAddrLib object. 55 * 56 * @return 57 * Returns an SIAddrLib object pointer. 58 *************************************************************************************************** 59 */ 60 AddrLib* AddrSIHwlInit(const AddrClient* pClient) 61 { 62 return SIAddrLib::CreateObj(pClient); 63 } 64 65 /** 66 *************************************************************************************************** 67 * SIAddrLib::SIAddrLib 68 * 69 * @brief 70 * Constructor 71 * 72 *************************************************************************************************** 73 */ 74 SIAddrLib::SIAddrLib(const AddrClient* pClient) : 75 EgBasedAddrLib(pClient), 76 m_noOfEntries(0) 77 { 78 m_class = SI_ADDRLIB; 79 memset(&m_settings, 0, sizeof(m_settings)); 80 } 81 82 /** 83 *************************************************************************************************** 84 * SIAddrLib::~SIAddrLib 85 * 86 * @brief 87 * Destructor 88 *************************************************************************************************** 89 */ 90 SIAddrLib::~SIAddrLib() 91 { 92 } 93 94 /** 95 *************************************************************************************************** 96 * SIAddrLib::HwlGetPipes 97 * 98 * @brief 99 * Get number pipes 100 * @return 101 * num pipes 102 *************************************************************************************************** 103 */ 104 UINT_32 SIAddrLib::HwlGetPipes( 105 const ADDR_TILEINFO* pTileInfo ///< [in] Tile info 106 ) const 107 { 108 UINT_32 numPipes; 109 110 if (pTileInfo) 111 { 112 numPipes = GetPipePerSurf(pTileInfo->pipeConfig); 113 } 114 else 115 { 116 ADDR_ASSERT_ALWAYS(); 117 numPipes = m_pipes; // Suppose we should still have a global pipes 118 } 119 120 return numPipes; 121 } 122 123 /** 124 *************************************************************************************************** 125 * SIAddrLib::GetPipePerSurf 126 * @brief 127 * get pipe num base on inputing tileinfo->pipeconfig 128 * @return 129 * pipe number 130 *************************************************************************************************** 131 */ 132 UINT_32 SIAddrLib::GetPipePerSurf( 133 AddrPipeCfg pipeConfig ///< [in] pipe config 134 ) const 135 { 136 UINT_32 numPipes = 0; 137 138 switch (pipeConfig) 139 { 140 case ADDR_PIPECFG_P2: 141 numPipes = 2; 142 break; 143 case ADDR_PIPECFG_P4_8x16: 144 case ADDR_PIPECFG_P4_16x16: 145 case ADDR_PIPECFG_P4_16x32: 146 case ADDR_PIPECFG_P4_32x32: 147 numPipes = 4; 148 break; 149 case ADDR_PIPECFG_P8_16x16_8x16: 150 case ADDR_PIPECFG_P8_16x32_8x16: 151 case ADDR_PIPECFG_P8_32x32_8x16: 152 case ADDR_PIPECFG_P8_16x32_16x16: 153 case ADDR_PIPECFG_P8_32x32_16x16: 154 case ADDR_PIPECFG_P8_32x32_16x32: 155 case ADDR_PIPECFG_P8_32x64_32x32: 156 numPipes = 8; 157 break; 158 case ADDR_PIPECFG_P16_32x32_8x16: 159 case ADDR_PIPECFG_P16_32x32_16x16: 160 numPipes = 16; 161 break; 162 default: 163 ADDR_ASSERT(!"Invalid pipe config"); 164 numPipes = m_pipes; 165 } 166 return numPipes; 167 } 168 169 /** 170 *************************************************************************************************** 171 * SIAddrLib::ComputePipeFromCoord 172 * 173 * @brief 174 * Compute pipe number from coordinates 175 * @return 176 * Pipe number 177 *************************************************************************************************** 178 */ 179 UINT_32 SIAddrLib::ComputePipeFromCoord( 180 UINT_32 x, ///< [in] x coordinate 181 UINT_32 y, ///< [in] y coordinate 182 UINT_32 slice, ///< [in] slice index 183 AddrTileMode tileMode, ///< [in] tile mode 184 UINT_32 pipeSwizzle, ///< [in] pipe swizzle 185 BOOL_32 ignoreSE, ///< [in] TRUE if shader engines are ignored 186 ADDR_TILEINFO* pTileInfo ///< [in] Tile info 187 ) const 188 { 189 UINT_32 pipe; 190 UINT_32 pipeBit0 = 0; 191 UINT_32 pipeBit1 = 0; 192 UINT_32 pipeBit2 = 0; 193 UINT_32 pipeBit3 = 0; 194 UINT_32 sliceRotation; 195 UINT_32 numPipes = 0; 196 197 UINT_32 tx = x / MicroTileWidth; 198 UINT_32 ty = y / MicroTileHeight; 199 UINT_32 x3 = _BIT(tx,0); 200 UINT_32 x4 = _BIT(tx,1); 201 UINT_32 x5 = _BIT(tx,2); 202 UINT_32 x6 = _BIT(tx,3); 203 UINT_32 y3 = _BIT(ty,0); 204 UINT_32 y4 = _BIT(ty,1); 205 UINT_32 y5 = _BIT(ty,2); 206 UINT_32 y6 = _BIT(ty,3); 207 208 switch (pTileInfo->pipeConfig) 209 { 210 case ADDR_PIPECFG_P2: 211 pipeBit0 = x3 ^ y3; 212 numPipes = 2; 213 break; 214 case ADDR_PIPECFG_P4_8x16: 215 pipeBit0 = x4 ^ y3; 216 pipeBit1 = x3 ^ y4; 217 numPipes = 4; 218 break; 219 case ADDR_PIPECFG_P4_16x16: 220 pipeBit0 = x3 ^ y3 ^ x4; 221 pipeBit1 = x4 ^ y4; 222 numPipes = 4; 223 break; 224 case ADDR_PIPECFG_P4_16x32: 225 pipeBit0 = x3 ^ y3 ^ x4; 226 pipeBit1 = x4 ^ y5; 227 numPipes = 4; 228 break; 229 case ADDR_PIPECFG_P4_32x32: 230 pipeBit0 = x3 ^ y3 ^ x5; 231 pipeBit1 = x5 ^ y5; 232 numPipes = 4; 233 break; 234 case ADDR_PIPECFG_P8_16x16_8x16: 235 pipeBit0 = x4 ^ y3 ^ x5; 236 pipeBit1 = x3 ^ y5; 237 numPipes = 8; 238 break; 239 case ADDR_PIPECFG_P8_16x32_8x16: 240 pipeBit0 = x4 ^ y3 ^ x5; 241 pipeBit1 = x3 ^ y4; 242 pipeBit2 = x4 ^ y5; 243 numPipes = 8; 244 break; 245 case ADDR_PIPECFG_P8_16x32_16x16: 246 pipeBit0 = x3 ^ y3 ^ x4; 247 pipeBit1 = x5 ^ y4; 248 pipeBit2 = x4 ^ y5; 249 numPipes = 8; 250 break; 251 case ADDR_PIPECFG_P8_32x32_8x16: 252 pipeBit0 = x4 ^ y3 ^ x5; 253 pipeBit1 = x3 ^ y4; 254 pipeBit2 = x5 ^ y5; 255 numPipes = 8; 256 break; 257 case ADDR_PIPECFG_P8_32x32_16x16: 258 pipeBit0 = x3 ^ y3 ^ x4; 259 pipeBit1 = x4 ^ y4; 260 pipeBit2 = x5 ^ y5; 261 numPipes = 8; 262 break; 263 case ADDR_PIPECFG_P8_32x32_16x32: 264 pipeBit0 = x3 ^ y3 ^ x4; 265 pipeBit1 = x4 ^ y6; 266 pipeBit2 = x5 ^ y5; 267 numPipes = 8; 268 break; 269 case ADDR_PIPECFG_P8_32x64_32x32: 270 pipeBit0 = x3 ^ y3 ^ x5; 271 pipeBit1 = x6 ^ y5; 272 pipeBit2 = x5 ^ y6; 273 numPipes = 8; 274 break; 275 case ADDR_PIPECFG_P16_32x32_8x16: 276 pipeBit0 = x4 ^ y3; 277 pipeBit1 = x3 ^ y4; 278 pipeBit2 = x5 ^ y6; 279 pipeBit3 = x6 ^ y5; 280 numPipes = 16; 281 break; 282 case ADDR_PIPECFG_P16_32x32_16x16: 283 pipeBit0 = x3 ^ y3 ^ x4; 284 pipeBit1 = x4 ^ y4; 285 pipeBit2 = x5 ^ y6; 286 pipeBit3 = x6 ^ y5; 287 numPipes = 16; 288 break; 289 default: 290 ADDR_UNHANDLED_CASE(); 291 break; 292 } 293 pipe = pipeBit0 | (pipeBit1 << 1) | (pipeBit2 << 2) | (pipeBit3 << 3); 294 295 UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode); 296 297 // 298 // Apply pipe rotation for the slice. 299 // 300 switch (tileMode) 301 { 302 case ADDR_TM_3D_TILED_THIN1: //fall through thin 303 case ADDR_TM_3D_TILED_THICK: //fall through thick 304 case ADDR_TM_3D_TILED_XTHICK: 305 sliceRotation = 306 Max(1, static_cast<INT_32>(numPipes / 2) - 1) * (slice / microTileThickness); 307 break; 308 default: 309 sliceRotation = 0; 310 break; 311 } 312 pipeSwizzle += sliceRotation; 313 pipeSwizzle &= (numPipes - 1); 314 315 pipe = pipe ^ pipeSwizzle; 316 317 return pipe; 318 } 319 320 /** 321 *************************************************************************************************** 322 * SIAddrLib::ComputeTileCoordFromPipeAndElemIdx 323 * 324 * @brief 325 * Compute (x,y) of a tile within a macro tile from address 326 * @return 327 * Pipe number 328 *************************************************************************************************** 329 */ 330 VOID SIAddrLib::ComputeTileCoordFromPipeAndElemIdx( 331 UINT_32 elemIdx, ///< [in] per pipe element index within a macro tile 332 UINT_32 pipe, ///< [in] pipe index 333 AddrPipeCfg pipeCfg, ///< [in] pipe config 334 UINT_32 pitchInMacroTile, ///< [in] surface pitch in macro tile 335 UINT_32 x, ///< [in] x coordinate of the (0,0) tile in a macro tile 336 UINT_32 y, ///< [in] y coordinate of the (0,0) tile in a macro tile 337 UINT_32* pX, ///< [out] x coordinate 338 UINT_32* pY ///< [out] y coordinate 339 ) const 340 { 341 UINT_32 pipebit0 = _BIT(pipe,0); 342 UINT_32 pipebit1 = _BIT(pipe,1); 343 UINT_32 pipebit2 = _BIT(pipe,2); 344 UINT_32 pipebit3 = _BIT(pipe,3); 345 UINT_32 elemIdx0 = _BIT(elemIdx,0); 346 UINT_32 elemIdx1 = _BIT(elemIdx,1); 347 UINT_32 elemIdx2 = _BIT(elemIdx,2); 348 UINT_32 x3 = 0; 349 UINT_32 x4 = 0; 350 UINT_32 x5 = 0; 351 UINT_32 x6 = 0; 352 UINT_32 y3 = 0; 353 UINT_32 y4 = 0; 354 UINT_32 y5 = 0; 355 UINT_32 y6 = 0; 356 357 switch(pipeCfg) 358 { 359 case ADDR_PIPECFG_P2: 360 x4 = elemIdx2; 361 y4 = elemIdx1 ^ x4; 362 y3 = elemIdx0 ^ x4; 363 x3 = pipebit0 ^ y3; 364 *pY = Bits2Number(2, y4, y3); 365 *pX = Bits2Number(2, x4, x3); 366 break; 367 case ADDR_PIPECFG_P4_8x16: 368 x4 = elemIdx1; 369 y4 = elemIdx0 ^ x4; 370 x3 = pipebit1 ^ y4; 371 y3 = pipebit0 ^ x4; 372 *pY = Bits2Number(2, y4, y3); 373 *pX = Bits2Number(2, x4, x3); 374 break; 375 case ADDR_PIPECFG_P4_16x16: 376 x4 = elemIdx1; 377 y3 = elemIdx0 ^ x4; 378 y4 = pipebit1 ^ x4; 379 x3 = pipebit0 ^ y3 ^ x4; 380 *pY = Bits2Number(2, y4, y3); 381 *pX = Bits2Number(2, x4, x3); 382 break; 383 case ADDR_PIPECFG_P4_16x32: 384 x3 = elemIdx0 ^ pipebit0; 385 y5 = _BIT(y,5); 386 x4 = pipebit1 ^ y5; 387 y3 = pipebit0 ^ x3 ^ x4; 388 y4 = elemIdx1 ^ x4; 389 *pY = Bits2Number(2, y4, y3); 390 *pX = Bits2Number(2, x4, x3); 391 break; 392 case ADDR_PIPECFG_P4_32x32: 393 x4 = elemIdx2; 394 y3 = elemIdx0 ^ x4; 395 y4 = elemIdx1 ^ x4; 396 if((pitchInMacroTile % 2) == 0) 397 { //even 398 y5 = _BIT(y,5); 399 x5 = pipebit1 ^ y5; 400 x3 = pipebit0 ^ y3 ^ x5; 401 *pY = Bits2Number(2, y4, y3); 402 *pX = Bits2Number(3, x5, x4, x3); 403 } 404 else 405 { //odd 406 x5 = _BIT(x,5); 407 x3 = pipebit0 ^ y3 ^ x5; 408 *pY = Bits2Number(2, y4, y3); 409 *pX = Bits2Number(2, x4, x3); 410 } 411 break; 412 case ADDR_PIPECFG_P8_16x16_8x16: 413 x4 = elemIdx0; 414 y5 = _BIT(y,5); 415 x5 = _BIT(x,5); 416 x3 = pipebit1 ^ y5; 417 y4 = pipebit2 ^ x4; 418 y3 = pipebit0 ^ x5 ^ x4; 419 *pY = Bits2Number(2, y4, y3); 420 *pX = Bits2Number(2, x4, x3); 421 break; 422 case ADDR_PIPECFG_P8_16x32_8x16: 423 x3 = elemIdx0; 424 y4 = pipebit1 ^ x3; 425 y5 = _BIT(y,5); 426 x5 = _BIT(x,5); 427 x4 = pipebit2 ^ y5; 428 y3 = pipebit0 ^ x4 ^ x5; 429 *pY = Bits2Number(2, y4, y3); 430 *pX = Bits2Number(2, x4, x3); 431 break; 432 case ADDR_PIPECFG_P8_32x32_8x16: 433 x4 = elemIdx1; 434 y4 = elemIdx0 ^ x4; 435 x3 = pipebit1 ^ y4; 436 if((pitchInMacroTile % 2) == 0) 437 { //even 438 y5 = _BIT(y,5); 439 x5 = _BIT(x,5); 440 x5 = pipebit2 ^ y5; 441 y3 = pipebit0 ^ x4 ^ x5; 442 *pY = Bits2Number(2, y4, y3); 443 *pX = Bits2Number(3, x5, x4, x3); 444 } 445 else 446 { //odd 447 x5 = _BIT(x,5); 448 y3 = pipebit0 ^ x4 ^ x5; 449 *pY = Bits2Number(2, y4, y3); 450 *pX = Bits2Number(2, x4, x3); 451 } 452 break; 453 case ADDR_PIPECFG_P8_16x32_16x16: 454 x3 = elemIdx0; 455 x5 = _BIT(x,5); 456 y5 = _BIT(y,5); 457 x4 = pipebit2 ^ y5; 458 y4 = pipebit1 ^ x5; 459 y3 = pipebit0 ^ x3 ^ x4; 460 *pY = Bits2Number(2, y4, y3); 461 *pX = Bits2Number(2, x4, x3); 462 break; 463 case ADDR_PIPECFG_P8_32x32_16x16: 464 x4 = elemIdx1; 465 y3 = elemIdx0 ^ x4; 466 x3 = y3^x4^pipebit0; 467 y4 = pipebit1 ^ x4; 468 if((pitchInMacroTile % 2) == 0) 469 { //even 470 y5 = _BIT(y,5); 471 x5 = pipebit2 ^ y5; 472 *pY = Bits2Number(2, y4, y3); 473 *pX = Bits2Number(3, x5, x4, x3); 474 } 475 else 476 { //odd 477 *pY = Bits2Number(2, y4, y3); 478 *pX = Bits2Number(2, x4, x3); 479 } 480 break; 481 case ADDR_PIPECFG_P8_32x32_16x32: 482 if((pitchInMacroTile % 2) == 0) 483 { //even 484 y5 = _BIT(y,5); 485 y6 = _BIT(y,6); 486 x4 = pipebit1 ^ y6; 487 y3 = elemIdx0 ^ x4; 488 y4 = elemIdx1 ^ x4; 489 x3 = pipebit0 ^ y3 ^ x4; 490 x5 = pipebit2 ^ y5; 491 *pY = Bits2Number(2, y4, y3); 492 *pX = Bits2Number(3, x5, x4, x3); 493 } 494 else 495 { //odd 496 y6 = _BIT(y,6); 497 x4 = pipebit1 ^ y6; 498 y3 = elemIdx0 ^ x4; 499 y4 = elemIdx1 ^ x4; 500 x3 = pipebit0 ^ y3 ^ x4; 501 *pY = Bits2Number(2, y4, y3); 502 *pX = Bits2Number(2, x4, x3); 503 } 504 break; 505 case ADDR_PIPECFG_P8_32x64_32x32: 506 x4 = elemIdx2; 507 y3 = elemIdx0 ^ x4; 508 y4 = elemIdx1 ^ x4; 509 if((pitchInMacroTile % 4) == 0) 510 { //multiple of 4 511 y5 = _BIT(y,5); 512 y6 = _BIT(y,6); 513 x5 = pipebit2 ^ y6; 514 x6 = pipebit1 ^ y5; 515 x3 = pipebit0 ^ y3 ^ x5; 516 *pY = Bits2Number(2, y4, y3); 517 *pX = Bits2Number(4, x6, x5, x4, x3); 518 } 519 else 520 { 521 y6 = _BIT(y,6); 522 x5 = pipebit2 ^ y6; 523 x3 = pipebit0 ^ y3 ^ x5; 524 *pY = Bits2Number(2, y4, y3); 525 *pX = Bits2Number(3, x5, x4, x3); 526 } 527 break; 528 case ADDR_PIPECFG_P16_32x32_8x16: 529 x4 = elemIdx1; 530 y4 = elemIdx0 ^ x4; 531 y3 = pipebit0 ^ x4; 532 x3 = pipebit1 ^ y4; 533 if((pitchInMacroTile % 4) == 0) 534 { //multiple of 4 535 y5 = _BIT(y,5); 536 y6 = _BIT(y,6); 537 x5 = pipebit2 ^ y6; 538 x6 = pipebit3 ^ y5; 539 *pY = Bits2Number(2, y4, y3); 540 *pX = Bits2Number(4, x6, x5,x4, x3); 541 } 542 else 543 { 544 y6 = _BIT(y,6); 545 x5 = pipebit2 ^ y6; 546 *pY = Bits2Number(2, y4, y3); 547 *pX = Bits2Number(3, x5, x4, x3); 548 } 549 break; 550 case ADDR_PIPECFG_P16_32x32_16x16: 551 x4 = elemIdx1; 552 y3 = elemIdx0 ^ x4; 553 y4 = pipebit1 ^ x4; 554 x3 = pipebit0 ^ y3 ^ x4; 555 if((pitchInMacroTile % 4) == 0) 556 { //multiple of 4 557 y5 = _BIT(y,5); 558 y6 = _BIT(y,6); 559 x5 = pipebit2 ^ y6; 560 x6 = pipebit3 ^ y5; 561 *pY = Bits2Number(2, y4, y3); 562 *pX = Bits2Number(4, x6, x5, x4, x3); 563 } 564 else 565 { 566 y6 = _BIT(y,6); 567 x5 = pipebit2 ^ y6; 568 *pY = Bits2Number(2, y4, y3); 569 *pX = Bits2Number(3, x5, x4, x3); 570 } 571 break; 572 default: 573 ADDR_UNHANDLED_CASE(); 574 } 575 } 576 577 /** 578 *************************************************************************************************** 579 * SIAddrLib::TileCoordToMaskElementIndex 580 * 581 * @brief 582 * Compute element index from coordinates in tiles 583 * @return 584 * Element index 585 *************************************************************************************************** 586 */ 587 UINT_32 SIAddrLib::TileCoordToMaskElementIndex( 588 UINT_32 tx, ///< [in] x coord, in Tiles 589 UINT_32 ty, ///< [in] y coord, in Tiles 590 AddrPipeCfg pipeConfig, ///< [in] pipe config 591 UINT_32* macroShift, ///< [out] macro shift 592 UINT_32* elemIdxBits ///< [out] tile offset bits 593 ) const 594 { 595 UINT_32 elemIdx = 0; 596 UINT_32 elemIdx0, elemIdx1, elemIdx2; 597 UINT_32 tx0, tx1; 598 UINT_32 ty0, ty1; 599 600 tx0 = _BIT(tx,0); 601 tx1 = _BIT(tx,1); 602 ty0 = _BIT(ty,0); 603 ty1 = _BIT(ty,1); 604 605 switch(pipeConfig) 606 { 607 case ADDR_PIPECFG_P2: 608 *macroShift = 3; 609 *elemIdxBits =3; 610 elemIdx2 = tx1; 611 elemIdx1 = tx1 ^ ty1; 612 elemIdx0 = tx1 ^ ty0; 613 elemIdx = Bits2Number(3,elemIdx2,elemIdx1,elemIdx0); 614 break; 615 case ADDR_PIPECFG_P4_8x16: 616 *macroShift = 2; 617 *elemIdxBits =2; 618 elemIdx1 = tx1; 619 elemIdx0 = tx1 ^ ty1; 620 elemIdx = Bits2Number(2,elemIdx1,elemIdx0); 621 break; 622 case ADDR_PIPECFG_P4_16x16: 623 *macroShift = 2; 624 *elemIdxBits =2; 625 elemIdx0 = tx1^ty0; 626 elemIdx1 = tx1; 627 elemIdx = Bits2Number(2, elemIdx1, elemIdx0); 628 break; 629 case ADDR_PIPECFG_P4_16x32: 630 *macroShift = 2; 631 *elemIdxBits =2; 632 elemIdx0 = tx1^ty0; 633 elemIdx1 = tx1^ty1; 634 elemIdx = Bits2Number(2, elemIdx1, elemIdx0); 635 break; 636 case ADDR_PIPECFG_P4_32x32: 637 *macroShift = 2; 638 *elemIdxBits =3; 639 elemIdx0 = tx1^ty0; 640 elemIdx1 = tx1^ty1; 641 elemIdx2 = tx1; 642 elemIdx = Bits2Number(3, elemIdx2, elemIdx1, elemIdx0); 643 break; 644 case ADDR_PIPECFG_P8_16x16_8x16: 645 *macroShift = 1; 646 *elemIdxBits =1; 647 elemIdx0 = tx1; 648 elemIdx = elemIdx0; 649 break; 650 case ADDR_PIPECFG_P8_16x32_8x16: 651 *macroShift = 1; 652 *elemIdxBits =1; 653 elemIdx0 = tx0; 654 elemIdx = elemIdx0; 655 break; 656 case ADDR_PIPECFG_P8_32x32_8x16: 657 *macroShift = 1; 658 *elemIdxBits =2; 659 elemIdx1 = tx1; 660 elemIdx0 = tx1^ty1; 661 elemIdx = Bits2Number(2, elemIdx1, elemIdx0); 662 break; 663 case ADDR_PIPECFG_P8_16x32_16x16: 664 *macroShift = 1; 665 *elemIdxBits =1; 666 elemIdx0 = tx0; 667 elemIdx = elemIdx0; 668 break; 669 case ADDR_PIPECFG_P8_32x32_16x16: 670 *macroShift = 1; 671 *elemIdxBits =2; 672 elemIdx0 = tx1^ty0; 673 elemIdx1 = tx1; 674 elemIdx = Bits2Number(2, elemIdx1, elemIdx0); 675 break; 676 case ADDR_PIPECFG_P8_32x32_16x32: 677 *macroShift = 1; 678 *elemIdxBits =2; 679 elemIdx0 = tx1^ty0; 680 elemIdx1 = tx1^ty1; 681 elemIdx = Bits2Number(2, elemIdx1, elemIdx0); 682 break; 683 case ADDR_PIPECFG_P8_32x64_32x32: 684 *macroShift = 1; 685 *elemIdxBits =3; 686 elemIdx0 = tx1^ty0; 687 elemIdx1 = tx1^ty1; 688 elemIdx2 = tx1; 689 elemIdx = Bits2Number(3, elemIdx2, elemIdx1, elemIdx0); 690 break; 691 case ADDR_PIPECFG_P16_32x32_8x16: 692 *macroShift = 0; 693 *elemIdxBits =2; 694 elemIdx0 = tx1^ty1; 695 elemIdx1 = tx1; 696 elemIdx = Bits2Number(2, elemIdx1, elemIdx0); 697 break; 698 case ADDR_PIPECFG_P16_32x32_16x16: 699 *macroShift = 0; 700 *elemIdxBits =2; 701 elemIdx0 = tx1^ty0; 702 elemIdx1 = tx1; 703 elemIdx = Bits2Number(2, elemIdx1, elemIdx0); 704 break; 705 default: 706 ADDR_UNHANDLED_CASE(); 707 break; 708 } 709 710 return elemIdx; 711 } 712 713 /** 714 *************************************************************************************************** 715 * SIAddrLib::HwlComputeTileDataWidthAndHeightLinear 716 * 717 * @brief 718 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout 719 * 720 * @return 721 * N/A 722 * 723 * @note 724 * MacroWidth and macroHeight are measured in pixels 725 *************************************************************************************************** 726 */ 727 VOID SIAddrLib::HwlComputeTileDataWidthAndHeightLinear( 728 UINT_32* pMacroWidth, ///< [out] macro tile width 729 UINT_32* pMacroHeight, ///< [out] macro tile height 730 UINT_32 bpp, ///< [in] bits per pixel 731 ADDR_TILEINFO* pTileInfo ///< [in] tile info 732 ) const 733 { 734 ADDR_ASSERT(pTileInfo != NULL); 735 UINT_32 macroWidth; 736 UINT_32 macroHeight; 737 738 /// In linear mode, the htile or cmask buffer must be padded out to 4 tiles 739 /// but for P8_32x64_32x32, it must be padded out to 8 tiles 740 /// Actually there are more pipe configs which need 8-tile padding but SI family 741 /// has a bug which is fixed in CI family 742 if ((pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32) || 743 (pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_8x16) || 744 (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x32_16x16)) 745 { 746 macroWidth = 8*MicroTileWidth; 747 macroHeight = 8*MicroTileHeight; 748 } 749 else 750 { 751 macroWidth = 4*MicroTileWidth; 752 macroHeight = 4*MicroTileHeight; 753 } 754 755 *pMacroWidth = macroWidth; 756 *pMacroHeight = macroHeight; 757 } 758 759 /** 760 *************************************************************************************************** 761 * SIAddrLib::HwlComputeHtileBytes 762 * 763 * @brief 764 * Compute htile size in bytes 765 * 766 * @return 767 * Htile size in bytes 768 *************************************************************************************************** 769 */ 770 UINT_64 SIAddrLib::HwlComputeHtileBytes( 771 UINT_32 pitch, ///< [in] pitch 772 UINT_32 height, ///< [in] height 773 UINT_32 bpp, ///< [in] bits per pixel 774 BOOL_32 isLinear, ///< [in] if it is linear mode 775 UINT_32 numSlices, ///< [in] number of slices 776 UINT_64* pSliceBytes, ///< [out] bytes per slice 777 UINT_32 baseAlign ///< [in] base alignments 778 ) const 779 { 780 return ComputeHtileBytes(pitch, height, bpp, isLinear, numSlices, pSliceBytes, baseAlign); 781 } 782 783 /** 784 *************************************************************************************************** 785 * SIAddrLib::HwlComputeXmaskAddrFromCoord 786 * 787 * @brief 788 * Compute address from coordinates for htile/cmask 789 * @return 790 * Byte address 791 *************************************************************************************************** 792 */ 793 UINT_64 SIAddrLib::HwlComputeXmaskAddrFromCoord( 794 UINT_32 pitch, ///< [in] pitch 795 UINT_32 height, ///< [in] height 796 UINT_32 x, ///< [in] x coord 797 UINT_32 y, ///< [in] y coord 798 UINT_32 slice, ///< [in] slice/depth index 799 UINT_32 numSlices, ///< [in] number of slices 800 UINT_32 factor, ///< [in] factor that indicates cmask(2) or htile(1) 801 BOOL_32 isLinear, ///< [in] linear or tiled HTILE layout 802 BOOL_32 isWidth8, ///< [in] TRUE if width is 8, FALSE means 4. It's register value 803 BOOL_32 isHeight8, ///< [in] TRUE if width is 8, FALSE means 4. It's register value 804 ADDR_TILEINFO* pTileInfo, ///< [in] Tile info 805 UINT_32* pBitPosition ///< [out] bit position inside a byte 806 ) const 807 { 808 UINT_32 tx = x / MicroTileWidth; 809 UINT_32 ty = y / MicroTileHeight; 810 UINT_32 newPitch; 811 UINT_32 newHeight; 812 UINT_64 totalBytes; 813 UINT_32 macroWidth; 814 UINT_32 macroHeight; 815 UINT_64 pSliceBytes; 816 UINT_32 pBaseAlign; 817 UINT_32 tileNumPerPipe; 818 UINT_32 elemBits; 819 820 if (factor == 2) //CMASK 821 { 822 ADDR_CMASK_FLAGS flags = {{0}}; 823 824 tileNumPerPipe = 256; 825 826 ComputeCmaskInfo(flags, 827 pitch, 828 height, 829 numSlices, 830 isLinear, 831 pTileInfo, 832 &newPitch, 833 &newHeight, 834 &totalBytes, 835 ¯oWidth, 836 ¯oHeight); 837 elemBits = CmaskElemBits; 838 } 839 else //HTile 840 { 841 ADDR_HTILE_FLAGS flags = {{0}}; 842 843 tileNumPerPipe = 512; 844 845 ComputeHtileInfo(flags, 846 pitch, 847 height, 848 numSlices, 849 isLinear, 850 TRUE, 851 TRUE, 852 pTileInfo, 853 &newPitch, 854 &newHeight, 855 &totalBytes, 856 ¯oWidth, 857 ¯oHeight, 858 &pSliceBytes, 859 &pBaseAlign); 860 elemBits = 32; 861 } 862 863 const UINT_32 pitchInTile = newPitch / MicroTileWidth; 864 const UINT_32 heightInTile = newHeight / MicroTileWidth; 865 UINT_64 macroOffset; // Per pipe starting offset of the macro tile in which this tile lies. 866 UINT_64 microNumber; // Per pipe starting offset of the macro tile in which this tile lies. 867 UINT_32 microX; 868 UINT_32 microY; 869 UINT_64 microOffset; 870 UINT_32 microShift; 871 UINT_64 totalOffset; 872 UINT_32 elemIdxBits; 873 UINT_32 elemIdx = 874 TileCoordToMaskElementIndex(tx, ty, pTileInfo->pipeConfig, µShift, &elemIdxBits); 875 876 UINT_32 numPipes = HwlGetPipes(pTileInfo); 877 878 if (isLinear) 879 { //linear addressing 880 // Linear addressing is extremelly wasting memory if slice > 1, since each pipe has the full 881 // slice memory foot print instead of divided by numPipes. 882 microX = tx / 4; // Macro Tile is 4x4 883 microY = ty / 4 ; 884 microNumber = static_cast<UINT_64>(microX + microY * (pitchInTile / 4)) << microShift; 885 886 UINT_32 sliceBits = pitchInTile * heightInTile; 887 888 // do htile single slice alignment if the flag is true 889 if (m_configFlags.useHtileSliceAlign && (factor == 1)) //Htile 890 { 891 sliceBits = PowTwoAlign(sliceBits, BITS_TO_BYTES(HtileCacheBits) * numPipes / elemBits); 892 } 893 macroOffset = slice * (sliceBits / numPipes) * elemBits ; 894 } 895 else 896 { //tiled addressing 897 const UINT_32 macroWidthInTile = macroWidth / MicroTileWidth; // Now in unit of Tiles 898 const UINT_32 macroHeightInTile = macroHeight / MicroTileHeight; 899 const UINT_32 pitchInCL = pitchInTile / macroWidthInTile; 900 const UINT_32 heightInCL = heightInTile / macroHeightInTile; 901 902 const UINT_32 macroX = x / macroWidth; 903 const UINT_32 macroY = y / macroHeight; 904 const UINT_32 macroNumber = macroX + macroY * pitchInCL + slice * pitchInCL * heightInCL; 905 906 // Per pipe starting offset of the cache line in which this tile lies. 907 microX = (x % macroWidth) / MicroTileWidth / 4; // Macro Tile is 4x4 908 microY = (y % macroHeight) / MicroTileHeight / 4 ; 909 microNumber = static_cast<UINT_64>(microX + microY * (macroWidth / MicroTileWidth / 4)) << microShift; 910 911 macroOffset = macroNumber * tileNumPerPipe * elemBits; 912 } 913 914 if(elemIdxBits == microShift) 915 { 916 microNumber += elemIdx; 917 } 918 else 919 { 920 microNumber >>= elemIdxBits; 921 microNumber <<= elemIdxBits; 922 microNumber += elemIdx; 923 } 924 925 microOffset = elemBits * microNumber; 926 totalOffset = microOffset + macroOffset; 927 928 UINT_32 pipe = ComputePipeFromCoord(x, y, 0, ADDR_TM_2D_TILED_THIN1, 0, FALSE, pTileInfo); 929 UINT_64 addrInBits = totalOffset % (m_pipeInterleaveBytes * 8) + 930 pipe * (m_pipeInterleaveBytes * 8) + 931 totalOffset / (m_pipeInterleaveBytes * 8) * (m_pipeInterleaveBytes * 8) * numPipes; 932 *pBitPosition = static_cast<UINT_32>(addrInBits) % 8; 933 UINT_64 addr = addrInBits / 8; 934 935 return addr; 936 } 937 938 /** 939 *************************************************************************************************** 940 * SIAddrLib::HwlComputeXmaskCoordFromAddr 941 * 942 * @brief 943 * Compute the coord from an address of a cmask/htile 944 * 945 * @return 946 * N/A 947 * 948 * @note 949 * This method is reused by htile, so rename to Xmask 950 *************************************************************************************************** 951 */ 952 VOID SIAddrLib::HwlComputeXmaskCoordFromAddr( 953 UINT_64 addr, ///< [in] address 954 UINT_32 bitPosition, ///< [in] bitPosition in a byte 955 UINT_32 pitch, ///< [in] pitch 956 UINT_32 height, ///< [in] height 957 UINT_32 numSlices, ///< [in] number of slices 958 UINT_32 factor, ///< [in] factor that indicates cmask or htile 959 BOOL_32 isLinear, ///< [in] linear or tiled HTILE layout 960 BOOL_32 isWidth8, ///< [in] Not used by SI 961 BOOL_32 isHeight8, ///< [in] Not used by SI 962 ADDR_TILEINFO* pTileInfo, ///< [in] Tile info 963 UINT_32* pX, ///< [out] x coord 964 UINT_32* pY, ///< [out] y coord 965 UINT_32* pSlice ///< [out] slice index 966 ) const 967 { 968 UINT_32 newPitch; 969 UINT_32 newHeight; 970 UINT_64 totalBytes; 971 UINT_32 clWidth; 972 UINT_32 clHeight; 973 UINT_32 tileNumPerPipe; 974 UINT_64 sliceBytes; 975 976 *pX = 0; 977 *pY = 0; 978 *pSlice = 0; 979 980 if (factor == 2) //CMASK 981 { 982 ADDR_CMASK_FLAGS flags = {{0}}; 983 984 tileNumPerPipe = 256; 985 986 ComputeCmaskInfo(flags, 987 pitch, 988 height, 989 numSlices, 990 isLinear, 991 pTileInfo, 992 &newPitch, 993 &newHeight, 994 &totalBytes, 995 &clWidth, 996 &clHeight); 997 } 998 else //HTile 999 { 1000 ADDR_HTILE_FLAGS flags = {{0}}; 1001 1002 tileNumPerPipe = 512; 1003 1004 ComputeHtileInfo(flags, 1005 pitch, 1006 height, 1007 numSlices, 1008 isLinear, 1009 TRUE, 1010 TRUE, 1011 pTileInfo, 1012 &newPitch, 1013 &newHeight, 1014 &totalBytes, 1015 &clWidth, 1016 &clHeight, 1017 &sliceBytes); 1018 } 1019 1020 const UINT_32 pitchInTile = newPitch / MicroTileWidth; 1021 const UINT_32 heightInTile = newHeight / MicroTileWidth; 1022 const UINT_32 pitchInMacroTile = pitchInTile / 4; 1023 UINT_32 macroShift; 1024 UINT_32 elemIdxBits; 1025 // get macroShift and elemIdxBits 1026 TileCoordToMaskElementIndex(0, 0, pTileInfo->pipeConfig, ¯oShift, &elemIdxBits); 1027 1028 const UINT_32 numPipes = HwlGetPipes(pTileInfo); 1029 const UINT_32 pipe = (UINT_32)((addr / m_pipeInterleaveBytes) % numPipes); 1030 // per pipe 1031 UINT_64 localOffset = (addr % m_pipeInterleaveBytes) + 1032 (addr / m_pipeInterleaveBytes / numPipes)* m_pipeInterleaveBytes; 1033 1034 UINT_32 tileIndex; 1035 if (factor == 2) //CMASK 1036 { 1037 tileIndex = (UINT_32)(localOffset * 2 + (bitPosition != 0)); 1038 } 1039 else 1040 { 1041 tileIndex = (UINT_32)(localOffset / 4); 1042 } 1043 1044 UINT_32 macroOffset; 1045 if (isLinear) 1046 { 1047 UINT_32 sliceSizeInTile = pitchInTile * heightInTile; 1048 1049 // do htile single slice alignment if the flag is true 1050 if (m_configFlags.useHtileSliceAlign && (factor == 1)) //Htile 1051 { 1052 sliceSizeInTile = PowTwoAlign(sliceSizeInTile, static_cast<UINT_32>(sliceBytes) / 64); 1053 } 1054 *pSlice = tileIndex / (sliceSizeInTile / numPipes); 1055 macroOffset = tileIndex % (sliceSizeInTile / numPipes); 1056 } 1057 else 1058 { 1059 const UINT_32 clWidthInTile = clWidth / MicroTileWidth; // Now in unit of Tiles 1060 const UINT_32 clHeightInTile = clHeight / MicroTileHeight; 1061 const UINT_32 pitchInCL = pitchInTile / clWidthInTile; 1062 const UINT_32 heightInCL = heightInTile / clHeightInTile; 1063 const UINT_32 clIndex = tileIndex / tileNumPerPipe; 1064 1065 UINT_32 clX = clIndex % pitchInCL; 1066 UINT_32 clY = (clIndex % (heightInCL * pitchInCL)) / pitchInCL; 1067 1068 *pX = clX * clWidthInTile * MicroTileWidth; 1069 *pY = clY * clHeightInTile * MicroTileHeight; 1070 *pSlice = clIndex / (heightInCL * pitchInCL); 1071 1072 macroOffset = tileIndex % tileNumPerPipe; 1073 } 1074 1075 UINT_32 elemIdx = macroOffset & 7; 1076 macroOffset >>= elemIdxBits; 1077 1078 if (elemIdxBits != macroShift) 1079 { 1080 macroOffset <<= (elemIdxBits - macroShift); 1081 1082 UINT_32 pipebit1 = _BIT(pipe,1); 1083 UINT_32 pipebit2 = _BIT(pipe,2); 1084 UINT_32 pipebit3 = _BIT(pipe,3); 1085 if (pitchInMacroTile % 2) 1086 { //odd 1087 switch (pTileInfo->pipeConfig) 1088 { 1089 case ADDR_PIPECFG_P4_32x32: 1090 macroOffset |= pipebit1; 1091 break; 1092 case ADDR_PIPECFG_P8_32x32_8x16: 1093 case ADDR_PIPECFG_P8_32x32_16x16: 1094 case ADDR_PIPECFG_P8_32x32_16x32: 1095 macroOffset |= pipebit2; 1096 break; 1097 default: 1098 break; 1099 } 1100 1101 } 1102 1103 if (pitchInMacroTile % 4) 1104 { 1105 if (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32) 1106 { 1107 macroOffset |= (pipebit1<<1); 1108 } 1109 if((pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_8x16) || 1110 (pTileInfo->pipeConfig == ADDR_PIPECFG_P16_32x32_16x16)) 1111 { 1112 macroOffset |= (pipebit3<<1); 1113 } 1114 } 1115 } 1116 1117 UINT_32 macroX; 1118 UINT_32 macroY; 1119 1120 if (isLinear) 1121 { 1122 macroX = macroOffset % pitchInMacroTile; 1123 macroY = macroOffset / pitchInMacroTile; 1124 } 1125 else 1126 { 1127 const UINT_32 clWidthInMacroTile = clWidth / (MicroTileWidth * 4); 1128 macroX = macroOffset % clWidthInMacroTile; 1129 macroY = macroOffset / clWidthInMacroTile; 1130 } 1131 1132 *pX += macroX * 4 * MicroTileWidth; 1133 *pY += macroY * 4 * MicroTileHeight; 1134 1135 UINT_32 microX; 1136 UINT_32 microY; 1137 ComputeTileCoordFromPipeAndElemIdx(elemIdx, pipe, pTileInfo->pipeConfig, pitchInMacroTile, 1138 *pX, *pY, µX, µY); 1139 1140 *pX += microX * MicroTileWidth; 1141 *pY += microY * MicroTileWidth; 1142 } 1143 1144 /** 1145 *************************************************************************************************** 1146 * SIAddrLib::HwlGetPitchAlignmentLinear 1147 * @brief 1148 * Get pitch alignment 1149 * @return 1150 * pitch alignment 1151 *************************************************************************************************** 1152 */ 1153 UINT_32 SIAddrLib::HwlGetPitchAlignmentLinear( 1154 UINT_32 bpp, ///< [in] bits per pixel 1155 ADDR_SURFACE_FLAGS flags ///< [in] surface flags 1156 ) const 1157 { 1158 UINT_32 pitchAlign; 1159 1160 // Interleaved access requires a 256B aligned pitch, so fall back to pre-SI alignment 1161 if (flags.interleaved) 1162 { 1163 pitchAlign = Max(64u, m_pipeInterleaveBytes / BITS_TO_BYTES(bpp)); 1164 1165 } 1166 else 1167 { 1168 pitchAlign = Max(8u, 64 / BITS_TO_BYTES(bpp)); 1169 } 1170 1171 return pitchAlign; 1172 } 1173 1174 /** 1175 *************************************************************************************************** 1176 * SIAddrLib::HwlGetSizeAdjustmentLinear 1177 * 1178 * @brief 1179 * Adjust linear surface pitch and slice size 1180 * 1181 * @return 1182 * Logical slice size in bytes 1183 *************************************************************************************************** 1184 */ 1185 UINT_64 SIAddrLib::HwlGetSizeAdjustmentLinear( 1186 AddrTileMode tileMode, ///< [in] tile mode 1187 UINT_32 bpp, ///< [in] bits per pixel 1188 UINT_32 numSamples, ///< [in] number of samples 1189 UINT_32 baseAlign, ///< [in] base alignment 1190 UINT_32 pitchAlign, ///< [in] pitch alignment 1191 UINT_32* pPitch, ///< [in/out] pointer to pitch 1192 UINT_32* pHeight, ///< [in/out] pointer to height 1193 UINT_32* pHeightAlign ///< [in/out] pointer to height align 1194 ) const 1195 { 1196 UINT_64 sliceSize; 1197 if (tileMode == ADDR_TM_LINEAR_GENERAL) 1198 { 1199 sliceSize = BITS_TO_BYTES(static_cast<UINT_64>(*pPitch) * (*pHeight) * bpp * numSamples); 1200 } 1201 else 1202 { 1203 UINT_32 pitch = *pPitch; 1204 UINT_32 height = *pHeight; 1205 1206 UINT_32 pixelsPerPipeInterleave = m_pipeInterleaveBytes / BITS_TO_BYTES(bpp); 1207 UINT_32 sliceAlignInPixel = pixelsPerPipeInterleave < 64 ? 64 : pixelsPerPipeInterleave; 1208 1209 // numSamples should be 1 in real cases (no MSAA for linear but TGL may pass non 1 value) 1210 UINT_64 pixelPerSlice = static_cast<UINT_64>(pitch) * height * numSamples; 1211 1212 while (pixelPerSlice % sliceAlignInPixel) 1213 { 1214 pitch += pitchAlign; 1215 pixelPerSlice = static_cast<UINT_64>(pitch) * height * numSamples; 1216 } 1217 1218 *pPitch = pitch; 1219 1220 UINT_32 heightAlign = 1; 1221 1222 while ((pitch * heightAlign) % sliceAlignInPixel) 1223 { 1224 heightAlign++; 1225 } 1226 1227 *pHeightAlign = heightAlign; 1228 1229 sliceSize = BITS_TO_BYTES(pixelPerSlice * bpp); 1230 } 1231 1232 return sliceSize; 1233 } 1234 1235 /** 1236 *************************************************************************************************** 1237 * SIAddrLib::HwlPreHandleBaseLvl3xPitch 1238 * 1239 * @brief 1240 * Pre-handler of 3x pitch (96 bit) adjustment 1241 * 1242 * @return 1243 * Expected pitch 1244 *************************************************************************************************** 1245 */ 1246 UINT_32 SIAddrLib::HwlPreHandleBaseLvl3xPitch( 1247 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input 1248 UINT_32 expPitch ///< [in] pitch 1249 ) const 1250 { 1251 ADDR_ASSERT(pIn->width == expPitch); 1252 1253 // From SI, if pow2Pad is 1 the pitch is expanded 3x first, then padded to pow2, so nothing to 1254 // do here 1255 if (!pIn->flags.pow2Pad) 1256 { 1257 AddrLib::HwlPreHandleBaseLvl3xPitch(pIn, expPitch); 1258 } 1259 else 1260 { 1261 ADDR_ASSERT(IsPow2(expPitch)); 1262 } 1263 1264 return expPitch; 1265 } 1266 1267 /** 1268 *************************************************************************************************** 1269 * SIAddrLib::HwlPostHandleBaseLvl3xPitch 1270 * 1271 * @brief 1272 * Post-handler of 3x pitch adjustment 1273 * 1274 * @return 1275 * Expected pitch 1276 *************************************************************************************************** 1277 */ 1278 UINT_32 SIAddrLib::HwlPostHandleBaseLvl3xPitch( 1279 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input 1280 UINT_32 expPitch ///< [in] pitch 1281 ) const 1282 { 1283 /** 1284 * @note The pitch will be divided by 3 in the end so the value will look odd but h/w should 1285 * be able to compute a correct pitch from it as h/w address library is doing the job. 1286 */ 1287 // From SI, the pitch is expanded 3x first, then padded to pow2, so no special handler here 1288 if (!pIn->flags.pow2Pad) 1289 { 1290 AddrLib::HwlPostHandleBaseLvl3xPitch(pIn, expPitch); 1291 } 1292 1293 return expPitch; 1294 } 1295 1296 /** 1297 *************************************************************************************************** 1298 * SIAddrLib::HwlGetPitchAlignmentMicroTiled 1299 * 1300 * @brief 1301 * Compute 1D tiled surface pitch alignment 1302 * 1303 * @return 1304 * pitch alignment 1305 *************************************************************************************************** 1306 */ 1307 UINT_32 SIAddrLib::HwlGetPitchAlignmentMicroTiled( 1308 AddrTileMode tileMode, ///< [in] tile mode 1309 UINT_32 bpp, ///< [in] bits per pixel 1310 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags 1311 UINT_32 numSamples ///< [in] number of samples 1312 ) const 1313 { 1314 UINT_32 pitchAlign; 1315 1316 if (flags.qbStereo) 1317 { 1318 pitchAlign = EgBasedAddrLib::HwlGetPitchAlignmentMicroTiled(tileMode,bpp,flags,numSamples); 1319 } 1320 else 1321 { 1322 pitchAlign = 8; 1323 } 1324 1325 return pitchAlign; 1326 } 1327 1328 /** 1329 *************************************************************************************************** 1330 * SIAddrLib::HwlGetSizeAdjustmentMicroTiled 1331 * 1332 * @brief 1333 * Adjust 1D tiled surface pitch and slice size 1334 * 1335 * @return 1336 * Logical slice size in bytes 1337 *************************************************************************************************** 1338 */ 1339 UINT_64 SIAddrLib::HwlGetSizeAdjustmentMicroTiled( 1340 UINT_32 thickness, ///< [in] thickness 1341 UINT_32 bpp, ///< [in] bits per pixel 1342 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags 1343 UINT_32 numSamples, ///< [in] number of samples 1344 UINT_32 baseAlign, ///< [in] base alignment 1345 UINT_32 pitchAlign, ///< [in] pitch alignment 1346 UINT_32* pPitch, ///< [in/out] pointer to pitch 1347 UINT_32* pHeight ///< [in/out] pointer to height 1348 ) const 1349 { 1350 UINT_64 logicalSliceSize; 1351 UINT_64 physicalSliceSize; 1352 1353 UINT_32 pitch = *pPitch; 1354 UINT_32 height = *pHeight; 1355 1356 // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1) 1357 logicalSliceSize = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples); 1358 1359 // Physical slice: multiplied by thickness 1360 physicalSliceSize = logicalSliceSize * thickness; 1361 1362 // Pitch alignment is always 8, so if slice size is not padded to base alignment 1363 // (pipe_interleave_size), we need to increase pitch 1364 while ((physicalSliceSize % baseAlign) != 0) 1365 { 1366 pitch += pitchAlign; 1367 1368 logicalSliceSize = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples); 1369 1370 physicalSliceSize = logicalSliceSize * thickness; 1371 } 1372 1373 #if !ALT_TEST 1374 // 1375 // Special workaround for depth/stencil buffer, use 8 bpp to align depth buffer again since 1376 // the stencil plane may have larger pitch if the slice size is smaller than base alignment. 1377 // 1378 // Note: this actually does not work for mipmap but mipmap depth texture is not really 1379 // sampled with mipmap. 1380 // 1381 if (flags.depth && !flags.noStencil) 1382 { 1383 ADDR_ASSERT(numSamples == 1); 1384 1385 UINT_64 logicalSiceSizeStencil = static_cast<UINT_64>(pitch) * height; // 1 byte stencil 1386 1387 while ((logicalSiceSizeStencil % baseAlign) != 0) 1388 { 1389 pitch += pitchAlign; // Stencil plane's pitch alignment is the same as depth plane's 1390 1391 logicalSiceSizeStencil = static_cast<UINT_64>(pitch) * height; 1392 } 1393 1394 if (pitch != *pPitch) 1395 { 1396 // If this is a mipmap, this padded one cannot be sampled as a whole mipmap! 1397 logicalSliceSize = logicalSiceSizeStencil * BITS_TO_BYTES(bpp); 1398 } 1399 } 1400 #endif 1401 *pPitch = pitch; 1402 1403 // No adjust for pHeight 1404 1405 return logicalSliceSize; 1406 } 1407 1408 /** 1409 *************************************************************************************************** 1410 * SIAddrLib::HwlConvertChipFamily 1411 * 1412 * @brief 1413 * Convert familyID defined in atiid.h to AddrChipFamily and set m_chipFamily/m_chipRevision 1414 * @return 1415 * AddrChipFamily 1416 *************************************************************************************************** 1417 */ 1418 AddrChipFamily SIAddrLib::HwlConvertChipFamily( 1419 UINT_32 uChipFamily, ///< [in] chip family defined in atiih.h 1420 UINT_32 uChipRevision) ///< [in] chip revision defined in "asic_family"_id.h 1421 { 1422 AddrChipFamily family = ADDR_CHIP_FAMILY_SI; 1423 1424 switch (uChipFamily) 1425 { 1426 case FAMILY_SI: 1427 m_settings.isSouthernIsland = 1; 1428 m_settings.isTahiti = ASICREV_IS_TAHITI_P(uChipRevision); 1429 m_settings.isPitCairn = ASICREV_IS_PITCAIRN_PM(uChipRevision); 1430 m_settings.isCapeVerde = ASICREV_IS_CAPEVERDE_M(uChipRevision); 1431 m_settings.isOland = ASICREV_IS_OLAND_M(uChipRevision); 1432 m_settings.isHainan = ASICREV_IS_HAINAN_V(uChipRevision); 1433 break; 1434 default: 1435 ADDR_ASSERT(!"This should be a Fusion"); 1436 break; 1437 } 1438 1439 return family; 1440 } 1441 1442 /** 1443 *************************************************************************************************** 1444 * SIAddrLib::HwlSetupTileInfo 1445 * 1446 * @brief 1447 * Setup default value of tile info for SI 1448 *************************************************************************************************** 1449 */ 1450 VOID SIAddrLib::HwlSetupTileInfo( 1451 AddrTileMode tileMode, ///< [in] Tile mode 1452 ADDR_SURFACE_FLAGS flags, ///< [in] Surface type flags 1453 UINT_32 bpp, ///< [in] Bits per pixel 1454 UINT_32 pitch, ///< [in] Pitch in pixels 1455 UINT_32 height, ///< [in] Height in pixels 1456 UINT_32 numSamples, ///< [in] Number of samples 1457 ADDR_TILEINFO* pTileInfoIn, ///< [in] Tile info input: NULL for default 1458 ADDR_TILEINFO* pTileInfoOut, ///< [out] Tile info output 1459 AddrTileType inTileType, ///< [in] Tile type 1460 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] Output 1461 ) const 1462 { 1463 UINT_32 thickness = ComputeSurfaceThickness(tileMode); 1464 ADDR_TILEINFO* pTileInfo = pTileInfoOut; 1465 INT index = TileIndexInvalid; 1466 1467 // Fail-safe code 1468 if (!IsLinear(tileMode)) 1469 { 1470 // 128 bpp/thick tiling must be non-displayable. 1471 // Fmask reuse color buffer's entry but bank-height field can be from another entry 1472 // To simplify the logic, fmask entry should be picked from non-displayable ones 1473 if (bpp == 128 || thickness > 1 || flags.fmask || flags.prt) 1474 { 1475 inTileType = ADDR_NON_DISPLAYABLE; 1476 } 1477 1478 if (flags.depth || flags.stencil) 1479 { 1480 inTileType = ADDR_DEPTH_SAMPLE_ORDER; 1481 } 1482 } 1483 1484 // Partial valid fields are not allowed for SI. 1485 if (IsTileInfoAllZero(pTileInfo)) 1486 { 1487 if (IsMacroTiled(tileMode)) 1488 { 1489 if (flags.prt) 1490 { 1491 if (numSamples == 1) 1492 { 1493 if (flags.depth) 1494 { 1495 switch (bpp) 1496 { 1497 case 16: 1498 index = 3; 1499 break; 1500 case 32: 1501 index = 6; 1502 break; 1503 default: 1504 ADDR_ASSERT_ALWAYS(); 1505 break; 1506 } 1507 } 1508 else 1509 { 1510 switch (bpp) 1511 { 1512 case 8: 1513 index = 21; 1514 break; 1515 case 16: 1516 index = 22; 1517 break; 1518 case 32: 1519 index = 23; 1520 break; 1521 case 64: 1522 index = 24; 1523 break; 1524 case 128: 1525 index = 25; 1526 break; 1527 default: 1528 break; 1529 } 1530 1531 if (thickness > 1) 1532 { 1533 ADDR_ASSERT(bpp != 128); 1534 index += 5; 1535 } 1536 } 1537 } 1538 else 1539 { 1540 ADDR_ASSERT(numSamples == 4); 1541 1542 if (flags.depth) 1543 { 1544 switch (bpp) 1545 { 1546 case 16: 1547 index = 5; 1548 break; 1549 case 32: 1550 index = 7; 1551 break; 1552 default: 1553 ADDR_ASSERT_ALWAYS(); 1554 break; 1555 } 1556 } 1557 else 1558 { 1559 switch (bpp) 1560 { 1561 case 8: 1562 index = 23; 1563 break; 1564 case 16: 1565 index = 24; 1566 break; 1567 case 32: 1568 index = 25; 1569 break; 1570 case 64: 1571 index = 30; 1572 break; 1573 default: 1574 ADDR_ASSERT_ALWAYS(); 1575 break; 1576 } 1577 } 1578 } 1579 }//end of PRT part 1580 // See table entries 0-7 1581 else if (flags.depth || flags.stencil) 1582 { 1583 if (flags.compressZ) 1584 { 1585 if (flags.stencil) 1586 { 1587 index = 0; 1588 } 1589 else 1590 { 1591 // optimal tile index for compressed depth/stencil. 1592 switch (numSamples) 1593 { 1594 case 1: 1595 index = 0; 1596 break; 1597 case 2: 1598 case 4: 1599 index = 1; 1600 break; 1601 case 8: 1602 index = 2; 1603 break; 1604 default: 1605 break; 1606 } 1607 } 1608 } 1609 else // unCompressZ 1610 { 1611 index = 3; 1612 } 1613 } 1614 else //non PRT & non Depth & non Stencil 1615 { 1616 // See table entries 9-12 1617 if (inTileType == ADDR_DISPLAYABLE) 1618 { 1619 switch (bpp) 1620 { 1621 case 8: 1622 index = 10; 1623 break; 1624 case 16: 1625 index = 11; 1626 break; 1627 case 32: 1628 index = 12; 1629 break; 1630 case 64: 1631 index = 12; 1632 break; 1633 default: 1634 break; 1635 } 1636 } 1637 else 1638 { 1639 // See table entries 13-17 1640 if (thickness == 1) 1641 { 1642 if (flags.fmask) 1643 { 1644 UINT_32 fmaskPixelSize = bpp * numSamples; 1645 1646 switch (fmaskPixelSize) 1647 { 1648 case 8: 1649 index = 14; 1650 break; 1651 case 16: 1652 index = 15; 1653 break; 1654 case 32: 1655 index = 16; 1656 break; 1657 case 64: 1658 index = 17; 1659 break; 1660 default: 1661 ADDR_ASSERT_ALWAYS(); 1662 } 1663 } 1664 else 1665 { 1666 switch (bpp) 1667 { 1668 case 8: 1669 index = 14; 1670 break; 1671 case 16: 1672 index = 15; 1673 break; 1674 case 32: 1675 index = 16; 1676 break; 1677 case 64: 1678 index = 17; 1679 break; 1680 case 128: 1681 index = 17; 1682 break; 1683 default: 1684 break; 1685 } 1686 } 1687 } 1688 else // thick tiling - entries 18-20 1689 { 1690 switch (thickness) 1691 { 1692 case 4: 1693 index = 20; 1694 break; 1695 case 8: 1696 index = 19; 1697 break; 1698 default: 1699 break; 1700 } 1701 } 1702 } 1703 } 1704 } 1705 else 1706 { 1707 if (tileMode == ADDR_TM_LINEAR_ALIGNED) 1708 { 1709 index = 8; 1710 } 1711 else if (tileMode == ADDR_TM_LINEAR_GENERAL) 1712 { 1713 index = TileIndexLinearGeneral; 1714 } 1715 else 1716 { 1717 if (flags.depth || flags.stencil) 1718 { 1719 index = 4; 1720 } 1721 else if (inTileType == ADDR_DISPLAYABLE) 1722 { 1723 index = 9; 1724 } 1725 else if (thickness == 1) 1726 { 1727 index = 13; 1728 } 1729 else 1730 { 1731 index = 18; 1732 } 1733 } 1734 } 1735 1736 if (index >= 0 && index <= 31) 1737 { 1738 *pTileInfo = m_tileTable[index].info; 1739 pOut->tileType = m_tileTable[index].type; 1740 } 1741 1742 if (index == TileIndexLinearGeneral) 1743 { 1744 *pTileInfo = m_tileTable[8].info; 1745 pOut->tileType = m_tileTable[8].type; 1746 } 1747 } 1748 else 1749 { 1750 if (pTileInfoIn) 1751 { 1752 if (flags.stencil && pTileInfoIn->tileSplitBytes == 0) 1753 { 1754 // Stencil always uses index 0 1755 *pTileInfo = m_tileTable[0].info; 1756 } 1757 } 1758 // Pass through tile type 1759 pOut->tileType = inTileType; 1760 } 1761 1762 pOut->tileIndex = index; 1763 } 1764 1765 /** 1766 *************************************************************************************************** 1767 * SIAddrLib::DecodeGbRegs 1768 * 1769 * @brief 1770 * Decodes GB_ADDR_CONFIG and noOfBanks/noOfRanks 1771 * 1772 * @return 1773 * TRUE if all settings are valid 1774 * 1775 *************************************************************************************************** 1776 */ 1777 BOOL_32 SIAddrLib::DecodeGbRegs( 1778 const ADDR_REGISTER_VALUE* pRegValue) ///< [in] create input 1779 { 1780 GB_ADDR_CONFIG reg; 1781 BOOL_32 valid = TRUE; 1782 1783 reg.val = pRegValue->gbAddrConfig; 1784 1785 switch (reg.f.pipe_interleave_size) 1786 { 1787 case ADDR_CONFIG_PIPE_INTERLEAVE_256B: 1788 m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_256B; 1789 break; 1790 case ADDR_CONFIG_PIPE_INTERLEAVE_512B: 1791 m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_512B; 1792 break; 1793 default: 1794 valid = FALSE; 1795 ADDR_UNHANDLED_CASE(); 1796 break; 1797 } 1798 1799 switch (reg.f.row_size) 1800 { 1801 case ADDR_CONFIG_1KB_ROW: 1802 m_rowSize = ADDR_ROWSIZE_1KB; 1803 break; 1804 case ADDR_CONFIG_2KB_ROW: 1805 m_rowSize = ADDR_ROWSIZE_2KB; 1806 break; 1807 case ADDR_CONFIG_4KB_ROW: 1808 m_rowSize = ADDR_ROWSIZE_4KB; 1809 break; 1810 default: 1811 valid = FALSE; 1812 ADDR_UNHANDLED_CASE(); 1813 break; 1814 } 1815 1816 switch (pRegValue->noOfBanks) 1817 { 1818 case 0: 1819 m_banks = 4; 1820 break; 1821 case 1: 1822 m_banks = 8; 1823 break; 1824 case 2: 1825 m_banks = 16; 1826 break; 1827 default: 1828 valid = FALSE; 1829 ADDR_UNHANDLED_CASE(); 1830 break; 1831 } 1832 1833 switch (pRegValue->noOfRanks) 1834 { 1835 case 0: 1836 m_ranks = 1; 1837 break; 1838 case 1: 1839 m_ranks = 2; 1840 break; 1841 default: 1842 valid = FALSE; 1843 ADDR_UNHANDLED_CASE(); 1844 break; 1845 } 1846 1847 m_logicalBanks = m_banks * m_ranks; 1848 1849 ADDR_ASSERT(m_logicalBanks <= 16); 1850 1851 return valid; 1852 } 1853 1854 /** 1855 *************************************************************************************************** 1856 * SIAddrLib::HwlInitGlobalParams 1857 * 1858 * @brief 1859 * Initializes global parameters 1860 * 1861 * @return 1862 * TRUE if all settings are valid 1863 * 1864 *************************************************************************************************** 1865 */ 1866 BOOL_32 SIAddrLib::HwlInitGlobalParams( 1867 const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input 1868 { 1869 BOOL_32 valid = TRUE; 1870 const ADDR_REGISTER_VALUE* pRegValue = &pCreateIn->regValue; 1871 1872 valid = DecodeGbRegs(pRegValue); 1873 1874 if (valid) 1875 { 1876 if (m_settings.isTahiti || m_settings.isPitCairn) 1877 { 1878 m_pipes = 8; 1879 } 1880 else if (m_settings.isCapeVerde || m_settings.isOland) 1881 { 1882 m_pipes = 4; 1883 } 1884 else 1885 { 1886 // Hainan is 2-pipe (m_settings.isHainan == 1) 1887 m_pipes = 2; 1888 } 1889 1890 valid = InitTileSettingTable(pRegValue->pTileConfig, pRegValue->noOfEntries); 1891 1892 m_maxSamples = 16; 1893 } 1894 1895 return valid; 1896 } 1897 1898 /** 1899 *************************************************************************************************** 1900 * SIAddrLib::HwlConvertTileInfoToHW 1901 * @brief 1902 * Entry of si's ConvertTileInfoToHW 1903 * @return 1904 * ADDR_E_RETURNCODE 1905 *************************************************************************************************** 1906 */ 1907 ADDR_E_RETURNCODE SIAddrLib::HwlConvertTileInfoToHW( 1908 const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure 1909 ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut ///< [out] output structure 1910 ) const 1911 { 1912 ADDR_E_RETURNCODE retCode = ADDR_OK; 1913 1914 retCode = EgBasedAddrLib::HwlConvertTileInfoToHW(pIn, pOut); 1915 1916 if (retCode == ADDR_OK) 1917 { 1918 if (pIn->reverse == FALSE) 1919 { 1920 if (pIn->pTileInfo->pipeConfig == ADDR_PIPECFG_INVALID) 1921 { 1922 retCode = ADDR_INVALIDPARAMS; 1923 } 1924 else 1925 { 1926 pOut->pTileInfo->pipeConfig = 1927 static_cast<AddrPipeCfg>(pIn->pTileInfo->pipeConfig - 1); 1928 } 1929 } 1930 else 1931 { 1932 pOut->pTileInfo->pipeConfig = 1933 static_cast<AddrPipeCfg>(pIn->pTileInfo->pipeConfig + 1); 1934 } 1935 } 1936 1937 return retCode; 1938 } 1939 1940 /** 1941 *************************************************************************************************** 1942 * SIAddrLib::HwlComputeXmaskCoordYFrom8Pipe 1943 * 1944 * @brief 1945 * Compute the Y coord which will be added to Xmask Y 1946 * coord. 1947 * @return 1948 * Y coord 1949 *************************************************************************************************** 1950 */ 1951 UINT_32 SIAddrLib::HwlComputeXmaskCoordYFrom8Pipe( 1952 UINT_32 pipe, ///< [in] pipe id 1953 UINT_32 x ///< [in] tile coord x, which is original x coord / 8 1954 ) const 1955 { 1956 // This function should never be called since it is 6xx/8xx specfic. 1957 // Keep this empty implementation to avoid any mis-use. 1958 ADDR_ASSERT_ALWAYS(); 1959 1960 return 0; 1961 } 1962 1963 /** 1964 *************************************************************************************************** 1965 * SIAddrLib::HwlComputeSurfaceCoord2DFromBankPipe 1966 * 1967 * @brief 1968 * Compute surface x,y coordinates from bank/pipe info 1969 * @return 1970 * N/A 1971 *************************************************************************************************** 1972 */ 1973 VOID SIAddrLib::HwlComputeSurfaceCoord2DFromBankPipe( 1974 AddrTileMode tileMode, ///< [in] tile mode 1975 UINT_32* pX, ///< [in/out] x coordinate 1976 UINT_32* pY, ///< [in/out] y coordinate 1977 UINT_32 slice, ///< [in] slice index 1978 UINT_32 bank, ///< [in] bank number 1979 UINT_32 pipe, ///< [in] pipe number 1980 UINT_32 bankSwizzle,///< [in] bank swizzle 1981 UINT_32 pipeSwizzle,///< [in] pipe swizzle 1982 UINT_32 tileSlices, ///< [in] slices in a micro tile 1983 BOOL_32 ignoreSE, ///< [in] TRUE if shader engines are ignored 1984 ADDR_TILEINFO* pTileInfo ///< [in] bank structure. **All fields to be valid on entry** 1985 ) const 1986 { 1987 UINT_32 xBit; 1988 UINT_32 yBit; 1989 UINT_32 yBit3 = 0; 1990 UINT_32 yBit4 = 0; 1991 UINT_32 yBit5 = 0; 1992 UINT_32 yBit6 = 0; 1993 1994 UINT_32 xBit3 = 0; 1995 UINT_32 xBit4 = 0; 1996 UINT_32 xBit5 = 0; 1997 1998 UINT_32 numPipes = GetPipePerSurf(pTileInfo->pipeConfig); 1999 2000 CoordFromBankPipe xyBits = {0}; 2001 ComputeSurfaceCoord2DFromBankPipe(tileMode, *pX, *pY, slice, bank, pipe, 2002 bankSwizzle, pipeSwizzle, tileSlices, pTileInfo, 2003 &xyBits); 2004 yBit3 = xyBits.yBit3; 2005 yBit4 = xyBits.yBit4; 2006 yBit5 = xyBits.yBit5; 2007 yBit6 = xyBits.yBit6; 2008 2009 xBit3 = xyBits.xBit3; 2010 xBit4 = xyBits.xBit4; 2011 xBit5 = xyBits.xBit5; 2012 2013 yBit = xyBits.yBits; 2014 2015 UINT_32 yBitTemp = 0; 2016 2017 if ((pTileInfo->pipeConfig == ADDR_PIPECFG_P4_32x32) || 2018 (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32)) 2019 { 2020 ADDR_ASSERT(pTileInfo->bankWidth == 1 && pTileInfo->macroAspectRatio > 1); 2021 UINT_32 yBitToCheck = QLog2(pTileInfo->banks) - 1; 2022 2023 ADDR_ASSERT(yBitToCheck <= 3); 2024 2025 yBitTemp = _BIT(yBit, yBitToCheck); 2026 2027 xBit3 = 0; 2028 } 2029 2030 yBit = Bits2Number(4, yBit6, yBit5, yBit4, yBit3); 2031 xBit = Bits2Number(3, xBit5, xBit4, xBit3); 2032 2033 *pY += yBit * pTileInfo->bankHeight * MicroTileHeight; 2034 *pX += xBit * numPipes * pTileInfo->bankWidth * MicroTileWidth; 2035 2036 //calculate the bank and pipe bits in x, y 2037 UINT_32 xTile; //x in micro tile 2038 UINT_32 x3 = 0; 2039 UINT_32 x4 = 0; 2040 UINT_32 x5 = 0; 2041 UINT_32 x6 = 0; 2042 UINT_32 y = *pY; 2043 2044 UINT_32 pipeBit0 = _BIT(pipe,0); 2045 UINT_32 pipeBit1 = _BIT(pipe,1); 2046 UINT_32 pipeBit2 = _BIT(pipe,2); 2047 2048 UINT_32 y3 = _BIT(y, 3); 2049 UINT_32 y4 = _BIT(y, 4); 2050 UINT_32 y5 = _BIT(y, 5); 2051 UINT_32 y6 = _BIT(y, 6); 2052 2053 // bankbit0 after ^x4^x5 2054 UINT_32 bankBit00 = _BIT(bank,0); 2055 UINT_32 bankBit0 = 0; 2056 2057 switch (pTileInfo->pipeConfig) 2058 { 2059 case ADDR_PIPECFG_P2: 2060 x3 = pipeBit0 ^ y3; 2061 break; 2062 case ADDR_PIPECFG_P4_8x16: 2063 x4 = pipeBit0 ^ y3; 2064 x3 = pipeBit0 ^ y4; 2065 break; 2066 case ADDR_PIPECFG_P4_16x16: 2067 x4 = pipeBit1 ^ y4; 2068 x3 = pipeBit0 ^ y3 ^ x4; 2069 break; 2070 case ADDR_PIPECFG_P4_16x32: 2071 x4 = pipeBit1 ^ y4; 2072 x3 = pipeBit0 ^ y3 ^ x4; 2073 break; 2074 case ADDR_PIPECFG_P4_32x32: 2075 x5 = pipeBit1 ^ y5; 2076 x3 = pipeBit0 ^ y3 ^ x5; 2077 bankBit0 = yBitTemp ^ x5; 2078 x4 = bankBit00 ^ x5 ^ bankBit0; 2079 *pX += x5 * 4 * 1 * 8; // x5 * num_pipes * bank_width * 8; 2080 break; 2081 case ADDR_PIPECFG_P8_16x16_8x16: 2082 x3 = pipeBit1 ^ y5; 2083 x4 = pipeBit2 ^ y4; 2084 x5 = pipeBit0 ^ y3 ^ x4; 2085 break; 2086 case ADDR_PIPECFG_P8_16x32_8x16: 2087 x3 = pipeBit1 ^ y4; 2088 x4 = pipeBit2 ^ y5; 2089 x5 = pipeBit0 ^ y3 ^ x4; 2090 break; 2091 case ADDR_PIPECFG_P8_32x32_8x16: 2092 x3 = pipeBit1 ^ y4; 2093 x5 = pipeBit2 ^ y5; 2094 x4 = pipeBit0 ^ y3 ^ x5; 2095 break; 2096 case ADDR_PIPECFG_P8_16x32_16x16: 2097 x4 = pipeBit2 ^ y5; 2098 x5 = pipeBit1 ^ y4; 2099 x3 = pipeBit0 ^ y3 ^ x4; 2100 break; 2101 case ADDR_PIPECFG_P8_32x32_16x16: 2102 x5 = pipeBit2 ^ y5; 2103 x4 = pipeBit1 ^ y4; 2104 x3 = pipeBit0 ^ y3 ^ x4; 2105 break; 2106 case ADDR_PIPECFG_P8_32x32_16x32: 2107 x5 = pipeBit2 ^ y5; 2108 x4 = pipeBit1 ^ y6; 2109 x3 = pipeBit0 ^ y3 ^ x4; 2110 break; 2111 case ADDR_PIPECFG_P8_32x64_32x32: 2112 x6 = pipeBit1 ^ y5; 2113 x5 = pipeBit2 ^ y6; 2114 x3 = pipeBit0 ^ y3 ^ x5; 2115 bankBit0 = yBitTemp ^ x6; 2116 x4 = bankBit00 ^ x5 ^ bankBit0; 2117 *pX += x6 * 8 * 1 * 8; // x6 * num_pipes * bank_width * 8; 2118 break; 2119 default: 2120 ADDR_ASSERT_ALWAYS(); 2121 } 2122 2123 xTile = Bits2Number(3, x5, x4, x3); 2124 2125 *pX += xTile << 3; 2126 } 2127 2128 /** 2129 *************************************************************************************************** 2130 * SIAddrLib::HwlPreAdjustBank 2131 * 2132 * @brief 2133 * Adjust bank before calculating address acoording to bank/pipe 2134 * @return 2135 * Adjusted bank 2136 *************************************************************************************************** 2137 */ 2138 UINT_32 SIAddrLib::HwlPreAdjustBank( 2139 UINT_32 tileX, ///< [in] x coordinate in unit of tile 2140 UINT_32 bank, ///< [in] bank 2141 ADDR_TILEINFO* pTileInfo ///< [in] tile info 2142 ) const 2143 { 2144 if (((pTileInfo->pipeConfig == ADDR_PIPECFG_P4_32x32) || 2145 (pTileInfo->pipeConfig == ADDR_PIPECFG_P8_32x64_32x32)) && (pTileInfo->bankWidth == 1)) 2146 { 2147 UINT_32 bankBit0 = _BIT(bank, 0); 2148 UINT_32 x4 = _BIT(tileX, 1); 2149 UINT_32 x5 = _BIT(tileX, 2); 2150 2151 bankBit0 = bankBit0 ^ x4 ^ x5; 2152 bank |= bankBit0; 2153 2154 ADDR_ASSERT(pTileInfo->macroAspectRatio > 1) 2155 } 2156 2157 return bank; 2158 } 2159 2160 /** 2161 *************************************************************************************************** 2162 * SIAddrLib::HwlComputeSurfaceInfo 2163 * 2164 * @brief 2165 * Entry of si's ComputeSurfaceInfo 2166 * @return 2167 * ADDR_E_RETURNCODE 2168 *************************************************************************************************** 2169 */ 2170 ADDR_E_RETURNCODE SIAddrLib::HwlComputeSurfaceInfo( 2171 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure 2172 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure 2173 ) const 2174 { 2175 pOut->tileIndex = pIn->tileIndex; 2176 2177 return EgBasedAddrLib::HwlComputeSurfaceInfo(pIn,pOut); 2178 } 2179 2180 /** 2181 *************************************************************************************************** 2182 * SIAddrLib::HwlComputeMipLevel 2183 * @brief 2184 * Compute MipLevel info (including level 0) 2185 * @return 2186 * TRUE if HWL's handled 2187 *************************************************************************************************** 2188 */ 2189 BOOL_32 SIAddrLib::HwlComputeMipLevel( 2190 ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in/out] Input structure 2191 ) const 2192 { 2193 // basePitch is calculated from level 0 so we only check this for mipLevel > 0 2194 if (pIn->mipLevel > 0) 2195 { 2196 // Note: Don't check expand 3x formats(96 bit) as the basePitch is not pow2 even if 2197 // we explicity set pow2Pad flag. The 3x base pitch is padded to pow2 but after being 2198 // divided by expandX factor (3) - to program texture pitch, the basePitch is never pow2. 2199 if (!AddrElemLib::IsExpand3x(pIn->format)) 2200 { 2201 // Sublevel pitches are generated from base level pitch instead of width on SI 2202 // If pow2Pad is 0, we don't assert - as this is not really used for a mip chain 2203 ADDR_ASSERT(!pIn->flags.pow2Pad || ((pIn->basePitch != 0) && IsPow2(pIn->basePitch))); 2204 } 2205 2206 if (pIn->basePitch != 0) 2207 { 2208 pIn->width = Max(1u, pIn->basePitch >> pIn->mipLevel); 2209 } 2210 } 2211 2212 // pow2Pad is done in PostComputeMipLevel 2213 2214 return TRUE; 2215 } 2216 2217 /** 2218 *************************************************************************************************** 2219 * SIAddrLib::HwlCheckLastMacroTiledLvl 2220 * 2221 * @brief 2222 * Sets pOut->last2DLevel to TRUE if it is 2223 * @note 2224 * 2225 *************************************************************************************************** 2226 */ 2227 VOID SIAddrLib::HwlCheckLastMacroTiledLvl( 2228 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure 2229 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in/out] Output structure (used as input, too) 2230 ) const 2231 { 2232 // pow2Pad covers all mipmap cases 2233 if (pIn->flags.pow2Pad) 2234 { 2235 ADDR_ASSERT(IsMacroTiled(pIn->tileMode)); 2236 2237 UINT_32 nextPitch; 2238 UINT_32 nextHeight; 2239 UINT_32 nextSlices; 2240 2241 AddrTileMode nextTileMode; 2242 2243 if (pIn->mipLevel == 0 || pIn->basePitch == 0) 2244 { 2245 // Base level or fail-safe case (basePitch == 0) 2246 nextPitch = pOut->pitch >> 1; 2247 } 2248 else 2249 { 2250 // Sub levels 2251 nextPitch = pIn->basePitch >> (pIn->mipLevel + 1); 2252 } 2253 2254 // nextHeight must be shifted from this level's original height rather than a pow2 padded 2255 // one but this requires original height stored somewhere (pOut->height) 2256 ADDR_ASSERT(pOut->height != 0); 2257 2258 // next level's height is just current level's >> 1 in pixels 2259 nextHeight = pOut->height >> 1; 2260 // Special format such as FMT_1 and FMT_32_32_32 can be linear only so we consider block 2261 // compressed foramts 2262 if (AddrElemLib::IsBlockCompressed(pIn->format)) 2263 { 2264 nextHeight = (nextHeight + 3) / 4; 2265 } 2266 nextHeight = NextPow2(nextHeight); 2267 2268 // nextSlices may be 0 if this level's is 1 2269 if (pIn->flags.volume) 2270 { 2271 nextSlices = Max(1u, pIn->numSlices >> 1); 2272 } 2273 else 2274 { 2275 nextSlices = pIn->numSlices; 2276 } 2277 2278 nextTileMode = ComputeSurfaceMipLevelTileMode(pIn->tileMode, 2279 pIn->bpp, 2280 nextPitch, 2281 nextHeight, 2282 nextSlices, 2283 pIn->numSamples, 2284 pOut->pitchAlign, 2285 pOut->heightAlign, 2286 pOut->pTileInfo); 2287 2288 pOut->last2DLevel = IsMicroTiled(nextTileMode); 2289 } 2290 } 2291 2292 /** 2293 *************************************************************************************************** 2294 * SIAddrLib::HwlDegradeThickTileMode 2295 * 2296 * @brief 2297 * Degrades valid tile mode for thick modes if needed 2298 * 2299 * @return 2300 * Suitable tile mode 2301 *************************************************************************************************** 2302 */ 2303 AddrTileMode SIAddrLib::HwlDegradeThickTileMode( 2304 AddrTileMode baseTileMode, ///< [in] base tile mode 2305 UINT_32 numSlices, ///< [in] current number of slices 2306 UINT_32* pBytesPerTile ///< [in/out] pointer to bytes per slice 2307 ) const 2308 { 2309 return EgBasedAddrLib::HwlDegradeThickTileMode(baseTileMode, numSlices, pBytesPerTile); 2310 } 2311 2312 /** 2313 *************************************************************************************************** 2314 * SIAddrLib::HwlTileInfoEqual 2315 * 2316 * @brief 2317 * Return TRUE if all field are equal 2318 * @note 2319 * Only takes care of current HWL's data 2320 *************************************************************************************************** 2321 */ 2322 BOOL_32 SIAddrLib::HwlTileInfoEqual( 2323 const ADDR_TILEINFO* pLeft, ///<[in] Left compare operand 2324 const ADDR_TILEINFO* pRight ///<[in] Right compare operand 2325 ) const 2326 { 2327 BOOL_32 equal = FALSE; 2328 2329 if (pLeft->pipeConfig == pRight->pipeConfig) 2330 { 2331 equal = EgBasedAddrLib::HwlTileInfoEqual(pLeft, pRight); 2332 } 2333 2334 return equal; 2335 } 2336 2337 /** 2338 *************************************************************************************************** 2339 * SIAddrLib::GetTileSettings 2340 * 2341 * @brief 2342 * Get tile setting infos by index. 2343 * @return 2344 * Tile setting info. 2345 *************************************************************************************************** 2346 */ 2347 const ADDR_TILECONFIG* SIAddrLib::GetTileSetting( 2348 UINT_32 index ///< [in] Tile index 2349 ) const 2350 { 2351 ADDR_ASSERT(index < m_noOfEntries); 2352 return &m_tileTable[index]; 2353 } 2354 2355 /** 2356 *************************************************************************************************** 2357 * SIAddrLib::HwlPostCheckTileIndex 2358 * 2359 * @brief 2360 * Map a tile setting to index if curIndex is invalid, otherwise check if curIndex matches 2361 * tile mode/type/info and change the index if needed 2362 * @return 2363 * Tile index. 2364 *************************************************************************************************** 2365 */ 2366 INT_32 SIAddrLib::HwlPostCheckTileIndex( 2367 const ADDR_TILEINFO* pInfo, ///< [in] Tile Info 2368 AddrTileMode mode, ///< [in] Tile mode 2369 AddrTileType type, ///< [in] Tile type 2370 INT curIndex ///< [in] Current index assigned in HwlSetupTileInfo 2371 ) const 2372 { 2373 INT_32 index = curIndex; 2374 2375 if (mode == ADDR_TM_LINEAR_GENERAL) 2376 { 2377 index = TileIndexLinearGeneral; 2378 } 2379 else 2380 { 2381 BOOL_32 macroTiled = IsMacroTiled(mode); 2382 2383 // We need to find a new index if either of them is true 2384 // 1. curIndex is invalid 2385 // 2. tile mode is changed 2386 // 3. tile info does not match for macro tiled 2387 if ((index == TileIndexInvalid || 2388 (mode != m_tileTable[index].mode) || 2389 (macroTiled && !HwlTileInfoEqual(pInfo, &m_tileTable[index].info)))) 2390 { 2391 for (index = 0; index < static_cast<INT_32>(m_noOfEntries); index++) 2392 { 2393 if (macroTiled) 2394 { 2395 // macro tile modes need all to match 2396 if (HwlTileInfoEqual(pInfo, &m_tileTable[index].info) && 2397 (mode == m_tileTable[index].mode) && 2398 (type == m_tileTable[index].type)) 2399 { 2400 break; 2401 } 2402 } 2403 else if (mode == ADDR_TM_LINEAR_ALIGNED) 2404 { 2405 // linear mode only needs tile mode to match 2406 if (mode == m_tileTable[index].mode) 2407 { 2408 break; 2409 } 2410 } 2411 else 2412 { 2413 // micro tile modes only need tile mode and tile type to match 2414 if (mode == m_tileTable[index].mode && 2415 type == m_tileTable[index].type) 2416 { 2417 break; 2418 } 2419 } 2420 } 2421 } 2422 } 2423 2424 ADDR_ASSERT(index < static_cast<INT_32>(m_noOfEntries)); 2425 2426 if (index >= static_cast<INT_32>(m_noOfEntries)) 2427 { 2428 index = TileIndexInvalid; 2429 } 2430 2431 return index; 2432 } 2433 2434 /** 2435 *************************************************************************************************** 2436 * SIAddrLib::HwlSetupTileCfg 2437 * 2438 * @brief 2439 * Map tile index to tile setting. 2440 * @return 2441 * ADDR_E_RETURNCODE 2442 *************************************************************************************************** 2443 */ 2444 ADDR_E_RETURNCODE SIAddrLib::HwlSetupTileCfg( 2445 INT_32 index, ///< [in] Tile index 2446 INT_32 macroModeIndex, ///< [in] Index in macro tile mode table(CI) 2447 ADDR_TILEINFO* pInfo, ///< [out] Tile Info 2448 AddrTileMode* pMode, ///< [out] Tile mode 2449 AddrTileType* pType ///< [out] Tile type 2450 ) const 2451 { 2452 ADDR_E_RETURNCODE returnCode = ADDR_OK; 2453 2454 // Global flag to control usage of tileIndex 2455 if (UseTileIndex(index)) 2456 { 2457 if (index == TileIndexLinearGeneral) 2458 { 2459 if (pMode) 2460 { 2461 *pMode = ADDR_TM_LINEAR_GENERAL; 2462 } 2463 2464 if (pType) 2465 { 2466 *pType = ADDR_DISPLAYABLE; 2467 } 2468 2469 if (pInfo) 2470 { 2471 pInfo->banks = 2; 2472 pInfo->bankWidth = 1; 2473 pInfo->bankHeight = 1; 2474 pInfo->macroAspectRatio = 1; 2475 pInfo->tileSplitBytes = 64; 2476 pInfo->pipeConfig = ADDR_PIPECFG_P2; 2477 } 2478 } 2479 else if (static_cast<UINT_32>(index) >= m_noOfEntries) 2480 { 2481 returnCode = ADDR_INVALIDPARAMS; 2482 } 2483 else 2484 { 2485 const ADDR_TILECONFIG* pCfgTable = GetTileSetting(index); 2486 2487 if (pInfo) 2488 { 2489 *pInfo = pCfgTable->info; 2490 } 2491 else 2492 { 2493 if (IsMacroTiled(pCfgTable->mode)) 2494 { 2495 returnCode = ADDR_INVALIDPARAMS; 2496 } 2497 } 2498 2499 if (pMode) 2500 { 2501 *pMode = pCfgTable->mode; 2502 } 2503 2504 if (pType) 2505 { 2506 *pType = pCfgTable->type; 2507 } 2508 } 2509 } 2510 2511 return returnCode; 2512 } 2513 2514 /** 2515 *************************************************************************************************** 2516 * SIAddrLib::ReadGbTileMode 2517 * 2518 * @brief 2519 * Convert GB_TILE_MODE HW value to ADDR_TILE_CONFIG. 2520 * @return 2521 * NA. 2522 *************************************************************************************************** 2523 */ 2524 VOID SIAddrLib::ReadGbTileMode( 2525 UINT_32 regValue, ///< [in] GB_TILE_MODE register 2526 ADDR_TILECONFIG* pCfg ///< [out] output structure 2527 ) const 2528 { 2529 GB_TILE_MODE gbTileMode; 2530 gbTileMode.val = regValue; 2531 2532 pCfg->type = static_cast<AddrTileType>(gbTileMode.f.micro_tile_mode); 2533 pCfg->info.bankHeight = 1 << gbTileMode.f.bank_height; 2534 pCfg->info.bankWidth = 1 << gbTileMode.f.bank_width; 2535 pCfg->info.banks = 1 << (gbTileMode.f.num_banks + 1); 2536 pCfg->info.macroAspectRatio = 1 << gbTileMode.f.macro_tile_aspect; 2537 pCfg->info.tileSplitBytes = 64 << gbTileMode.f.tile_split; 2538 pCfg->info.pipeConfig = static_cast<AddrPipeCfg>(gbTileMode.f.pipe_config + 1); 2539 2540 UINT_32 regArrayMode = gbTileMode.f.array_mode; 2541 2542 pCfg->mode = static_cast<AddrTileMode>(regArrayMode); 2543 2544 if (regArrayMode == 8) //ARRAY_2D_TILED_XTHICK 2545 { 2546 pCfg->mode = ADDR_TM_2D_TILED_XTHICK; 2547 } 2548 else if (regArrayMode >= 14) //ARRAY_3D_TILED_XTHICK 2549 { 2550 pCfg->mode = static_cast<AddrTileMode>(pCfg->mode + 3); 2551 } 2552 } 2553 2554 /** 2555 *************************************************************************************************** 2556 * SIAddrLib::InitTileSettingTable 2557 * 2558 * @brief 2559 * Initialize the ADDR_TILE_CONFIG table. 2560 * @return 2561 * TRUE if tile table is correctly initialized 2562 *************************************************************************************************** 2563 */ 2564 BOOL_32 SIAddrLib::InitTileSettingTable( 2565 const UINT_32* pCfg, ///< [in] Pointer to table of tile configs 2566 UINT_32 noOfEntries ///< [in] Numbe of entries in the table above 2567 ) 2568 { 2569 BOOL_32 initOk = TRUE; 2570 2571 ADDR_ASSERT(noOfEntries <= TileTableSize); 2572 2573 memset(m_tileTable, 0, sizeof(m_tileTable)); 2574 2575 if (noOfEntries != 0) 2576 { 2577 m_noOfEntries = noOfEntries; 2578 } 2579 else 2580 { 2581 m_noOfEntries = TileTableSize; 2582 } 2583 2584 if (pCfg) // From Client 2585 { 2586 for (UINT_32 i = 0; i < m_noOfEntries; i++) 2587 { 2588 ReadGbTileMode(*(pCfg + i), &m_tileTable[i]); 2589 } 2590 } 2591 else 2592 { 2593 ADDR_ASSERT_ALWAYS(); 2594 initOk = FALSE; 2595 } 2596 2597 if (initOk) 2598 { 2599 ADDR_ASSERT(m_tileTable[TILEINDEX_LINEAR_ALIGNED].mode == ADDR_TM_LINEAR_ALIGNED); 2600 } 2601 2602 return initOk; 2603 } 2604 2605 /** 2606 *************************************************************************************************** 2607 * SIAddrLib::HwlGetTileIndex 2608 * 2609 * @brief 2610 * Return the virtual/real index for given mode/type/info 2611 * @return 2612 * ADDR_OK if successful. 2613 *************************************************************************************************** 2614 */ 2615 ADDR_E_RETURNCODE SIAddrLib::HwlGetTileIndex( 2616 const ADDR_GET_TILEINDEX_INPUT* pIn, 2617 ADDR_GET_TILEINDEX_OUTPUT* pOut) const 2618 { 2619 ADDR_E_RETURNCODE returnCode = ADDR_OK; 2620 2621 pOut->index = HwlPostCheckTileIndex(pIn->pTileInfo, pIn->tileMode, pIn->tileType); 2622 2623 return returnCode; 2624 } 2625 2626 /** 2627 *************************************************************************************************** 2628 * SIAddrLib::HwlFmaskPreThunkSurfInfo 2629 * 2630 * @brief 2631 * Some preparation before thunking a ComputeSurfaceInfo call for Fmask 2632 * @return 2633 * ADDR_E_RETURNCODE 2634 *************************************************************************************************** 2635 */ 2636 VOID SIAddrLib::HwlFmaskPreThunkSurfInfo( 2637 const ADDR_COMPUTE_FMASK_INFO_INPUT* pFmaskIn, ///< [in] Input of fmask info 2638 const ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut, ///< [in] Output of fmask info 2639 ADDR_COMPUTE_SURFACE_INFO_INPUT* pSurfIn, ///< [out] Input of thunked surface info 2640 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut ///< [out] Output of thunked surface info 2641 ) const 2642 { 2643 pSurfIn->tileIndex = pFmaskIn->tileIndex; 2644 } 2645 2646 /** 2647 *************************************************************************************************** 2648 * SIAddrLib::HwlFmaskPostThunkSurfInfo 2649 * 2650 * @brief 2651 * Copy hwl extra field after calling thunked ComputeSurfaceInfo 2652 * @return 2653 * ADDR_E_RETURNCODE 2654 *************************************************************************************************** 2655 */ 2656 VOID SIAddrLib::HwlFmaskPostThunkSurfInfo( 2657 const ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pSurfOut, ///< [in] Output of surface info 2658 ADDR_COMPUTE_FMASK_INFO_OUTPUT* pFmaskOut ///< [out] Output of fmask info 2659 ) const 2660 { 2661 pFmaskOut->macroModeIndex = TileIndexInvalid; 2662 pFmaskOut->tileIndex = pSurfOut->tileIndex; 2663 } 2664 2665 /** 2666 *************************************************************************************************** 2667 * SIAddrLib::HwlComputeFmaskBits 2668 * @brief 2669 * Computes fmask bits 2670 * @return 2671 * Fmask bits 2672 *************************************************************************************************** 2673 */ 2674 UINT_32 SIAddrLib::HwlComputeFmaskBits( 2675 const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn, 2676 UINT_32* pNumSamples 2677 ) const 2678 { 2679 UINT_32 numSamples = pIn->numSamples; 2680 UINT_32 numFrags = GetNumFragments(numSamples, pIn->numFrags); 2681 UINT_32 bpp; 2682 2683 if (numFrags != numSamples) // EQAA 2684 { 2685 ADDR_ASSERT(numFrags <= 8); 2686 2687 if (!pIn->resolved) 2688 { 2689 if (numFrags == 1) 2690 { 2691 bpp = 1; 2692 numSamples = numSamples == 16 ? 16 : 8; 2693 } 2694 else if (numFrags == 2) 2695 { 2696 ADDR_ASSERT(numSamples >= 4); 2697 2698 bpp = 2; 2699 numSamples = numSamples; 2700 } 2701 else if (numFrags == 4) 2702 { 2703 ADDR_ASSERT(numSamples >= 4); 2704 2705 bpp = 4; 2706 numSamples = numSamples; 2707 } 2708 else // numFrags == 8 2709 { 2710 ADDR_ASSERT(numSamples == 16); 2711 2712 bpp = 4; 2713 numSamples = numSamples; 2714 } 2715 } 2716 else 2717 { 2718 if (numFrags == 1) 2719 { 2720 bpp = (numSamples == 16) ? 16 : 8; 2721 numSamples = 1; 2722 } 2723 else if (numFrags == 2) 2724 { 2725 ADDR_ASSERT(numSamples >= 4); 2726 2727 bpp = numSamples*2; 2728 numSamples = 1; 2729 } 2730 else if (numFrags == 4) 2731 { 2732 ADDR_ASSERT(numSamples >= 4); 2733 2734 bpp = numSamples*4; 2735 numSamples = 1; 2736 } 2737 else // numFrags == 8 2738 { 2739 ADDR_ASSERT(numSamples >= 16); 2740 2741 bpp = 16*4; 2742 numSamples = 1; 2743 } 2744 } 2745 } 2746 else // Normal AA 2747 { 2748 if (!pIn->resolved) 2749 { 2750 bpp = ComputeFmaskNumPlanesFromNumSamples(numSamples); 2751 numSamples = numSamples == 2 ? 8 : numSamples; 2752 } 2753 else 2754 { 2755 // The same as 8XX 2756 bpp = ComputeFmaskResolvedBppFromNumSamples(numSamples); 2757 numSamples = 1; // 1x sample 2758 } 2759 } 2760 2761 SafeAssign(pNumSamples, numSamples); 2762 2763 return bpp; 2764 } 2765 2766 /** 2767 *************************************************************************************************** 2768 * SIAddrLib::HwlOverrideTileMode 2769 * 2770 * @brief 2771 * Override tile modes (for PRT only, avoid client passes in an invalid PRT mode for SI. 2772 * 2773 * @return 2774 * Suitable tile mode 2775 * 2776 *************************************************************************************************** 2777 */ 2778 BOOL_32 SIAddrLib::HwlOverrideTileMode( 2779 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure 2780 AddrTileMode* pTileMode, ///< [in/out] pointer to the tile mode 2781 AddrTileType* pTileType ///< [in/out] pointer to the tile type 2782 ) const 2783 { 2784 BOOL_32 bOverrided = FALSE; 2785 AddrTileMode tileMode = *pTileMode; 2786 2787 switch (tileMode) 2788 { 2789 case ADDR_TM_PRT_TILED_THIN1: 2790 tileMode = ADDR_TM_2D_TILED_THIN1; 2791 break; 2792 2793 case ADDR_TM_PRT_TILED_THICK: 2794 tileMode = ADDR_TM_2D_TILED_THICK; 2795 break; 2796 2797 case ADDR_TM_PRT_2D_TILED_THICK: 2798 tileMode = ADDR_TM_2D_TILED_THICK; 2799 break; 2800 2801 case ADDR_TM_PRT_3D_TILED_THICK: 2802 tileMode = ADDR_TM_3D_TILED_THICK; 2803 break; 2804 2805 default: 2806 break; 2807 } 2808 2809 if (tileMode != *pTileMode) 2810 { 2811 *pTileMode = tileMode; 2812 bOverrided = TRUE; 2813 ADDR_ASSERT(pIn->flags.prt == TRUE); 2814 } 2815 2816 return bOverrided; 2817 } 2818 2819