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