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