1 /*
2  * Copyright © 2007-2019 Advanced Micro Devices, Inc.
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sub license, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16  * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17  * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20  * USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * The above copyright notice and this permission notice (including the
23  * next paragraph) shall be included in all copies or substantial portions
24  * of the Software.
25  */
26 
27 /**
28 ****************************************************************************************************
29 * @file  addrelemlib.cpp
30 * @brief Contains the class implementation for element/pixel related functions.
31 ****************************************************************************************************
32 */
33 
34 #include "addrelemlib.h"
35 #include "addrlib.h"
36 
37 namespace Addr
38 {
39 
40 /**
41 ****************************************************************************************************
42 *   ElemLib::ElemLib
43 *
44 *   @brief
45 *       constructor
46 *
47 *   @return
48 *       N/A
49 ****************************************************************************************************
50 */
ElemLib(Lib * pAddrLib)51 ElemLib::ElemLib(
52     Lib* pAddrLib)  ///< [in] Parent addrlib instance pointer
53     :
54     Object(pAddrLib->GetClient()),
55     m_pAddrLib(pAddrLib)
56 {
57     switch (m_pAddrLib->GetChipFamily())
58     {
59         case ADDR_CHIP_FAMILY_R6XX:
60             m_depthPlanarType = ADDR_DEPTH_PLANAR_R600;
61             m_fp16ExportNorm = 0;
62             break;
63         case ADDR_CHIP_FAMILY_R7XX:
64             m_depthPlanarType = ADDR_DEPTH_PLANAR_R600;
65             m_fp16ExportNorm = 1;
66             break;
67         case ADDR_CHIP_FAMILY_R8XX:
68         case ADDR_CHIP_FAMILY_NI: // Same as 8xx
69             m_depthPlanarType = ADDR_DEPTH_PLANAR_R800;
70             m_fp16ExportNorm = 1;
71             break;
72         default:
73             m_fp16ExportNorm = 1;
74             m_depthPlanarType = ADDR_DEPTH_PLANAR_R800;
75             break;
76     }
77 
78     m_configFlags.value = 0;
79 }
80 
81 /**
82 ****************************************************************************************************
83 *   ElemLib::~ElemLib
84 *
85 *   @brief
86 *       destructor
87 *
88 *   @return
89 *       N/A
90 ****************************************************************************************************
91 */
~ElemLib()92 ElemLib::~ElemLib()
93 {
94 }
95 
96 /**
97 ****************************************************************************************************
98 *   ElemLib::Create
99 *
100 *   @brief
101 *       Creates and initializes AddrLib object.
102 *
103 *   @return
104 *       Returns point to ADDR_CREATEINFO if successful.
105 ****************************************************************************************************
106 */
Create(const Lib * pAddrLib)107 ElemLib* ElemLib::Create(
108     const Lib* pAddrLib)   ///< [in] Pointer of parent AddrLib instance
109 {
110     ElemLib* pElemLib = NULL;
111 
112     if (pAddrLib)
113     {
114         VOID* pObj = Object::ClientAlloc(sizeof(ElemLib), pAddrLib->GetClient());
115         if (pObj)
116         {
117             pElemLib = new(pObj) ElemLib(const_cast<Lib* const>(pAddrLib));
118         }
119     }
120 
121     return pElemLib;
122 }
123 
124 /**************************************************************************************************
125 *   ElemLib::Flt32sToInt32s
126 *
127 *   @brief
128 *       Convert a ADDR_FLT_32 value to Int32 value
129 *
130 *   @return
131 *       N/A
132 ****************************************************************************************************
133 */
Flt32sToInt32s(ADDR_FLT_32 value,UINT_32 bits,NumberType numberType,UINT_32 * pResult)134 VOID ElemLib::Flt32sToInt32s(
135     ADDR_FLT_32     value,      ///< [in] ADDR_FLT_32 value
136     UINT_32         bits,       ///< [in] nubmer of bits in value
137     NumberType      numberType, ///< [in] the type of number
138     UINT_32*        pResult)    ///< [out] Int32 value
139 {
140     UINT_8 round = 128;    //ADDR_ROUND_BY_HALF
141     UINT_32 uscale;
142     UINT_32 sign;
143 
144     //convert each component to an INT_32
145     switch ( numberType )
146     {
147         case ADDR_NO_NUMBER:    //fall through
148         case ADDR_ZERO:         //fall through
149         case ADDR_ONE:          //fall through
150         case ADDR_EPSILON:      //fall through
151             return;        // these are zero-bit components, so don't set result
152 
153         case ADDR_UINT_BITS:            // unsigned integer bit field, clamped to range
154             uscale = (1<<bits) - 1;
155             if (bits == 32)               // special case unsigned 32-bit int
156             {
157                 *pResult = value.i;
158             }
159             else
160             {
161                 if ((value.i < 0) || (value.u > uscale))
162                 {
163                     *pResult = uscale;
164                 }
165                 else
166                 {
167                     *pResult = value.i;
168                 }
169                 return;
170             }
171 
172         // The algorithm used in the DB and TX differs at one value for 24-bit unorms
173         case ADDR_UNORM_R6XXDB:        // unsigned repeating fraction
174             if ((bits==24) && (value.i == 0x33000000))
175             {
176                 *pResult = 1;
177                 return;
178             }              // Else treat like ADDR_UNORM_R6XX
179 
180         case ADDR_UNORM_R6XX:            // unsigned repeating fraction
181             if (value.f <= 0)
182             {
183                 *pResult = 0;            // first clamp to [0..1]
184             }
185             else
186             {
187                 if (value.f >= 1)
188                 {
189                      *pResult = (1<<bits) - 1;
190                 }
191                 else
192                 {
193                     if ((value.i | 0x87FFFFFF) == 0xFFFFFFFF)
194                     {
195                         *pResult = 0;                        // NaN, so force to 0
196                     }
197 
198                     #if 0 // floating point version for documentation
199                     else
200                     {
201                         FLOAT f = value.f * ((1<<bits) - 1);
202                         *pResult = static_cast<INT_32>(f + (round/256.0f));
203                     }
204                     #endif
205                     else
206                     {
207                         ADDR_FLT_32 scaled;
208                         ADDR_FLT_32 shifted;
209                         UINT_64 truncated, rounded;
210                         UINT_32 altShift;
211                         UINT_32 mask = (1 << bits) - 1;
212                         UINT_32 half = 1 << (bits - 1);
213                         UINT_32 mant24 = (value.i & 0x7FFFFF) + 0x800000;
214                         UINT_64 temp = mant24 - (mant24>>bits) -
215                             static_cast<INT_32>((mant24 & mask) > half);
216                         UINT_32 exp8 = value.i >> 23;
217                         UINT_32 shift = 126 - exp8 + 24 - bits;
218                         UINT_64 final;
219 
220                         if (shift >= 32) // This is zero, even with maximum dither add
221                         {
222                             final = 0;
223                         }
224                         else
225                         {
226                             final = ((temp<<8) + (static_cast<UINT_64>(round)<<shift)) >> (shift+8);
227                         }
228                         //ADDR_EXIT( *pResult == final,
229                         //    ("Float %x converted to %d-bit Unorm %x != bitwise %x",
230                         //     value.u, bits, (UINT_32)*pResult, (UINT_32)final) );
231                         if (final > mask)
232                         {
233                             final = mask;
234                         }
235 
236                         scaled.f  = value.f * ((1<<bits) - 1);
237                         shifted.f = (scaled.f * 256);
238                         truncated = ((shifted.i&0x7FFFFF) + (INT_64)0x800000) << 8;
239                         altShift  = 126 + 24 + 8 - ((shifted.i>>23)&0xFF);
240                         truncated = (altShift > 60) ? 0 : truncated >> altShift;
241                         rounded   = static_cast<INT_32>((round + truncated) >> 8);
242                         //if (rounded > ((1<<bits) - 1))
243                         //    rounded = ((1<<bits) - 1);
244                         *pResult = static_cast<INT_32>(rounded); //(INT_32)final;
245                     }
246                 }
247             }
248 
249             return;
250 
251         case ADDR_S8FLOAT32:    // 32-bit IEEE float, passes through NaN values
252             *pResult = value.i;
253             return;
254 
255         // @@ FIX ROUNDING in this code, fix the denorm case
256         case ADDR_U4FLOATC:         // Unsigned float, 4-bit exponent. bias 15, clamped [0..1]
257             sign = (value.i >> 31) & 1;
258             if ((value.i&0x7F800000) == 0x7F800000)    // If NaN or INF:
259             {
260                 if ((value.i&0x007FFFFF) != 0)             // then if NaN
261                 {
262                     *pResult = 0;                       // return 0
263                 }
264                 else
265                 {
266                     *pResult = (sign)?0:0xF00000;           // else +INF->+1, -INF->0
267                 }
268                 return;
269             }
270             if (value.f <= 0)
271             {
272                 *pResult = 0;
273             }
274             else
275             {
276                 if (value.f>=1)
277                 {
278                     *pResult = 0xF << (bits-4);
279                 }
280                 else
281                 {
282                     if ((value.i>>23) > 112 )
283                     {
284                         // 24-bit float: normalized
285                         // value.i += 1 << (22-bits+4);
286                         // round the IEEE mantissa to mantissa size
287                         // @@ NOTE: add code to support rounding
288                         value.u &= 0x7FFFFFF;             // mask off high 4 exponent bits
289                         *pResult = value.i >> (23-bits+4);// shift off unused mantissa bits
290                     }
291                     else
292                     {
293                         // 24-bit float: denormalized
294                         value.f = value.f / (1<<28) / (1<<28);
295                         value.f = value.f / (1<<28) / (1<<28);    // convert to IEEE denorm
296                         // value.i += 1 << (22-bits+4);
297                         // round the IEEE mantissa to mantissa size
298                         // @@ NOTE: add code to support rounding
299                         *pResult = value.i >> (23-bits+4);    // shift off unused mantissa bits
300                     }
301                 }
302             }
303 
304             return;
305 
306         default:                    // invalid number mode
307             //ADDR_EXIT(0, ("Invalid AddrNumber %d", numberType) );
308             break;
309 
310     }
311 }
312 
313 /**
314 ****************************************************************************************************
315 *   ElemLib::Int32sToPixel
316 *
317 *   @brief
318 *       Pack 32-bit integer values into an uncompressed pixel,
319 *       in the proper order
320 *
321 *   @return
322 *       N/A
323 *
324 *   @note
325 *       This entry point packes four 32-bit integer values into
326 *       an uncompressed pixel. The pixel values are specifies in
327 *       standard order, e.g. depth/stencil. This routine asserts
328 *       if called on compressed pixel.
329 ****************************************************************************************************
330 */
Int32sToPixel(UINT_32 numComps,UINT_32 * pComps,UINT_32 * pCompBits,UINT_32 * pCompStart,ComponentFlags properties,UINT_32 resultBits,UINT_8 * pPixel)331 VOID ElemLib::Int32sToPixel(
332     UINT_32              numComps,      ///< [in] number of components
333     UINT_32*             pComps,        ///< [in] compnents
334     UINT_32*             pCompBits,     ///< [in] total bits in each component
335     UINT_32*             pCompStart,    ///< [in] the first bit position of each component
336     ComponentFlags       properties,    ///< [in] properties about byteAligned, exportNorm
337     UINT_32              resultBits,    ///< [in] result bits: total bpp after decompression
338     UINT_8*              pPixel)        ///< [out] a depth/stencil pixel value
339 {
340     UINT_32 i;
341     UINT_32 j;
342     UINT_32 start;
343     UINT_32 size;
344     UINT_32 byte;
345     UINT_32 value = 0;
346     UINT_32 compMask;
347     UINT_32 elemMask=0;
348     UINT_32 elementXor = 0;  // address xor when reading bytes from elements
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     (void)bBCnFormat;
1276 
1277     ADDR_ASSERT(pBpp != NULL);
1278     ADDR_ASSERT(pWidth != NULL && pHeight != NULL);
1279 
1280     if (pBpp)
1281     {
1282         bpp = *pBpp;
1283 
1284         switch (elemMode)
1285         {
1286         case ADDR_EXPANDED:
1287             originalBits = bpp * expandX * expandY;
1288             break;
1289         case ADDR_PACKED_STD: // Different bit order
1290         case ADDR_PACKED_REV:
1291             originalBits = bpp / expandX / expandY;
1292             break;
1293         case ADDR_PACKED_GBGR:
1294         case ADDR_PACKED_BGRG:
1295             originalBits = bpp; // 32-bit packed ==> 2 32-bit result
1296             break;
1297         case ADDR_PACKED_BC1: // Fall through
1298         case ADDR_PACKED_BC4:
1299             originalBits = 64;
1300             bBCnFormat = TRUE;
1301             break;
1302         case ADDR_PACKED_BC2: // Fall through
1303         case ADDR_PACKED_BC3: // Fall through
1304         case ADDR_PACKED_BC5:
1305             bBCnFormat = TRUE;
1306             // fall through
1307         case ADDR_PACKED_ASTC:
1308         case ADDR_PACKED_ETC2_128BPP:
1309             originalBits = 128;
1310             break;
1311         case ADDR_PACKED_ETC2_64BPP:
1312             originalBits = 64;
1313             break;
1314         case ADDR_ROUND_BY_HALF:  // Fall through
1315         case ADDR_ROUND_TRUNCATE: // Fall through
1316         case ADDR_ROUND_DITHER:   // Fall through
1317         case ADDR_UNCOMPRESSED:
1318             originalBits = bpp;
1319             break;
1320         default:
1321             originalBits = bpp;
1322             ADDR_ASSERT_ALWAYS();
1323             break;
1324         }
1325 
1326         *pBpp = originalBits;
1327     }
1328 
1329     if (pWidth && pHeight)
1330     {
1331         width    = *pWidth;
1332         height   = *pHeight;
1333 
1334         if ((expandX > 1) || (expandY > 1))
1335         {
1336             if (elemMode == ADDR_EXPANDED)
1337             {
1338                 width /= expandX;
1339                 height /= expandY;
1340             }
1341             else
1342             {
1343                 width *= expandX;
1344                 height *= expandY;
1345             }
1346         }
1347 
1348         *pWidth  = (width == 0) ? 1 : width;
1349         *pHeight = (height == 0) ? 1 : height;
1350     }
1351 }
1352 
1353 /**
1354 ****************************************************************************************************
1355 *   ElemLib::GetBitsPerPixel
1356 *
1357 *   @brief
1358 *       Compute the total bits per element according to a format
1359 *       code. For compressed formats, this is not the same as
1360 *       the number of bits per decompressed element.
1361 *
1362 *   @return
1363 *       Bits per pixel
1364 ****************************************************************************************************
1365 */
GetBitsPerPixel(AddrFormat format,ElemMode * pElemMode,UINT_32 * pExpandX,UINT_32 * pExpandY,UINT_32 * pUnusedBits)1366 UINT_32 ElemLib::GetBitsPerPixel(
1367     AddrFormat          format,         ///< [in] surface format code
1368     ElemMode*           pElemMode,      ///< [out] element mode
1369     UINT_32*            pExpandX,       ///< [out] decompression expansion factor in X
1370     UINT_32*            pExpandY,       ///< [out] decompression expansion factor in Y
1371     UINT_32*            pUnusedBits)    ///< [out] bits unused
1372 {
1373     UINT_32 bpp;
1374     UINT_32 expandX = 1;
1375     UINT_32 expandY = 1;
1376     UINT_32 bitUnused = 0;
1377     ElemMode elemMode = ADDR_UNCOMPRESSED; // default value
1378 
1379     switch (format)
1380     {
1381         case ADDR_FMT_8:
1382             bpp = 8;
1383             break;
1384         case ADDR_FMT_1_5_5_5:
1385         case ADDR_FMT_5_6_5:
1386         case ADDR_FMT_6_5_5:
1387         case ADDR_FMT_8_8:
1388         case ADDR_FMT_4_4_4_4:
1389         case ADDR_FMT_16:
1390             bpp = 16;
1391             break;
1392         case ADDR_FMT_GB_GR:
1393             elemMode = ADDR_PACKED_GBGR;
1394             bpp      = m_configFlags.use32bppFor422Fmt ? 32 : 16;
1395             expandX  = m_configFlags.use32bppFor422Fmt ? 2 : 1;
1396             break;
1397         case ADDR_FMT_BG_RG:
1398             elemMode = ADDR_PACKED_BGRG;
1399             bpp      = m_configFlags.use32bppFor422Fmt ? 32 : 16;
1400             expandX  = m_configFlags.use32bppFor422Fmt ? 2 : 1;
1401             break;
1402         case ADDR_FMT_8_8_8_8:
1403         case ADDR_FMT_2_10_10_10:
1404         case ADDR_FMT_10_11_11:
1405         case ADDR_FMT_11_11_10:
1406         case ADDR_FMT_16_16:
1407         case ADDR_FMT_32:
1408         case ADDR_FMT_24_8:
1409             bpp = 32;
1410             break;
1411         case ADDR_FMT_16_16_16_16:
1412         case ADDR_FMT_32_32:
1413         case ADDR_FMT_CTX1:
1414             bpp = 64;
1415             break;
1416         case ADDR_FMT_32_32_32_32:
1417             bpp = 128;
1418             break;
1419         case ADDR_FMT_INVALID:
1420             bpp = 0;
1421             break;
1422         case ADDR_FMT_1_REVERSED:
1423             elemMode = ADDR_PACKED_REV;
1424             expandX = 8;
1425             bpp = 1;
1426             break;
1427         case ADDR_FMT_1:
1428             elemMode = ADDR_PACKED_STD;
1429             expandX = 8;
1430             bpp = 1;
1431             break;
1432         case ADDR_FMT_4_4:
1433         case ADDR_FMT_3_3_2:
1434             bpp = 8;
1435             break;
1436         case ADDR_FMT_5_5_5_1:
1437             bpp = 16;
1438             break;
1439         case ADDR_FMT_32_AS_8:
1440         case ADDR_FMT_32_AS_8_8:
1441         case ADDR_FMT_8_24:
1442         case ADDR_FMT_10_10_10_2:
1443         case ADDR_FMT_5_9_9_9_SHAREDEXP:
1444             bpp = 32;
1445             break;
1446         case ADDR_FMT_X24_8_32_FLOAT:
1447             bpp = 64;
1448             bitUnused = 24;
1449             break;
1450         case ADDR_FMT_8_8_8:
1451             elemMode = ADDR_EXPANDED;
1452             bpp = 24;//@@ 8;      // read 3 elements per pixel
1453             expandX = 3;
1454             break;
1455         case ADDR_FMT_16_16_16:
1456             elemMode = ADDR_EXPANDED;
1457             bpp = 48;//@@ 16;      // read 3 elements per pixel
1458             expandX = 3;
1459             break;
1460         case ADDR_FMT_32_32_32:
1461             elemMode = ADDR_EXPANDED;
1462             expandX = 3;
1463             bpp = 96;//@@ 32;      // read 3 elements per pixel
1464             break;
1465         case ADDR_FMT_BC1:
1466             elemMode = ADDR_PACKED_BC1;
1467             expandX = 4;
1468             expandY = 4;
1469             bpp = 64;
1470             break;
1471         case ADDR_FMT_BC4:
1472             elemMode = ADDR_PACKED_BC4;
1473             expandX = 4;
1474             expandY = 4;
1475             bpp = 64;
1476             break;
1477         case ADDR_FMT_BC2:
1478             elemMode = ADDR_PACKED_BC2;
1479             expandX = 4;
1480             expandY = 4;
1481             bpp = 128;
1482             break;
1483         case ADDR_FMT_BC3:
1484             elemMode = ADDR_PACKED_BC3;
1485             expandX = 4;
1486             expandY = 4;
1487             bpp = 128;
1488             break;
1489         case ADDR_FMT_BC5:
1490         case ADDR_FMT_BC6: // reuse ADDR_PACKED_BC5
1491         case ADDR_FMT_BC7: // reuse ADDR_PACKED_BC5
1492             elemMode = ADDR_PACKED_BC5;
1493             expandX = 4;
1494             expandY = 4;
1495             bpp = 128;
1496             break;
1497 
1498         case ADDR_FMT_ETC2_64BPP:
1499             elemMode = ADDR_PACKED_ETC2_64BPP;
1500             expandX  = 4;
1501             expandY  = 4;
1502             bpp      = 64;
1503             break;
1504 
1505         case ADDR_FMT_ETC2_128BPP:
1506             elemMode = ADDR_PACKED_ETC2_128BPP;
1507             expandX  = 4;
1508             expandY  = 4;
1509             bpp      = 128;
1510             break;
1511 
1512         case ADDR_FMT_ASTC_4x4:
1513             elemMode = ADDR_PACKED_ASTC;
1514             expandX  = 4;
1515             expandY  = 4;
1516             bpp      = 128;
1517             break;
1518 
1519         case ADDR_FMT_ASTC_5x4:
1520             elemMode = ADDR_PACKED_ASTC;
1521             expandX  = 5;
1522             expandY  = 4;
1523             bpp      = 128;
1524             break;
1525 
1526         case ADDR_FMT_ASTC_5x5:
1527             elemMode = ADDR_PACKED_ASTC;
1528             expandX  = 5;
1529             expandY  = 5;
1530             bpp      = 128;
1531             break;
1532 
1533         case ADDR_FMT_ASTC_6x5:
1534             elemMode = ADDR_PACKED_ASTC;
1535             expandX  = 6;
1536             expandY  = 5;
1537             bpp      = 128;
1538             break;
1539 
1540         case ADDR_FMT_ASTC_6x6:
1541             elemMode = ADDR_PACKED_ASTC;
1542             expandX  = 6;
1543             expandY  = 6;
1544             bpp      = 128;
1545             break;
1546 
1547         case ADDR_FMT_ASTC_8x5:
1548             elemMode = ADDR_PACKED_ASTC;
1549             expandX  = 8;
1550             expandY  = 5;
1551             bpp      = 128;
1552             break;
1553 
1554         case ADDR_FMT_ASTC_8x6:
1555             elemMode = ADDR_PACKED_ASTC;
1556             expandX  = 8;
1557             expandY  = 6;
1558             bpp      = 128;
1559             break;
1560 
1561         case ADDR_FMT_ASTC_8x8:
1562             elemMode = ADDR_PACKED_ASTC;
1563             expandX  = 8;
1564             expandY  = 8;
1565             bpp      = 128;
1566             break;
1567 
1568         case ADDR_FMT_ASTC_10x5:
1569             elemMode = ADDR_PACKED_ASTC;
1570             expandX  = 10;
1571             expandY  = 5;
1572             bpp      = 128;
1573             break;
1574 
1575         case ADDR_FMT_ASTC_10x6:
1576             elemMode = ADDR_PACKED_ASTC;
1577             expandX  = 10;
1578             expandY  = 6;
1579             bpp      = 128;
1580             break;
1581 
1582         case ADDR_FMT_ASTC_10x8:
1583             elemMode = ADDR_PACKED_ASTC;
1584             expandX  = 10;
1585             expandY  = 8;
1586             bpp      = 128;
1587             break;
1588 
1589         case ADDR_FMT_ASTC_10x10:
1590             elemMode = ADDR_PACKED_ASTC;
1591             expandX  = 10;
1592             expandY  = 10;
1593             bpp      = 128;
1594             break;
1595 
1596         case ADDR_FMT_ASTC_12x10:
1597             elemMode = ADDR_PACKED_ASTC;
1598             expandX  = 12;
1599             expandY  = 10;
1600             bpp      = 128;
1601             break;
1602 
1603         case ADDR_FMT_ASTC_12x12:
1604             elemMode = ADDR_PACKED_ASTC;
1605             expandX  = 12;
1606             expandY  = 12;
1607             bpp      = 128;
1608             break;
1609 
1610         default:
1611             bpp = 0;
1612             ADDR_ASSERT_ALWAYS();
1613             break;
1614             // @@ or should this be an error?
1615     }
1616 
1617     SafeAssign(pExpandX, expandX);
1618     SafeAssign(pExpandY, expandY);
1619     SafeAssign(pUnusedBits, bitUnused);
1620     SafeAssign(reinterpret_cast<UINT_32*>(pElemMode), elemMode);
1621 
1622     return bpp;
1623 }
1624 
1625 /**
1626 ****************************************************************************************************
1627 *   ElemLib::GetCompBits
1628 *
1629 *   @brief
1630 *       Set each component's bit size and bit start. And set element mode and number type
1631 *
1632 *   @return
1633 *       N/A
1634 ****************************************************************************************************
1635 */
GetCompBits(UINT_32 c0,UINT_32 c1,UINT_32 c2,UINT_32 c3,PixelFormatInfo * pInfo,ElemMode elemMode)1636 VOID ElemLib::GetCompBits(
1637     UINT_32          c0,        ///< [in] bits of component 0
1638     UINT_32          c1,        ///< [in] bits of component 1
1639     UINT_32          c2,        ///< [in] bits of component 2
1640     UINT_32          c3,        ///< [in] bits of component 3
1641     PixelFormatInfo* pInfo,     ///< [out] per component info out
1642     ElemMode         elemMode)  ///< [in] element mode
1643 {
1644     pInfo->comps = 0;
1645 
1646     pInfo->compBit[0] = c0;
1647     pInfo->compBit[1] = c1;
1648     pInfo->compBit[2] = c2;
1649     pInfo->compBit[3] = c3;
1650 
1651     pInfo->compStart[0] = 0;
1652     pInfo->compStart[1] = c0;
1653     pInfo->compStart[2] = c0+c1;
1654     pInfo->compStart[3] = c0+c1+c2;
1655 
1656     pInfo->elemMode = elemMode;
1657     // still needed since component swap may depend on number of components
1658     for (INT i=0; i<4; i++)
1659     {
1660         if (pInfo->compBit[i] == 0)
1661         {
1662             pInfo->compStart[i]  = 0;       // all null components start at bit 0
1663             pInfo->numType[i] = ADDR_NO_NUMBER; // and have no number type
1664         }
1665         else
1666         {
1667             pInfo->comps++;
1668         }
1669     }
1670 }
1671 
1672 /**
1673 ****************************************************************************************************
1674 *   ElemLib::GetCompBits
1675 *
1676 *   @brief
1677 *       Set the clear color (or clear depth/stencil) for a surface
1678 *
1679 *   @note
1680 *       If clearColor is zero, a default clear value is used in place of comps[4].
1681 *       If float32 is set, full precision is used, else the mantissa is reduced to 12-bits
1682 *
1683 *   @return
1684 *       N/A
1685 ****************************************************************************************************
1686 */
SetClearComps(ADDR_FLT_32 comps[4],BOOL_32 clearColor,BOOL_32 float32)1687 VOID ElemLib::SetClearComps(
1688     ADDR_FLT_32 comps[4],   ///< [in,out] components
1689     BOOL_32 clearColor,     ///< [in] TRUE if clear color is set (CLEAR_COLOR)
1690     BOOL_32 float32)        ///< [in] TRUE if float32 component (BLEND_FLOAT32)
1691 {
1692     INT_32 i;
1693 
1694     // Use default clearvalues if clearColor is disabled
1695     if (clearColor == FALSE)
1696     {
1697         for (i=0; i<3; i++)
1698         {
1699             comps[i].f = 0.0;
1700         }
1701         comps[3].f = 1.0;
1702     }
1703 
1704     // Otherwise use the (modified) clear value
1705     else
1706     {
1707         for (i=0; i<4; i++)
1708         {   // If full precision, use clear value unchanged
1709             if (float32)
1710             {
1711                 // Do nothing
1712                 //comps[i] = comps[i];
1713             }
1714             // Else if it is a NaN, use the standard NaN value
1715             else if ((comps[i].u & 0x7FFFFFFF) > 0x7F800000)
1716             {
1717                 comps[i].u = 0xFFC00000;
1718             }
1719             // Else reduce the mantissa precision
1720             else
1721             {
1722                 comps[i].u = comps[i].u & 0xFFFFF000;
1723             }
1724         }
1725     }
1726 }
1727 
1728 /**
1729 ****************************************************************************************************
1730 *   ElemLib::IsBlockCompressed
1731 *
1732 *   @brief
1733 *       TRUE if this is block compressed format
1734 *
1735 *   @note
1736 *
1737 *   @return
1738 *       BOOL_32
1739 ****************************************************************************************************
1740 */
IsBlockCompressed(AddrFormat format)1741 BOOL_32 ElemLib::IsBlockCompressed(
1742     AddrFormat format)  ///< [in] Format
1743 {
1744     return (((format >= ADDR_FMT_BC1) && (format <= ADDR_FMT_BC7)) ||
1745             ((format >= ADDR_FMT_ASTC_4x4) && (format <= ADDR_FMT_ETC2_128BPP)));
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