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