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