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
7 static inline void
u_box_1d(unsigned x,unsigned w,struct pipe_box * box)8 u_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
18 static inline void
u_box_2d(unsigned x,unsigned y,unsigned w,unsigned h,struct pipe_box * box)19 u_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
29 static inline void
u_box_origin_2d(unsigned w,unsigned h,struct pipe_box * box)30 u_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
40 static inline void
u_box_2d_zslice(unsigned x,unsigned y,unsigned z,unsigned w,unsigned h,struct pipe_box * box)41 u_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
52 static inline void
u_box_3d(unsigned x,unsigned y,unsigned z,unsigned w,unsigned h,unsigned d,struct pipe_box * box)53 u_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 */
73 static inline int
u_box_clip_2d(struct pipe_box * dst,const struct pipe_box * box,int w,int h)74 u_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
116 static inline int64_t
u_box_volume_3d(const struct pipe_box * box)117 u_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. */
123 static inline void
u_box_union_2d(struct pipe_box * dst,const struct pipe_box * a,const struct pipe_box * b)124 u_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. */
139 static inline void
u_box_union_3d(struct pipe_box * dst,const struct pipe_box * a,const struct pipe_box * b)140 u_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
157 static inline boolean
u_box_test_intersection_2d(const struct pipe_box * a,const struct pipe_box * b)158 u_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
181 static inline void
u_box_minify_2d(struct pipe_box * dst,const struct pipe_box * src,unsigned l)182 u_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
191 static inline void
u_box_minify_3d(struct pipe_box * dst,const struct pipe_box * src,unsigned l)192 u_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