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 addrelemlib.cpp 30 * @brief Contains the class implementation for element/pixel related functions. 31 **************************************************************************************************** 32 */ 33 34 #include "addrelemlib.h" 35 #include "addrlib.h" 36 37 namespace Addr 38 { 39 40 /** 41 **************************************************************************************************** 42 * ElemLib::ElemLib 43 * 44 * @brief 45 * constructor 46 * 47 * @return 48 * N/A 49 **************************************************************************************************** 50 */ 51 ElemLib::ElemLib( 52 Lib* pAddrLib) ///< [in] Parent addrlib instance pointer 53 : 54 Object(pAddrLib->GetClient()), 55 m_pAddrLib(pAddrLib) 56 { 57 switch (m_pAddrLib->GetChipFamily()) 58 { 59 case ADDR_CHIP_FAMILY_R6XX: 60 m_depthPlanarType = ADDR_DEPTH_PLANAR_R600; 61 m_fp16ExportNorm = 0; 62 break; 63 case ADDR_CHIP_FAMILY_R7XX: 64 m_depthPlanarType = ADDR_DEPTH_PLANAR_R600; 65 m_fp16ExportNorm = 1; 66 break; 67 case ADDR_CHIP_FAMILY_R8XX: 68 case ADDR_CHIP_FAMILY_NI: // Same as 8xx 69 m_depthPlanarType = ADDR_DEPTH_PLANAR_R800; 70 m_fp16ExportNorm = 1; 71 break; 72 default: 73 m_fp16ExportNorm = 1; 74 m_depthPlanarType = ADDR_DEPTH_PLANAR_R800; 75 } 76 77 m_configFlags.value = 0; 78 } 79 80 /** 81 **************************************************************************************************** 82 * ElemLib::~ElemLib 83 * 84 * @brief 85 * destructor 86 * 87 * @return 88 * N/A 89 **************************************************************************************************** 90 */ 91 ElemLib::~ElemLib() 92 { 93 } 94 95 /** 96 **************************************************************************************************** 97 * ElemLib::Create 98 * 99 * @brief 100 * Creates and initializes AddrLib object. 101 * 102 * @return 103 * Returns point to ADDR_CREATEINFO if successful. 104 **************************************************************************************************** 105 */ 106 ElemLib* ElemLib::Create( 107 const Lib* pAddrLib) ///< [in] Pointer of parent AddrLib instance 108 { 109 ElemLib* pElemLib = NULL; 110 111 if (pAddrLib) 112 { 113 VOID* pObj = Object::ClientAlloc(sizeof(ElemLib), pAddrLib->GetClient()); 114 if (pObj) 115 { 116 pElemLib = new(pObj) ElemLib(const_cast<Lib* const>(pAddrLib)); 117 } 118 } 119 120 return pElemLib; 121 } 122 123 /************************************************************************************************** 124 * ElemLib::Flt32sToInt32s 125 * 126 * @brief 127 * Convert a ADDR_FLT_32 value to Int32 value 128 * 129 * @return 130 * N/A 131 **************************************************************************************************** 132 */ 133 VOID ElemLib::Flt32sToInt32s( 134 ADDR_FLT_32 value, ///< [in] ADDR_FLT_32 value 135 UINT_32 bits, ///< [in] nubmer of bits in value 136 NumberType numberType, ///< [in] the type of number 137 UINT_32* pResult) ///< [out] Int32 value 138 { 139 UINT_8 round = 128; //ADDR_ROUND_BY_HALF 140 UINT_32 uscale; 141 UINT_32 sign; 142 143 //convert each component to an INT_32 144 switch ( numberType ) 145 { 146 case ADDR_NO_NUMBER: //fall through 147 case ADDR_ZERO: //fall through 148 case ADDR_ONE: //fall through 149 case ADDR_EPSILON: //fall through 150 return; // these are zero-bit components, so don't set result 151 152 case ADDR_UINT_BITS: // unsigned integer bit field, clamped to range 153 uscale = (1<<bits) - 1; 154 if (bits == 32) // special case unsigned 32-bit int 155 { 156 *pResult = value.i; 157 } 158 else 159 { 160 if ((value.i < 0) || (value.u > uscale)) 161 { 162 *pResult = uscale; 163 } 164 else 165 { 166 *pResult = value.i; 167 } 168 return; 169 } 170 171 // The algorithm used in the DB and TX differs at one value for 24-bit unorms 172 case ADDR_UNORM_R6XXDB: // unsigned repeating fraction 173 if ((bits==24) && (value.i == 0x33000000)) 174 { 175 *pResult = 1; 176 return; 177 } // Else treat like ADDR_UNORM_R6XX 178 179 case ADDR_UNORM_R6XX: // unsigned repeating fraction 180 if (value.f <= 0) 181 { 182 *pResult = 0; // first clamp to [0..1] 183 } 184 else 185 { 186 if (value.f >= 1) 187 { 188 *pResult = (1<<bits) - 1; 189 } 190 else 191 { 192 if ((value.i | 0x87FFFFFF) == 0xFFFFFFFF) 193 { 194 *pResult = 0; // NaN, so force to 0 195 } 196 197 #if 0 // floating point version for documentation 198 else 199 { 200 FLOAT f = value.f * ((1<<bits) - 1); 201 *pResult = static_cast<INT_32>(f + (round/256.0f)); 202 } 203 #endif 204 else 205 { 206 ADDR_FLT_32 scaled; 207 ADDR_FLT_32 shifted; 208 UINT_64 truncated, rounded; 209 UINT_32 altShift; 210 UINT_32 mask = (1 << bits) - 1; 211 UINT_32 half = 1 << (bits - 1); 212 UINT_32 mant24 = (value.i & 0x7FFFFF) + 0x800000; 213 UINT_64 temp = mant24 - (mant24>>bits) - 214 static_cast<INT_32>((mant24 & mask) > half); 215 UINT_32 exp8 = value.i >> 23; 216 UINT_32 shift = 126 - exp8 + 24 - bits; 217 UINT_64 final; 218 219 if (shift >= 32) // This is zero, even with maximum dither add 220 { 221 final = 0; 222 } 223 else 224 { 225 final = ((temp<<8) + (static_cast<UINT_64>(round)<<shift)) >> (shift+8); 226 } 227 //ADDR_EXIT( *pResult == final, 228 // ("Float %x converted to %d-bit Unorm %x != bitwise %x", 229 // value.u, bits, (UINT_32)*pResult, (UINT_32)final) ); 230 if (final > mask) 231 { 232 final = mask; 233 } 234 235 scaled.f = value.f * ((1<<bits) - 1); 236 shifted.f = (scaled.f * 256); 237 truncated = ((shifted.i&0x7FFFFF) + (INT_64)0x800000) << 8; 238 altShift = 126 + 24 + 8 - ((shifted.i>>23)&0xFF); 239 truncated = (altShift > 60) ? 0 : truncated >> altShift; 240 rounded = static_cast<INT_32>((round + truncated) >> 8); 241 //if (rounded > ((1<<bits) - 1)) 242 // rounded = ((1<<bits) - 1); 243 *pResult = static_cast<INT_32>(rounded); //(INT_32)final; 244 } 245 } 246 } 247 248 return; 249 250 case ADDR_S8FLOAT32: // 32-bit IEEE float, passes through NaN values 251 *pResult = value.i; 252 return; 253 254 // @@ FIX ROUNDING in this code, fix the denorm case 255 case ADDR_U4FLOATC: // Unsigned float, 4-bit exponent. bias 15, clamped [0..1] 256 sign = (value.i >> 31) & 1; 257 if ((value.i&0x7F800000) == 0x7F800000) // If NaN or INF: 258 { 259 if ((value.i&0x007FFFFF) != 0) // then if NaN 260 { 261 *pResult = 0; // return 0 262 } 263 else 264 { 265 *pResult = (sign)?0:0xF00000; // else +INF->+1, -INF->0 266 } 267 return; 268 } 269 if (value.f <= 0) 270 { 271 *pResult = 0; 272 } 273 else 274 { 275 if (value.f>=1) 276 { 277 *pResult = 0xF << (bits-4); 278 } 279 else 280 { 281 if ((value.i>>23) > 112 ) 282 { 283 // 24-bit float: normalized 284 // value.i += 1 << (22-bits+4); 285 // round the IEEE mantissa to mantissa size 286 // @@ NOTE: add code to support rounding 287 value.u &= 0x7FFFFFF; // mask off high 4 exponent bits 288 *pResult = value.i >> (23-bits+4);// shift off unused mantissa bits 289 } 290 else 291 { 292 // 24-bit float: denormalized 293 value.f = value.f / (1<<28) / (1<<28); 294 value.f = value.f / (1<<28) / (1<<28); // convert to IEEE denorm 295 // value.i += 1 << (22-bits+4); 296 // round the IEEE mantissa to mantissa size 297 // @@ NOTE: add code to support rounding 298 *pResult = value.i >> (23-bits+4); // shift off unused mantissa bits 299 } 300 } 301 } 302 303 return; 304 305 default: // invalid number mode 306 //ADDR_EXIT(0, ("Invalid AddrNumber %d", numberType) ); 307 break; 308 309 } 310 } 311 312 /** 313 **************************************************************************************************** 314 * ElemLib::Int32sToPixel 315 * 316 * @brief 317 * Pack 32-bit integer values into an uncompressed pixel, 318 * in the proper order 319 * 320 * @return 321 * N/A 322 * 323 * @note 324 * This entry point packes four 32-bit integer values into 325 * an uncompressed pixel. The pixel values are specifies in 326 * standard order, e.g. depth/stencil. This routine asserts 327 * if called on compressed pixel. 328 **************************************************************************************************** 329 */ 330 VOID ElemLib::Int32sToPixel( 331 UINT_32 numComps, ///< [in] number of components 332 UINT_32* pComps, ///< [in] compnents 333 UINT_32* pCompBits, ///< [in] total bits in each component 334 UINT_32* pCompStart, ///< [in] the first bit position of each component 335 ComponentFlags properties, ///< [in] properties about byteAligned, exportNorm 336 UINT_32 resultBits, ///< [in] result bits: total bpp after decompression 337 UINT_8* pPixel) ///< [out] a depth/stencil pixel value 338 { 339 UINT_32 i; 340 UINT_32 j; 341 UINT_32 start; 342 UINT_32 size; 343 UINT_32 byte; 344 UINT_32 value = 0; 345 UINT_32 compMask; 346 UINT_32 elemMask=0; 347 UINT_32 elementXor = 0; // address xor when reading bytes from elements 348 349 350 // @@ NOTE: assert if called on a compressed format! 351 352 if (properties.byteAligned) // Components are all byte-sized 353 { 354 for (i = 0; i < numComps; i++) // Then for each component 355 { 356 // Copy the bytes of the component into the element 357 start = pCompStart[i] / 8; 358 size = pCompBits[i] / 8; 359 for (j = 0; j < size; j++) 360 { 361 pPixel[(j+start)^elementXor] = static_cast<UINT_8>(pComps[i] >> (8*j)); 362 } 363 } 364 } 365 else // Element is 32-bits or less, components are bit fields 366 { 367 // First, extract each component in turn and combine it into a 32-bit value 368 for (i = 0; i < numComps; i++) 369 { 370 compMask = (1 << pCompBits[i]) - 1; 371 elemMask |= compMask << pCompStart[i]; 372 value |= (pComps[i] & compMask) << pCompStart[i]; 373 } 374 375 // Mext, copy the masked value into the element 376 size = (resultBits + 7) / 8; 377 for (i = 0; i < size; i++) 378 { 379 byte = pPixel[i^elementXor] & ~(elemMask >> (8*i)); 380 pPixel[i^elementXor] = static_cast<UINT_8>(byte | ((elemMask & value) >> (8*i))); 381 } 382 } 383 } 384 385 /** 386 **************************************************************************************************** 387 * Flt32ToDepthPixel 388 * 389 * @brief 390 * Convert a FLT_32 value to a depth/stencil pixel value 391 * 392 * @return 393 * N/A 394 **************************************************************************************************** 395 */ 396 VOID ElemLib::Flt32ToDepthPixel( 397 AddrDepthFormat format, ///< [in] Depth format 398 const ADDR_FLT_32 comps[2], ///< [in] two components of depth 399 UINT_8* pPixel ///< [out] depth pixel value 400 ) const 401 { 402 UINT_32 i; 403 UINT_32 values[2]; 404 ComponentFlags properties; // byteAligned, exportNorm 405 UINT_32 resultBits = 0; // result bits: total bits per pixel after decompression 406 407 PixelFormatInfo fmt; 408 409 // get type for each component 410 PixGetDepthCompInfo(format, &fmt); 411 412 //initialize properties 413 properties.byteAligned = TRUE; 414 properties.exportNorm = TRUE; 415 properties.floatComp = FALSE; 416 417 //set properties and result bits 418 for (i = 0; i < 2; i++) 419 { 420 if ((fmt.compBit[i] & 7) || (fmt.compStart[i] & 7)) 421 { 422 properties.byteAligned = FALSE; 423 } 424 425 if (resultBits < fmt.compStart[i] + fmt.compBit[i]) 426 { 427 resultBits = fmt.compStart[i] + fmt.compBit[i]; 428 } 429 430 // Clear ADDR_EXPORT_NORM if can't be represented as 11-bit or smaller [-1..+1] format 431 if (fmt.compBit[i] > 11 || fmt.numType[i] >= ADDR_USCALED) 432 { 433 properties.exportNorm = FALSE; 434 } 435 436 // Mark if there are any floating point components 437 if ((fmt.numType[i] == ADDR_U4FLOATC) || (fmt.numType[i] >= ADDR_S8FLOAT) ) 438 { 439 properties.floatComp = TRUE; 440 } 441 } 442 443 // Convert the two input floats to integer values 444 for (i = 0; i < 2; i++) 445 { 446 Flt32sToInt32s(comps[i], fmt.compBit[i], fmt.numType[i], &values[i]); 447 } 448 449 // Then pack the two integer components, in the proper order 450 Int32sToPixel(2, values, fmt.compBit, fmt.compStart, properties, resultBits, pPixel ); 451 452 } 453 454 /** 455 **************************************************************************************************** 456 * Flt32ToColorPixel 457 * 458 * @brief 459 * Convert a FLT_32 value to a red/green/blue/alpha pixel value 460 * 461 * @return 462 * N/A 463 **************************************************************************************************** 464 */ 465 VOID ElemLib::Flt32ToColorPixel( 466 AddrColorFormat format, ///< [in] Color format 467 AddrSurfaceNumber surfNum, ///< [in] Surface number 468 AddrSurfaceSwap surfSwap, ///< [in] Surface swap 469 const ADDR_FLT_32 comps[4], ///< [in] four components of color 470 UINT_8* pPixel ///< [out] a red/green/blue/alpha pixel value 471 ) const 472 { 473 PixelFormatInfo pixelInfo; 474 475 UINT_32 i; 476 UINT_32 values[4]; 477 ComponentFlags properties; // byteAligned, exportNorm 478 UINT_32 resultBits = 0; // result bits: total bits per pixel after decompression 479 480 memset(&pixelInfo, 0, sizeof(PixelFormatInfo)); 481 482 PixGetColorCompInfo(format, surfNum, surfSwap, &pixelInfo); 483 484 //initialize properties 485 properties.byteAligned = TRUE; 486 properties.exportNorm = TRUE; 487 properties.floatComp = FALSE; 488 489 //set properties and result bits 490 for (i = 0; i < 4; i++) 491 { 492 if ( (pixelInfo.compBit[i] & 7) || (pixelInfo.compStart[i] & 7) ) 493 { 494 properties.byteAligned = FALSE; 495 } 496 497 if (resultBits < pixelInfo.compStart[i] + pixelInfo.compBit[i]) 498 { 499 resultBits = pixelInfo.compStart[i] + pixelInfo.compBit[i]; 500 } 501 502 if (m_fp16ExportNorm) 503 { 504 // Clear ADDR_EXPORT_NORM if can't be represented as 11-bit or smaller [-1..+1] format 505 // or if it's not FP and <=16 bits 506 if (((pixelInfo.compBit[i] > 11) || (pixelInfo.numType[i] >= ADDR_USCALED)) 507 && (pixelInfo.numType[i] !=ADDR_U4FLOATC)) 508 { 509 properties.exportNorm = FALSE; 510 } 511 } 512 else 513 { 514 // Clear ADDR_EXPORT_NORM if can't be represented as 11-bit or smaller [-1..+1] format 515 if (pixelInfo.compBit[i] > 11 || pixelInfo.numType[i] >= ADDR_USCALED) 516 { 517 properties.exportNorm = FALSE; 518 } 519 } 520 521 // Mark if there are any floating point components 522 if ( (pixelInfo.numType[i] == ADDR_U4FLOATC) || 523 (pixelInfo.numType[i] >= ADDR_S8FLOAT) ) 524 { 525 properties.floatComp = TRUE; 526 } 527 } 528 529 // Convert the four input floats to integer values 530 for (i = 0; i < 4; i++) 531 { 532 Flt32sToInt32s(comps[i], pixelInfo.compBit[i], pixelInfo.numType[i], &values[i]); 533 } 534 535 // Then pack the four integer components, in the proper order 536 Int32sToPixel(4, values, &pixelInfo.compBit[0], &pixelInfo.compStart[0], 537 properties, resultBits, pPixel); 538 } 539 540 /** 541 **************************************************************************************************** 542 * ElemLib::GetCompType 543 * 544 * @brief 545 * Fill per component info 546 * 547 * @return 548 * N/A 549 * 550 **************************************************************************************************** 551 */ 552 VOID ElemLib::GetCompType( 553 AddrColorFormat format, ///< [in] surface format 554 AddrSurfaceNumber numType, ///< [in] number type 555 PixelFormatInfo* pInfo) ///< [in][out] per component info out 556 { 557 BOOL_32 handled = FALSE; 558 559 // Floating point formats override the number format 560 switch (format) 561 { 562 case ADDR_COLOR_16_FLOAT: // fall through for all pure floating point format 563 case ADDR_COLOR_16_16_FLOAT: 564 case ADDR_COLOR_16_16_16_16_FLOAT: 565 case ADDR_COLOR_32_FLOAT: 566 case ADDR_COLOR_32_32_FLOAT: 567 case ADDR_COLOR_32_32_32_32_FLOAT: 568 case ADDR_COLOR_10_11_11_FLOAT: 569 case ADDR_COLOR_11_11_10_FLOAT: 570 numType = ADDR_NUMBER_FLOAT; 571 break; 572 // Special handling for the depth formats 573 case ADDR_COLOR_8_24: // fall through for these 2 similar format 574 case ADDR_COLOR_24_8: 575 for (UINT_32 c = 0; c < 4; c++) 576 { 577 if (pInfo->compBit[c] == 8) 578 { 579 pInfo->numType[c] = ADDR_UINT_BITS; 580 } 581 else if (pInfo->compBit[c] == 24) 582 { 583 pInfo->numType[c] = ADDR_UNORM_R6XX; 584 } 585 else 586 { 587 pInfo->numType[c] = ADDR_NO_NUMBER; 588 } 589 } 590 handled = TRUE; 591 break; 592 case ADDR_COLOR_8_24_FLOAT: // fall through for these 3 similar format 593 case ADDR_COLOR_24_8_FLOAT: 594 case ADDR_COLOR_X24_8_32_FLOAT: 595 for (UINT_32 c = 0; c < 4; c++) 596 { 597 if (pInfo->compBit[c] == 8) 598 { 599 pInfo->numType[c] = ADDR_UINT_BITS; 600 } 601 else if (pInfo->compBit[c] == 24) 602 { 603 pInfo->numType[c] = ADDR_U4FLOATC; 604 } 605 else if (pInfo->compBit[c] == 32) 606 { 607 pInfo->numType[c] = ADDR_S8FLOAT32; 608 } 609 else 610 { 611 pInfo->numType[c] = ADDR_NO_NUMBER; 612 } 613 } 614 handled = TRUE; 615 break; 616 default: 617 break; 618 } 619 620 if (!handled) 621 { 622 for (UINT_32 c = 0; c < 4; c++) 623 { 624 // Assign a number type for each component 625 AddrSurfaceNumber cnum; 626 627 // First handle default component values 628 if (pInfo->compBit[c] == 0) 629 { 630 if (c < 3) 631 { 632 pInfo->numType[c] = ADDR_ZERO; // Default is zero for RGB 633 } 634 else if (numType == ADDR_NUMBER_UINT || numType == ADDR_NUMBER_SINT) 635 { 636 pInfo->numType[c] = ADDR_EPSILON; // Alpha INT_32 bits default is 0x01 637 } 638 else 639 { 640 pInfo->numType[c] = ADDR_ONE; // Alpha normal default is float 1.0 641 } 642 continue; 643 } 644 // Now handle small components 645 else if (pInfo->compBit[c] == 1) 646 { 647 if (numType == ADDR_NUMBER_UINT || numType == ADDR_NUMBER_SINT) 648 { 649 cnum = ADDR_NUMBER_UINT; 650 } 651 else 652 { 653 cnum = ADDR_NUMBER_UNORM; 654 } 655 } 656 else 657 { 658 cnum = numType; 659 } 660 661 // If no default, set the number type fom num, compbits, and architecture 662 switch (cnum) 663 { 664 case ADDR_NUMBER_SRGB: 665 pInfo->numType[c] = (c < 3) ? ADDR_GAMMA8_R6XX : ADDR_UNORM_R6XX; 666 break; 667 case ADDR_NUMBER_UNORM: 668 pInfo->numType[c] = ADDR_UNORM_R6XX; 669 break; 670 case ADDR_NUMBER_SNORM: 671 pInfo->numType[c] = ADDR_SNORM_R6XX; 672 break; 673 case ADDR_NUMBER_USCALED: 674 pInfo->numType[c] = ADDR_USCALED; // @@ Do we need separate Pele routine? 675 break; 676 case ADDR_NUMBER_SSCALED: 677 pInfo->numType[c] = ADDR_SSCALED; // @@ Do we need separate Pele routine? 678 break; 679 case ADDR_NUMBER_FLOAT: 680 if (pInfo->compBit[c] == 32) 681 { 682 pInfo->numType[c] = ADDR_S8FLOAT32; 683 } 684 else if (pInfo->compBit[c] == 16) 685 { 686 pInfo->numType[c] = ADDR_S5FLOAT; 687 } 688 else if (pInfo->compBit[c] >= 10) 689 { 690 pInfo->numType[c] = ADDR_U5FLOAT; 691 } 692 else 693 { 694 ADDR_ASSERT_ALWAYS(); 695 } 696 break; 697 case ADDR_NUMBER_SINT: 698 pInfo->numType[c] = ADDR_SINT_BITS; 699 break; 700 case ADDR_NUMBER_UINT: 701 pInfo->numType[c] = ADDR_UINT_BITS; 702 break; 703 704 default: 705 ADDR_ASSERT(!"Invalid number type"); 706 pInfo->numType[c] = ADDR_NO_NUMBER; 707 break; 708 } 709 } 710 } 711 } 712 713 /** 714 **************************************************************************************************** 715 * ElemLib::GetCompSwap 716 * 717 * @brief 718 * Get components swapped for color surface 719 * 720 * @return 721 * N/A 722 * 723 **************************************************************************************************** 724 */ 725 VOID ElemLib::GetCompSwap( 726 AddrSurfaceSwap swap, ///< [in] swap mode 727 PixelFormatInfo* pInfo) ///< [in,out] output per component info 728 { 729 switch (pInfo->comps) 730 { 731 case 4: 732 switch (swap) 733 { 734 case ADDR_SWAP_ALT: 735 SwapComps( 0, 2, pInfo ); 736 break; // BGRA 737 case ADDR_SWAP_STD_REV: 738 SwapComps( 0, 3, pInfo ); 739 SwapComps( 1, 2, pInfo ); 740 break; // ABGR 741 case ADDR_SWAP_ALT_REV: 742 SwapComps( 0, 3, pInfo ); 743 SwapComps( 0, 2, pInfo ); 744 SwapComps( 0, 1, pInfo ); 745 break; // ARGB 746 default: 747 break; 748 } 749 break; 750 case 3: 751 switch (swap) 752 { 753 case ADDR_SWAP_ALT_REV: 754 SwapComps( 0, 3, pInfo ); 755 SwapComps( 0, 2, pInfo ); 756 break; // AGR 757 case ADDR_SWAP_STD_REV: 758 SwapComps( 0, 2, pInfo ); 759 break; // BGR 760 case ADDR_SWAP_ALT: 761 SwapComps( 2, 3, pInfo ); 762 break; // RGA 763 default: 764 break; // RGB 765 } 766 break; 767 case 2: 768 switch (swap) 769 { 770 case ADDR_SWAP_ALT_REV: 771 SwapComps( 0, 1, pInfo ); 772 SwapComps( 1, 3, pInfo ); 773 break; // AR 774 case ADDR_SWAP_STD_REV: 775 SwapComps( 0, 1, pInfo ); 776 break; // GR 777 case ADDR_SWAP_ALT: 778 SwapComps( 1, 3, pInfo ); 779 break; // RA 780 default: 781 break; // RG 782 } 783 break; 784 case 1: 785 switch (swap) 786 { 787 case ADDR_SWAP_ALT_REV: 788 SwapComps( 0, 3, pInfo ); 789 break; // A 790 case ADDR_SWAP_STD_REV: 791 SwapComps( 0, 2, pInfo ); 792 break; // B 793 case ADDR_SWAP_ALT: 794 SwapComps( 0, 1, pInfo ); 795 break; // G 796 default: 797 break; // R 798 } 799 break; 800 } 801 } 802 803 /** 804 **************************************************************************************************** 805 * ElemLib::GetCompSwap 806 * 807 * @brief 808 * Get components swapped for color surface 809 * 810 * @return 811 * N/A 812 * 813 **************************************************************************************************** 814 */ 815 VOID ElemLib::SwapComps( 816 UINT_32 c0, ///< [in] component index 0 817 UINT_32 c1, ///< [in] component index 1 818 PixelFormatInfo* pInfo) ///< [in,out] output per component info 819 { 820 UINT_32 start; 821 UINT_32 bits; 822 823 start = pInfo->compStart[c0]; 824 pInfo->compStart[c0] = pInfo->compStart[c1]; 825 pInfo->compStart[c1] = start; 826 827 bits = pInfo->compBit[c0]; 828 pInfo->compBit[c0] = pInfo->compBit[c1]; 829 pInfo->compBit[c1] = bits; 830 } 831 832 /** 833 **************************************************************************************************** 834 * ElemLib::PixGetColorCompInfo 835 * 836 * @brief 837 * Get per component info for color surface 838 * 839 * @return 840 * N/A 841 * 842 **************************************************************************************************** 843 */ 844 VOID ElemLib::PixGetColorCompInfo( 845 AddrColorFormat format, ///< [in] surface format, read from register 846 AddrSurfaceNumber number, ///< [in] pixel number type 847 AddrSurfaceSwap swap, ///< [in] component swap mode 848 PixelFormatInfo* pInfo ///< [out] output per component info 849 ) const 850 { 851 // 1. Get componet bits 852 switch (format) 853 { 854 case ADDR_COLOR_8: 855 GetCompBits(8, 0, 0, 0, pInfo); 856 break; 857 case ADDR_COLOR_1_5_5_5: 858 GetCompBits(5, 5, 5, 1, pInfo); 859 break; 860 case ADDR_COLOR_5_6_5: 861 GetCompBits(8, 6, 5, 0, pInfo); 862 break; 863 case ADDR_COLOR_6_5_5: 864 GetCompBits(5, 5, 6, 0, pInfo); 865 break; 866 case ADDR_COLOR_8_8: 867 GetCompBits(8, 8, 0, 0, pInfo); 868 break; 869 case ADDR_COLOR_4_4_4_4: 870 GetCompBits(4, 4, 4, 4, pInfo); 871 break; 872 case ADDR_COLOR_16: 873 GetCompBits(16, 0, 0, 0, pInfo); 874 break; 875 case ADDR_COLOR_8_8_8_8: 876 GetCompBits(8, 8, 8, 8, pInfo); 877 break; 878 case ADDR_COLOR_2_10_10_10: 879 GetCompBits(10, 10, 10, 2, pInfo); 880 break; 881 case ADDR_COLOR_10_11_11: 882 GetCompBits(11, 11, 10, 0, pInfo); 883 break; 884 case ADDR_COLOR_11_11_10: 885 GetCompBits(10, 11, 11, 0, pInfo); 886 break; 887 case ADDR_COLOR_16_16: 888 GetCompBits(16, 16, 0, 0, pInfo); 889 break; 890 case ADDR_COLOR_16_16_16_16: 891 GetCompBits(16, 16, 16, 16, pInfo); 892 break; 893 case ADDR_COLOR_16_FLOAT: 894 GetCompBits(16, 0, 0, 0, pInfo); 895 break; 896 case ADDR_COLOR_16_16_FLOAT: 897 GetCompBits(16, 16, 0, 0, pInfo); 898 break; 899 case ADDR_COLOR_32_FLOAT: 900 GetCompBits(32, 0, 0, 0, pInfo); 901 break; 902 case ADDR_COLOR_32_32_FLOAT: 903 GetCompBits(32, 32, 0, 0, pInfo); 904 break; 905 case ADDR_COLOR_16_16_16_16_FLOAT: 906 GetCompBits(16, 16, 16, 16, pInfo); 907 break; 908 case ADDR_COLOR_32_32_32_32_FLOAT: 909 GetCompBits(32, 32, 32, 32, pInfo); 910 break; 911 912 case ADDR_COLOR_32: 913 GetCompBits(32, 0, 0, 0, pInfo); 914 break; 915 case ADDR_COLOR_32_32: 916 GetCompBits(32, 32, 0, 0, pInfo); 917 break; 918 case ADDR_COLOR_32_32_32_32: 919 GetCompBits(32, 32, 32, 32, pInfo); 920 break; 921 case ADDR_COLOR_10_10_10_2: 922 GetCompBits(2, 10, 10, 10, pInfo); 923 break; 924 case ADDR_COLOR_10_11_11_FLOAT: 925 GetCompBits(11, 11, 10, 0, pInfo); 926 break; 927 case ADDR_COLOR_11_11_10_FLOAT: 928 GetCompBits(10, 11, 11, 0, pInfo); 929 break; 930 case ADDR_COLOR_5_5_5_1: 931 GetCompBits(1, 5, 5, 5, pInfo); 932 break; 933 case ADDR_COLOR_3_3_2: 934 GetCompBits(2, 3, 3, 0, pInfo); 935 break; 936 case ADDR_COLOR_4_4: 937 GetCompBits(4, 4, 0, 0, pInfo); 938 break; 939 case ADDR_COLOR_8_24: 940 case ADDR_COLOR_8_24_FLOAT: // same bit count, fall through 941 GetCompBits(24, 8, 0, 0, pInfo); 942 break; 943 case ADDR_COLOR_24_8: 944 case ADDR_COLOR_24_8_FLOAT: // same bit count, fall through 945 GetCompBits(8, 24, 0, 0, pInfo); 946 break; 947 case ADDR_COLOR_X24_8_32_FLOAT: 948 GetCompBits(32, 8, 0, 0, pInfo); 949 break; 950 951 case ADDR_COLOR_INVALID: 952 GetCompBits(0, 0, 0, 0, pInfo); 953 break; 954 default: 955 ADDR_ASSERT(0); 956 GetCompBits(0, 0, 0, 0, pInfo); 957 break; 958 } 959 960 // 2. Get component number type 961 962 GetCompType(format, number, pInfo); 963 964 // 3. Swap components if needed 965 966 GetCompSwap(swap, pInfo); 967 } 968 969 /** 970 **************************************************************************************************** 971 * ElemLib::PixGetDepthCompInfo 972 * 973 * @brief 974 * Get per component info for depth surface 975 * 976 * @return 977 * N/A 978 * 979 **************************************************************************************************** 980 */ 981 VOID ElemLib::PixGetDepthCompInfo( 982 AddrDepthFormat format, ///< [in] surface format, read from register 983 PixelFormatInfo* pInfo ///< [out] output per component bits and type 984 ) const 985 { 986 if (m_depthPlanarType == ADDR_DEPTH_PLANAR_R800) 987 { 988 if (format == ADDR_DEPTH_8_24_FLOAT) 989 { 990 format = ADDR_DEPTH_X24_8_32_FLOAT; // Use this format to represent R800's D24FS8 991 } 992 993 if (format == ADDR_DEPTH_X8_24_FLOAT) 994 { 995 format = ADDR_DEPTH_32_FLOAT; 996 } 997 } 998 999 switch (format) 1000 { 1001 case ADDR_DEPTH_16: 1002 GetCompBits(16, 0, 0, 0, pInfo); 1003 break; 1004 case ADDR_DEPTH_8_24: 1005 case ADDR_DEPTH_8_24_FLOAT: // similar format, fall through 1006 GetCompBits(24, 8, 0, 0, pInfo); 1007 break; 1008 case ADDR_DEPTH_X8_24: 1009 case ADDR_DEPTH_X8_24_FLOAT: // similar format, fall through 1010 GetCompBits(24, 0, 0, 0, pInfo); 1011 break; 1012 case ADDR_DEPTH_32_FLOAT: 1013 GetCompBits(32, 0, 0, 0, pInfo); 1014 break; 1015 case ADDR_DEPTH_X24_8_32_FLOAT: 1016 GetCompBits(32, 8, 0, 0, pInfo); 1017 break; 1018 case ADDR_DEPTH_INVALID: 1019 GetCompBits(0, 0, 0, 0, pInfo); 1020 break; 1021 default: 1022 ADDR_ASSERT(0); 1023 GetCompBits(0, 0, 0, 0, pInfo); 1024 break; 1025 } 1026 1027 switch (format) 1028 { 1029 case ADDR_DEPTH_16: 1030 pInfo->numType [0] = ADDR_UNORM_R6XX; 1031 pInfo->numType [1] = ADDR_ZERO; 1032 break; 1033 case ADDR_DEPTH_8_24: 1034 pInfo->numType [0] = ADDR_UNORM_R6XXDB; 1035 pInfo->numType [1] = ADDR_UINT_BITS; 1036 break; 1037 case ADDR_DEPTH_8_24_FLOAT: 1038 pInfo->numType [0] = ADDR_U4FLOATC; 1039 pInfo->numType [1] = ADDR_UINT_BITS; 1040 break; 1041 case ADDR_DEPTH_X8_24: 1042 pInfo->numType [0] = ADDR_UNORM_R6XXDB; 1043 pInfo->numType [1] = ADDR_ZERO; 1044 break; 1045 case ADDR_DEPTH_X8_24_FLOAT: 1046 pInfo->numType [0] = ADDR_U4FLOATC; 1047 pInfo->numType [1] = ADDR_ZERO; 1048 break; 1049 case ADDR_DEPTH_32_FLOAT: 1050 pInfo->numType [0] = ADDR_S8FLOAT32; 1051 pInfo->numType [1] = ADDR_ZERO; 1052 break; 1053 case ADDR_DEPTH_X24_8_32_FLOAT: 1054 pInfo->numType [0] = ADDR_S8FLOAT32; 1055 pInfo->numType [1] = ADDR_UINT_BITS; 1056 break; 1057 default: 1058 pInfo->numType [0] = ADDR_NO_NUMBER; 1059 pInfo->numType [1] = ADDR_NO_NUMBER; 1060 break; 1061 } 1062 1063 pInfo->numType [2] = ADDR_NO_NUMBER; 1064 pInfo->numType [3] = ADDR_NO_NUMBER; 1065 } 1066 1067 /** 1068 **************************************************************************************************** 1069 * ElemLib::PixGetExportNorm 1070 * 1071 * @brief 1072 * Check if fp16 export norm can be enabled. 1073 * 1074 * @return 1075 * TRUE if this can be enabled. 1076 * 1077 **************************************************************************************************** 1078 */ 1079 BOOL_32 ElemLib::PixGetExportNorm( 1080 AddrColorFormat colorFmt, ///< [in] surface format, read from register 1081 AddrSurfaceNumber numberFmt, ///< [in] pixel number type 1082 AddrSurfaceSwap swap ///< [in] components swap type 1083 ) const 1084 { 1085 BOOL_32 enabled = TRUE; 1086 1087 PixelFormatInfo formatInfo; 1088 1089 PixGetColorCompInfo(colorFmt, numberFmt, swap, &formatInfo); 1090 1091 for (UINT_32 c = 0; c < 4; c++) 1092 { 1093 if (m_fp16ExportNorm) 1094 { 1095 if (((formatInfo.compBit[c] > 11) || (formatInfo.numType[c] > ADDR_USCALED)) && 1096 (formatInfo.numType[c] != ADDR_U4FLOATC) && 1097 (formatInfo.numType[c] != ADDR_S5FLOAT) && 1098 (formatInfo.numType[c] != ADDR_S5FLOATM) && 1099 (formatInfo.numType[c] != ADDR_U5FLOAT) && 1100 (formatInfo.numType[c] != ADDR_U3FLOATM)) 1101 { 1102 enabled = FALSE; 1103 break; 1104 } 1105 } 1106 else 1107 { 1108 if ((formatInfo.compBit[c] > 11) || (formatInfo.numType[c] > ADDR_USCALED)) 1109 { 1110 enabled = FALSE; 1111 break; 1112 } 1113 } 1114 } 1115 1116 return enabled; 1117 } 1118 1119 /** 1120 **************************************************************************************************** 1121 * ElemLib::AdjustSurfaceInfo 1122 * 1123 * @brief 1124 * Adjust bpp/base pitch/width/height according to elemMode and expandX/Y 1125 * 1126 * @return 1127 * N/A 1128 **************************************************************************************************** 1129 */ 1130 VOID ElemLib::AdjustSurfaceInfo( 1131 ElemMode elemMode, ///< [in] element mode 1132 UINT_32 expandX, ///< [in] decompression expansion factor in X 1133 UINT_32 expandY, ///< [in] decompression expansion factor in Y 1134 UINT_32* pBpp, ///< [in,out] bpp 1135 UINT_32* pBasePitch, ///< [in,out] base pitch 1136 UINT_32* pWidth, ///< [in,out] width 1137 UINT_32* pHeight) ///< [in,out] height 1138 { 1139 UINT_32 packedBits; 1140 UINT_32 basePitch; 1141 UINT_32 width; 1142 UINT_32 height; 1143 UINT_32 bpp; 1144 BOOL_32 bBCnFormat = FALSE; 1145 1146 ADDR_ASSERT(pBpp != NULL); 1147 ADDR_ASSERT(pWidth != NULL && pHeight != NULL && pBasePitch != NULL); 1148 1149 if (pBpp) 1150 { 1151 bpp = *pBpp; 1152 1153 switch (elemMode) 1154 { 1155 case ADDR_EXPANDED: 1156 packedBits = bpp / expandX / expandY; 1157 break; 1158 case ADDR_PACKED_STD: // Different bit order 1159 case ADDR_PACKED_REV: 1160 packedBits = bpp * expandX * expandY; 1161 break; 1162 case ADDR_PACKED_GBGR: 1163 case ADDR_PACKED_BGRG: 1164 packedBits = bpp; // 32-bit packed ==> 2 32-bit result 1165 break; 1166 case ADDR_PACKED_BC1: // Fall through 1167 case ADDR_PACKED_BC4: 1168 packedBits = 64; 1169 bBCnFormat = TRUE; 1170 break; 1171 case ADDR_PACKED_BC2: // Fall through 1172 case ADDR_PACKED_BC3: // Fall through 1173 case ADDR_PACKED_BC5: // Fall through 1174 bBCnFormat = TRUE; 1175 // fall through 1176 case ADDR_PACKED_ASTC: 1177 case ADDR_PACKED_ETC2_128BPP: 1178 packedBits = 128; 1179 break; 1180 case ADDR_PACKED_ETC2_64BPP: 1181 packedBits = 64; 1182 break; 1183 case ADDR_ROUND_BY_HALF: // Fall through 1184 case ADDR_ROUND_TRUNCATE: // Fall through 1185 case ADDR_ROUND_DITHER: // Fall through 1186 case ADDR_UNCOMPRESSED: 1187 packedBits = bpp; 1188 break; 1189 default: 1190 packedBits = bpp; 1191 ADDR_ASSERT_ALWAYS(); 1192 break; 1193 } 1194 1195 *pBpp = packedBits; 1196 } 1197 1198 if (pWidth && pHeight && pBasePitch) 1199 { 1200 basePitch = *pBasePitch; 1201 width = *pWidth; 1202 height = *pHeight; 1203 1204 if ((expandX > 1) || (expandY > 1)) 1205 { 1206 if (elemMode == ADDR_EXPANDED) 1207 { 1208 basePitch *= expandX; 1209 width *= expandX; 1210 height *= expandY; 1211 } 1212 else 1213 { 1214 // Evergreen family workaround 1215 if (bBCnFormat && (m_pAddrLib->GetChipFamily() == ADDR_CHIP_FAMILY_R8XX)) 1216 { 1217 // For BCn we now pad it to POW2 at the beginning so it is safe to 1218 // divide by 4 directly 1219 basePitch = basePitch / expandX; 1220 width = width / expandX; 1221 height = height / expandY; 1222 #if DEBUG 1223 width = (width == 0) ? 1 : width; 1224 height = (height == 0) ? 1 : height; 1225 1226 if ((*pWidth > PowTwoAlign(width, 8) * expandX) || 1227 (*pHeight > PowTwoAlign(height, 8) * expandY)) // 8 is 1D tiling alignment 1228 { 1229 // if this assertion is hit we may have issues if app samples 1230 // rightmost/bottommost pixels 1231 ADDR_ASSERT_ALWAYS(); 1232 } 1233 #endif 1234 } 1235 else // Not BCn format we still keep old way (FMT_1? No real test yet) 1236 { 1237 basePitch = (basePitch + expandX - 1) / expandX; 1238 width = (width + expandX - 1) / expandX; 1239 height = (height + expandY - 1) / expandY; 1240 } 1241 } 1242 1243 *pBasePitch = basePitch; // 0 is legal value for base pitch. 1244 *pWidth = (width == 0) ? 1 : width; 1245 *pHeight = (height == 0) ? 1 : height; 1246 } //if (pWidth && pHeight && pBasePitch) 1247 } 1248 } 1249 1250 /** 1251 **************************************************************************************************** 1252 * ElemLib::RestoreSurfaceInfo 1253 * 1254 * @brief 1255 * Reverse operation of AdjustSurfaceInfo 1256 * 1257 * @return 1258 * N/A 1259 **************************************************************************************************** 1260 */ 1261 VOID ElemLib::RestoreSurfaceInfo( 1262 ElemMode elemMode, ///< [in] element mode 1263 UINT_32 expandX, ///< [in] decompression expansion factor in X 1264 UINT_32 expandY, ///< [out] decompression expansion factor in Y 1265 UINT_32* pBpp, ///< [in,out] bpp 1266 UINT_32* pWidth, ///< [in,out] width 1267 UINT_32* pHeight) ///< [in,out] height 1268 { 1269 UINT_32 originalBits; 1270 UINT_32 width; 1271 UINT_32 height; 1272 UINT_32 bpp; 1273 1274 BOOL_32 bBCnFormat = FALSE; 1275 (void)bBCnFormat; 1276 1277 ADDR_ASSERT(pBpp != NULL); 1278 ADDR_ASSERT(pWidth != NULL && pHeight != NULL); 1279 1280 if (pBpp) 1281 { 1282 bpp = *pBpp; 1283 1284 switch (elemMode) 1285 { 1286 case ADDR_EXPANDED: 1287 originalBits = bpp * expandX * expandY; 1288 break; 1289 case ADDR_PACKED_STD: // Different bit order 1290 case ADDR_PACKED_REV: 1291 originalBits = bpp / expandX / expandY; 1292 break; 1293 case ADDR_PACKED_GBGR: 1294 case ADDR_PACKED_BGRG: 1295 originalBits = bpp; // 32-bit packed ==> 2 32-bit result 1296 break; 1297 case ADDR_PACKED_BC1: // Fall through 1298 case ADDR_PACKED_BC4: 1299 originalBits = 64; 1300 bBCnFormat = TRUE; 1301 break; 1302 case ADDR_PACKED_BC2: // Fall through 1303 case ADDR_PACKED_BC3: // Fall through 1304 case ADDR_PACKED_BC5: 1305 bBCnFormat = TRUE; 1306 // fall through 1307 case ADDR_PACKED_ASTC: 1308 case ADDR_PACKED_ETC2_128BPP: 1309 originalBits = 128; 1310 break; 1311 case ADDR_PACKED_ETC2_64BPP: 1312 originalBits = 64; 1313 break; 1314 case ADDR_ROUND_BY_HALF: // Fall through 1315 case ADDR_ROUND_TRUNCATE: // Fall through 1316 case ADDR_ROUND_DITHER: // Fall through 1317 case ADDR_UNCOMPRESSED: 1318 originalBits = bpp; 1319 break; 1320 default: 1321 originalBits = bpp; 1322 ADDR_ASSERT_ALWAYS(); 1323 break; 1324 } 1325 1326 *pBpp = originalBits; 1327 } 1328 1329 if (pWidth && pHeight) 1330 { 1331 width = *pWidth; 1332 height = *pHeight; 1333 1334 if ((expandX > 1) || (expandY > 1)) 1335 { 1336 if (elemMode == ADDR_EXPANDED) 1337 { 1338 width /= expandX; 1339 height /= expandY; 1340 } 1341 else 1342 { 1343 width *= expandX; 1344 height *= expandY; 1345 } 1346 } 1347 1348 *pWidth = (width == 0) ? 1 : width; 1349 *pHeight = (height == 0) ? 1 : height; 1350 } 1351 } 1352 1353 /** 1354 **************************************************************************************************** 1355 * ElemLib::GetBitsPerPixel 1356 * 1357 * @brief 1358 * Compute the total bits per element according to a format 1359 * code. For compressed formats, this is not the same as 1360 * the number of bits per decompressed element. 1361 * 1362 * @return 1363 * Bits per pixel 1364 **************************************************************************************************** 1365 */ 1366 UINT_32 ElemLib::GetBitsPerPixel( 1367 AddrFormat format, ///< [in] surface format code 1368 ElemMode* pElemMode, ///< [out] element mode 1369 UINT_32* pExpandX, ///< [out] decompression expansion factor in X 1370 UINT_32* pExpandY, ///< [out] decompression expansion factor in Y 1371 UINT_32* pUnusedBits) ///< [out] bits unused 1372 { 1373 UINT_32 bpp; 1374 UINT_32 expandX = 1; 1375 UINT_32 expandY = 1; 1376 UINT_32 bitUnused = 0; 1377 ElemMode elemMode = ADDR_UNCOMPRESSED; // default value 1378 1379 switch (format) 1380 { 1381 case ADDR_FMT_8: 1382 bpp = 8; 1383 break; 1384 case ADDR_FMT_1_5_5_5: 1385 case ADDR_FMT_5_6_5: 1386 case ADDR_FMT_6_5_5: 1387 case ADDR_FMT_8_8: 1388 case ADDR_FMT_4_4_4_4: 1389 case ADDR_FMT_16: 1390 case ADDR_FMT_16_FLOAT: 1391 bpp = 16; 1392 break; 1393 case ADDR_FMT_GB_GR: // treat as FMT_8_8 1394 elemMode = ADDR_PACKED_GBGR; 1395 bpp = 16; 1396 break; 1397 case ADDR_FMT_BG_RG: // treat as FMT_8_8 1398 elemMode = ADDR_PACKED_BGRG; 1399 bpp = 16; 1400 break; 1401 case ADDR_FMT_8_8_8_8: 1402 case ADDR_FMT_2_10_10_10: 1403 case ADDR_FMT_10_11_11: 1404 case ADDR_FMT_11_11_10: 1405 case ADDR_FMT_16_16: 1406 case ADDR_FMT_16_16_FLOAT: 1407 case ADDR_FMT_32: 1408 case ADDR_FMT_32_FLOAT: 1409 case ADDR_FMT_24_8: 1410 case ADDR_FMT_24_8_FLOAT: 1411 bpp = 32; 1412 break; 1413 case ADDR_FMT_16_16_16_16: 1414 case ADDR_FMT_16_16_16_16_FLOAT: 1415 case ADDR_FMT_32_32: 1416 case ADDR_FMT_32_32_FLOAT: 1417 case ADDR_FMT_CTX1: 1418 bpp = 64; 1419 break; 1420 case ADDR_FMT_32_32_32_32: 1421 case ADDR_FMT_32_32_32_32_FLOAT: 1422 bpp = 128; 1423 break; 1424 case ADDR_FMT_INVALID: 1425 bpp = 0; 1426 break; 1427 case ADDR_FMT_1_REVERSED: 1428 elemMode = ADDR_PACKED_REV; 1429 expandX = 8; 1430 bpp = 1; 1431 break; 1432 case ADDR_FMT_1: 1433 elemMode = ADDR_PACKED_STD; 1434 expandX = 8; 1435 bpp = 1; 1436 break; 1437 case ADDR_FMT_4_4: 1438 case ADDR_FMT_3_3_2: 1439 bpp = 8; 1440 break; 1441 case ADDR_FMT_5_5_5_1: 1442 bpp = 16; 1443 break; 1444 case ADDR_FMT_32_AS_8: 1445 case ADDR_FMT_32_AS_8_8: 1446 case ADDR_FMT_8_24: 1447 case ADDR_FMT_8_24_FLOAT: 1448 case ADDR_FMT_10_10_10_2: 1449 case ADDR_FMT_10_11_11_FLOAT: 1450 case ADDR_FMT_11_11_10_FLOAT: 1451 case ADDR_FMT_5_9_9_9_SHAREDEXP: 1452 bpp = 32; 1453 break; 1454 case ADDR_FMT_X24_8_32_FLOAT: 1455 bpp = 64; 1456 bitUnused = 24; 1457 break; 1458 case ADDR_FMT_8_8_8: 1459 elemMode = ADDR_EXPANDED; 1460 bpp = 24;//@@ 8; // read 3 elements per pixel 1461 expandX = 3; 1462 break; 1463 case ADDR_FMT_16_16_16: 1464 case ADDR_FMT_16_16_16_FLOAT: 1465 elemMode = ADDR_EXPANDED; 1466 bpp = 48;//@@ 16; // read 3 elements per pixel 1467 expandX = 3; 1468 break; 1469 case ADDR_FMT_32_32_32_FLOAT: 1470 case ADDR_FMT_32_32_32: 1471 elemMode = ADDR_EXPANDED; 1472 expandX = 3; 1473 bpp = 96;//@@ 32; // read 3 elements per pixel 1474 break; 1475 case ADDR_FMT_BC1: 1476 elemMode = ADDR_PACKED_BC1; 1477 expandX = 4; 1478 expandY = 4; 1479 bpp = 64; 1480 break; 1481 case ADDR_FMT_BC4: 1482 elemMode = ADDR_PACKED_BC4; 1483 expandX = 4; 1484 expandY = 4; 1485 bpp = 64; 1486 break; 1487 case ADDR_FMT_BC2: 1488 elemMode = ADDR_PACKED_BC2; 1489 expandX = 4; 1490 expandY = 4; 1491 bpp = 128; 1492 break; 1493 case ADDR_FMT_BC3: 1494 elemMode = ADDR_PACKED_BC3; 1495 expandX = 4; 1496 expandY = 4; 1497 bpp = 128; 1498 break; 1499 case ADDR_FMT_BC5: 1500 case ADDR_FMT_BC6: // reuse ADDR_PACKED_BC5 1501 case ADDR_FMT_BC7: // reuse ADDR_PACKED_BC5 1502 elemMode = ADDR_PACKED_BC5; 1503 expandX = 4; 1504 expandY = 4; 1505 bpp = 128; 1506 break; 1507 1508 case ADDR_FMT_ETC2_64BPP: 1509 elemMode = ADDR_PACKED_ETC2_64BPP; 1510 expandX = 4; 1511 expandY = 4; 1512 bpp = 64; 1513 break; 1514 1515 case ADDR_FMT_ETC2_128BPP: 1516 elemMode = ADDR_PACKED_ETC2_128BPP; 1517 expandX = 4; 1518 expandY = 4; 1519 bpp = 128; 1520 break; 1521 1522 case ADDR_FMT_ASTC_4x4: 1523 elemMode = ADDR_PACKED_ASTC; 1524 expandX = 4; 1525 expandY = 4; 1526 bpp = 128; 1527 break; 1528 1529 case ADDR_FMT_ASTC_5x4: 1530 elemMode = ADDR_PACKED_ASTC; 1531 expandX = 5; 1532 expandY = 4; 1533 bpp = 128; 1534 break; 1535 1536 case ADDR_FMT_ASTC_5x5: 1537 elemMode = ADDR_PACKED_ASTC; 1538 expandX = 5; 1539 expandY = 5; 1540 bpp = 128; 1541 break; 1542 1543 case ADDR_FMT_ASTC_6x5: 1544 elemMode = ADDR_PACKED_ASTC; 1545 expandX = 6; 1546 expandY = 5; 1547 bpp = 128; 1548 break; 1549 1550 case ADDR_FMT_ASTC_6x6: 1551 elemMode = ADDR_PACKED_ASTC; 1552 expandX = 6; 1553 expandY = 6; 1554 bpp = 128; 1555 break; 1556 1557 case ADDR_FMT_ASTC_8x5: 1558 elemMode = ADDR_PACKED_ASTC; 1559 expandX = 8; 1560 expandY = 5; 1561 bpp = 128; 1562 break; 1563 1564 case ADDR_FMT_ASTC_8x6: 1565 elemMode = ADDR_PACKED_ASTC; 1566 expandX = 8; 1567 expandY = 6; 1568 bpp = 128; 1569 break; 1570 1571 case ADDR_FMT_ASTC_8x8: 1572 elemMode = ADDR_PACKED_ASTC; 1573 expandX = 8; 1574 expandY = 8; 1575 bpp = 128; 1576 break; 1577 1578 case ADDR_FMT_ASTC_10x5: 1579 elemMode = ADDR_PACKED_ASTC; 1580 expandX = 10; 1581 expandY = 5; 1582 bpp = 128; 1583 break; 1584 1585 case ADDR_FMT_ASTC_10x6: 1586 elemMode = ADDR_PACKED_ASTC; 1587 expandX = 10; 1588 expandY = 6; 1589 bpp = 128; 1590 break; 1591 1592 case ADDR_FMT_ASTC_10x8: 1593 elemMode = ADDR_PACKED_ASTC; 1594 expandX = 10; 1595 expandY = 8; 1596 bpp = 128; 1597 break; 1598 1599 case ADDR_FMT_ASTC_10x10: 1600 elemMode = ADDR_PACKED_ASTC; 1601 expandX = 10; 1602 expandY = 10; 1603 bpp = 128; 1604 break; 1605 1606 case ADDR_FMT_ASTC_12x10: 1607 elemMode = ADDR_PACKED_ASTC; 1608 expandX = 12; 1609 expandY = 10; 1610 bpp = 128; 1611 break; 1612 1613 case ADDR_FMT_ASTC_12x12: 1614 elemMode = ADDR_PACKED_ASTC; 1615 expandX = 12; 1616 expandY = 12; 1617 bpp = 128; 1618 break; 1619 1620 default: 1621 bpp = 0; 1622 ADDR_ASSERT_ALWAYS(); 1623 break; 1624 // @@ or should this be an error? 1625 } 1626 1627 SafeAssign(pExpandX, expandX); 1628 SafeAssign(pExpandY, expandY); 1629 SafeAssign(pUnusedBits, bitUnused); 1630 SafeAssign(reinterpret_cast<UINT_32*>(pElemMode), elemMode); 1631 1632 return bpp; 1633 } 1634 1635 /** 1636 **************************************************************************************************** 1637 * ElemLib::GetCompBits 1638 * 1639 * @brief 1640 * Set each component's bit size and bit start. And set element mode and number type 1641 * 1642 * @return 1643 * N/A 1644 **************************************************************************************************** 1645 */ 1646 VOID ElemLib::GetCompBits( 1647 UINT_32 c0, ///< [in] bits of component 0 1648 UINT_32 c1, ///< [in] bits of component 1 1649 UINT_32 c2, ///< [in] bits of component 2 1650 UINT_32 c3, ///< [in] bits of component 3 1651 PixelFormatInfo* pInfo, ///< [out] per component info out 1652 ElemMode elemMode) ///< [in] element mode 1653 { 1654 pInfo->comps = 0; 1655 1656 pInfo->compBit[0] = c0; 1657 pInfo->compBit[1] = c1; 1658 pInfo->compBit[2] = c2; 1659 pInfo->compBit[3] = c3; 1660 1661 pInfo->compStart[0] = 0; 1662 pInfo->compStart[1] = c0; 1663 pInfo->compStart[2] = c0+c1; 1664 pInfo->compStart[3] = c0+c1+c2; 1665 1666 pInfo->elemMode = elemMode; 1667 // still needed since component swap may depend on number of components 1668 for (INT i=0; i<4; i++) 1669 { 1670 if (pInfo->compBit[i] == 0) 1671 { 1672 pInfo->compStart[i] = 0; // all null components start at bit 0 1673 pInfo->numType[i] = ADDR_NO_NUMBER; // and have no number type 1674 } 1675 else 1676 { 1677 pInfo->comps++; 1678 } 1679 } 1680 } 1681 1682 /** 1683 **************************************************************************************************** 1684 * ElemLib::GetCompBits 1685 * 1686 * @brief 1687 * Set the clear color (or clear depth/stencil) for a surface 1688 * 1689 * @note 1690 * If clearColor is zero, a default clear value is used in place of comps[4]. 1691 * If float32 is set, full precision is used, else the mantissa is reduced to 12-bits 1692 * 1693 * @return 1694 * N/A 1695 **************************************************************************************************** 1696 */ 1697 VOID ElemLib::SetClearComps( 1698 ADDR_FLT_32 comps[4], ///< [in,out] components 1699 BOOL_32 clearColor, ///< [in] TRUE if clear color is set (CLEAR_COLOR) 1700 BOOL_32 float32) ///< [in] TRUE if float32 component (BLEND_FLOAT32) 1701 { 1702 INT_32 i; 1703 1704 // Use default clearvalues if clearColor is disabled 1705 if (clearColor == FALSE) 1706 { 1707 for (i=0; i<3; i++) 1708 { 1709 comps[i].f = 0.0; 1710 } 1711 comps[3].f = 1.0; 1712 } 1713 1714 // Otherwise use the (modified) clear value 1715 else 1716 { 1717 for (i=0; i<4; i++) 1718 { // If full precision, use clear value unchanged 1719 if (float32) 1720 { 1721 // Do nothing 1722 //comps[i] = comps[i]; 1723 } 1724 // Else if it is a NaN, use the standard NaN value 1725 else if ((comps[i].u & 0x7FFFFFFF) > 0x7F800000) 1726 { 1727 comps[i].u = 0xFFC00000; 1728 } 1729 // Else reduce the mantissa precision 1730 else 1731 { 1732 comps[i].u = comps[i].u & 0xFFFFF000; 1733 } 1734 } 1735 } 1736 } 1737 1738 /** 1739 **************************************************************************************************** 1740 * ElemLib::IsBlockCompressed 1741 * 1742 * @brief 1743 * TRUE if this is block compressed format 1744 * 1745 * @note 1746 * 1747 * @return 1748 * BOOL_32 1749 **************************************************************************************************** 1750 */ 1751 BOOL_32 ElemLib::IsBlockCompressed( 1752 AddrFormat format) ///< [in] Format 1753 { 1754 return (((format >= ADDR_FMT_BC1) && (format <= ADDR_FMT_BC7)) || 1755 ((format >= ADDR_FMT_ASTC_4x4) && (format <= ADDR_FMT_ETC2_128BPP))); 1756 } 1757 1758 1759 /** 1760 **************************************************************************************************** 1761 * ElemLib::IsCompressed 1762 * 1763 * @brief 1764 * TRUE if this is block compressed format or 1 bit format 1765 * 1766 * @note 1767 * 1768 * @return 1769 * BOOL_32 1770 **************************************************************************************************** 1771 */ 1772 BOOL_32 ElemLib::IsCompressed( 1773 AddrFormat format) ///< [in] Format 1774 { 1775 return IsBlockCompressed(format) || format == ADDR_FMT_BC1 || format == ADDR_FMT_BC7; 1776 } 1777 1778 /** 1779 **************************************************************************************************** 1780 * ElemLib::IsExpand3x 1781 * 1782 * @brief 1783 * TRUE if this is 3x expand format 1784 * 1785 * @note 1786 * 1787 * @return 1788 * BOOL_32 1789 **************************************************************************************************** 1790 */ 1791 BOOL_32 ElemLib::IsExpand3x( 1792 AddrFormat format) ///< [in] Format 1793 { 1794 BOOL_32 is3x = FALSE; 1795 1796 switch (format) 1797 { 1798 case ADDR_FMT_8_8_8: 1799 case ADDR_FMT_16_16_16: 1800 case ADDR_FMT_16_16_16_FLOAT: 1801 case ADDR_FMT_32_32_32: 1802 case ADDR_FMT_32_32_32_FLOAT: 1803 is3x = TRUE; 1804 break; 1805 default: 1806 break; 1807 } 1808 1809 return is3x; 1810 } 1811 1812 /** 1813 **************************************************************************************************** 1814 * ElemLib::IsMacroPixelPacked 1815 * 1816 * @brief 1817 * TRUE if this is a macro-pixel-packed format. 1818 * 1819 * @note 1820 * 1821 * @return 1822 * BOOL_32 1823 **************************************************************************************************** 1824 */ 1825 BOOL_32 ElemLib::IsMacroPixelPacked( 1826 AddrFormat format) ///< [in] Format 1827 { 1828 BOOL_32 isMacroPixelPacked = FALSE; 1829 1830 switch (format) 1831 { 1832 case ADDR_FMT_BG_RG: 1833 case ADDR_FMT_GB_GR: 1834 isMacroPixelPacked = TRUE; 1835 break; 1836 default: 1837 break; 1838 } 1839 1840 return isMacroPixelPacked; 1841 } 1842 1843 } 1844