• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2022 Google, Inc.
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 FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 
24 #ifndef FREEDRENO_COMMON_H_
25 #define FREEDRENO_COMMON_H_
26 
27 #include "util/u_atomic.h"
28 
29 #ifdef __cplusplus
30 template<typename E>
31 struct BitmaskEnum {
32    E value;
33 
34    using underlying = typename std::underlying_type_t<E>;
35 
36 #define FOREACH_TYPE(M, ...) \
37    M(E,          ##__VA_ARGS__) \
38    M(bool,       ##__VA_ARGS__) \
39    M(uint8_t,    ##__VA_ARGS__) \
40    M(int8_t,     ##__VA_ARGS__) \
41    M(uint16_t,   ##__VA_ARGS__) \
42    M(int16_t,    ##__VA_ARGS__) \
43    M(uint32_t,   ##__VA_ARGS__) \
44    M(int32_t,    ##__VA_ARGS__)
45 
46 #define CONSTRUCTOR(T) BitmaskEnum(T value) :  value(static_cast<E>(value)) {}
47    FOREACH_TYPE(CONSTRUCTOR)
48 #undef CONSTRUCTOR
49 
50 #define CAST(T) inline operator T() const { return static_cast<T>(value); }
51    FOREACH_TYPE(CAST)
52 #undef CAST
53 
54 #define BOP(T, OP)                          \
55    inline E operator OP(T rhs) const {      \
56       return static_cast<E> (               \
57          static_cast<underlying>(value) OP  \
58          static_cast<underlying>(rhs)       \
59       );                                    \
60    }
61    FOREACH_TYPE(BOP, |)
62    FOREACH_TYPE(BOP, &)
63 #undef BOP
64 
65 #define BOP(OP)                                                    \
66    inline BitmaskEnum<E> operator OP(BitmaskEnum<E> rhs) const {   \
67       return static_cast<E> (                                      \
68          static_cast<underlying>(value) OP                         \
69          static_cast<underlying>(rhs.value)                        \
70       );                                                           \
71    }
72    BOP(|)
73    BOP(&)
74 #undef BOP
75 
76 #if defined(__GNUC__) && !defined(__clang)
77 /*
78  * Silence:
79  *
80  *   ../src/freedreno/common/freedreno_common.h: In instantiation of 'E& BitmaskEnum<E>::operator|=(BitmaskEnum<E>::underlying) [with E = fd_dirty_3d_state; BitmaskEnum<E>::underlying = unsigned int]':
81  *   ../src/gallium/drivers/freedreno/freedreno_context.h:620:16:   required from here
82  *   ../src/freedreno/common/freedreno_common.h:68:39: error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
83  *      68 |         reinterpret_cast<underlying&>(value) OP static_cast<underlying>(rhs) ); \
84  *         |                                       ^~~~~
85  *
86  * I cannot reproduce on gcc 12.2.1 or with clang 14.0.5 so I'm going to assume
87  * this is a bug with gcc 10.x
88  */
89 #pragma GCC diagnostic push
90 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
91 #endif
92 
93 #define UOP(T, OP)                          \
94    inline E& operator OP(T rhs) {           \
95       return reinterpret_cast<E&>(          \
96         reinterpret_cast<underlying&>(value) OP static_cast<underlying>(rhs) ); \
97    }
98    UOP(underlying, |=)
99    UOP(underlying, &=)
100 #undef UOP
101 
102 #if defined(__GNUC__) && !defined(__clang) && (__GNUC__ < 7)
103 #pragma GCC diagnostic pop
104 #endif
105 
106    inline E operator ~() const {
107       static_assert(sizeof(E) == sizeof(BitmaskEnum<E>));
108       return static_cast<E> (
109             ~static_cast<underlying>(value)
110       );
111    }
112 #undef FOREACH_TYPE
113 };
114 #define BITMASK_ENUM(E) BitmaskEnum<E>
115 #else
116 #define BITMASK_ENUM(E) enum E
117 #endif
118 
119 #ifdef __cplusplus
120 #  define EXTERNC extern "C"
121 #  define BEGINC EXTERNC {
122 #  define ENDC }
123 #else
124 #  define EXTERNC
125 #  define BEGINC
126 #  define ENDC
127 #endif
128 
129 /*
130  * SWAP - swap value of @a and @b
131  */
132 #define SWAP(a, b)                                                             \
133    do {                                                                        \
134       __typeof(a) __tmp = (a);                                                 \
135       (a) = (b);                                                               \
136       (b) = __tmp;                                                             \
137    } while (0)
138 
139 /* for conditionally setting boolean flag(s): */
140 #define COND(bool, val) ((bool) ? (val) : 0)
141 
142 #define BIT(bit) BITFIELD64_BIT(bit)
143 
144 /**
145  * Helper for allocating sequence #s where zero is a non-valid seqno
146  */
147 typedef struct {
148    uint32_t counter;
149 } seqno_t;
150 
151 static inline uint32_t
seqno_next(seqno_t * seq)152 seqno_next(seqno_t *seq)
153 {
154    uint32_t n;
155    do {
156       n = p_atomic_inc_return(&seq->counter);
157    } while (n == 0);
158    return n;
159 }
160 
161 static inline uint16_t
seqno_next_u16(seqno_t * seq)162 seqno_next_u16(seqno_t *seq)
163 {
164    uint16_t n;
165    do {
166       n = p_atomic_inc_return(&seq->counter);
167    } while (n == 0);
168    return n;
169 }
170 
171 #endif /* FREEDRENO_COMMON_H_ */
172