xref: /aosp_15_r20/external/mesa3d/src/gallium/frontends/nine/nine_helpers.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2011 Joakim Sindholt <[email protected]>
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #ifndef _NINE_HELPERS_H_
7 #define _NINE_HELPERS_H_
8 
9 #include "iunknown.h"
10 #include "nine_lock.h"
11 
12 /*
13  * Note: we use these function rather than the MIN2, MAX2, CLAMP macros to
14  * avoid evaluating arguments (which are often function calls) more than once.
15  */
16 
_min(unsigned a,unsigned b)17 static inline unsigned _min(unsigned a, unsigned b)
18 {
19    return (a < b) ? a : b;
20 }
21 
22 
23 /* Sshhh ... */
24 #define nine_reference(a, b) _nine_reference((void **)(a), (b))
25 
_nine_reference(void ** ref,void * ptr)26 static inline void _nine_reference(void **ref, void *ptr)
27 {
28     if (*ref != ptr) {
29         if (*ref)
30             NineUnknown_Release(*ref);
31         if (ptr)
32             NineUnknown_AddRef(ptr);
33         *ref = ptr;
34     }
35 }
36 
37 #define nine_reference_set(a, b) _nine_reference_set((void **)(a), (b))
38 
_nine_reference_set(void ** ref,void * ptr)39 static inline void _nine_reference_set(void **ref, void *ptr)
40 {
41     *ref = ptr;
42     if (ptr)
43         NineUnknown_AddRef(ptr);
44 }
45 
46 #define nine_bind(a, b) _nine_bind((void **)(a), (b))
47 
_nine_bind(void ** dst,void * obj)48 static inline void _nine_bind(void **dst, void *obj)
49 {
50     if (*dst != obj) {
51         if (*dst)
52             NineUnknown_Unbind(*dst);
53         if (obj)
54             NineUnknown_Bind(obj);
55         *dst = obj;
56     }
57 }
58 
59 #define NINE_DEVICE_CHILD_NEW(nine, out, dev, ...) \
60     { \
61         struct NineUnknownParams __params; \
62         struct Nine##nine *__data; \
63          \
64         __data = CALLOC_STRUCT(Nine##nine); \
65         if (!__data) { return E_OUTOFMEMORY; } \
66          \
67         __params.vtable = ((dev)->params.BehaviorFlags & D3DCREATE_MULTITHREADED) ? &Lock##nine##_vtable : &Nine##nine##_vtable; \
68         __params.guids = Nine##nine##_IIDs; \
69         __params.dtor = (void *)Nine##nine##_dtor; \
70         __params.container = NULL; \
71         __params.device = dev; \
72         __params.start_with_bind_not_ref = false; \
73         { \
74             HRESULT __hr = Nine##nine##_ctor(__data, &__params, ## __VA_ARGS__); \
75             if (FAILED(__hr)) { \
76                 Nine##nine##_dtor(__data); \
77                 return __hr; \
78             } \
79         } \
80          \
81         *(out) = __data; \
82     } \
83     return D3D_OK
84 
85 #define NINE_DEVICE_CHILD_BIND_NEW(nine, out, dev, ...) \
86     { \
87         struct NineUnknownParams __params; \
88         struct Nine##nine *__data; \
89          \
90         __data = CALLOC_STRUCT(Nine##nine); \
91         if (!__data) { return E_OUTOFMEMORY; } \
92          \
93         __params.vtable = ((dev)->params.BehaviorFlags & D3DCREATE_MULTITHREADED) ? &Lock##nine##_vtable : &Nine##nine##_vtable; \
94         __params.guids = Nine##nine##_IIDs; \
95         __params.dtor = (void *)Nine##nine##_dtor; \
96         __params.container = NULL; \
97         __params.device = dev; \
98         __params.start_with_bind_not_ref = true; \
99         { \
100             HRESULT __hr = Nine##nine##_ctor(__data, &__params, ## __VA_ARGS__); \
101             if (FAILED(__hr)) { \
102                 Nine##nine##_dtor(__data); \
103                 return __hr; \
104             } \
105         } \
106          \
107         *(out) = __data; \
108     } \
109     return D3D_OK
110 
111 #define NINE_NEW(nine, out, lock, ...) \
112     { \
113         struct NineUnknownParams __params; \
114         struct Nine##nine *__data; \
115          \
116         __data = CALLOC_STRUCT(Nine##nine); \
117         if (!__data) { return E_OUTOFMEMORY; } \
118          \
119         __params.vtable = (lock) ? &Lock##nine##_vtable : &Nine##nine##_vtable; \
120         __params.guids = Nine##nine##_IIDs; \
121         __params.dtor = (void *)Nine##nine##_dtor; \
122         __params.container = NULL; \
123         __params.device = NULL; \
124         __params.start_with_bind_not_ref = false; \
125         { \
126             HRESULT __hr = Nine##nine##_ctor(__data, &__params, ## __VA_ARGS__); \
127             if (FAILED(__hr)) { \
128                 Nine##nine##_dtor(__data); \
129                 return __hr; \
130             } \
131         } \
132          \
133         *(out) = __data; \
134     } \
135     return D3D_OK
136 
asfloat(DWORD value)137 static inline float asfloat(DWORD value)
138 {
139     union {
140         float f;
141         DWORD w;
142     } u;
143     u.w = value;
144     return u.f;
145 }
146 
147 struct nine_range
148 {
149     struct nine_range *next;
150     int16_t bgn; /* inclusive */
151     int16_t end; /* exclusive */
152 };
153 
154 /* We won't ever need more than 256 ranges, so just allocate once. */
155 struct nine_range_pool
156 {
157     struct nine_range *free;
158     struct nine_range **slabs;
159     unsigned num_slabs;
160     unsigned num_slabs_max;
161 };
162 
163 static inline void
nine_range_pool_put(struct nine_range_pool * pool,struct nine_range * r)164 nine_range_pool_put(struct nine_range_pool *pool, struct nine_range *r)
165 {
166     r->next = pool->free;
167     pool->free = r;
168 }
169 
170 static inline void
nine_range_pool_put_chain(struct nine_range_pool * pool,struct nine_range * head,struct nine_range * tail)171 nine_range_pool_put_chain(struct nine_range_pool *pool,
172                           struct nine_range *head,
173                           struct nine_range *tail)
174 {
175     tail->next = pool->free;
176     pool->free = head;
177 }
178 
179 void
180 nine_ranges_insert(struct nine_range **head, int16_t bgn, int16_t end,
181                    struct nine_range_pool *pool);
182 
183 #endif /* _NINE_HELPERS_H_ */
184