• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 ************************************************************************************************************************
3 *
4 *  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE
23 *
24 ***********************************************************************************************************************/
25 
26 /**
27 ****************************************************************************************************
28 * @file  addrelemlib.cpp
29 * @brief Contains the class implementation for element/pixel related functions.
30 ****************************************************************************************************
31 */
32 
33 #include "addrelemlib.h"
34 #include "addrlib.h"
35 
36 namespace Addr
37 {
38 
39 /**
40 ****************************************************************************************************
41 *   ElemLib::ElemLib
42 *
43 *   @brief
44 *       constructor
45 *
46 *   @return
47 *       N/A
48 ****************************************************************************************************
49 */
ElemLib(Lib * pAddrLib)50 ElemLib::ElemLib(
51     Lib* pAddrLib)  ///< [in] Parent addrlib instance pointer
52     :
53     Object(pAddrLib->GetClient()),
54     m_pAddrLib(pAddrLib)
55 {
56     switch (m_pAddrLib->GetChipFamily())
57     {
58         case ADDR_CHIP_FAMILY_R6XX:
59             m_depthPlanarType = ADDR_DEPTH_PLANAR_R600;
60             m_fp16ExportNorm = 0;
61             break;
62         case ADDR_CHIP_FAMILY_R7XX:
63             m_depthPlanarType = ADDR_DEPTH_PLANAR_R600;
64             m_fp16ExportNorm = 1;
65             break;
66         case ADDR_CHIP_FAMILY_R8XX:
67         case ADDR_CHIP_FAMILY_NI: // Same as 8xx
68             m_depthPlanarType = ADDR_DEPTH_PLANAR_R800;
69             m_fp16ExportNorm = 1;
70             break;
71         default:
72             m_fp16ExportNorm = 1;
73             m_depthPlanarType = ADDR_DEPTH_PLANAR_R800;
74             break;
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 */
~ElemLib()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 */
Create(const Lib * pAddrLib)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 */
Flt32sToInt32s(ADDR_FLT_32 value,UINT_32 bits,NumberType numberType,UINT_32 * pResult)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 */
Int32sToPixel(UINT_32 numComps,UINT_32 * pComps,UINT_32 * pCompBits,UINT_32 * pCompStart,ComponentFlags properties,UINT_32 resultBits,UINT_8 * pPixel)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 */
Flt32ToDepthPixel(AddrDepthFormat format,const ADDR_FLT_32 comps[2],UINT_8 * pPixel) const396 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 */
Flt32ToColorPixel(AddrColorFormat format,AddrSurfaceNumber surfNum,AddrSurfaceSwap surfSwap,const ADDR_FLT_32 comps[4],UINT_8 * pPixel) const465 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 */
GetCompType(AddrColorFormat format,AddrSurfaceNumber numType,PixelFormatInfo * pInfo)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 */
GetCompSwap(AddrSurfaceSwap swap,PixelFormatInfo * pInfo)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 */
SwapComps(UINT_32 c0,UINT_32 c1,PixelFormatInfo * pInfo)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 */
PixGetColorCompInfo(AddrColorFormat format,AddrSurfaceNumber number,AddrSurfaceSwap swap,PixelFormatInfo * pInfo) const844 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 */
PixGetDepthCompInfo(AddrDepthFormat format,PixelFormatInfo * pInfo) const981 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 */
PixGetExportNorm(AddrColorFormat colorFmt,AddrSurfaceNumber numberFmt,AddrSurfaceSwap swap) const1079 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 */
AdjustSurfaceInfo(ElemMode elemMode,UINT_32 expandX,UINT_32 expandY,UINT_32 * pBpp,UINT_32 * pBasePitch,UINT_32 * pWidth,UINT_32 * pHeight)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 */
RestoreSurfaceInfo(ElemMode elemMode,UINT_32 expandX,UINT_32 expandY,UINT_32 * pBpp,UINT_32 * pWidth,UINT_32 * pHeight)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 
1276     ADDR_ASSERT(pBpp != NULL);
1277     ADDR_ASSERT(pWidth != NULL && pHeight != NULL);
1278 
1279     if (pBpp)
1280     {
1281         bpp = *pBpp;
1282 
1283         switch (elemMode)
1284         {
1285         case ADDR_EXPANDED:
1286             originalBits = bpp * expandX * expandY;
1287             break;
1288         case ADDR_PACKED_STD: // Different bit order
1289         case ADDR_PACKED_REV:
1290             originalBits = bpp / expandX / expandY;
1291             break;
1292         case ADDR_PACKED_GBGR:
1293         case ADDR_PACKED_BGRG:
1294             originalBits = bpp; // 32-bit packed ==> 2 32-bit result
1295             break;
1296         case ADDR_PACKED_BC1: // Fall through
1297         case ADDR_PACKED_BC4:
1298             originalBits = 64;
1299             bBCnFormat = TRUE;
1300             break;
1301         case ADDR_PACKED_BC2: // Fall through
1302         case ADDR_PACKED_BC3: // Fall through
1303         case ADDR_PACKED_BC5:
1304             bBCnFormat = TRUE;
1305             // fall through
1306         case ADDR_PACKED_ASTC:
1307         case ADDR_PACKED_ETC2_128BPP:
1308             originalBits = 128;
1309             break;
1310         case ADDR_PACKED_ETC2_64BPP:
1311             originalBits = 64;
1312             break;
1313         case ADDR_ROUND_BY_HALF:  // Fall through
1314         case ADDR_ROUND_TRUNCATE: // Fall through
1315         case ADDR_ROUND_DITHER:   // Fall through
1316         case ADDR_UNCOMPRESSED:
1317             originalBits = bpp;
1318             break;
1319         default:
1320             originalBits = bpp;
1321             ADDR_ASSERT_ALWAYS();
1322             break;
1323         }
1324 
1325         *pBpp = originalBits;
1326     }
1327 
1328     if (pWidth && pHeight)
1329     {
1330         width    = *pWidth;
1331         height   = *pHeight;
1332 
1333         if ((expandX > 1) || (expandY > 1))
1334         {
1335             if (elemMode == ADDR_EXPANDED)
1336             {
1337                 width /= expandX;
1338                 height /= expandY;
1339             }
1340             else
1341             {
1342                 width *= expandX;
1343                 height *= expandY;
1344             }
1345         }
1346 
1347         *pWidth  = (width == 0) ? 1 : width;
1348         *pHeight = (height == 0) ? 1 : height;
1349     }
1350 }
1351 
1352 /**
1353 ****************************************************************************************************
1354 *   ElemLib::GetBitsPerPixel
1355 *
1356 *   @brief
1357 *       Compute the total bits per element according to a format
1358 *       code. For compressed formats, this is not the same as
1359 *       the number of bits per decompressed element.
1360 *
1361 *   @return
1362 *       Bits per pixel
1363 ****************************************************************************************************
1364 */
GetBitsPerPixel(AddrFormat format,ElemMode * pElemMode,UINT_32 * pExpandX,UINT_32 * pExpandY,UINT_32 * pUnusedBits)1365 UINT_32 ElemLib::GetBitsPerPixel(
1366     AddrFormat          format,         ///< [in] surface format code
1367     ElemMode*           pElemMode,      ///< [out] element mode
1368     UINT_32*            pExpandX,       ///< [out] decompression expansion factor in X
1369     UINT_32*            pExpandY,       ///< [out] decompression expansion factor in Y
1370     UINT_32*            pUnusedBits)    ///< [out] bits unused
1371 {
1372     UINT_32 bpp;
1373     UINT_32 expandX = 1;
1374     UINT_32 expandY = 1;
1375     UINT_32 bitUnused = 0;
1376     ElemMode elemMode = ADDR_UNCOMPRESSED; // default value
1377 
1378     switch (format)
1379     {
1380         case ADDR_FMT_8:
1381             bpp = 8;
1382             break;
1383         case ADDR_FMT_1_5_5_5:
1384         case ADDR_FMT_5_6_5:
1385         case ADDR_FMT_6_5_5:
1386         case ADDR_FMT_8_8:
1387         case ADDR_FMT_4_4_4_4:
1388         case ADDR_FMT_16:
1389             bpp = 16;
1390             break;
1391         case ADDR_FMT_GB_GR:
1392             elemMode = ADDR_PACKED_GBGR;
1393             bpp      = m_configFlags.use32bppFor422Fmt ? 32 : 16;
1394             expandX  = m_configFlags.use32bppFor422Fmt ? 2 : 1;
1395             break;
1396         case ADDR_FMT_BG_RG:
1397             elemMode = ADDR_PACKED_BGRG;
1398             bpp      = m_configFlags.use32bppFor422Fmt ? 32 : 16;
1399             expandX  = m_configFlags.use32bppFor422Fmt ? 2 : 1;
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_32:
1407         case ADDR_FMT_24_8:
1408             bpp = 32;
1409             break;
1410         case ADDR_FMT_16_16_16_16:
1411         case ADDR_FMT_32_32:
1412         case ADDR_FMT_CTX1:
1413             bpp = 64;
1414             break;
1415         case ADDR_FMT_32_32_32_32:
1416             bpp = 128;
1417             break;
1418         case ADDR_FMT_INVALID:
1419             bpp = 0;
1420             break;
1421         case ADDR_FMT_1_REVERSED:
1422             elemMode = ADDR_PACKED_REV;
1423             expandX = 8;
1424             bpp = 1;
1425             break;
1426         case ADDR_FMT_1:
1427             elemMode = ADDR_PACKED_STD;
1428             expandX = 8;
1429             bpp = 1;
1430             break;
1431         case ADDR_FMT_4_4:
1432         case ADDR_FMT_3_3_2:
1433             bpp = 8;
1434             break;
1435         case ADDR_FMT_5_5_5_1:
1436             bpp = 16;
1437             break;
1438         case ADDR_FMT_32_AS_8:
1439         case ADDR_FMT_32_AS_8_8:
1440         case ADDR_FMT_8_24:
1441         case ADDR_FMT_10_10_10_2:
1442         case ADDR_FMT_5_9_9_9_SHAREDEXP:
1443             bpp = 32;
1444             break;
1445         case ADDR_FMT_X24_8_32_FLOAT:
1446             bpp = 64;
1447             bitUnused = 24;
1448             break;
1449         case ADDR_FMT_8_8_8:
1450             elemMode = ADDR_EXPANDED;
1451             bpp = 24;//@@ 8;      // read 3 elements per pixel
1452             expandX = 3;
1453             break;
1454         case ADDR_FMT_16_16_16:
1455             elemMode = ADDR_EXPANDED;
1456             bpp = 48;//@@ 16;      // read 3 elements per pixel
1457             expandX = 3;
1458             break;
1459         case ADDR_FMT_32_32_32:
1460             elemMode = ADDR_EXPANDED;
1461             expandX = 3;
1462             bpp = 96;//@@ 32;      // read 3 elements per pixel
1463             break;
1464         case ADDR_FMT_BC1:
1465             elemMode = ADDR_PACKED_BC1;
1466             expandX = 4;
1467             expandY = 4;
1468             bpp = 64;
1469             break;
1470         case ADDR_FMT_BC4:
1471             elemMode = ADDR_PACKED_BC4;
1472             expandX = 4;
1473             expandY = 4;
1474             bpp = 64;
1475             break;
1476         case ADDR_FMT_BC2:
1477             elemMode = ADDR_PACKED_BC2;
1478             expandX = 4;
1479             expandY = 4;
1480             bpp = 128;
1481             break;
1482         case ADDR_FMT_BC3:
1483             elemMode = ADDR_PACKED_BC3;
1484             expandX = 4;
1485             expandY = 4;
1486             bpp = 128;
1487             break;
1488         case ADDR_FMT_BC5:
1489         case ADDR_FMT_BC6: // reuse ADDR_PACKED_BC5
1490         case ADDR_FMT_BC7: // reuse ADDR_PACKED_BC5
1491             elemMode = ADDR_PACKED_BC5;
1492             expandX = 4;
1493             expandY = 4;
1494             bpp = 128;
1495             break;
1496 
1497         case ADDR_FMT_ETC2_64BPP:
1498             elemMode = ADDR_PACKED_ETC2_64BPP;
1499             expandX  = 4;
1500             expandY  = 4;
1501             bpp      = 64;
1502             break;
1503 
1504         case ADDR_FMT_ETC2_128BPP:
1505             elemMode = ADDR_PACKED_ETC2_128BPP;
1506             expandX  = 4;
1507             expandY  = 4;
1508             bpp      = 128;
1509             break;
1510 
1511         case ADDR_FMT_ASTC_4x4:
1512             elemMode = ADDR_PACKED_ASTC;
1513             expandX  = 4;
1514             expandY  = 4;
1515             bpp      = 128;
1516             break;
1517 
1518         case ADDR_FMT_ASTC_5x4:
1519             elemMode = ADDR_PACKED_ASTC;
1520             expandX  = 5;
1521             expandY  = 4;
1522             bpp      = 128;
1523             break;
1524 
1525         case ADDR_FMT_ASTC_5x5:
1526             elemMode = ADDR_PACKED_ASTC;
1527             expandX  = 5;
1528             expandY  = 5;
1529             bpp      = 128;
1530             break;
1531 
1532         case ADDR_FMT_ASTC_6x5:
1533             elemMode = ADDR_PACKED_ASTC;
1534             expandX  = 6;
1535             expandY  = 5;
1536             bpp      = 128;
1537             break;
1538 
1539         case ADDR_FMT_ASTC_6x6:
1540             elemMode = ADDR_PACKED_ASTC;
1541             expandX  = 6;
1542             expandY  = 6;
1543             bpp      = 128;
1544             break;
1545 
1546         case ADDR_FMT_ASTC_8x5:
1547             elemMode = ADDR_PACKED_ASTC;
1548             expandX  = 8;
1549             expandY  = 5;
1550             bpp      = 128;
1551             break;
1552 
1553         case ADDR_FMT_ASTC_8x6:
1554             elemMode = ADDR_PACKED_ASTC;
1555             expandX  = 8;
1556             expandY  = 6;
1557             bpp      = 128;
1558             break;
1559 
1560         case ADDR_FMT_ASTC_8x8:
1561             elemMode = ADDR_PACKED_ASTC;
1562             expandX  = 8;
1563             expandY  = 8;
1564             bpp      = 128;
1565             break;
1566 
1567         case ADDR_FMT_ASTC_10x5:
1568             elemMode = ADDR_PACKED_ASTC;
1569             expandX  = 10;
1570             expandY  = 5;
1571             bpp      = 128;
1572             break;
1573 
1574         case ADDR_FMT_ASTC_10x6:
1575             elemMode = ADDR_PACKED_ASTC;
1576             expandX  = 10;
1577             expandY  = 6;
1578             bpp      = 128;
1579             break;
1580 
1581         case ADDR_FMT_ASTC_10x8:
1582             elemMode = ADDR_PACKED_ASTC;
1583             expandX  = 10;
1584             expandY  = 8;
1585             bpp      = 128;
1586             break;
1587 
1588         case ADDR_FMT_ASTC_10x10:
1589             elemMode = ADDR_PACKED_ASTC;
1590             expandX  = 10;
1591             expandY  = 10;
1592             bpp      = 128;
1593             break;
1594 
1595         case ADDR_FMT_ASTC_12x10:
1596             elemMode = ADDR_PACKED_ASTC;
1597             expandX  = 12;
1598             expandY  = 10;
1599             bpp      = 128;
1600             break;
1601 
1602         case ADDR_FMT_ASTC_12x12:
1603             elemMode = ADDR_PACKED_ASTC;
1604             expandX  = 12;
1605             expandY  = 12;
1606             bpp      = 128;
1607             break;
1608 
1609         default:
1610             bpp = 0;
1611             ADDR_ASSERT_ALWAYS();
1612             break;
1613             // @@ or should this be an error?
1614     }
1615 
1616     SafeAssign(pExpandX, expandX);
1617     SafeAssign(pExpandY, expandY);
1618     SafeAssign(pUnusedBits, bitUnused);
1619     SafeAssign(reinterpret_cast<UINT_32*>(pElemMode), elemMode);
1620 
1621     return bpp;
1622 }
1623 
1624 /**
1625 ****************************************************************************************************
1626 *   ElemLib::GetCompBits
1627 *
1628 *   @brief
1629 *       Set each component's bit size and bit start. And set element mode and number type
1630 *
1631 *   @return
1632 *       N/A
1633 ****************************************************************************************************
1634 */
GetCompBits(UINT_32 c0,UINT_32 c1,UINT_32 c2,UINT_32 c3,PixelFormatInfo * pInfo,ElemMode elemMode)1635 VOID ElemLib::GetCompBits(
1636     UINT_32          c0,        ///< [in] bits of component 0
1637     UINT_32          c1,        ///< [in] bits of component 1
1638     UINT_32          c2,        ///< [in] bits of component 2
1639     UINT_32          c3,        ///< [in] bits of component 3
1640     PixelFormatInfo* pInfo,     ///< [out] per component info out
1641     ElemMode         elemMode)  ///< [in] element mode
1642 {
1643     pInfo->comps = 0;
1644 
1645     pInfo->compBit[0] = c0;
1646     pInfo->compBit[1] = c1;
1647     pInfo->compBit[2] = c2;
1648     pInfo->compBit[3] = c3;
1649 
1650     pInfo->compStart[0] = 0;
1651     pInfo->compStart[1] = c0;
1652     pInfo->compStart[2] = c0+c1;
1653     pInfo->compStart[3] = c0+c1+c2;
1654 
1655     pInfo->elemMode = elemMode;
1656     // still needed since component swap may depend on number of components
1657     for (INT i=0; i<4; i++)
1658     {
1659         if (pInfo->compBit[i] == 0)
1660         {
1661             pInfo->compStart[i]  = 0;       // all null components start at bit 0
1662             pInfo->numType[i] = ADDR_NO_NUMBER; // and have no number type
1663         }
1664         else
1665         {
1666             pInfo->comps++;
1667         }
1668     }
1669 }
1670 
1671 /**
1672 ****************************************************************************************************
1673 *   ElemLib::GetCompBits
1674 *
1675 *   @brief
1676 *       Set the clear color (or clear depth/stencil) for a surface
1677 *
1678 *   @note
1679 *       If clearColor is zero, a default clear value is used in place of comps[4].
1680 *       If float32 is set, full precision is used, else the mantissa is reduced to 12-bits
1681 *
1682 *   @return
1683 *       N/A
1684 ****************************************************************************************************
1685 */
SetClearComps(ADDR_FLT_32 comps[4],BOOL_32 clearColor,BOOL_32 float32)1686 VOID ElemLib::SetClearComps(
1687     ADDR_FLT_32 comps[4],   ///< [in,out] components
1688     BOOL_32 clearColor,     ///< [in] TRUE if clear color is set (CLEAR_COLOR)
1689     BOOL_32 float32)        ///< [in] TRUE if float32 component (BLEND_FLOAT32)
1690 {
1691     INT_32 i;
1692 
1693     // Use default clearvalues if clearColor is disabled
1694     if (clearColor == FALSE)
1695     {
1696         for (i=0; i<3; i++)
1697         {
1698             comps[i].f = 0.0;
1699         }
1700         comps[3].f = 1.0;
1701     }
1702 
1703     // Otherwise use the (modified) clear value
1704     else
1705     {
1706         for (i=0; i<4; i++)
1707         {   // If full precision, use clear value unchanged
1708             if (float32)
1709             {
1710                 // Do nothing
1711                 //comps[i] = comps[i];
1712             }
1713             // Else if it is a NaN, use the standard NaN value
1714             else if ((comps[i].u & 0x7FFFFFFF) > 0x7F800000)
1715             {
1716                 comps[i].u = 0xFFC00000;
1717             }
1718             // Else reduce the mantissa precision
1719             else
1720             {
1721                 comps[i].u = comps[i].u & 0xFFFFF000;
1722             }
1723         }
1724     }
1725 }
1726 
1727 /**
1728 ****************************************************************************************************
1729 *   ElemLib::IsBlockCompressed
1730 *
1731 *   @brief
1732 *       TRUE if this is block compressed format
1733 *
1734 *   @note
1735 *
1736 *   @return
1737 *       BOOL_32
1738 ****************************************************************************************************
1739 */
IsBlockCompressed(AddrFormat format)1740 BOOL_32 ElemLib::IsBlockCompressed(
1741     AddrFormat format)  ///< [in] Format
1742 {
1743     return (((format >= ADDR_FMT_BC1) && (format <= ADDR_FMT_BC7)) ||
1744             ((format >= ADDR_FMT_ASTC_4x4) && (format <= ADDR_FMT_ETC2_128BPP)));
1745 }
1746 
1747 
1748 /**
1749 ****************************************************************************************************
1750 *   ElemLib::IsCompressed
1751 *
1752 *   @brief
1753 *       TRUE if this is block compressed format or 1 bit format
1754 *
1755 *   @note
1756 *
1757 *   @return
1758 *       BOOL_32
1759 ****************************************************************************************************
1760 */
IsCompressed(AddrFormat format)1761 BOOL_32 ElemLib::IsCompressed(
1762     AddrFormat format)  ///< [in] Format
1763 {
1764     return IsBlockCompressed(format) || format == ADDR_FMT_BC1 || format == ADDR_FMT_BC7;
1765 }
1766 
1767 /**
1768 ****************************************************************************************************
1769 *   ElemLib::IsExpand3x
1770 *
1771 *   @brief
1772 *       TRUE if this is 3x expand format
1773 *
1774 *   @note
1775 *
1776 *   @return
1777 *       BOOL_32
1778 ****************************************************************************************************
1779 */
IsExpand3x(AddrFormat format)1780 BOOL_32 ElemLib::IsExpand3x(
1781     AddrFormat format)  ///< [in] Format
1782 {
1783     BOOL_32 is3x = FALSE;
1784 
1785     switch (format)
1786     {
1787         case ADDR_FMT_8_8_8:
1788         case ADDR_FMT_16_16_16:
1789         case ADDR_FMT_32_32_32:
1790             is3x = TRUE;
1791             break;
1792         default:
1793             break;
1794     }
1795 
1796     return is3x;
1797 }
1798 
1799 /**
1800 ****************************************************************************************************
1801 *   ElemLib::IsMacroPixelPacked
1802 *
1803 *   @brief
1804 *       TRUE if this is a macro-pixel-packed format.
1805 *
1806 *   @note
1807 *
1808 *   @return
1809 *       BOOL_32
1810 ****************************************************************************************************
1811 */
IsMacroPixelPacked(AddrFormat format)1812 BOOL_32 ElemLib::IsMacroPixelPacked(
1813     AddrFormat format)  ///< [in] Format
1814 {
1815     BOOL_32 isMacroPixelPacked = FALSE;
1816 
1817     switch (format)
1818     {
1819         case ADDR_FMT_BG_RG:
1820         case ADDR_FMT_GB_GR:
1821             isMacroPixelPacked = TRUE;
1822             break;
1823         default:
1824             break;
1825     }
1826 
1827     return isMacroPixelPacked;
1828 }
1829 
1830 }
1831