• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #ifndef MESA_V3D_PACKET_HELPERS_H
25 #define MESA_V3D_PACKET_HELPERS_H
26 
27 #include <stdio.h>
28 #include <stdint.h>
29 #include <stdbool.h>
30 #include <assert.h>
31 #include <math.h>
32 #include "util/u_math.h"
33 
34 #ifdef HAVE_VALGRIND
35 #include <valgrind.h>
36 #include <memcheck.h>
37 #define VG(x) x
38 #ifndef NDEBUG
39 #define __gen_validate_value(x) VALGRIND_CHECK_MEM_IS_DEFINED(&(x), sizeof(x))
40 #endif
41 #else
42 #define VG(x) ((void)0)
43 #endif
44 
45 #ifndef __gen_validate_value
46 #define __gen_validate_value(x)
47 #endif
48 /*
49 #ifndef __gen_address_type
50 #error #define __gen_address_type before including this file
51 #endif
52 
53 #ifndef __gen_user_data
54 #error #define __gen_combine_address before including this file
55 #endif
56 */
57 union __gen_value {
58    float f;
59    uint32_t dw;
60 };
61 
62 static inline uint64_t
__gen_mbo(uint32_t start,uint32_t end)63 __gen_mbo(uint32_t start, uint32_t end)
64 {
65    return (~0ull >> (64 - (end - start + 1))) << start;
66 }
67 
68 static inline uint64_t
__gen_uint(uint64_t v,uint32_t start,uint32_t end)69 __gen_uint(uint64_t v, uint32_t start, uint32_t end)
70 {
71    __gen_validate_value(v);
72 
73 #ifndef NDEBUG
74    const int width = end - start + 1;
75    if (width < 64) {
76       const uint64_t max = (1ull << width) - 1;
77       assert(v <= max);
78    }
79 #endif
80 
81    return v << start;
82 }
83 
84 static inline uint64_t
__gen_sint(int64_t v,uint32_t start,uint32_t end)85 __gen_sint(int64_t v, uint32_t start, uint32_t end)
86 {
87    const int width = end - start + 1;
88 
89    __gen_validate_value(v);
90 
91 #ifndef NDEBUG
92    if (width < 64) {
93       const int64_t max = (1ll << (width - 1)) - 1;
94       const int64_t min = -(1ll << (width - 1));
95       assert(min <= v && v <= max);
96    }
97 #endif
98 
99    const uint64_t mask = ~0ull >> (64 - width);
100 
101    return (v & mask) << start;
102 }
103 
104 static inline uint64_t
__gen_offset(uint64_t v,uint32_t start,uint32_t end)105 __gen_offset(uint64_t v, uint32_t start, uint32_t end)
106 {
107    __gen_validate_value(v);
108 #ifndef NDEBUG
109    uint64_t mask = (~0ull >> (64 - (end - start + 1))) << start;
110 
111    assert((v & ~mask) == 0);
112 #endif
113 
114    return v;
115 }
116 
117 static inline uint32_t
__gen_float(float v)118 __gen_float(float v)
119 {
120    __gen_validate_value(v);
121    return ((union __gen_value) { .f = (v) }).dw;
122 }
123 
124 static inline uint64_t
__gen_sfixed(float v,uint32_t start,uint32_t end,uint32_t fract_bits)125 __gen_sfixed(float v, uint32_t start, uint32_t end, uint32_t fract_bits)
126 {
127    __gen_validate_value(v);
128 
129    const float factor = (1 << fract_bits);
130 
131 #ifndef NDEBUG
132    const float max = ((1 << (end - start)) - 1) / factor;
133    const float min = -(1 << (end - start)) / factor;
134    assert(min <= v && v <= max);
135 #endif
136 
137    const int64_t int_val = llroundf(v * factor);
138    const uint64_t mask = ~0ull >> (64 - (end - start + 1));
139 
140    return (int_val & mask) << start;
141 }
142 
143 static inline uint64_t
__gen_ufixed(float v,uint32_t start,uint32_t end,uint32_t fract_bits)144 __gen_ufixed(float v, uint32_t start, uint32_t end, uint32_t fract_bits)
145 {
146    __gen_validate_value(v);
147 
148    const float factor = (1 << fract_bits);
149 
150 #ifndef NDEBUG
151    const float max = ((1 << (end - start + 1)) - 1) / factor;
152    const float min = 0.0f;
153    assert(min <= v && v <= max);
154 #endif
155 
156    const uint64_t uint_val = llroundf(v * factor);
157 
158    return uint_val << start;
159 }
160 
161 static inline uint64_t
__gen_unpack_uint(const uint8_t * restrict cl,uint32_t start,uint32_t end)162 __gen_unpack_uint(const uint8_t *restrict cl, uint32_t start, uint32_t end)
163 {
164    uint64_t val = 0;
165    const int width = end - start + 1;
166    const uint32_t mask = (width == 32 ? ~0 : (1 << width) - 1 );
167 
168    for (int byte = start / 8; byte <= end / 8; byte++) {
169       val |= cl[byte] << ((byte - start / 8) * 8);
170    }
171 
172    return (val >> (start % 8)) & mask;
173 }
174 
175 static inline uint64_t
__gen_unpack_sint(const uint8_t * restrict cl,uint32_t start,uint32_t end)176 __gen_unpack_sint(const uint8_t *restrict cl, uint32_t start, uint32_t end)
177 {
178    int size = end - start + 1;
179    int64_t val = __gen_unpack_uint(cl, start, end);
180 
181    /* Get the sign bit extended. */
182    return (val << (64 - size)) >> (64 - size);
183 }
184 
185 static inline float
__gen_unpack_sfixed(const uint8_t * restrict cl,uint32_t start,uint32_t end,uint32_t fractional_size)186 __gen_unpack_sfixed(const uint8_t *restrict cl, uint32_t start, uint32_t end,
187                     uint32_t fractional_size)
188 {
189         int32_t bits = __gen_unpack_sint(cl, start, end);
190         return (float)bits / (1 << fractional_size);
191 }
192 
193 static inline float
__gen_unpack_ufixed(const uint8_t * restrict cl,uint32_t start,uint32_t end,uint32_t fractional_size)194 __gen_unpack_ufixed(const uint8_t *restrict cl, uint32_t start, uint32_t end,
195                     uint32_t fractional_size)
196 {
197         int32_t bits = __gen_unpack_uint(cl, start, end);
198         return (float)bits / (1 << fractional_size);
199 }
200 
201 static inline float
__gen_unpack_float(const uint8_t * restrict cl,uint32_t start,uint32_t end)202 __gen_unpack_float(const uint8_t *restrict cl, uint32_t start, uint32_t end)
203 {
204    assert(start % 8 == 0);
205    assert(end - start == 31);
206 
207    struct PACKED { float f; } *f = (void *)(cl + (start / 8));
208 
209    return f->f;
210 }
211 
212 static inline float
__gen_unpack_f187(const uint8_t * restrict cl,uint32_t start,uint32_t end)213 __gen_unpack_f187(const uint8_t *restrict cl, uint32_t start, uint32_t end)
214 {
215    assert(end - start == 15);
216    uint32_t bits = __gen_unpack_uint(cl, start, end);
217    return uif(bits << 16);
218 }
219 
220 #endif
221