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
7static inline void
8u_box_1d(unsigned x, unsigned w, struct pipe_box *box)
9{
10   box->x = x;
11   box->y = 0;
12   box->z = 0;
13   box->width = w;
14   box->height = 1;
15   box->depth = 1;
16}
17
18static inline void
19u_box_2d(unsigned x,unsigned y, unsigned w, unsigned h, struct pipe_box *box)
20{
21   box->x = x;
22   box->y = y;
23   box->z = 0;
24   box->width = w;
25   box->height = h;
26   box->depth = 1;
27}
28
29static inline void
30u_box_origin_2d(unsigned w, unsigned h, struct pipe_box *box)
31{
32   box->x = 0;
33   box->y = 0;
34   box->z = 0;
35   box->width = w;
36   box->height = h;
37   box->depth = 1;
38}
39
40static inline void
41u_box_2d_zslice(unsigned x, unsigned y, unsigned z,
42                unsigned w, unsigned h, struct pipe_box *box)
43{
44   box->x = x;
45   box->y = y;
46   box->z = z;
47   box->width = w;
48   box->height = h;
49   box->depth = 1;
50}
51
52static inline void
53u_box_3d(unsigned x, unsigned y, unsigned z,
54         unsigned w, unsigned h, unsigned d,
55         struct pipe_box *box)
56{
57   box->x = x;
58   box->y = y;
59   box->z = z;
60   box->width = w;
61   box->height = h;
62   box->depth = d;
63}
64
65/* Clips @dst to width @w and height @h.
66 * Returns -1 if the resulting box would be empty (then @dst is left unchanged).
67 *          0 if nothing has been reduced.
68 *          1 if width has been reduced.
69 *          2 if height has been reduced.
70 *          3 if both width and height have been reduced.
71 * Aliasing permitted.
72 */
73static inline int
74u_box_clip_2d(struct pipe_box *dst,
75              const struct pipe_box *box, int w, int h)
76{
77   unsigned i;
78   int a[2], b[2], dim[2];
79   int *start, *end;
80   int res = 0;
81
82   if (!box->width || !box->height)
83      return -1;
84   dim[0] = w;
85   dim[1] = h;
86   a[0] = box->x;
87   a[1] = box->y;
88   b[0] = box->x + box->width;
89   b[1] = box->y + box->height;
90
91   for (i = 0; i < 2; ++i) {
92      start = (a[i] <= b[i]) ? &a[i] : &b[i];
93      end = (a[i] <= b[i]) ? &b[i] : &a[i];
94
95      if (*end < 0 || *start >= dim[i])
96         return -1;
97      if (*start < 0) {
98         *start = 0;
99         res |= (1 << i);
100      }
101      if (*end > dim[i]) {
102         *end = dim[i];
103         res |= (1 << i);
104      }
105   }
106
107   if (res) {
108      dst->x = a[0];
109      dst->y = a[1];
110      dst->width = b[0] - a[0];
111      dst->height = b[1] - a[1];
112   }
113   return res;
114}
115
116static inline int64_t
117u_box_volume_3d(const struct pipe_box *box)
118{
119   return (int64_t)box->width * box->height * box->depth;
120}
121
122/* Aliasing of @dst permitted. */
123static inline void
124u_box_union_2d(struct pipe_box *dst,
125               const struct pipe_box *a, const struct pipe_box *b)
126{
127   int x, y;
128
129   x = MIN2(a->x, b->x);
130   y = MIN2(a->y, b->y);
131
132   dst->width = MAX2(a->x + a->width, b->x + b->width) - x;
133   dst->height = MAX2(a->y + a->height, b->y + b->height) - y;
134   dst->x = x;
135   dst->y = y;
136}
137
138/* Aliasing of @dst permitted. */
139static inline void
140u_box_union_3d(struct pipe_box *dst,
141               const struct pipe_box *a, const struct pipe_box *b)
142{
143   int x, y, z;
144
145   x = MIN2(a->x, b->x);
146   y = MIN2(a->y, b->y);
147   z = MIN2(a->z, b->z);
148
149   dst->width = MAX2(a->x + a->width, b->x + b->width) - x;
150   dst->height = MAX2(a->y + a->height, b->y + b->height) - y;
151   dst->depth = MAX2(a->z + a->depth, b->z + b->depth) - z;
152   dst->x = x;
153   dst->y = y;
154   dst->z = z;
155}
156
157static inline boolean
158u_box_test_intersection_2d(const struct pipe_box *a,
159                           const struct pipe_box *b)
160{
161   unsigned i;
162   int a_l[2], a_r[2], b_l[2], b_r[2];
163
164   a_l[0] = MIN2(a->x, a->x + a->width);
165   a_r[0] = MAX2(a->x, a->x + a->width);
166   a_l[1] = MIN2(a->y, a->y + a->height);
167   a_r[1] = MAX2(a->y, a->y + a->height);
168
169   b_l[0] = MIN2(b->x, b->x + b->width);
170   b_r[0] = MAX2(b->x, b->x + b->width);
171   b_l[1] = MIN2(b->y, b->y + b->height);
172   b_r[1] = MAX2(b->y, b->y + b->height);
173
174   for (i = 0; i < 2; ++i) {
175      if (a_l[i] > b_r[i] || a_r[i] < b_l[i])
176         return FALSE;
177   }
178   return TRUE;
179}
180
181static inline void
182u_box_minify_2d(struct pipe_box *dst,
183                const struct pipe_box *src, unsigned l)
184{
185   dst->x = src->x >> l;
186   dst->y = src->y >> l;
187   dst->width = MAX2(src->width >> l, 1);
188   dst->height = MAX2(src->height >> l, 1);
189}
190
191static inline void
192u_box_minify_3d(struct pipe_box *dst,
193                const struct pipe_box *src, unsigned l)
194{
195   dst->x = src->x >> l;
196   dst->y = src->y >> l;
197   dst->z = src->z >> l;
198   dst->width = MAX2(src->width >> l, 1);
199   dst->height = MAX2(src->height >> l, 1);
200   dst->depth = MAX2(src->depth >> l, 1);
201}
202
203#endif
204