• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef UTIL_BOX_INLINES_H
2 #define UTIL_BOX_INLINES_H
3 
4 #include "pipe/p_state.h"
5 #include "util/u_math.h"
6 #include "util/format/u_format.h"
7 
8 static inline void
u_box_1d(unsigned x,unsigned w,struct pipe_box * box)9 u_box_1d(unsigned x, unsigned w, struct pipe_box *box)
10 {
11    box->x = x;
12    box->y = 0;
13    box->z = 0;
14    box->width = w;
15    box->height = 1;
16    box->depth = 1;
17 }
18 
19 static inline void
u_box_2d(unsigned x,unsigned y,unsigned w,unsigned h,struct pipe_box * box)20 u_box_2d(unsigned x,unsigned y, unsigned w, unsigned h, struct pipe_box *box)
21 {
22    box->x = x;
23    box->y = y;
24    box->z = 0;
25    box->width = w;
26    box->height = h;
27    box->depth = 1;
28 }
29 
30 static inline void
u_box_origin_2d(unsigned w,unsigned h,struct pipe_box * box)31 u_box_origin_2d(unsigned w, unsigned h, struct pipe_box *box)
32 {
33    box->x = 0;
34    box->y = 0;
35    box->z = 0;
36    box->width = w;
37    box->height = h;
38    box->depth = 1;
39 }
40 
41 static inline void
u_box_2d_zslice(unsigned x,unsigned y,unsigned z,unsigned w,unsigned h,struct pipe_box * box)42 u_box_2d_zslice(unsigned x, unsigned y, unsigned z,
43                 unsigned w, unsigned h, struct pipe_box *box)
44 {
45    box->x = x;
46    box->y = y;
47    box->z = z;
48    box->width = w;
49    box->height = h;
50    box->depth = 1;
51 }
52 
53 static inline void
u_box_3d(unsigned x,unsigned y,unsigned z,unsigned w,unsigned h,unsigned d,struct pipe_box * box)54 u_box_3d(unsigned x, unsigned y, unsigned z,
55          unsigned w, unsigned h, unsigned d,
56          struct pipe_box *box)
57 {
58    box->x = x;
59    box->y = y;
60    box->z = z;
61    box->width = w;
62    box->height = h;
63    box->depth = d;
64 }
65 
66 /* Clips @dst to width @w and height @h.
67  * Returns -1 if the resulting box would be empty (then @dst is left unchanged).
68  *          0 if nothing has been reduced.
69  *          1 if width has been reduced.
70  *          2 if height has been reduced.
71  *          3 if both width and height have been reduced.
72  * Aliasing permitted.
73  */
74 static inline int
u_box_clip_2d(struct pipe_box * dst,const struct pipe_box * box,int w,int h)75 u_box_clip_2d(struct pipe_box *dst,
76               const struct pipe_box *box, int w, int h)
77 {
78    unsigned i;
79    int a[2], b[2], dim[2];
80    int *start, *end;
81    int res = 0;
82 
83    if (!box->width || !box->height)
84       return -1;
85    dim[0] = w;
86    dim[1] = h;
87    a[0] = box->x;
88    a[1] = box->y;
89    b[0] = box->x + box->width;
90    b[1] = box->y + box->height;
91 
92    for (i = 0; i < 2; ++i) {
93       start = (a[i] <= b[i]) ? &a[i] : &b[i];
94       end = (a[i] <= b[i]) ? &b[i] : &a[i];
95 
96       if (*end < 0 || *start >= dim[i])
97          return -1;
98       if (*start < 0) {
99          *start = 0;
100          res |= (1 << i);
101       }
102       if (*end > dim[i]) {
103          *end = dim[i];
104          res |= (1 << i);
105       }
106    }
107 
108    if (res) {
109       dst->x = a[0];
110       dst->y = a[1];
111       dst->width = b[0] - a[0];
112       dst->height = b[1] - a[1];
113    }
114    return res;
115 }
116 
117 static inline int64_t
u_box_volume_3d(const struct pipe_box * box)118 u_box_volume_3d(const struct pipe_box *box)
119 {
120    return (int64_t)box->width * box->height * box->depth;
121 }
122 
123 /* Aliasing of @dst permitted. Supports empty width */
124 static inline void
u_box_union_1d(struct pipe_box * dst,const struct pipe_box * a,const struct pipe_box * b)125 u_box_union_1d(struct pipe_box *dst,
126                const struct pipe_box *a, const struct pipe_box *b)
127 {
128    int x, width;
129 
130    if (a->width == 0) {
131        x = b->x;
132        width = b->width;
133    } else if (b->width == 0) {
134        x = a->x;
135        width = a->width;
136    } else {
137        x = MIN2(a->x, b->x);
138        width = MAX2(a->x + a->width, b->x + b->width) - x;
139    }
140 
141    dst->x = x;
142    dst->width = width;
143 }
144 
145 /* Aliasing of @dst permitted. */
146 static inline void
u_box_intersect_1d(struct pipe_box * dst,const struct pipe_box * a,const struct pipe_box * b)147 u_box_intersect_1d(struct pipe_box *dst,
148                const struct pipe_box *a, const struct pipe_box *b)
149 {
150    int x;
151 
152    x = MAX2(a->x, b->x);
153 
154    dst->width = MIN2(a->x + a->width, b->x + b->width) - x;
155    dst->x = x;
156    if (dst->width <= 0) {
157       dst->x = 0;
158       dst->width = 0;
159    }
160 }
161 
162 /* Aliasing of @dst permitted. */
163 static inline void
u_box_union_2d(struct pipe_box * dst,const struct pipe_box * a,const struct pipe_box * b)164 u_box_union_2d(struct pipe_box *dst,
165                const struct pipe_box *a, const struct pipe_box *b)
166 {
167    int x, y;
168 
169    x = MIN2(a->x, b->x);
170    y = MIN2(a->y, b->y);
171 
172    dst->width = MAX2(a->x + a->width, b->x + b->width) - x;
173    dst->height = MAX2(a->y + a->height, b->y + b->height) - y;
174    dst->x = x;
175    dst->y = y;
176 }
177 
178 /* Aliasing of @dst permitted. */
179 static inline void
u_box_union_3d(struct pipe_box * dst,const struct pipe_box * a,const struct pipe_box * b)180 u_box_union_3d(struct pipe_box *dst,
181                const struct pipe_box *a, const struct pipe_box *b)
182 {
183    int x, y, z;
184 
185    x = MIN2(a->x, b->x);
186    y = MIN2(a->y, b->y);
187    z = MIN2(a->z, b->z);
188 
189    dst->width = MAX2(a->x + a->width, b->x + b->width) - x;
190    dst->height = MAX2(a->y + a->height, b->y + b->height) - y;
191    dst->depth = MAX2(a->z + a->depth, b->z + b->depth) - z;
192    dst->x = x;
193    dst->y = y;
194    dst->z = z;
195 }
196 
197 static inline bool
u_box_test_intersection_1d(const struct pipe_box * a,const struct pipe_box * b)198 u_box_test_intersection_1d(const struct pipe_box *a,
199                            const struct pipe_box *b)
200 {
201    int ax[2], bx[2];
202 
203    ax[0] = MIN2(a->x, a->x + a->width);
204    ax[1] = MAX2(a->x, a->x + a->width - 1);
205 
206    bx[0] = MIN2(b->x, b->x + b->width);
207    bx[1] = MAX2(b->x, b->x + b->width - 1);
208 
209    return ax[1] >= bx[0] && bx[1] >= ax[0];
210 }
211 
212 static inline bool
u_box_test_intersection_2d(const struct pipe_box * a,const struct pipe_box * b)213 u_box_test_intersection_2d(const struct pipe_box *a,
214                            const struct pipe_box *b)
215 {
216    unsigned i;
217    int a_l[2], a_r[2], b_l[2], b_r[2];
218 
219    a_l[0] = MIN2(a->x, a->x + a->width);
220    a_r[0] = MAX2(a->x, a->x + a->width);
221    a_l[1] = MIN2(a->y, a->y + a->height);
222    a_r[1] = MAX2(a->y, a->y + a->height);
223 
224    b_l[0] = MIN2(b->x, b->x + b->width);
225    b_r[0] = MAX2(b->x, b->x + b->width);
226    b_l[1] = MIN2(b->y, b->y + b->height);
227    b_r[1] = MAX2(b->y, b->y + b->height);
228 
229    for (i = 0; i < 2; ++i) {
230       if (a_l[i] > b_r[i] || a_r[i] < b_l[i])
231          return false;
232    }
233    return true;
234 }
235 
236 static inline bool
u_box_test_intersection_3d(const struct pipe_box * a,const struct pipe_box * b)237 u_box_test_intersection_3d(const struct pipe_box *a,
238                            const struct pipe_box *b)
239 {
240    int ax[2], ay[2], ad[2], bx[2], by[2], bd[2];
241 
242    ax[0] = MIN2(a->x, a->x + a->width);
243    ax[1] = MAX2(a->x, a->x + a->width - 1);
244    ay[0] = MIN2(a->y, a->y + a->height);
245    ay[1] = MAX2(a->y, a->y + a->height - 1);
246    ad[0] = MIN2(a->z, a->z + a->depth);
247    ad[1] = MAX2(a->z, a->z + a->depth - 1);
248 
249    bx[0] = MIN2(b->x, b->x + b->width);
250    bx[1] = MAX2(b->x, b->x + b->width - 1);
251    by[0] = MIN2(b->y, b->y + b->height);
252    by[1] = MAX2(b->y, b->y + b->height - 1);
253    bd[0] = MIN2(b->z, b->z + b->depth);
254    bd[1] = MAX2(b->z, b->z + b->depth - 1);
255 
256    return ax[1] >= bx[0] && bx[1] >= ax[0] &&
257           ay[1] >= by[0] && by[1] >= ay[0] &&
258           ad[1] >= bd[0] && bd[1] >= ad[0];
259 }
260 
261 static inline void
u_box_minify_2d(struct pipe_box * dst,const struct pipe_box * src,unsigned l)262 u_box_minify_2d(struct pipe_box *dst,
263                 const struct pipe_box *src, unsigned l)
264 {
265    dst->x = src->x >> l;
266    dst->y = src->y >> l;
267    dst->width = MAX2(src->width >> l, 1);
268    dst->height = MAX2(src->height >> l, 1);
269 }
270 
271 static inline void
u_box_minify_3d(struct pipe_box * dst,const struct pipe_box * src,unsigned l)272 u_box_minify_3d(struct pipe_box *dst,
273                 const struct pipe_box *src, unsigned l)
274 {
275    dst->x = src->x >> l;
276    dst->y = src->y >> l;
277    dst->z = src->z >> l;
278    dst->width = MAX2(src->width >> l, 1);
279    dst->height = MAX2(src->height >> l, 1);
280    dst->depth = MAX2(src->depth >> l, 1);
281 }
282 
283 /* Converts a box specified in pixels to an equivalent box specified
284  * in blocks, where the boxes represent a region-of-interest of an image with
285  * the given format. This is trivial (a copy) for uncompressed formats.
286  */
287 static inline void
u_box_pixels_to_blocks(struct pipe_box * blocks,const struct pipe_box * pixels,enum pipe_format format)288 u_box_pixels_to_blocks(struct pipe_box *blocks,
289                        const struct pipe_box *pixels, enum pipe_format format)
290 {
291    u_box_3d(
292          pixels->x / util_format_get_blockwidth(format),
293          pixels->y / util_format_get_blockheight(format),
294          pixels->z,
295          DIV_ROUND_UP(pixels->width, util_format_get_blockwidth(format)),
296          DIV_ROUND_UP(pixels->height, util_format_get_blockheight(format)),
297          pixels->depth,
298          blocks);
299 }
300 
301 #endif
302