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