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