xref: /aosp_15_r20/external/mesa3d/src/amd/vpelib/src/utils/conversion.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /* Copyright 2022 Advanced Micro Devices, Inc.
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a
4  * copy of this software and associated documentation files (the "Software"),
5  * to deal in the Software without restriction, including without limitation
6  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7  * and/or sell copies of the Software, and to permit persons to whom the
8  * Software is furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
16  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
17  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
19  * OTHER DEALINGS IN THE SOFTWARE.
20  *
21  * Authors: AMD
22  *
23  */
24 #include "conversion.h"
25 
26 #define DIVIDER 10000
27 
28 /* S2D13 value in [-3.99...3.9999] */
29 #define S2D13_MIN ((long long)(-3.999 * DIVIDER))
30 #define S2D13_MAX ((long long)(3.999 * DIVIDER))
31 
32 #define FRACTIONAL_PART_MASK ((1ULL << FIXED31_32_BITS_PER_FRACTIONAL_PART) - 1)
33 
34 #define GET_INTEGER_PART(x) ((x) >> FIXED31_32_BITS_PER_FRACTIONAL_PART)
35 
36 #define GET_FRACTIONAL_PART(x) (FRACTIONAL_PART_MASK & (x))
37 
conv_fixed_point_to_int_frac(struct fixed31_32 arg,uint8_t integer_bits,uint8_t fractional_bits)38 uint16_t conv_fixed_point_to_int_frac(
39     struct fixed31_32 arg, uint8_t integer_bits, uint8_t fractional_bits)
40 {
41     int32_t numerator;
42     int32_t divisor = 1 << fractional_bits;
43 
44     uint16_t result;
45 
46     uint16_t d = (uint16_t)vpe_fixpt_floor(vpe_fixpt_abs(arg));
47 
48     if (d <= (uint16_t)(1 << integer_bits) - (1 / (uint16_t)divisor))
49         numerator = (uint16_t)vpe_fixpt_round(vpe_fixpt_mul_int(arg, divisor));
50     else {
51         numerator = vpe_fixpt_floor(vpe_fixpt_sub(
52             vpe_fixpt_from_int(1LL << integer_bits), vpe_fixpt_recip(vpe_fixpt_from_int(divisor))));
53     }
54 
55     if (numerator >= 0)
56         result = (uint16_t)numerator;
57     else
58         result = (uint16_t)((1 << (integer_bits + fractional_bits + 1)) + numerator);
59 
60     if ((result != 0) && vpe_fixpt_lt(arg, vpe_fixpt_zero))
61         result |= 1 << (integer_bits + fractional_bits);
62 
63     return result;
64 }
65 
conv_convert_float_matrix(uint16_t * matrix,const struct fixed31_32 * flt,uint32_t buffer_size)66 void conv_convert_float_matrix(uint16_t *matrix, const struct fixed31_32 *flt, uint32_t buffer_size)
67 {
68     const struct fixed31_32 min_2_13 = vpe_fixpt_from_fraction(S2D13_MIN, DIVIDER);
69     const struct fixed31_32 max_2_13 = vpe_fixpt_from_fraction(S2D13_MAX, DIVIDER);
70     uint32_t                i;
71 
72     for (i = 0; i < buffer_size; ++i) {
73         uint32_t reg_value =
74             conv_fixed_point_to_int_frac(vpe_fixpt_clamp(flt[i], min_2_13, max_2_13), 2, 13);
75 
76         matrix[i] = (uint16_t)reg_value;
77     }
78 }
79 
vpe_convfix31_32(int16_t inval)80 struct fixed31_32 vpe_convfix31_32(int16_t inval)
81 {
82     const int         integerBits    = 2;
83     const int         fractionalBits = 13;
84     struct fixed31_32 result;
85     long long         outintegerPart;
86     long long         outfractionalPart;
87     int               sign = 1;
88     if (inval & (1 << (integerBits + fractionalBits + 1))) {
89         sign  = -1;
90         inval = -inval;
91     }
92     outintegerPart    = ((long long)inval >> fractionalBits) << 32;
93     outfractionalPart = ((long long)inval & (((long long)1 << fractionalBits) - 1));
94     ;
95     outfractionalPart <<= (32 - fractionalBits);
96     result.value = outintegerPart | outfractionalPart;
97     if (sign < 0)
98         result.value = -result.value;
99     return result;
100 }
101