1 /* 2 * Copyright 2017 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 addrlib2.cpp 30 * @brief Contains the implementation for the AddrLib2 base class. 31 ************************************************************************************************************************ 32 */ 33 34 #include "addrinterface.h" 35 #include "addrlib2.h" 36 #include "addrcommon.h" 37 38 namespace Addr 39 { 40 namespace V2 41 { 42 43 //////////////////////////////////////////////////////////////////////////////////////////////////// 44 // Static Const Member 45 //////////////////////////////////////////////////////////////////////////////////////////////////// 46 47 const Dim2d Lib::Block256_2d[] = {{16, 16}, {16, 8}, {8, 8}, {8, 4}, {4, 4}}; 48 49 const Dim3d Lib::Block1K_3d[] = {{16, 8, 8}, {8, 8, 8}, {8, 8, 4}, {8, 4, 4}, {4, 4, 4}}; 50 51 //////////////////////////////////////////////////////////////////////////////////////////////////// 52 // Constructor/Destructor 53 //////////////////////////////////////////////////////////////////////////////////////////////////// 54 55 /** 56 ************************************************************************************************************************ 57 * Lib::Lib 58 * 59 * @brief 60 * Constructor for the Addr::V2::Lib class 61 * 62 ************************************************************************************************************************ 63 */ 64 Lib::Lib() 65 : 66 Addr::Lib() 67 { 68 } 69 70 /** 71 ************************************************************************************************************************ 72 * Lib::Lib 73 * 74 * @brief 75 * Constructor for the AddrLib2 class with hClient as parameter 76 * 77 ************************************************************************************************************************ 78 */ 79 Lib::Lib(const Client* pClient) 80 : 81 Addr::Lib(pClient) 82 { 83 } 84 85 /** 86 ************************************************************************************************************************ 87 * Lib::~Lib 88 * 89 * @brief 90 * Destructor for the AddrLib2 class 91 * 92 ************************************************************************************************************************ 93 */ 94 Lib::~Lib() 95 { 96 } 97 98 /** 99 ************************************************************************************************************************ 100 * Lib::GetLib 101 * 102 * @brief 103 * Get Addr::V2::Lib pointer 104 * 105 * @return 106 * An Addr::V2::Lib class pointer 107 ************************************************************************************************************************ 108 */ 109 Lib* Lib::GetLib( 110 ADDR_HANDLE hLib) ///< [in] handle of ADDR_HANDLE 111 { 112 Addr::Lib* pAddrLib = Addr::Lib::GetLib(hLib); 113 if ((pAddrLib != NULL) && 114 (pAddrLib->GetChipFamily() <= ADDR_CHIP_FAMILY_VI)) 115 { 116 // only valid and GFX9+ AISC can use AddrLib2 function. 117 ADDR_ASSERT_ALWAYS(); 118 hLib = NULL; 119 } 120 return static_cast<Lib*>(hLib); 121 } 122 123 124 //////////////////////////////////////////////////////////////////////////////////////////////////// 125 // Surface Methods 126 //////////////////////////////////////////////////////////////////////////////////////////////////// 127 128 129 /** 130 ************************************************************************************************************************ 131 * Lib::ComputeSurfaceInfo 132 * 133 * @brief 134 * Interface function stub of AddrComputeSurfaceInfo. 135 * 136 * @return 137 * ADDR_E_RETURNCODE 138 ************************************************************************************************************************ 139 */ 140 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo( 141 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure 142 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure 143 ) const 144 { 145 ADDR_E_RETURNCODE returnCode = ADDR_OK; 146 147 if (GetFillSizeFieldsFlags() == TRUE) 148 { 149 if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT)) || 150 (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT))) 151 { 152 returnCode = ADDR_PARAMSIZEMISMATCH; 153 } 154 } 155 156 // Adjust coming parameters. 157 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn; 158 localIn.width = Max(pIn->width, 1u); 159 localIn.height = Max(pIn->height, 1u); 160 localIn.numMipLevels = Max(pIn->numMipLevels, 1u); 161 localIn.numSlices = Max(pIn->numSlices, 1u); 162 localIn.numSamples = Max(pIn->numSamples, 1u); 163 localIn.numFrags = (localIn.numFrags == 0) ? localIn.numSamples : pIn->numFrags; 164 165 UINT_32 expandX = 1; 166 UINT_32 expandY = 1; 167 ElemMode elemMode = ADDR_UNCOMPRESSED; 168 169 if (returnCode == ADDR_OK) 170 { 171 // Set format to INVALID will skip this conversion 172 if (localIn.format != ADDR_FMT_INVALID) 173 { 174 // Get compression/expansion factors and element mode which indicates compression/expansion 175 localIn.bpp = GetElemLib()->GetBitsPerPixel(localIn.format, 176 &elemMode, 177 &expandX, 178 &expandY); 179 180 // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is 181 // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear- 182 // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw 183 // restrictions are different. 184 // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround 185 // but we use this flag to skip RestoreSurfaceInfo below 186 187 if ((elemMode == ADDR_EXPANDED) && (expandX > 1)) 188 { 189 ADDR_ASSERT(IsLinear(localIn.swizzleMode)); 190 } 191 192 UINT_32 basePitch = 0; 193 GetElemLib()->AdjustSurfaceInfo(elemMode, 194 expandX, 195 expandY, 196 &localIn.bpp, 197 &basePitch, 198 &localIn.width, 199 &localIn.height); 200 201 // Overwrite these parameters if we have a valid format 202 } 203 204 if (localIn.bpp != 0) 205 { 206 localIn.width = Max(localIn.width, 1u); 207 localIn.height = Max(localIn.height, 1u); 208 } 209 else // Rule out some invalid parameters 210 { 211 ADDR_ASSERT_ALWAYS(); 212 213 returnCode = ADDR_INVALIDPARAMS; 214 } 215 } 216 217 if (returnCode == ADDR_OK) 218 { 219 returnCode = ComputeSurfaceInfoSanityCheck(&localIn); 220 } 221 222 if (returnCode == ADDR_OK) 223 { 224 VerifyMipLevelInfo(pIn); 225 226 if (IsLinear(pIn->swizzleMode)) 227 { 228 // linear mode 229 returnCode = ComputeSurfaceInfoLinear(&localIn, pOut); 230 } 231 else 232 { 233 // tiled mode 234 returnCode = ComputeSurfaceInfoTiled(&localIn, pOut); 235 } 236 237 if (returnCode == ADDR_OK) 238 { 239 pOut->bpp = localIn.bpp; 240 pOut->pixelPitch = pOut->pitch; 241 pOut->pixelHeight = pOut->height; 242 pOut->pixelMipChainPitch = pOut->mipChainPitch; 243 pOut->pixelMipChainHeight = pOut->mipChainHeight; 244 pOut->pixelBits = localIn.bpp; 245 246 if (localIn.format != ADDR_FMT_INVALID) 247 { 248 UINT_32 pixelBits = pOut->pixelBits; 249 250 GetElemLib()->RestoreSurfaceInfo(elemMode, 251 expandX, 252 expandY, 253 &pOut->pixelBits, 254 &pOut->pixelPitch, 255 &pOut->pixelHeight); 256 257 GetElemLib()->RestoreSurfaceInfo(elemMode, 258 expandX, 259 expandY, 260 &pixelBits, 261 &pOut->pixelMipChainPitch, 262 &pOut->pixelMipChainHeight); 263 264 if ((localIn.numMipLevels > 1) && (pOut->pMipInfo != NULL)) 265 { 266 for (UINT_32 i = 0; i < localIn.numMipLevels; i++) 267 { 268 pOut->pMipInfo[i].pixelPitch = pOut->pMipInfo[i].pitch; 269 pOut->pMipInfo[i].pixelHeight = pOut->pMipInfo[i].height; 270 271 GetElemLib()->RestoreSurfaceInfo(elemMode, 272 expandX, 273 expandY, 274 &pixelBits, 275 &pOut->pMipInfo[i].pixelPitch, 276 &pOut->pMipInfo[i].pixelHeight); 277 } 278 } 279 } 280 281 if (localIn.flags.needEquation && (Log2(localIn.numFrags) == 0)) 282 { 283 pOut->equationIndex = GetEquationIndex(&localIn, pOut); 284 } 285 286 if (localIn.flags.qbStereo) 287 { 288 if (pOut->pStereoInfo != NULL) 289 { 290 ComputeQbStereoInfo(pOut); 291 } 292 } 293 } 294 } 295 296 ADDR_ASSERT(pOut->surfSize != 0); 297 298 return returnCode; 299 } 300 301 /** 302 ************************************************************************************************************************ 303 * Lib::ComputeSurfaceInfo 304 * 305 * @brief 306 * Interface function stub of AddrComputeSurfaceInfo. 307 * 308 * @return 309 * ADDR_E_RETURNCODE 310 ************************************************************************************************************************ 311 */ 312 ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoord( 313 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure 314 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure 315 ) const 316 { 317 ADDR_E_RETURNCODE returnCode = ADDR_OK; 318 319 if (GetFillSizeFieldsFlags() == TRUE) 320 { 321 if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT)) || 322 (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT))) 323 { 324 returnCode = ADDR_PARAMSIZEMISMATCH; 325 } 326 } 327 328 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT localIn = *pIn; 329 localIn.unalignedWidth = Max(pIn->unalignedWidth, 1u); 330 localIn.unalignedHeight = Max(pIn->unalignedHeight, 1u); 331 localIn.numMipLevels = Max(pIn->numMipLevels, 1u); 332 localIn.numSlices = Max(pIn->numSlices, 1u); 333 localIn.numSamples = Max(pIn->numSamples, 1u); 334 localIn.numFrags = Max(pIn->numFrags, 1u); 335 336 if ((localIn.bpp < 8) || 337 (localIn.bpp > 128) || 338 ((localIn.bpp % 8) != 0) || 339 (localIn.sample >= localIn.numSamples) || 340 (localIn.slice >= localIn.numSlices) || 341 (localIn.mipId >= localIn.numMipLevels) || 342 (IsTex3d(localIn.resourceType) && 343 (Valid3DMipSliceIdConstraint(localIn.numSlices, localIn.mipId, localIn.slice) == FALSE))) 344 { 345 returnCode = ADDR_INVALIDPARAMS; 346 } 347 348 if (returnCode == ADDR_OK) 349 { 350 if (IsLinear(localIn.swizzleMode)) 351 { 352 returnCode = ComputeSurfaceAddrFromCoordLinear(&localIn, pOut); 353 } 354 else 355 { 356 returnCode = ComputeSurfaceAddrFromCoordTiled(&localIn, pOut); 357 } 358 359 if (returnCode == ADDR_OK) 360 { 361 pOut->prtBlockIndex = static_cast<UINT_32>(pOut->addr / (64 * 1024)); 362 } 363 } 364 365 return returnCode; 366 } 367 368 /** 369 ************************************************************************************************************************ 370 * Lib::ComputeSurfaceCoordFromAddr 371 * 372 * @brief 373 * Interface function stub of ComputeSurfaceCoordFromAddr. 374 * 375 * @return 376 * ADDR_E_RETURNCODE 377 ************************************************************************************************************************ 378 */ 379 ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddr( 380 const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure 381 ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure 382 ) const 383 { 384 ADDR_E_RETURNCODE returnCode = ADDR_OK; 385 386 if (GetFillSizeFieldsFlags() == TRUE) 387 { 388 if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT)) || 389 (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT))) 390 { 391 returnCode = ADDR_PARAMSIZEMISMATCH; 392 } 393 } 394 395 if ((pIn->bpp < 8) || 396 (pIn->bpp > 128) || 397 ((pIn->bpp % 8) != 0) || 398 (pIn->bitPosition >= 8)) 399 { 400 returnCode = ADDR_INVALIDPARAMS; 401 } 402 403 if (returnCode == ADDR_OK) 404 { 405 if (IsLinear(pIn->swizzleMode)) 406 { 407 returnCode = ComputeSurfaceCoordFromAddrLinear(pIn, pOut); 408 } 409 else 410 { 411 returnCode = ComputeSurfaceCoordFromAddrTiled(pIn, pOut); 412 } 413 } 414 415 return returnCode; 416 } 417 418 419 //////////////////////////////////////////////////////////////////////////////////////////////////// 420 // CMASK/HTILE 421 //////////////////////////////////////////////////////////////////////////////////////////////////// 422 423 /** 424 ************************************************************************************************************************ 425 * Lib::ComputeHtileInfo 426 * 427 * @brief 428 * Interface function stub of AddrComputeHtilenfo 429 * 430 * @return 431 * ADDR_E_RETURNCODE 432 ************************************************************************************************************************ 433 */ 434 ADDR_E_RETURNCODE Lib::ComputeHtileInfo( 435 const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn, ///< [in] input structure 436 ADDR2_COMPUTE_HTILE_INFO_OUTPUT* pOut ///< [out] output structure 437 ) const 438 { 439 ADDR_E_RETURNCODE returnCode; 440 441 if ((GetFillSizeFieldsFlags() == TRUE) && 442 ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT)) || 443 (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT)))) 444 { 445 returnCode = ADDR_INVALIDPARAMS; 446 } 447 else 448 { 449 returnCode = HwlComputeHtileInfo(pIn, pOut); 450 } 451 452 return returnCode; 453 } 454 455 /** 456 ************************************************************************************************************************ 457 * Lib::ComputeHtileAddrFromCoord 458 * 459 * @brief 460 * Interface function stub of AddrComputeHtileAddrFromCoord 461 * 462 * @return 463 * ADDR_E_RETURNCODE 464 ************************************************************************************************************************ 465 */ 466 ADDR_E_RETURNCODE Lib::ComputeHtileAddrFromCoord( 467 const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure 468 ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT* pOut) ///< [out] output structure 469 { 470 ADDR_E_RETURNCODE returnCode; 471 472 if ((GetFillSizeFieldsFlags() == TRUE) && 473 ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT)) || 474 (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT)))) 475 { 476 returnCode = ADDR_INVALIDPARAMS; 477 } 478 else 479 { 480 returnCode = HwlComputeHtileAddrFromCoord(pIn, pOut); 481 } 482 483 return returnCode; 484 } 485 486 /** 487 ************************************************************************************************************************ 488 * Lib::ComputeHtileCoordFromAddr 489 * 490 * @brief 491 * Interface function stub of AddrComputeHtileCoordFromAddr 492 * 493 * @return 494 * ADDR_E_RETURNCODE 495 ************************************************************************************************************************ 496 */ 497 ADDR_E_RETURNCODE Lib::ComputeHtileCoordFromAddr( 498 const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure 499 ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT* pOut) ///< [out] output structure 500 { 501 ADDR_E_RETURNCODE returnCode; 502 503 if ((GetFillSizeFieldsFlags() == TRUE) && 504 ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT)) || 505 (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT)))) 506 { 507 returnCode = ADDR_INVALIDPARAMS; 508 } 509 else 510 { 511 returnCode = HwlComputeHtileCoordFromAddr(pIn, pOut); 512 } 513 514 return returnCode; 515 } 516 517 /** 518 ************************************************************************************************************************ 519 * Lib::ComputeCmaskInfo 520 * 521 * @brief 522 * Interface function stub of AddrComputeCmaskInfo 523 * 524 * @return 525 * ADDR_E_RETURNCODE 526 ************************************************************************************************************************ 527 */ 528 ADDR_E_RETURNCODE Lib::ComputeCmaskInfo( 529 const ADDR2_COMPUTE_CMASK_INFO_INPUT* pIn, ///< [in] input structure 530 ADDR2_COMPUTE_CMASK_INFO_OUTPUT* pOut ///< [out] output structure 531 ) const 532 { 533 ADDR_E_RETURNCODE returnCode; 534 535 if ((GetFillSizeFieldsFlags() == TRUE) && 536 ((pIn->size != sizeof(ADDR2_COMPUTE_CMASK_INFO_INPUT)) || 537 (pOut->size != sizeof(ADDR2_COMPUTE_CMASK_INFO_OUTPUT)))) 538 { 539 returnCode = ADDR_INVALIDPARAMS; 540 } 541 else if (pIn->cMaskFlags.linear) 542 { 543 returnCode = ADDR_INVALIDPARAMS; 544 } 545 else 546 { 547 returnCode = HwlComputeCmaskInfo(pIn, pOut); 548 } 549 550 return returnCode; 551 } 552 553 /** 554 ************************************************************************************************************************ 555 * Lib::ComputeCmaskAddrFromCoord 556 * 557 * @brief 558 * Interface function stub of AddrComputeCmaskAddrFromCoord 559 * 560 * @return 561 * ADDR_E_RETURNCODE 562 ************************************************************************************************************************ 563 */ 564 ADDR_E_RETURNCODE Lib::ComputeCmaskAddrFromCoord( 565 const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure 566 ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut) ///< [out] output structure 567 { 568 ADDR_E_RETURNCODE returnCode; 569 570 if ((GetFillSizeFieldsFlags() == TRUE) && 571 ((pIn->size != sizeof(ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT)) || 572 (pOut->size != sizeof(ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT)))) 573 { 574 returnCode = ADDR_INVALIDPARAMS; 575 } 576 else 577 { 578 returnCode = HwlComputeCmaskAddrFromCoord(pIn, pOut); 579 } 580 581 return returnCode; 582 } 583 584 /** 585 ************************************************************************************************************************ 586 * Lib::ComputeCmaskCoordFromAddr 587 * 588 * @brief 589 * Interface function stub of AddrComputeCmaskCoordFromAddr 590 * 591 * @return 592 * ADDR_E_RETURNCODE 593 ************************************************************************************************************************ 594 */ 595 ADDR_E_RETURNCODE Lib::ComputeCmaskCoordFromAddr( 596 const ADDR2_COMPUTE_CMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure 597 ADDR2_COMPUTE_CMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure 598 ) const 599 { 600 ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED; 601 602 ADDR_NOT_IMPLEMENTED(); 603 604 return returnCode; 605 } 606 607 /** 608 ************************************************************************************************************************ 609 * Lib::ComputeFmaskInfo 610 * 611 * @brief 612 * Interface function stub of ComputeFmaskInfo. 613 * 614 * @return 615 * ADDR_E_RETURNCODE 616 ************************************************************************************************************************ 617 */ 618 ADDR_E_RETURNCODE Lib::ComputeFmaskInfo( 619 const ADDR2_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure 620 ADDR2_COMPUTE_FMASK_INFO_OUTPUT* pOut ///< [out] output structure 621 ) 622 { 623 ADDR_E_RETURNCODE returnCode; 624 625 BOOL_32 valid = (IsZOrderSwizzle(pIn->swizzleMode) == TRUE) && 626 ((pIn->numSamples > 0) || (pIn->numFrags > 0)); 627 628 if (GetFillSizeFieldsFlags()) 629 { 630 if ((pIn->size != sizeof(ADDR2_COMPUTE_FMASK_INFO_INPUT)) || 631 (pOut->size != sizeof(ADDR2_COMPUTE_FMASK_INFO_OUTPUT))) 632 { 633 valid = FALSE; 634 } 635 } 636 637 if (valid == FALSE) 638 { 639 returnCode = ADDR_INVALIDPARAMS; 640 } 641 else 642 { 643 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0}; 644 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0}; 645 646 localIn.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT); 647 localOut.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT); 648 649 localIn.swizzleMode = pIn->swizzleMode; 650 localIn.numSlices = Max(pIn->numSlices, 1u); 651 localIn.width = Max(pIn->unalignedWidth, 1u); 652 localIn.height = Max(pIn->unalignedHeight, 1u); 653 localIn.bpp = GetFmaskBpp(pIn->numSamples, pIn->numFrags); 654 localIn.flags.fmask = 1; 655 localIn.numFrags = 1; 656 localIn.numSamples = 1; 657 localIn.resourceType = ADDR_RSRC_TEX_2D; 658 659 if (localIn.bpp == 8) 660 { 661 localIn.format = ADDR_FMT_8; 662 } 663 else if (localIn.bpp == 16) 664 { 665 localIn.format = ADDR_FMT_16; 666 } 667 else if (localIn.bpp == 32) 668 { 669 localIn.format = ADDR_FMT_32; 670 } 671 else 672 { 673 localIn.format = ADDR_FMT_32_32; 674 } 675 676 returnCode = ComputeSurfaceInfo(&localIn, &localOut); 677 678 if (returnCode == ADDR_OK) 679 { 680 pOut->pitch = localOut.pitch; 681 pOut->height = localOut.height; 682 pOut->baseAlign = localOut.baseAlign; 683 pOut->numSlices = localOut.numSlices; 684 pOut->fmaskBytes = static_cast<UINT_32>(localOut.surfSize); 685 pOut->sliceSize = static_cast<UINT_32>(localOut.sliceSize); 686 pOut->bpp = localIn.bpp; 687 pOut->numSamples = 1; 688 } 689 } 690 691 return returnCode; 692 } 693 694 /** 695 ************************************************************************************************************************ 696 * Lib::ComputeFmaskAddrFromCoord 697 * 698 * @brief 699 * Interface function stub of ComputeFmaskAddrFromCoord. 700 * 701 * @return 702 * ADDR_E_RETURNCODE 703 ************************************************************************************************************************ 704 */ 705 ADDR_E_RETURNCODE Lib::ComputeFmaskAddrFromCoord( 706 const ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure 707 ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure 708 ) const 709 { 710 ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED; 711 712 ADDR_NOT_IMPLEMENTED(); 713 714 return returnCode; 715 } 716 717 /** 718 ************************************************************************************************************************ 719 * Lib::ComputeFmaskCoordFromAddr 720 * 721 * @brief 722 * Interface function stub of ComputeFmaskAddrFromCoord. 723 * 724 * @return 725 * ADDR_E_RETURNCODE 726 ************************************************************************************************************************ 727 */ 728 ADDR_E_RETURNCODE Lib::ComputeFmaskCoordFromAddr( 729 const ADDR2_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure 730 ADDR2_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure 731 ) const 732 { 733 ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED; 734 735 ADDR_NOT_IMPLEMENTED(); 736 737 return returnCode; 738 } 739 740 /** 741 ************************************************************************************************************************ 742 * Lib::ComputeDccInfo 743 * 744 * @brief 745 * Interface function to compute DCC key info 746 * 747 * @return 748 * return code of HwlComputeDccInfo 749 ************************************************************************************************************************ 750 */ 751 ADDR_E_RETURNCODE Lib::ComputeDccInfo( 752 const ADDR2_COMPUTE_DCCINFO_INPUT* pIn, ///< [in] input structure 753 ADDR2_COMPUTE_DCCINFO_OUTPUT* pOut ///< [out] output structure 754 ) const 755 { 756 ADDR_E_RETURNCODE returnCode; 757 758 if ((GetFillSizeFieldsFlags() == TRUE) && 759 ((pIn->size != sizeof(ADDR2_COMPUTE_DCCINFO_INPUT)) || 760 (pOut->size != sizeof(ADDR2_COMPUTE_DCCINFO_OUTPUT)))) 761 { 762 returnCode = ADDR_INVALIDPARAMS; 763 } 764 else 765 { 766 returnCode = HwlComputeDccInfo(pIn, pOut); 767 } 768 769 return returnCode; 770 } 771 772 /** 773 ************************************************************************************************************************ 774 * Lib::ComputeDccAddrFromCoord 775 * 776 * @brief 777 * Interface function stub of ComputeDccAddrFromCoord 778 * 779 * @return 780 * ADDR_E_RETURNCODE 781 ************************************************************************************************************************ 782 */ 783 ADDR_E_RETURNCODE Lib::ComputeDccAddrFromCoord( 784 const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure 785 ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT* pOut) ///< [out] output structure 786 { 787 ADDR_E_RETURNCODE returnCode; 788 789 if ((GetFillSizeFieldsFlags() == TRUE) && 790 ((pIn->size != sizeof(ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT)) || 791 (pOut->size != sizeof(ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT)))) 792 { 793 returnCode = ADDR_INVALIDPARAMS; 794 } 795 else 796 { 797 returnCode = HwlComputeDccAddrFromCoord(pIn, pOut); 798 } 799 800 return returnCode; 801 } 802 803 /** 804 ************************************************************************************************************************ 805 * Lib::ComputePipeBankXor 806 * 807 * @brief 808 * Interface function stub of Addr2ComputePipeBankXor. 809 * 810 * @return 811 * ADDR_E_RETURNCODE 812 ************************************************************************************************************************ 813 */ 814 ADDR_E_RETURNCODE Lib::ComputePipeBankXor( 815 const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn, 816 ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT* pOut) 817 { 818 ADDR_E_RETURNCODE returnCode; 819 820 if ((GetFillSizeFieldsFlags() == TRUE) && 821 ((pIn->size != sizeof(ADDR2_COMPUTE_PIPEBANKXOR_INPUT)) || 822 (pOut->size != sizeof(ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT)))) 823 { 824 returnCode = ADDR_INVALIDPARAMS; 825 } 826 else if (IsXor(pIn->swizzleMode) == FALSE) 827 { 828 returnCode = ADDR_NOTSUPPORTED; 829 } 830 else 831 { 832 returnCode = HwlComputePipeBankXor(pIn, pOut); 833 } 834 835 return returnCode; 836 } 837 838 /** 839 ************************************************************************************************************************ 840 * Lib::ComputeSlicePipeBankXor 841 * 842 * @brief 843 * Interface function stub of Addr2ComputeSlicePipeBankXor. 844 * 845 * @return 846 * ADDR_E_RETURNCODE 847 ************************************************************************************************************************ 848 */ 849 ADDR_E_RETURNCODE Lib::ComputeSlicePipeBankXor( 850 const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn, 851 ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT* pOut) 852 { 853 ADDR_E_RETURNCODE returnCode; 854 855 if ((GetFillSizeFieldsFlags() == TRUE) && 856 ((pIn->size != sizeof(ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT)) || 857 (pOut->size != sizeof(ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT)))) 858 { 859 returnCode = ADDR_INVALIDPARAMS; 860 } 861 else if ((IsThin(pIn->resourceType, pIn->swizzleMode) == FALSE) || 862 (IsNonPrtXor(pIn->swizzleMode) == FALSE) || 863 (pIn->numSamples > 1)) 864 { 865 returnCode = ADDR_NOTSUPPORTED; 866 } 867 else 868 { 869 returnCode = HwlComputeSlicePipeBankXor(pIn, pOut); 870 } 871 872 return returnCode; 873 } 874 875 /** 876 ************************************************************************************************************************ 877 * Lib::ComputeSubResourceOffsetForSwizzlePattern 878 * 879 * @brief 880 * Interface function stub of Addr2ComputeSubResourceOffsetForSwizzlePattern. 881 * 882 * @return 883 * ADDR_E_RETURNCODE 884 ************************************************************************************************************************ 885 */ 886 ADDR_E_RETURNCODE Lib::ComputeSubResourceOffsetForSwizzlePattern( 887 const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn, 888 ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT* pOut) 889 { 890 ADDR_E_RETURNCODE returnCode; 891 892 if ((GetFillSizeFieldsFlags() == TRUE) && 893 ((pIn->size != sizeof(ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT)) || 894 (pOut->size != sizeof(ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT)))) 895 { 896 returnCode = ADDR_INVALIDPARAMS; 897 } 898 else 899 { 900 returnCode = HwlComputeSubResourceOffsetForSwizzlePattern(pIn, pOut); 901 } 902 903 return returnCode; 904 } 905 906 /** 907 ************************************************************************************************************************ 908 * Lib::ExtractPipeBankXor 909 * 910 * @brief 911 * Internal function to extract bank and pipe xor bits from combined xor bits. 912 * 913 * @return 914 * ADDR_E_RETURNCODE 915 ************************************************************************************************************************ 916 */ 917 ADDR_E_RETURNCODE Lib::ExtractPipeBankXor( 918 UINT_32 pipeBankXor, 919 UINT_32 bankBits, 920 UINT_32 pipeBits, 921 UINT_32* pBankX, 922 UINT_32* pPipeX) 923 { 924 ADDR_E_RETURNCODE returnCode; 925 926 if (pipeBankXor < (1u << (pipeBits + bankBits))) 927 { 928 *pPipeX = pipeBankXor % (1 << pipeBits); 929 *pBankX = pipeBankXor >> pipeBits; 930 returnCode = ADDR_OK; 931 } 932 else 933 { 934 ADDR_ASSERT_ALWAYS(); 935 returnCode = ADDR_INVALIDPARAMS; 936 } 937 938 return returnCode; 939 } 940 941 /** 942 ************************************************************************************************************************ 943 * Lib::ComputeSurfaceInfoSanityCheck 944 * 945 * @brief 946 * Internal function to do basic sanity check before compute surface info 947 * 948 * @return 949 * ADDR_E_RETURNCODE 950 ************************************************************************************************************************ 951 */ 952 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoSanityCheck( 953 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in] input structure 954 ) const 955 { 956 ADDR_E_RETURNCODE returnCode; 957 958 if ((GetFillSizeFieldsFlags() == TRUE) && 959 (pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT))) 960 { 961 returnCode = ADDR_INVALIDPARAMS; 962 } 963 else 964 { 965 returnCode = HwlComputeSurfaceInfoSanityCheck(pIn); 966 } 967 968 return returnCode; 969 } 970 971 /** 972 ************************************************************************************************************************ 973 * Lib::ApplyCustomizedPitchHeight 974 * 975 * @brief 976 * Helper function to override hw required row pitch/slice pitch by customrized one 977 * 978 * @return 979 * ADDR_E_RETURNCODE 980 ************************************************************************************************************************ 981 */ 982 ADDR_E_RETURNCODE Lib::ApplyCustomizedPitchHeight( 983 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure 984 UINT_32 elementBytes, ///< [in] element bytes per element 985 UINT_32 pitchAlignInElement, ///< [in] pitch alignment in element 986 UINT_32* pPitch, ///< [in/out] pitch 987 UINT_32* pHeight ///< [in/out] height 988 ) const 989 { 990 ADDR_E_RETURNCODE returnCode = ADDR_OK; 991 992 if (pIn->numMipLevels <= 1) 993 { 994 if (pIn->pitchInElement > 0) 995 { 996 if ((pIn->pitchInElement % pitchAlignInElement) != 0) 997 { 998 returnCode = ADDR_INVALIDPARAMS; 999 } 1000 else if (pIn->pitchInElement < (*pPitch)) 1001 { 1002 returnCode = ADDR_INVALIDPARAMS; 1003 } 1004 else 1005 { 1006 *pPitch = pIn->pitchInElement; 1007 } 1008 } 1009 1010 if (returnCode == ADDR_OK) 1011 { 1012 if (pIn->sliceAlign > 0) 1013 { 1014 UINT_32 customizedHeight = pIn->sliceAlign / elementBytes / (*pPitch); 1015 1016 if (customizedHeight * elementBytes * (*pPitch) != pIn->sliceAlign) 1017 { 1018 returnCode = ADDR_INVALIDPARAMS; 1019 } 1020 else if ((pIn->numSlices > 1) && ((*pHeight) != customizedHeight)) 1021 { 1022 returnCode = ADDR_INVALIDPARAMS; 1023 } 1024 else 1025 { 1026 *pHeight = customizedHeight; 1027 } 1028 } 1029 } 1030 } 1031 1032 return returnCode; 1033 } 1034 1035 /** 1036 ************************************************************************************************************************ 1037 * Lib::ComputeSurfaceInfoLinear 1038 * 1039 * @brief 1040 * Internal function to calculate alignment for linear swizzle surface 1041 * 1042 * @return 1043 * ADDR_E_RETURNCODE 1044 ************************************************************************************************************************ 1045 */ 1046 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoLinear( 1047 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure 1048 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure 1049 ) const 1050 { 1051 return HwlComputeSurfaceInfoLinear(pIn, pOut); 1052 } 1053 1054 /** 1055 ************************************************************************************************************************ 1056 * Lib::ComputeSurfaceInfoTiled 1057 * 1058 * @brief 1059 * Internal function to calculate alignment for tiled swizzle surface 1060 * 1061 * @return 1062 * ADDR_E_RETURNCODE 1063 ************************************************************************************************************************ 1064 */ 1065 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoTiled( 1066 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure 1067 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure 1068 ) const 1069 { 1070 return HwlComputeSurfaceInfoTiled(pIn, pOut); 1071 } 1072 1073 /** 1074 ************************************************************************************************************************ 1075 * Lib::ComputeSurfaceAddrFromCoordLinear 1076 * 1077 * @brief 1078 * Internal function to calculate address from coord for linear swizzle surface 1079 * 1080 * @return 1081 * ADDR_E_RETURNCODE 1082 ************************************************************************************************************************ 1083 */ 1084 ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordLinear( 1085 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure 1086 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure 1087 ) const 1088 { 1089 ADDR_E_RETURNCODE returnCode = ADDR_OK; 1090 BOOL_32 valid = (pIn->numSamples <= 1) && (pIn->numFrags <= 1) && (pIn->pipeBankXor == 0); 1091 1092 if (valid) 1093 { 1094 if (IsTex1d(pIn->resourceType)) 1095 { 1096 valid = (pIn->y == 0); 1097 } 1098 } 1099 1100 if (valid) 1101 { 1102 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0}; 1103 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0}; 1104 ADDR2_MIP_INFO mipInfo[MaxMipLevels]; 1105 1106 localIn.bpp = pIn->bpp; 1107 localIn.flags = pIn->flags; 1108 localIn.width = Max(pIn->unalignedWidth, 1u); 1109 localIn.height = Max(pIn->unalignedHeight, 1u); 1110 localIn.numSlices = Max(pIn->numSlices, 1u); 1111 localIn.numMipLevels = Max(pIn->numMipLevels, 1u); 1112 localIn.resourceType = pIn->resourceType; 1113 1114 if (localIn.numMipLevels <= 1) 1115 { 1116 localIn.pitchInElement = pIn->pitchInElement; 1117 } 1118 1119 localOut.pMipInfo = mipInfo; 1120 1121 returnCode = ComputeSurfaceInfoLinear(&localIn, &localOut); 1122 1123 if (returnCode == ADDR_OK) 1124 { 1125 pOut->addr = (localOut.sliceSize * pIn->slice) + 1126 mipInfo[pIn->mipId].offset + 1127 (pIn->y * mipInfo[pIn->mipId].pitch + pIn->x) * (pIn->bpp >> 3); 1128 pOut->bitPosition = 0; 1129 } 1130 else 1131 { 1132 valid = FALSE; 1133 } 1134 } 1135 1136 if (valid == FALSE) 1137 { 1138 returnCode = ADDR_INVALIDPARAMS; 1139 } 1140 1141 return returnCode; 1142 } 1143 1144 /** 1145 ************************************************************************************************************************ 1146 * Lib::ComputeSurfaceAddrFromCoordTiled 1147 * 1148 * @brief 1149 * Internal function to calculate address from coord for tiled swizzle surface 1150 * 1151 * @return 1152 * ADDR_E_RETURNCODE 1153 ************************************************************************************************************************ 1154 */ 1155 ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordTiled( 1156 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure 1157 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure 1158 ) const 1159 { 1160 return HwlComputeSurfaceAddrFromCoordTiled(pIn, pOut); 1161 } 1162 1163 /** 1164 ************************************************************************************************************************ 1165 * Lib::ComputeSurfaceCoordFromAddrLinear 1166 * 1167 * @brief 1168 * Internal function to calculate coord from address for linear swizzle surface 1169 * 1170 * @return 1171 * ADDR_E_RETURNCODE 1172 ************************************************************************************************************************ 1173 */ 1174 ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrLinear( 1175 const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure 1176 ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure 1177 ) const 1178 { 1179 ADDR_E_RETURNCODE returnCode = ADDR_OK; 1180 1181 BOOL_32 valid = (pIn->numSamples <= 1) && (pIn->numFrags <= 1); 1182 1183 if (valid) 1184 { 1185 if (IsTex1d(pIn->resourceType)) 1186 { 1187 valid = (pIn->unalignedHeight == 1); 1188 } 1189 } 1190 1191 if (valid) 1192 { 1193 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0}; 1194 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0}; 1195 localIn.bpp = pIn->bpp; 1196 localIn.flags = pIn->flags; 1197 localIn.width = Max(pIn->unalignedWidth, 1u); 1198 localIn.height = Max(pIn->unalignedHeight, 1u); 1199 localIn.numSlices = Max(pIn->numSlices, 1u); 1200 localIn.numMipLevels = Max(pIn->numMipLevels, 1u); 1201 localIn.resourceType = pIn->resourceType; 1202 if (localIn.numMipLevels <= 1) 1203 { 1204 localIn.pitchInElement = pIn->pitchInElement; 1205 } 1206 returnCode = ComputeSurfaceInfoLinear(&localIn, &localOut); 1207 1208 if (returnCode == ADDR_OK) 1209 { 1210 pOut->slice = static_cast<UINT_32>(pIn->addr / localOut.sliceSize); 1211 pOut->sample = 0; 1212 1213 UINT_32 offsetInSlice = static_cast<UINT_32>(pIn->addr % localOut.sliceSize); 1214 UINT_32 elementBytes = pIn->bpp >> 3; 1215 UINT_32 mipOffsetInSlice = 0; 1216 UINT_32 mipSize = 0; 1217 UINT_32 mipId = 0; 1218 for (; mipId < pIn->numMipLevels ; mipId++) 1219 { 1220 if (IsTex1d(pIn->resourceType)) 1221 { 1222 mipSize = localOut.pitch * elementBytes; 1223 } 1224 else 1225 { 1226 UINT_32 currentMipHeight = (PowTwoAlign(localIn.height, (1 << mipId))) >> mipId; 1227 mipSize = currentMipHeight * localOut.pitch * elementBytes; 1228 } 1229 1230 if (mipSize == 0) 1231 { 1232 valid = FALSE; 1233 break; 1234 } 1235 else if ((mipSize + mipOffsetInSlice) > offsetInSlice) 1236 { 1237 break; 1238 } 1239 else 1240 { 1241 mipOffsetInSlice += mipSize; 1242 if ((mipId == (pIn->numMipLevels - 1)) || 1243 (mipOffsetInSlice >= localOut.sliceSize)) 1244 { 1245 valid = FALSE; 1246 } 1247 } 1248 } 1249 1250 if (valid) 1251 { 1252 pOut->mipId = mipId; 1253 1254 UINT_32 elemOffsetInMip = (offsetInSlice - mipOffsetInSlice) / elementBytes; 1255 if (IsTex1d(pIn->resourceType)) 1256 { 1257 if (elemOffsetInMip < localOut.pitch) 1258 { 1259 pOut->x = elemOffsetInMip; 1260 pOut->y = 0; 1261 } 1262 else 1263 { 1264 valid = FALSE; 1265 } 1266 } 1267 else 1268 { 1269 pOut->y = elemOffsetInMip / localOut.pitch; 1270 pOut->x = elemOffsetInMip % localOut.pitch; 1271 } 1272 1273 if ((pOut->slice >= pIn->numSlices) || 1274 (pOut->mipId >= pIn->numMipLevels) || 1275 (pOut->x >= Max((pIn->unalignedWidth >> pOut->mipId), 1u)) || 1276 (pOut->y >= Max((pIn->unalignedHeight >> pOut->mipId), 1u)) || 1277 (IsTex3d(pIn->resourceType) && 1278 (FALSE == Valid3DMipSliceIdConstraint(pIn->numSlices, 1279 pOut->mipId, 1280 pOut->slice)))) 1281 { 1282 valid = FALSE; 1283 } 1284 } 1285 } 1286 else 1287 { 1288 valid = FALSE; 1289 } 1290 } 1291 1292 if (valid == FALSE) 1293 { 1294 returnCode = ADDR_INVALIDPARAMS; 1295 } 1296 1297 return returnCode; 1298 } 1299 1300 /** 1301 ************************************************************************************************************************ 1302 * Lib::ComputeSurfaceCoordFromAddrTiled 1303 * 1304 * @brief 1305 * Internal function to calculate coord from address for tiled swizzle surface 1306 * 1307 * @return 1308 * ADDR_E_RETURNCODE 1309 ************************************************************************************************************************ 1310 */ 1311 ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrTiled( 1312 const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure 1313 ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure 1314 ) const 1315 { 1316 ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED; 1317 1318 ADDR_NOT_IMPLEMENTED(); 1319 1320 return returnCode; 1321 } 1322 1323 /** 1324 ************************************************************************************************************************ 1325 * Lib::ComputeBlockDimensionForSurf 1326 * 1327 * @brief 1328 * Internal function to get block width/height/depth in element from surface input params. 1329 * 1330 * @return 1331 * ADDR_E_RETURNCODE 1332 ************************************************************************************************************************ 1333 */ 1334 ADDR_E_RETURNCODE Lib::ComputeBlockDimensionForSurf( 1335 UINT_32* pWidth, 1336 UINT_32* pHeight, 1337 UINT_32* pDepth, 1338 UINT_32 bpp, 1339 UINT_32 numSamples, 1340 AddrResourceType resourceType, 1341 AddrSwizzleMode swizzleMode) const 1342 { 1343 ADDR_E_RETURNCODE returnCode = ComputeBlockDimension(pWidth, 1344 pHeight, 1345 pDepth, 1346 bpp, 1347 resourceType, 1348 swizzleMode); 1349 1350 if ((returnCode == ADDR_OK) && (numSamples > 1) && IsThin(resourceType, swizzleMode)) 1351 { 1352 const UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode); 1353 const UINT_32 log2sample = Log2(numSamples); 1354 const UINT_32 q = log2sample >> 1; 1355 const UINT_32 r = log2sample & 1; 1356 1357 if (log2blkSize & 1) 1358 { 1359 *pWidth >>= q; 1360 *pHeight >>= (q + r); 1361 } 1362 else 1363 { 1364 *pWidth >>= (q + r); 1365 *pHeight >>= q; 1366 } 1367 } 1368 1369 return returnCode; 1370 } 1371 1372 /** 1373 ************************************************************************************************************************ 1374 * Lib::ComputeBlockDimension 1375 * 1376 * @brief 1377 * Internal function to get block width/height/depth in element without considering MSAA case 1378 * 1379 * @return 1380 * ADDR_E_RETURNCODE 1381 ************************************************************************************************************************ 1382 */ 1383 ADDR_E_RETURNCODE Lib::ComputeBlockDimension( 1384 UINT_32* pWidth, 1385 UINT_32* pHeight, 1386 UINT_32* pDepth, 1387 UINT_32 bpp, 1388 AddrResourceType resourceType, 1389 AddrSwizzleMode swizzleMode) const 1390 { 1391 ADDR_E_RETURNCODE returnCode = ADDR_OK; 1392 1393 UINT_32 eleBytes = bpp >> 3; 1394 UINT_32 microBlockSizeTableIndex = Log2(eleBytes); 1395 UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode); 1396 1397 if (IsThin(resourceType, swizzleMode)) 1398 { 1399 UINT_32 log2blkSizeIn256B = log2blkSize - 8; 1400 UINT_32 widthAmp = log2blkSizeIn256B / 2; 1401 UINT_32 heightAmp = log2blkSizeIn256B - widthAmp; 1402 1403 ADDR_ASSERT(microBlockSizeTableIndex < sizeof(Block256_2d) / sizeof(Block256_2d[0])); 1404 1405 *pWidth = (Block256_2d[microBlockSizeTableIndex].w << widthAmp); 1406 *pHeight = (Block256_2d[microBlockSizeTableIndex].h << heightAmp); 1407 *pDepth = 1; 1408 } 1409 else if (IsThick(resourceType, swizzleMode)) 1410 { 1411 UINT_32 log2blkSizeIn1KB = log2blkSize - 10; 1412 UINT_32 averageAmp = log2blkSizeIn1KB / 3; 1413 UINT_32 restAmp = log2blkSizeIn1KB % 3; 1414 1415 ADDR_ASSERT(microBlockSizeTableIndex < sizeof(Block1K_3d) / sizeof(Block1K_3d[0])); 1416 1417 *pWidth = Block1K_3d[microBlockSizeTableIndex].w << averageAmp; 1418 *pHeight = Block1K_3d[microBlockSizeTableIndex].h << (averageAmp + (restAmp / 2)); 1419 *pDepth = Block1K_3d[microBlockSizeTableIndex].d << (averageAmp + ((restAmp != 0) ? 1 : 0)); 1420 } 1421 else 1422 { 1423 ADDR_ASSERT_ALWAYS(); 1424 returnCode = ADDR_INVALIDPARAMS; 1425 } 1426 1427 return returnCode; 1428 } 1429 1430 /** 1431 ************************************************************************************************************************ 1432 * Lib::GetMipTailDim 1433 * 1434 * @brief 1435 * Internal function to get out max dimension of first level in mip tail 1436 * 1437 * @return 1438 * Max Width/Height/Depth value of the first mip fitted in mip tail 1439 ************************************************************************************************************************ 1440 */ 1441 Dim3d Lib::GetMipTailDim( 1442 AddrResourceType resourceType, 1443 AddrSwizzleMode swizzleMode, 1444 UINT_32 blockWidth, 1445 UINT_32 blockHeight, 1446 UINT_32 blockDepth) const 1447 { 1448 Dim3d out = {blockWidth, blockHeight, blockDepth}; 1449 UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode); 1450 1451 if (IsThick(resourceType, swizzleMode)) 1452 { 1453 UINT_32 dim = log2blkSize % 3; 1454 1455 if (dim == 0) 1456 { 1457 out.h >>= 1; 1458 } 1459 else if (dim == 1) 1460 { 1461 out.w >>= 1; 1462 } 1463 else 1464 { 1465 out.d >>= 1; 1466 } 1467 } 1468 else 1469 { 1470 if (log2blkSize & 1) 1471 { 1472 out.h >>= 1; 1473 } 1474 else 1475 { 1476 out.w >>= 1; 1477 } 1478 } 1479 1480 return out; 1481 } 1482 1483 /** 1484 ************************************************************************************************************************ 1485 * Lib::ComputeSurface2DMicroBlockOffset 1486 * 1487 * @brief 1488 * Internal function to calculate micro block (256B) offset from coord for 2D resource 1489 * 1490 * @return 1491 * micro block (256B) offset for 2D resource 1492 ************************************************************************************************************************ 1493 */ 1494 UINT_32 Lib::ComputeSurface2DMicroBlockOffset( 1495 const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const 1496 { 1497 ADDR_ASSERT(IsThin(pIn->resourceType, pIn->swizzleMode)); 1498 1499 UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3); 1500 UINT_32 microBlockOffset = 0; 1501 if (IsStandardSwizzle(pIn->resourceType, pIn->swizzleMode)) 1502 { 1503 UINT_32 xBits = pIn->x << log2ElementBytes; 1504 microBlockOffset = (xBits & 0xf) | ((pIn->y & 0x3) << 4); 1505 if (log2ElementBytes < 3) 1506 { 1507 microBlockOffset |= (pIn->y & 0x4) << 4; 1508 if (log2ElementBytes == 0) 1509 { 1510 microBlockOffset |= (pIn->y & 0x8) << 4; 1511 } 1512 else 1513 { 1514 microBlockOffset |= (xBits & 0x10) << 3; 1515 } 1516 } 1517 else 1518 { 1519 microBlockOffset |= (xBits & 0x30) << 2; 1520 } 1521 } 1522 else if (IsDisplaySwizzle(pIn->resourceType, pIn->swizzleMode)) 1523 { 1524 if (log2ElementBytes == 4) 1525 { 1526 microBlockOffset = (GetBit(pIn->x, 0) << 4) | 1527 (GetBit(pIn->y, 0) << 5) | 1528 (GetBit(pIn->x, 1) << 6) | 1529 (GetBit(pIn->y, 1) << 7); 1530 } 1531 else 1532 { 1533 microBlockOffset = GetBits(pIn->x, 0, 3, log2ElementBytes) | 1534 GetBits(pIn->y, 1, 2, 3 + log2ElementBytes) | 1535 GetBits(pIn->x, 3, 1, 5 + log2ElementBytes) | 1536 GetBits(pIn->y, 3, 1, 6 + log2ElementBytes); 1537 microBlockOffset = GetBits(microBlockOffset, 0, 4, 0) | 1538 (GetBit(pIn->y, 0) << 4) | 1539 GetBits(microBlockOffset, 4, 3, 5); 1540 } 1541 } 1542 else if (IsRotateSwizzle(pIn->swizzleMode)) 1543 { 1544 microBlockOffset = GetBits(pIn->y, 0, 3, log2ElementBytes) | 1545 GetBits(pIn->x, 1, 2, 3 + log2ElementBytes) | 1546 GetBits(pIn->x, 3, 1, 5 + log2ElementBytes) | 1547 GetBits(pIn->y, 3, 1, 6 + log2ElementBytes); 1548 microBlockOffset = GetBits(microBlockOffset, 0, 4, 0) | 1549 (GetBit(pIn->x, 0) << 4) | 1550 GetBits(microBlockOffset, 4, 3, 5); 1551 if (log2ElementBytes == 3) 1552 { 1553 microBlockOffset = GetBits(microBlockOffset, 0, 6, 0) | 1554 GetBits(pIn->x, 1, 2, 6); 1555 } 1556 } 1557 1558 return microBlockOffset; 1559 } 1560 1561 /** 1562 ************************************************************************************************************************ 1563 * Lib::ComputeSurface3DMicroBlockOffset 1564 * 1565 * @brief 1566 * Internal function to calculate micro block (1KB) offset from coord for 3D resource 1567 * 1568 * @return 1569 * micro block (1KB) offset for 3D resource 1570 ************************************************************************************************************************ 1571 */ 1572 UINT_32 Lib::ComputeSurface3DMicroBlockOffset( 1573 const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const 1574 { 1575 ADDR_ASSERT(IsThick(pIn->resourceType, pIn->swizzleMode)); 1576 1577 UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3); 1578 UINT_32 microBlockOffset = 0; 1579 if (IsStandardSwizzle(pIn->resourceType, pIn->swizzleMode)) 1580 { 1581 if (log2ElementBytes == 0) 1582 { 1583 microBlockOffset = ((pIn->slice & 4) >> 2) | ((pIn->y & 4) >> 1); 1584 } 1585 else if (log2ElementBytes == 1) 1586 { 1587 microBlockOffset = ((pIn->slice & 4) >> 2) | ((pIn->y & 4) >> 1); 1588 } 1589 else if (log2ElementBytes == 2) 1590 { 1591 microBlockOffset = ((pIn->y & 4) >> 2) | ((pIn->x & 4) >> 1); 1592 } 1593 else if (log2ElementBytes == 3) 1594 { 1595 microBlockOffset = (pIn->x & 6) >> 1; 1596 } 1597 else 1598 { 1599 microBlockOffset = pIn->x & 3; 1600 } 1601 1602 microBlockOffset <<= 8; 1603 1604 UINT_32 xBits = pIn->x << log2ElementBytes; 1605 microBlockOffset |= (xBits & 0xf) | ((pIn->y & 0x3) << 4) | ((pIn->slice & 0x3) << 6); 1606 } 1607 else if (IsZOrderSwizzle(pIn->swizzleMode)) 1608 { 1609 UINT_32 xh, yh, zh; 1610 1611 if (log2ElementBytes == 0) 1612 { 1613 microBlockOffset = 1614 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->y & 2) << 2); 1615 microBlockOffset = microBlockOffset | ((pIn->slice & 3) << 4) | ((pIn->x & 4) << 4); 1616 1617 xh = pIn->x >> 3; 1618 yh = pIn->y >> 2; 1619 zh = pIn->slice >> 2; 1620 } 1621 else if (log2ElementBytes == 1) 1622 { 1623 microBlockOffset = 1624 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->y & 2) << 2); 1625 microBlockOffset = (microBlockOffset << 1) | ((pIn->slice & 3) << 5); 1626 1627 xh = pIn->x >> 2; 1628 yh = pIn->y >> 2; 1629 zh = pIn->slice >> 2; 1630 } 1631 else if (log2ElementBytes == 2) 1632 { 1633 microBlockOffset = 1634 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->slice & 1) << 3); 1635 microBlockOffset = (microBlockOffset << 2) | ((pIn->y & 2) << 5); 1636 1637 xh = pIn->x >> 2; 1638 yh = pIn->y >> 2; 1639 zh = pIn->slice >> 1; 1640 } 1641 else if (log2ElementBytes == 3) 1642 { 1643 microBlockOffset = 1644 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->slice & 1) << 2) | ((pIn->x & 2) << 2); 1645 microBlockOffset <<= 3; 1646 1647 xh = pIn->x >> 2; 1648 yh = pIn->y >> 1; 1649 zh = pIn->slice >> 1; 1650 } 1651 else 1652 { 1653 microBlockOffset = 1654 (((pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->slice & 1) << 2)) << 4); 1655 1656 xh = pIn->x >> 1; 1657 yh = pIn->y >> 1; 1658 zh = pIn->slice >> 1; 1659 } 1660 1661 microBlockOffset |= ((MortonGen3d(xh, yh, zh, 1) << 7) & 0x380); 1662 } 1663 1664 return microBlockOffset; 1665 } 1666 1667 /** 1668 ************************************************************************************************************************ 1669 * Lib::GetPipeXorBits 1670 * 1671 * @brief 1672 * Internal function to get bits number for pipe/se xor operation 1673 * 1674 * @return 1675 * ADDR_E_RETURNCODE 1676 ************************************************************************************************************************ 1677 */ 1678 UINT_32 Lib::GetPipeXorBits( 1679 UINT_32 macroBlockBits) const 1680 { 1681 ADDR_ASSERT(macroBlockBits >= m_pipeInterleaveLog2); 1682 1683 // Total available xor bits 1684 UINT_32 xorBits = macroBlockBits - m_pipeInterleaveLog2; 1685 1686 // Pipe/Se xor bits 1687 UINT_32 pipeBits = Min(xorBits, m_pipesLog2 + m_seLog2); 1688 1689 return pipeBits; 1690 } 1691 1692 /** 1693 ************************************************************************************************************************ 1694 * Lib::GetBankXorBits 1695 * 1696 * @brief 1697 * Internal function to get bits number for pipe/se xor operation 1698 * 1699 * @return 1700 * ADDR_E_RETURNCODE 1701 ************************************************************************************************************************ 1702 */ 1703 UINT_32 Lib::GetBankXorBits( 1704 UINT_32 macroBlockBits) const 1705 { 1706 UINT_32 pipeBits = GetPipeXorBits(macroBlockBits); 1707 1708 // Bank xor bits 1709 UINT_32 bankBits = Min(macroBlockBits - pipeBits - m_pipeInterleaveLog2, m_banksLog2); 1710 1711 return bankBits; 1712 } 1713 1714 /** 1715 ************************************************************************************************************************ 1716 * Lib::Addr2GetPreferredSurfaceSetting 1717 * 1718 * @brief 1719 * Internal function to get suggested surface information for cliet to use 1720 * 1721 * @return 1722 * ADDR_E_RETURNCODE 1723 ************************************************************************************************************************ 1724 */ 1725 ADDR_E_RETURNCODE Lib::Addr2GetPreferredSurfaceSetting( 1726 const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn, 1727 ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT* pOut) const 1728 { 1729 ADDR_E_RETURNCODE returnCode; 1730 1731 if ((GetFillSizeFieldsFlags() == TRUE) && 1732 ((pIn->size != sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_INPUT)) || 1733 (pOut->size != sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT)))) 1734 { 1735 returnCode = ADDR_INVALIDPARAMS; 1736 } 1737 else 1738 { 1739 returnCode = HwlGetPreferredSurfaceSetting(pIn, pOut); 1740 } 1741 1742 return returnCode; 1743 } 1744 1745 /** 1746 ************************************************************************************************************************ 1747 * Lib::ComputeBlock256Equation 1748 * 1749 * @brief 1750 * Compute equation for block 256B 1751 * 1752 * @return 1753 * If equation computed successfully 1754 * 1755 ************************************************************************************************************************ 1756 */ 1757 ADDR_E_RETURNCODE Lib::ComputeBlock256Equation( 1758 AddrResourceType rsrcType, 1759 AddrSwizzleMode swMode, 1760 UINT_32 elementBytesLog2, 1761 ADDR_EQUATION* pEquation) const 1762 { 1763 ADDR_E_RETURNCODE ret; 1764 1765 if (IsBlock256b(swMode)) 1766 { 1767 ret = HwlComputeBlock256Equation(rsrcType, swMode, elementBytesLog2, pEquation); 1768 } 1769 else 1770 { 1771 ADDR_ASSERT_ALWAYS(); 1772 ret = ADDR_INVALIDPARAMS; 1773 } 1774 1775 return ret; 1776 } 1777 1778 /** 1779 ************************************************************************************************************************ 1780 * Lib::ComputeThinEquation 1781 * 1782 * @brief 1783 * Compute equation for 2D/3D resource which use THIN mode 1784 * 1785 * @return 1786 * If equation computed successfully 1787 * 1788 ************************************************************************************************************************ 1789 */ 1790 ADDR_E_RETURNCODE Lib::ComputeThinEquation( 1791 AddrResourceType rsrcType, 1792 AddrSwizzleMode swMode, 1793 UINT_32 elementBytesLog2, 1794 ADDR_EQUATION* pEquation) const 1795 { 1796 ADDR_E_RETURNCODE ret; 1797 1798 if (IsThin(rsrcType, swMode)) 1799 { 1800 ret = HwlComputeThinEquation(rsrcType, swMode, elementBytesLog2, pEquation); 1801 } 1802 else 1803 { 1804 ADDR_ASSERT_ALWAYS(); 1805 ret = ADDR_INVALIDPARAMS; 1806 } 1807 1808 return ret; 1809 } 1810 1811 /** 1812 ************************************************************************************************************************ 1813 * Lib::ComputeThickEquation 1814 * 1815 * @brief 1816 * Compute equation for 3D resource which use THICK mode 1817 * 1818 * @return 1819 * If equation computed successfully 1820 * 1821 ************************************************************************************************************************ 1822 */ 1823 ADDR_E_RETURNCODE Lib::ComputeThickEquation( 1824 AddrResourceType rsrcType, 1825 AddrSwizzleMode swMode, 1826 UINT_32 elementBytesLog2, 1827 ADDR_EQUATION* pEquation) const 1828 { 1829 ADDR_E_RETURNCODE ret; 1830 1831 if (IsThick(rsrcType, swMode)) 1832 { 1833 ret = HwlComputeThickEquation(rsrcType, swMode, elementBytesLog2, pEquation); 1834 } 1835 else 1836 { 1837 ADDR_ASSERT_ALWAYS(); 1838 ret = ADDR_INVALIDPARAMS; 1839 } 1840 1841 return ret; 1842 } 1843 1844 /** 1845 ************************************************************************************************************************ 1846 * Lib::ComputeQbStereoInfo 1847 * 1848 * @brief 1849 * Get quad buffer stereo information 1850 * @return 1851 * N/A 1852 ************************************************************************************************************************ 1853 */ 1854 VOID Lib::ComputeQbStereoInfo( 1855 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in,out] updated pOut+pStereoInfo 1856 ) const 1857 { 1858 ADDR_ASSERT(pOut->bpp >= 8); 1859 ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0); 1860 1861 // Save original height 1862 pOut->pStereoInfo->eyeHeight = pOut->height; 1863 1864 // Right offset 1865 pOut->pStereoInfo->rightOffset = static_cast<UINT_32>(pOut->surfSize); 1866 1867 // Double height 1868 pOut->height <<= 1; 1869 1870 ADDR_ASSERT(pOut->height <= MaxSurfaceHeight); 1871 1872 pOut->pixelHeight <<= 1; 1873 1874 // Double size 1875 pOut->surfSize <<= 1; 1876 } 1877 1878 1879 } // V2 1880 } // Addr 1881 1882