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