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 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