2 * Copyright © 2014 Advanced Micro Devices, Inc.
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:
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.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
28 ****************************************************************************************************
29 * @file addrelemlib.cpp
30 * @brief Contains the class implementation for element/pixel related functions
31 ****************************************************************************************************
34 #include "addrelemlib.h"
39 ****************************************************************************************************
40 * AddrElemLib::AddrElemLib
47 ****************************************************************************************************
49 AddrElemLib::AddrElemLib(
50 AddrLib
* const pAddrLib
) : ///< [in] Parent addrlib instance pointer
51 AddrObject(pAddrLib
->GetClient()),
54 switch (m_pAddrLib
->GetAddrChipFamily())
56 case ADDR_CHIP_FAMILY_R6XX
:
57 m_depthPlanarType
= ADDR_DEPTH_PLANAR_R600
;
60 case ADDR_CHIP_FAMILY_R7XX
:
61 m_depthPlanarType
= ADDR_DEPTH_PLANAR_R600
;
64 case ADDR_CHIP_FAMILY_R8XX
:
65 case ADDR_CHIP_FAMILY_NI
: // Same as 8xx
66 m_depthPlanarType
= ADDR_DEPTH_PLANAR_R800
;
71 m_depthPlanarType
= ADDR_DEPTH_PLANAR_R800
;
74 m_configFlags
.value
= 0;
78 ****************************************************************************************************
79 * AddrElemLib::~AddrElemLib
86 ****************************************************************************************************
88 AddrElemLib::~AddrElemLib()
93 ****************************************************************************************************
97 * Creates and initializes AddrLib object.
100 * Returns point to ADDR_CREATEINFO if successful.
101 ****************************************************************************************************
103 AddrElemLib
* AddrElemLib::Create(
104 const AddrLib
* const pAddrLib
) ///< [in] Pointer of parent AddrLib instance
106 AddrElemLib
* pElemLib
= NULL
;
110 pElemLib
= new(pAddrLib
->GetClient()) AddrElemLib(const_cast<AddrLib
* const>(pAddrLib
));
116 /**************************************************************************************************
117 * AddrElemLib::Flt32sToInt32s
120 * Convert a ADDR_FLT_32 value to Int32 value
124 ****************************************************************************************************
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
132 UINT_8 round
= 128; //ADDR_ROUND_BY_HALF
136 //convert each component to an INT_32
137 switch ( numberType
)
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
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
153 if ((value
.i
< 0) || (value
.u
> uscale
))
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))
170 } // Else treat like ADDR_UNORM_R6XX
172 case ADDR_UNORM_R6XX
: // unsigned repeating fraction
175 *pResult
= 0; // first clamp to [0..1]
181 *pResult
= (1<<bits
) - 1;
185 if ((value
.i
| 0x87FFFFFF) == 0xFFFFFFFF)
187 *pResult
= 0; // NaN, so force to 0
190 #if 0 // floating point version for documentation
193 FLOAT f
= value
.f
* ((1<<bits
) - 1);
194 *pResult
= static_cast<INT_32
>(f
+ (round
/256.0f
));
201 UINT_64 truncated
, rounded
;
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
;
212 if (shift
>= 32) // This is zero, even with maximum dither add
218 final
= ((temp
<<8) + (static_cast<UINT_64
>(round
)<<shift
)) >> (shift
+8);
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) );
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;
243 case ADDR_S8FLOAT32
: // 32-bit IEEE float, passes through NaN values
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:
252 if ((value
.i
&0x007FFFFF) != 0) // then if NaN
254 *pResult
= 0; // return 0
258 *pResult
= (sign
)?0:0xF00000; // else +INF->+1, -INF->0
270 *pResult
= 0xF << (bits
-4);
274 if ((value
.i
>>23) > 112 )
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
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
298 default: // invalid number mode
299 //ADDR_EXIT(0, ("Invalid AddrNumber %d", numberType) );
306 ****************************************************************************************************
307 * AddrElemLib::Int32sToPixel
310 * Pack 32-bit integer values into an uncompressed pixel,
311 * in the proper order
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 ****************************************************************************************************
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
340 UINT_32 elementXor
= 0; // address xor when reading bytes from elements
343 // @@ NOTE: assert if called on a compressed format!
345 if (properties
.byteAligned
) // Components are all byte-sized
347 for (i
= 0; i
< numComps
; i
++) // Then for each component
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
++)
354 pPixel
[(j
+start
)^elementXor
] = static_cast<UINT_8
>(pComps
[i
] >> (8*j
));
358 else // Element is 32-bits or less, components are bit fields
360 // First, extract each component in turn and combine it into a 32-bit value
361 for (i
= 0; i
< numComps
; i
++)
363 compMask
= (1 << pCompBits
[i
]) - 1;
364 elemMask
|= compMask
<< pCompStart
[i
];
365 value
|= (pComps
[i
] & compMask
) << pCompStart
[i
];
368 // Mext, copy the masked value into the element
369 size
= (resultBits
+ 7) / 8;
370 for (i
= 0; i
< size
; i
++)
372 byte
= pPixel
[i
^elementXor
] & ~(elemMask
>> (8*i
));
373 pPixel
[i
^elementXor
] = static_cast<UINT_8
>(byte
| ((elemMask
& value
) >> (8*i
)));
379 ****************************************************************************************************
383 * Convert a FLT_32 value to a depth/stencil pixel value
387 ****************************************************************************************************
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
397 ADDR_COMPONENT_FLAGS properties
; // byteAligned, exportNorm
398 UINT_32 resultBits
= 0; // result bits: total bits per pixel after decompression
400 ADDR_PIXEL_FORMATINFO fmt
;
402 // get type for each component
403 PixGetDepthCompInfo(format
, &fmt
);
405 //initialize properties
406 properties
.byteAligned
= TRUE
;
407 properties
.exportNorm
= TRUE
;
408 properties
.floatComp
= FALSE
;
410 //set properties and result bits
411 for (i
= 0; i
< 2; i
++)
413 if ((fmt
.compBit
[i
] & 7) || (fmt
.compStart
[i
] & 7))
415 properties
.byteAligned
= FALSE
;
418 if (resultBits
< fmt
.compStart
[i
] + fmt
.compBit
[i
])
420 resultBits
= fmt
.compStart
[i
] + fmt
.compBit
[i
];
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
)
426 properties
.exportNorm
= FALSE
;
429 // Mark if there are any floating point components
430 if ((fmt
.numType
[i
] == ADDR_U4FLOATC
) || (fmt
.numType
[i
] >= ADDR_S8FLOAT
) )
432 properties
.floatComp
= TRUE
;
436 // Convert the two input floats to integer values
437 for (i
= 0; i
< 2; i
++)
439 Flt32sToInt32s(comps
[i
], fmt
.compBit
[i
], fmt
.numType
[i
], &values
[i
]);
442 // Then pack the two integer components, in the proper order
443 Int32sToPixel(2, values
, fmt
.compBit
, fmt
.compStart
, properties
, resultBits
, pPixel
);
448 ****************************************************************************************************
452 * Convert a FLT_32 value to a red/green/blue/alpha pixel value
456 ****************************************************************************************************
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
466 ADDR_PIXEL_FORMATINFO pixelInfo
;
470 ADDR_COMPONENT_FLAGS properties
; // byteAligned, exportNorm
471 UINT_32 resultBits
= 0; // result bits: total bits per pixel after decompression
473 memset(&pixelInfo
, 0, sizeof(ADDR_PIXEL_FORMATINFO
));
475 PixGetColorCompInfo(format
, surfNum
, surfSwap
, &pixelInfo
);
477 //initialize properties
478 properties
.byteAligned
= TRUE
;
479 properties
.exportNorm
= TRUE
;
480 properties
.floatComp
= FALSE
;
482 //set properties and result bits
483 for (i
= 0; i
< 4; i
++)
485 if ( (pixelInfo
.compBit
[i
] & 7) || (pixelInfo
.compStart
[i
] & 7) )
487 properties
.byteAligned
= FALSE
;
490 if (resultBits
< pixelInfo
.compStart
[i
] + pixelInfo
.compBit
[i
])
492 resultBits
= pixelInfo
.compStart
[i
] + pixelInfo
.compBit
[i
];
495 if (m_fp16ExportNorm
)
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
))
502 properties
.exportNorm
= FALSE
;
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
)
510 properties
.exportNorm
= FALSE
;
514 // Mark if there are any floating point components
515 if ( (pixelInfo
.numType
[i
] == ADDR_U4FLOATC
) ||
516 (pixelInfo
.numType
[i
] >= ADDR_S8FLOAT
) )
518 properties
.floatComp
= TRUE
;
522 // Convert the four input floats to integer values
523 for (i
= 0; i
< 4; i
++)
525 Flt32sToInt32s(comps
[i
], pixelInfo
.compBit
[i
], pixelInfo
.numType
[i
], &values
[i
]);
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
);
534 ****************************************************************************************************
535 * AddrElemLib::GetCompType
538 * Fill per component info
543 ****************************************************************************************************
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
550 BOOL_32 handled
= FALSE
;
552 // Floating point formats override the number format
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
;
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
++)
570 if (pInfo
->compBit
[c
] == 8)
572 pInfo
->numType
[c
] = ADDR_UINT_BITS
;
574 else if (pInfo
->compBit
[c
] == 24)
576 pInfo
->numType
[c
] = ADDR_UNORM_R6XX
;
580 pInfo
->numType
[c
] = ADDR_NO_NUMBER
;
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
++)
590 if (pInfo
->compBit
[c
] == 8)
592 pInfo
->numType
[c
] = ADDR_UINT_BITS
;
594 else if (pInfo
->compBit
[c
] == 24)
596 pInfo
->numType
[c
] = ADDR_U4FLOATC
;
598 else if (pInfo
->compBit
[c
] == 32)
600 pInfo
->numType
[c
] = ADDR_S8FLOAT32
;
604 pInfo
->numType
[c
] = ADDR_NO_NUMBER
;
615 for (UINT_32 c
= 0; c
< 4; c
++)
617 // Assign a number type for each component
618 AddrSurfaceNumber cnum
;
620 // First handle default component values
621 if (pInfo
->compBit
[c
] == 0)
625 pInfo
->numType
[c
] = ADDR_ZERO
; // Default is zero for RGB
627 else if (numType
== ADDR_NUMBER_UINT
|| numType
== ADDR_NUMBER_SINT
)
629 pInfo
->numType
[c
] = ADDR_EPSILON
; // Alpha INT_32 bits default is 0x01
633 pInfo
->numType
[c
] = ADDR_ONE
; // Alpha normal default is float 1.0
637 // Now handle small components
638 else if (pInfo
->compBit
[c
] == 1)
640 if (numType
== ADDR_NUMBER_UINT
|| numType
== ADDR_NUMBER_SINT
)
642 cnum
= ADDR_NUMBER_UINT
;
646 cnum
= ADDR_NUMBER_UNORM
;
654 // If no default, set the number type fom num, compbits, and architecture
657 case ADDR_NUMBER_SRGB
:
658 pInfo
->numType
[c
] = (c
< 3) ? ADDR_GAMMA8_R6XX
: ADDR_UNORM_R6XX
;
660 case ADDR_NUMBER_UNORM
:
661 pInfo
->numType
[c
] = ADDR_UNORM_R6XX
;
663 case ADDR_NUMBER_SNORM
:
664 pInfo
->numType
[c
] = ADDR_SNORM_R6XX
;
666 case ADDR_NUMBER_USCALED
:
667 pInfo
->numType
[c
] = ADDR_USCALED
; // @@ Do we need separate Pele routine?
669 case ADDR_NUMBER_SSCALED
:
670 pInfo
->numType
[c
] = ADDR_SSCALED
; // @@ Do we need separate Pele routine?
672 case ADDR_NUMBER_FLOAT
:
673 if (pInfo
->compBit
[c
] == 32)
675 pInfo
->numType
[c
] = ADDR_S8FLOAT32
;
677 else if (pInfo
->compBit
[c
] == 16)
679 pInfo
->numType
[c
] = ADDR_S5FLOAT
;
681 else if (pInfo
->compBit
[c
] >= 10)
683 pInfo
->numType
[c
] = ADDR_U5FLOAT
;
687 ADDR_ASSERT_ALWAYS();
690 case ADDR_NUMBER_SINT
:
691 pInfo
->numType
[c
] = ADDR_SINT_BITS
;
693 case ADDR_NUMBER_UINT
:
694 pInfo
->numType
[c
] = ADDR_UINT_BITS
;
698 ADDR_ASSERT(!"Invalid number type");
699 pInfo
->numType
[c
] = ADDR_NO_NUMBER
;
707 ****************************************************************************************************
708 * AddrElemLib::GetCompSwap
711 * Get components swapped for color surface
716 ****************************************************************************************************
718 VOID
AddrElemLib::GetCompSwap(
719 AddrSurfaceSwap swap
, ///< [in] swap mode
720 ADDR_PIXEL_FORMATINFO
* pInfo
) ///< [in/out] output per component info
722 switch (pInfo
->comps
)
728 SwapComps( 0, 2, pInfo
);
730 case ADDR_SWAP_STD_REV
:
731 SwapComps( 0, 3, pInfo
);
732 SwapComps( 1, 2, pInfo
);
734 case ADDR_SWAP_ALT_REV
:
735 SwapComps( 0, 3, pInfo
);
736 SwapComps( 0, 2, pInfo
);
737 SwapComps( 0, 1, pInfo
);
746 case ADDR_SWAP_ALT_REV
:
747 SwapComps( 0, 3, pInfo
);
748 SwapComps( 0, 2, pInfo
);
750 case ADDR_SWAP_STD_REV
:
751 SwapComps( 0, 2, pInfo
);
754 SwapComps( 2, 3, pInfo
);
763 case ADDR_SWAP_ALT_REV
:
764 SwapComps( 0, 1, pInfo
);
765 SwapComps( 1, 3, pInfo
);
767 case ADDR_SWAP_STD_REV
:
768 SwapComps( 0, 1, pInfo
);
771 SwapComps( 1, 3, pInfo
);
780 case ADDR_SWAP_ALT_REV
:
781 SwapComps( 0, 3, pInfo
);
783 case ADDR_SWAP_STD_REV
:
784 SwapComps( 0, 2, pInfo
);
787 SwapComps( 0, 1, pInfo
);
797 ****************************************************************************************************
798 * AddrElemLib::GetCompSwap
801 * Get components swapped for color surface
806 ****************************************************************************************************
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
816 start
= pInfo
->compStart
[c0
];
817 pInfo
->compStart
[c0
] = pInfo
->compStart
[c1
];
818 pInfo
->compStart
[c1
] = start
;
820 bits
= pInfo
->compBit
[c0
];
821 pInfo
->compBit
[c0
] = pInfo
->compBit
[c1
];
822 pInfo
->compBit
[c1
] = bits
;
826 ****************************************************************************************************
827 * AddrElemLib::PixGetColorCompInfo
830 * Get per component info for color surface
835 ****************************************************************************************************
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
844 // 1. Get componet bits
848 GetCompBits(8, 0, 0, 0, pInfo
);
850 case ADDR_COLOR_1_5_5_5
:
851 GetCompBits(5, 5, 5, 1, pInfo
);
853 case ADDR_COLOR_5_6_5
:
854 GetCompBits(8, 6, 5, 0, pInfo
);
856 case ADDR_COLOR_6_5_5
:
857 GetCompBits(5, 5, 6, 0, pInfo
);
860 GetCompBits(8, 8, 0, 0, pInfo
);
862 case ADDR_COLOR_4_4_4_4
:
863 GetCompBits(4, 4, 4, 4, pInfo
);
866 GetCompBits(16, 0, 0, 0, pInfo
);
868 case ADDR_COLOR_8_8_8_8
:
869 GetCompBits(8, 8, 8, 8, pInfo
);
871 case ADDR_COLOR_2_10_10_10
:
872 GetCompBits(10, 10, 10, 2, pInfo
);
874 case ADDR_COLOR_10_11_11
:
875 GetCompBits(11, 11, 10, 0, pInfo
);
877 case ADDR_COLOR_11_11_10
:
878 GetCompBits(10, 11, 11, 0, pInfo
);
880 case ADDR_COLOR_16_16
:
881 GetCompBits(16, 16, 0, 0, pInfo
);
883 case ADDR_COLOR_16_16_16_16
:
884 GetCompBits(16, 16, 16, 16, pInfo
);
886 case ADDR_COLOR_16_FLOAT
:
887 GetCompBits(16, 0, 0, 0, pInfo
);
889 case ADDR_COLOR_16_16_FLOAT
:
890 GetCompBits(16, 16, 0, 0, pInfo
);
892 case ADDR_COLOR_32_FLOAT
:
893 GetCompBits(32, 0, 0, 0, pInfo
);
895 case ADDR_COLOR_32_32_FLOAT
:
896 GetCompBits(32, 32, 0, 0, pInfo
);
898 case ADDR_COLOR_16_16_16_16_FLOAT
:
899 GetCompBits(16, 16, 16, 16, pInfo
);
901 case ADDR_COLOR_32_32_32_32_FLOAT
:
902 GetCompBits(32, 32, 32, 32, pInfo
);
906 GetCompBits(32, 0, 0, 0, pInfo
);
908 case ADDR_COLOR_32_32
:
909 GetCompBits(32, 32, 0, 0, pInfo
);
911 case ADDR_COLOR_32_32_32_32
:
912 GetCompBits(32, 32, 32, 32, pInfo
);
914 case ADDR_COLOR_10_10_10_2
:
915 GetCompBits(2, 10, 10, 10, pInfo
);
917 case ADDR_COLOR_10_11_11_FLOAT
:
918 GetCompBits(11, 11, 10, 0, pInfo
);
920 case ADDR_COLOR_11_11_10_FLOAT
:
921 GetCompBits(10, 11, 11, 0, pInfo
);
923 case ADDR_COLOR_5_5_5_1
:
924 GetCompBits(1, 5, 5, 5, pInfo
);
926 case ADDR_COLOR_3_3_2
:
927 GetCompBits(2, 3, 3, 0, pInfo
);
930 GetCompBits(4, 4, 0, 0, pInfo
);
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
);
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
);
940 case ADDR_COLOR_X24_8_32_FLOAT
:
941 GetCompBits(32, 8, 0, 0, pInfo
);
944 case ADDR_COLOR_INVALID
:
945 GetCompBits(0, 0, 0, 0, pInfo
);
949 GetCompBits(0, 0, 0, 0, pInfo
);
953 // 2. Get component number type
955 GetCompType(format
, number
, pInfo
);
957 // 3. Swap components if needed
959 GetCompSwap(swap
, pInfo
);
963 ****************************************************************************************************
964 * AddrElemLib::PixGetDepthCompInfo
967 * Get per component info for depth surface
972 ****************************************************************************************************
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
979 if (m_depthPlanarType
== ADDR_DEPTH_PLANAR_R800
)
981 if (format
== ADDR_DEPTH_8_24_FLOAT
)
983 format
= ADDR_DEPTH_X24_8_32_FLOAT
; // Use this format to represent R800's D24FS8
986 if (format
== ADDR_DEPTH_X8_24_FLOAT
)
988 format
= ADDR_DEPTH_32_FLOAT
;
995 GetCompBits(16, 0, 0, 0, pInfo
);
997 case ADDR_DEPTH_8_24
:
998 case ADDR_DEPTH_8_24_FLOAT
: // similar format, fall through
999 GetCompBits(24, 8, 0, 0, pInfo
);
1001 case ADDR_DEPTH_X8_24
:
1002 case ADDR_DEPTH_X8_24_FLOAT
: // similar format, fall through
1003 GetCompBits(24, 0, 0, 0, pInfo
);
1005 case ADDR_DEPTH_32_FLOAT
:
1006 GetCompBits(32, 0, 0, 0, pInfo
);
1008 case ADDR_DEPTH_X24_8_32_FLOAT
:
1009 GetCompBits(32, 8, 0, 0, pInfo
);
1011 case ADDR_DEPTH_INVALID
:
1012 GetCompBits(0, 0, 0, 0, pInfo
);
1016 GetCompBits(0, 0, 0, 0, pInfo
);
1023 pInfo
->numType
[0] = ADDR_UNORM_R6XX
;
1024 pInfo
->numType
[1] = ADDR_ZERO
;
1026 case ADDR_DEPTH_8_24
:
1027 pInfo
->numType
[0] = ADDR_UNORM_R6XXDB
;
1028 pInfo
->numType
[1] = ADDR_UINT_BITS
;
1030 case ADDR_DEPTH_8_24_FLOAT
:
1031 pInfo
->numType
[0] = ADDR_U4FLOATC
;
1032 pInfo
->numType
[1] = ADDR_UINT_BITS
;
1034 case ADDR_DEPTH_X8_24
:
1035 pInfo
->numType
[0] = ADDR_UNORM_R6XXDB
;
1036 pInfo
->numType
[1] = ADDR_ZERO
;
1038 case ADDR_DEPTH_X8_24_FLOAT
:
1039 pInfo
->numType
[0] = ADDR_U4FLOATC
;
1040 pInfo
->numType
[1] = ADDR_ZERO
;
1042 case ADDR_DEPTH_32_FLOAT
:
1043 pInfo
->numType
[0] = ADDR_S8FLOAT32
;
1044 pInfo
->numType
[1] = ADDR_ZERO
;
1046 case ADDR_DEPTH_X24_8_32_FLOAT
:
1047 pInfo
->numType
[0] = ADDR_S8FLOAT32
;
1048 pInfo
->numType
[1] = ADDR_UINT_BITS
;
1051 pInfo
->numType
[0] = ADDR_NO_NUMBER
;
1052 pInfo
->numType
[1] = ADDR_NO_NUMBER
;
1056 pInfo
->numType
[2] = ADDR_NO_NUMBER
;
1057 pInfo
->numType
[3] = ADDR_NO_NUMBER
;
1061 ****************************************************************************************************
1062 * AddrElemLib::PixGetExportNorm
1065 * Check if fp16 export norm can be enabled.
1068 * TRUE if this can be enabled.
1070 ****************************************************************************************************
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
1078 BOOL_32 enabled
= TRUE
;
1080 ADDR_PIXEL_FORMATINFO formatInfo
;
1082 PixGetColorCompInfo(colorFmt
, numberFmt
, swap
, &formatInfo
);
1084 for (UINT_32 c
= 0; c
< 4; c
++)
1086 if (m_fp16ExportNorm
)
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
))
1101 if ((formatInfo
.compBit
[c
] > 11) || (formatInfo
.numType
[c
] > ADDR_USCALED
))
1113 ****************************************************************************************************
1114 * AddrElemLib::AdjustSurfaceInfo
1117 * Adjust bpp/base pitch/width/height according to elemMode and expandX/Y
1121 ****************************************************************************************************
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
1137 BOOL_32 bBCnFormat
= FALSE
;
1139 ADDR_ASSERT(pBpp
!= NULL
);
1140 ADDR_ASSERT(pWidth
!= NULL
&& pHeight
!= NULL
&& pBasePitch
!= NULL
);
1149 packedBits
= bpp
/ expandX
/ expandY
;
1151 case ADDR_PACKED_STD
: // Different bit order
1152 case ADDR_PACKED_REV
:
1153 packedBits
= bpp
* expandX
* expandY
;
1155 case ADDR_PACKED_GBGR
:
1156 case ADDR_PACKED_BGRG
:
1157 packedBits
= bpp
; // 32-bit packed ==> 2 32-bit result
1159 case ADDR_PACKED_BC1
: // Fall through
1160 case ADDR_PACKED_BC4
:
1164 case ADDR_PACKED_BC2
: // Fall through
1165 case ADDR_PACKED_BC3
: // Fall through
1166 case ADDR_PACKED_BC5
: // Fall through
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
:
1178 ADDR_ASSERT_ALWAYS();
1185 if (pWidth
&& pHeight
&& pBasePitch
)
1187 basePitch
= *pBasePitch
;
1191 if ((expandX
> 1) || (expandY
> 1))
1193 if (elemMode
== ADDR_EXPANDED
)
1195 basePitch
*= expandX
;
1201 // Evergreen family workaround
1202 if (bBCnFormat
&& (m_pAddrLib
->GetAddrChipFamily() == ADDR_CHIP_FAMILY_R8XX
))
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
;
1210 width
= (width
== 0) ? 1 : width
;
1211 height
= (height
== 0) ? 1 : height
;
1213 if ((*pWidth
> PowTwoAlign(width
, 8) * expandX
) ||
1214 (*pHeight
> PowTwoAlign(height
, 8) * expandY
)) // 8 is 1D tiling alignment
1216 // if this assertion is hit we may have issues if app samples
1217 // rightmost/bottommost pixels
1218 ADDR_ASSERT_ALWAYS();
1222 else // Not BCn format we still keep old way (FMT_1? No real test yet)
1224 basePitch
= (basePitch
+ expandX
- 1) / expandX
;
1225 width
= (width
+ expandX
- 1) / expandX
;
1226 height
= (height
+ expandY
- 1) / expandY
;
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)
1238 ****************************************************************************************************
1239 * AddrElemLib::RestoreSurfaceInfo
1242 * Reverse operation of AdjustSurfaceInfo
1246 ****************************************************************************************************
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
1256 UINT_32 originalBits
;
1261 ADDR_ASSERT(pBpp
!= NULL
);
1262 ADDR_ASSERT(pWidth
!= NULL
&& pHeight
!= NULL
);
1271 originalBits
= bpp
* expandX
* expandY
;
1273 case ADDR_PACKED_STD
: // Different bit order
1274 case ADDR_PACKED_REV
:
1275 originalBits
= bpp
/ expandX
/ expandY
;
1277 case ADDR_PACKED_GBGR
:
1278 case ADDR_PACKED_BGRG
:
1279 originalBits
= bpp
; // 32-bit packed ==> 2 32-bit result
1281 case ADDR_PACKED_BC1
: // Fall through
1282 case ADDR_PACKED_BC4
:
1285 case ADDR_PACKED_BC2
: // Fall through
1286 case ADDR_PACKED_BC3
: // Fall through
1287 case ADDR_PACKED_BC5
:
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
:
1298 ADDR_ASSERT_ALWAYS();
1302 *pBpp
= originalBits
;
1305 if (pWidth
&& pHeight
)
1310 if ((expandX
> 1) || (expandY
> 1))
1312 if (elemMode
== ADDR_EXPANDED
)
1324 *pWidth
= (width
== 0) ? 1 : width
;
1325 *pHeight
= (height
== 0) ? 1 : height
;
1330 ****************************************************************************************************
1331 * AddrElemLib::GetBitsPerPixel
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.
1340 ****************************************************************************************************
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
1350 UINT_32 expandX
= 1;
1351 UINT_32 expandY
= 1;
1352 UINT_32 bitUnused
= 0;
1353 AddrElemMode elemMode
= ADDR_UNCOMPRESSED
; // default value
1360 case ADDR_FMT_1_5_5_5
:
1361 case ADDR_FMT_5_6_5
:
1362 case ADDR_FMT_6_5_5
:
1364 case ADDR_FMT_4_4_4_4
:
1366 case ADDR_FMT_16_FLOAT
:
1369 case ADDR_FMT_GB_GR
: // treat as FMT_8_8
1370 elemMode
= ADDR_PACKED_GBGR
;
1373 case ADDR_FMT_BG_RG
: // treat as FMT_8_8
1374 elemMode
= ADDR_PACKED_BGRG
;
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
:
1384 case ADDR_FMT_32_FLOAT
:
1386 case ADDR_FMT_24_8_FLOAT
:
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
:
1396 case ADDR_FMT_32_32_32_32
:
1397 case ADDR_FMT_32_32_32_32_FLOAT
:
1400 case ADDR_FMT_INVALID
:
1403 case ADDR_FMT_1_REVERSED
:
1404 elemMode
= ADDR_PACKED_REV
;
1409 elemMode
= ADDR_PACKED_STD
;
1414 case ADDR_FMT_3_3_2
:
1417 case ADDR_FMT_5_5_5_1
:
1420 case ADDR_FMT_32_AS_8
:
1421 case ADDR_FMT_32_AS_8_8
:
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
:
1430 case ADDR_FMT_X24_8_32_FLOAT
:
1434 case ADDR_FMT_8_8_8
:
1435 elemMode
= ADDR_EXPANDED
;
1436 bpp
= 24;//@@ 8; // read 3 elements per pixel
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
1445 case ADDR_FMT_32_32_32_FLOAT
:
1446 case ADDR_FMT_32_32_32
:
1447 elemMode
= ADDR_EXPANDED
;
1449 bpp
= 96;//@@ 32; // read 3 elements per pixel
1452 elemMode
= ADDR_PACKED_BC1
;
1458 elemMode
= ADDR_PACKED_BC4
;
1464 elemMode
= ADDR_PACKED_BC2
;
1470 elemMode
= ADDR_PACKED_BC3
;
1476 case ADDR_FMT_BC6
: // reuse ADDR_PACKED_BC5
1477 case ADDR_FMT_BC7
: // reuse ADDR_PACKED_BC5
1478 elemMode
= ADDR_PACKED_BC5
;
1485 ADDR_ASSERT_ALWAYS();
1487 // @@ or should this be an error?
1490 SafeAssign(pExpandX
, expandX
);
1491 SafeAssign(pExpandY
, expandY
);
1492 SafeAssign(pUnusedBits
, bitUnused
);
1493 SafeAssign(reinterpret_cast<UINT_32
*>(pElemMode
), elemMode
);
1499 ****************************************************************************************************
1500 * AddrElemLib::GetCompBits
1503 * Set each component's bit size and bit start. And set element mode and number type
1507 ****************************************************************************************************
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
1519 pInfo
->compBit
[0] = c0
;
1520 pInfo
->compBit
[1] = c1
;
1521 pInfo
->compBit
[2] = c2
;
1522 pInfo
->compBit
[3] = c3
;
1524 pInfo
->compStart
[0] = 0;
1525 pInfo
->compStart
[1] = c0
;
1526 pInfo
->compStart
[2] = c0
+c1
;
1527 pInfo
->compStart
[3] = c0
+c1
+c2
;
1529 pInfo
->elemMode
= elemMode
;
1530 // still needed since component swap may depend on number of components
1531 for (INT i
=0; i
<4; i
++)
1533 if (pInfo
->compBit
[i
] == 0)
1535 pInfo
->compStart
[i
] = 0; // all null components start at bit 0
1536 pInfo
->numType
[i
] = ADDR_NO_NUMBER
; // and have no number type
1546 ****************************************************************************************************
1547 * AddrElemLib::GetCompBits
1550 * Set the clear color (or clear depth/stencil) for a surface
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
1558 ****************************************************************************************************
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)
1567 // Use default clearvalues if clearColor is disabled
1568 if (clearColor
== FALSE
)
1577 // Otherwise use the (modified) clear value
1581 { // If full precision, use clear value unchanged
1585 //comps[i] = comps[i];
1587 // Else if it is a NaN, use the standard NaN value
1588 else if ((comps
[i
].u
& 0x7FFFFFFF) > 0x7F800000)
1590 comps
[i
].u
= 0xFFC00000;
1592 // Else reduce the mantissa precision
1595 comps
[i
].u
= comps
[i
].u
& 0xFFFFF000;
1602 ****************************************************************************************************
1603 * AddrElemLib::IsBlockCompressed
1606 * TRUE if this is block compressed format
1612 ****************************************************************************************************
1614 BOOL_32
AddrElemLib::IsBlockCompressed(
1615 AddrFormat format
) ///< [in] Format
1617 return format
>= ADDR_FMT_BC1
&& format
<= ADDR_FMT_BC7
;
1622 ****************************************************************************************************
1623 * AddrElemLib::IsCompressed
1626 * TRUE if this is block compressed format or 1 bit format
1632 ****************************************************************************************************
1634 BOOL_32
AddrElemLib::IsCompressed(
1635 AddrFormat format
) ///< [in] Format
1637 return IsBlockCompressed(format
) || format
== ADDR_FMT_BC1
|| format
== ADDR_FMT_BC7
;
1641 ****************************************************************************************************
1642 * AddrElemLib::IsExpand3x
1645 * TRUE if this is 3x expand format
1651 ****************************************************************************************************
1653 BOOL_32
AddrElemLib::IsExpand3x(
1654 AddrFormat format
) ///< [in] Format
1656 BOOL_32 is3x
= FALSE
;
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
: