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