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 boolean
u_box_test_intersection_2d(const struct pipe_box * a,const struct pipe_box * b)198 u_box_test_intersection_2d(const struct pipe_box *a,
199 const struct pipe_box *b)
200 {
201 unsigned i;
202 int a_l[2], a_r[2], b_l[2], b_r[2];
203
204 a_l[0] = MIN2(a->x, a->x + a->width);
205 a_r[0] = MAX2(a->x, a->x + a->width);
206 a_l[1] = MIN2(a->y, a->y + a->height);
207 a_r[1] = MAX2(a->y, a->y + a->height);
208
209 b_l[0] = MIN2(b->x, b->x + b->width);
210 b_r[0] = MAX2(b->x, b->x + b->width);
211 b_l[1] = MIN2(b->y, b->y + b->height);
212 b_r[1] = MAX2(b->y, b->y + b->height);
213
214 for (i = 0; i < 2; ++i) {
215 if (a_l[i] > b_r[i] || a_r[i] < b_l[i])
216 return FALSE;
217 }
218 return TRUE;
219 }
220
221 static inline void
u_box_minify_2d(struct pipe_box * dst,const struct pipe_box * src,unsigned l)222 u_box_minify_2d(struct pipe_box *dst,
223 const struct pipe_box *src, unsigned l)
224 {
225 dst->x = src->x >> l;
226 dst->y = src->y >> l;
227 dst->width = MAX2(src->width >> l, 1);
228 dst->height = MAX2(src->height >> l, 1);
229 }
230
231 static inline void
u_box_minify_3d(struct pipe_box * dst,const struct pipe_box * src,unsigned l)232 u_box_minify_3d(struct pipe_box *dst,
233 const struct pipe_box *src, unsigned l)
234 {
235 dst->x = src->x >> l;
236 dst->y = src->y >> l;
237 dst->z = src->z >> l;
238 dst->width = MAX2(src->width >> l, 1);
239 dst->height = MAX2(src->height >> l, 1);
240 dst->depth = MAX2(src->depth >> l, 1);
241 }
242
243 /* Converts a box specified in pixels to an equivalent box specified
244 * in blocks, where the boxes represent a region-of-interest of an image with
245 * the given format. This is trivial (a copy) for uncompressed formats.
246 */
247 static inline void
u_box_pixels_to_blocks(struct pipe_box * blocks,const struct pipe_box * pixels,enum pipe_format format)248 u_box_pixels_to_blocks(struct pipe_box *blocks,
249 const struct pipe_box *pixels, enum pipe_format format)
250 {
251 u_box_3d(
252 pixels->x / util_format_get_blockwidth(format),
253 pixels->y / util_format_get_blockheight(format),
254 pixels->z,
255 DIV_ROUND_UP(pixels->width, util_format_get_blockwidth(format)),
256 DIV_ROUND_UP(pixels->height, util_format_get_blockheight(format)),
257 pixels->depth,
258 blocks);
259 }
260
261 #endif
262