13464ebd5Sriastradh#ifndef UTIL_BOX_INLINES_H
23464ebd5Sriastradh#define UTIL_BOX_INLINES_H
33464ebd5Sriastradh
43464ebd5Sriastradh#include "pipe/p_state.h"
501e04c3fSmrg#include "util/u_math.h"
67ec681f3Smrg#include "util/format/u_format.h"
73464ebd5Sriastradh
801e04c3fSmrgstatic inline void
901e04c3fSmrgu_box_1d(unsigned x, unsigned w, struct pipe_box *box)
103464ebd5Sriastradh{
113464ebd5Sriastradh   box->x = x;
123464ebd5Sriastradh   box->y = 0;
133464ebd5Sriastradh   box->z = 0;
143464ebd5Sriastradh   box->width = w;
153464ebd5Sriastradh   box->height = 1;
163464ebd5Sriastradh   box->depth = 1;
173464ebd5Sriastradh}
183464ebd5Sriastradh
1901e04c3fSmrgstatic inline void
2001e04c3fSmrgu_box_2d(unsigned x,unsigned y, unsigned w, unsigned h, struct pipe_box *box)
213464ebd5Sriastradh{
223464ebd5Sriastradh   box->x = x;
233464ebd5Sriastradh   box->y = y;
243464ebd5Sriastradh   box->z = 0;
253464ebd5Sriastradh   box->width = w;
263464ebd5Sriastradh   box->height = h;
273464ebd5Sriastradh   box->depth = 1;
283464ebd5Sriastradh}
293464ebd5Sriastradh
3001e04c3fSmrgstatic inline void
3101e04c3fSmrgu_box_origin_2d(unsigned w, unsigned h, struct pipe_box *box)
323464ebd5Sriastradh{
333464ebd5Sriastradh   box->x = 0;
343464ebd5Sriastradh   box->y = 0;
353464ebd5Sriastradh   box->z = 0;
363464ebd5Sriastradh   box->width = w;
373464ebd5Sriastradh   box->height = h;
383464ebd5Sriastradh   box->depth = 1;
393464ebd5Sriastradh}
403464ebd5Sriastradh
4101e04c3fSmrgstatic inline void
4201e04c3fSmrgu_box_2d_zslice(unsigned x, unsigned y, unsigned z,
4301e04c3fSmrg                unsigned w, unsigned h, struct pipe_box *box)
443464ebd5Sriastradh{
453464ebd5Sriastradh   box->x = x;
463464ebd5Sriastradh   box->y = y;
473464ebd5Sriastradh   box->z = z;
483464ebd5Sriastradh   box->width = w;
493464ebd5Sriastradh   box->height = h;
503464ebd5Sriastradh   box->depth = 1;
513464ebd5Sriastradh}
523464ebd5Sriastradh
5301e04c3fSmrgstatic inline void
5401e04c3fSmrgu_box_3d(unsigned x, unsigned y, unsigned z,
5501e04c3fSmrg         unsigned w, unsigned h, unsigned d,
5601e04c3fSmrg         struct pipe_box *box)
573464ebd5Sriastradh{
583464ebd5Sriastradh   box->x = x;
593464ebd5Sriastradh   box->y = y;
603464ebd5Sriastradh   box->z = z;
613464ebd5Sriastradh   box->width = w;
623464ebd5Sriastradh   box->height = h;
633464ebd5Sriastradh   box->depth = d;
643464ebd5Sriastradh}
653464ebd5Sriastradh
6601e04c3fSmrg/* Clips @dst to width @w and height @h.
6701e04c3fSmrg * Returns -1 if the resulting box would be empty (then @dst is left unchanged).
6801e04c3fSmrg *          0 if nothing has been reduced.
6901e04c3fSmrg *          1 if width has been reduced.
7001e04c3fSmrg *          2 if height has been reduced.
7101e04c3fSmrg *          3 if both width and height have been reduced.
7201e04c3fSmrg * Aliasing permitted.
7301e04c3fSmrg */
7401e04c3fSmrgstatic inline int
7501e04c3fSmrgu_box_clip_2d(struct pipe_box *dst,
7601e04c3fSmrg              const struct pipe_box *box, int w, int h)
7701e04c3fSmrg{
7801e04c3fSmrg   unsigned i;
7901e04c3fSmrg   int a[2], b[2], dim[2];
8001e04c3fSmrg   int *start, *end;
8101e04c3fSmrg   int res = 0;
8201e04c3fSmrg
8301e04c3fSmrg   if (!box->width || !box->height)
8401e04c3fSmrg      return -1;
8501e04c3fSmrg   dim[0] = w;
8601e04c3fSmrg   dim[1] = h;
8701e04c3fSmrg   a[0] = box->x;
8801e04c3fSmrg   a[1] = box->y;
8901e04c3fSmrg   b[0] = box->x + box->width;
9001e04c3fSmrg   b[1] = box->y + box->height;
9101e04c3fSmrg
9201e04c3fSmrg   for (i = 0; i < 2; ++i) {
9301e04c3fSmrg      start = (a[i] <= b[i]) ? &a[i] : &b[i];
9401e04c3fSmrg      end = (a[i] <= b[i]) ? &b[i] : &a[i];
9501e04c3fSmrg
9601e04c3fSmrg      if (*end < 0 || *start >= dim[i])
9701e04c3fSmrg         return -1;
9801e04c3fSmrg      if (*start < 0) {
9901e04c3fSmrg         *start = 0;
10001e04c3fSmrg         res |= (1 << i);
10101e04c3fSmrg      }
10201e04c3fSmrg      if (*end > dim[i]) {
10301e04c3fSmrg         *end = dim[i];
10401e04c3fSmrg         res |= (1 << i);
10501e04c3fSmrg      }
10601e04c3fSmrg   }
10701e04c3fSmrg
10801e04c3fSmrg   if (res) {
10901e04c3fSmrg      dst->x = a[0];
11001e04c3fSmrg      dst->y = a[1];
11101e04c3fSmrg      dst->width = b[0] - a[0];
11201e04c3fSmrg      dst->height = b[1] - a[1];
11301e04c3fSmrg   }
11401e04c3fSmrg   return res;
11501e04c3fSmrg}
11601e04c3fSmrg
11701e04c3fSmrgstatic inline int64_t
11801e04c3fSmrgu_box_volume_3d(const struct pipe_box *box)
11901e04c3fSmrg{
12001e04c3fSmrg   return (int64_t)box->width * box->height * box->depth;
12101e04c3fSmrg}
12201e04c3fSmrg
1237ec681f3Smrg/* Aliasing of @dst permitted. Supports empty width */
1247ec681f3Smrgstatic inline void
1257ec681f3Smrgu_box_union_1d(struct pipe_box *dst,
1267ec681f3Smrg               const struct pipe_box *a, const struct pipe_box *b)
1277ec681f3Smrg{
1287ec681f3Smrg   int x, width;
1297ec681f3Smrg
1307ec681f3Smrg   if (a->width == 0) {
1317ec681f3Smrg       x = b->x;
1327ec681f3Smrg       width = b->width;
1337ec681f3Smrg   } else if (b->width == 0) {
1347ec681f3Smrg       x = a->x;
1357ec681f3Smrg       width = a->width;
1367ec681f3Smrg   } else {
1377ec681f3Smrg       x = MIN2(a->x, b->x);
1387ec681f3Smrg       width = MAX2(a->x + a->width, b->x + b->width) - x;
1397ec681f3Smrg   }
1407ec681f3Smrg
1417ec681f3Smrg   dst->x = x;
1427ec681f3Smrg   dst->width = width;
1437ec681f3Smrg}
1447ec681f3Smrg
1457ec681f3Smrg/* Aliasing of @dst permitted. */
1467ec681f3Smrgstatic inline void
1477ec681f3Smrgu_box_intersect_1d(struct pipe_box *dst,
1487ec681f3Smrg               const struct pipe_box *a, const struct pipe_box *b)
1497ec681f3Smrg{
1507ec681f3Smrg   int x;
1517ec681f3Smrg
1527ec681f3Smrg   x = MAX2(a->x, b->x);
1537ec681f3Smrg
1547ec681f3Smrg   dst->width = MIN2(a->x + a->width, b->x + b->width) - x;
1557ec681f3Smrg   dst->x = x;
1567ec681f3Smrg   if (dst->width <= 0) {
1577ec681f3Smrg      dst->x = 0;
1587ec681f3Smrg      dst->width = 0;
1597ec681f3Smrg   }
1607ec681f3Smrg}
1617ec681f3Smrg
16201e04c3fSmrg/* Aliasing of @dst permitted. */
16301e04c3fSmrgstatic inline void
16401e04c3fSmrgu_box_union_2d(struct pipe_box *dst,
16501e04c3fSmrg               const struct pipe_box *a, const struct pipe_box *b)
16601e04c3fSmrg{
16701e04c3fSmrg   int x, y;
16801e04c3fSmrg
16901e04c3fSmrg   x = MIN2(a->x, b->x);
17001e04c3fSmrg   y = MIN2(a->y, b->y);
17101e04c3fSmrg
17201e04c3fSmrg   dst->width = MAX2(a->x + a->width, b->x + b->width) - x;
17301e04c3fSmrg   dst->height = MAX2(a->y + a->height, b->y + b->height) - y;
17401e04c3fSmrg   dst->x = x;
17501e04c3fSmrg   dst->y = y;
17601e04c3fSmrg}
17701e04c3fSmrg
17801e04c3fSmrg/* Aliasing of @dst permitted. */
17901e04c3fSmrgstatic inline void
18001e04c3fSmrgu_box_union_3d(struct pipe_box *dst,
18101e04c3fSmrg               const struct pipe_box *a, const struct pipe_box *b)
18201e04c3fSmrg{
18301e04c3fSmrg   int x, y, z;
18401e04c3fSmrg
18501e04c3fSmrg   x = MIN2(a->x, b->x);
18601e04c3fSmrg   y = MIN2(a->y, b->y);
18701e04c3fSmrg   z = MIN2(a->z, b->z);
18801e04c3fSmrg
18901e04c3fSmrg   dst->width = MAX2(a->x + a->width, b->x + b->width) - x;
19001e04c3fSmrg   dst->height = MAX2(a->y + a->height, b->y + b->height) - y;
19101e04c3fSmrg   dst->depth = MAX2(a->z + a->depth, b->z + b->depth) - z;
19201e04c3fSmrg   dst->x = x;
19301e04c3fSmrg   dst->y = y;
19401e04c3fSmrg   dst->z = z;
19501e04c3fSmrg}
19601e04c3fSmrg
19701e04c3fSmrgstatic inline boolean
19801e04c3fSmrgu_box_test_intersection_2d(const struct pipe_box *a,
19901e04c3fSmrg                           const struct pipe_box *b)
20001e04c3fSmrg{
20101e04c3fSmrg   unsigned i;
20201e04c3fSmrg   int a_l[2], a_r[2], b_l[2], b_r[2];
20301e04c3fSmrg
20401e04c3fSmrg   a_l[0] = MIN2(a->x, a->x + a->width);
20501e04c3fSmrg   a_r[0] = MAX2(a->x, a->x + a->width);
20601e04c3fSmrg   a_l[1] = MIN2(a->y, a->y + a->height);
20701e04c3fSmrg   a_r[1] = MAX2(a->y, a->y + a->height);
20801e04c3fSmrg
20901e04c3fSmrg   b_l[0] = MIN2(b->x, b->x + b->width);
21001e04c3fSmrg   b_r[0] = MAX2(b->x, b->x + b->width);
21101e04c3fSmrg   b_l[1] = MIN2(b->y, b->y + b->height);
21201e04c3fSmrg   b_r[1] = MAX2(b->y, b->y + b->height);
21301e04c3fSmrg
21401e04c3fSmrg   for (i = 0; i < 2; ++i) {
21501e04c3fSmrg      if (a_l[i] > b_r[i] || a_r[i] < b_l[i])
21601e04c3fSmrg         return FALSE;
21701e04c3fSmrg   }
21801e04c3fSmrg   return TRUE;
21901e04c3fSmrg}
22001e04c3fSmrg
22101e04c3fSmrgstatic inline void
22201e04c3fSmrgu_box_minify_2d(struct pipe_box *dst,
22301e04c3fSmrg                const struct pipe_box *src, unsigned l)
22401e04c3fSmrg{
22501e04c3fSmrg   dst->x = src->x >> l;
22601e04c3fSmrg   dst->y = src->y >> l;
22701e04c3fSmrg   dst->width = MAX2(src->width >> l, 1);
22801e04c3fSmrg   dst->height = MAX2(src->height >> l, 1);
22901e04c3fSmrg}
23001e04c3fSmrg
23101e04c3fSmrgstatic inline void
23201e04c3fSmrgu_box_minify_3d(struct pipe_box *dst,
23301e04c3fSmrg                const struct pipe_box *src, unsigned l)
23401e04c3fSmrg{
23501e04c3fSmrg   dst->x = src->x >> l;
23601e04c3fSmrg   dst->y = src->y >> l;
23701e04c3fSmrg   dst->z = src->z >> l;
23801e04c3fSmrg   dst->width = MAX2(src->width >> l, 1);
23901e04c3fSmrg   dst->height = MAX2(src->height >> l, 1);
24001e04c3fSmrg   dst->depth = MAX2(src->depth >> l, 1);
24101e04c3fSmrg}
24201e04c3fSmrg
2437ec681f3Smrg/* Converts a box specified in pixels to an equivalent box specified
2447ec681f3Smrg * in blocks, where the boxes represent a region-of-interest of an image with
2457ec681f3Smrg * the given format. This is trivial (a copy) for uncompressed formats.
2467ec681f3Smrg */
2477ec681f3Smrgstatic inline void
2487ec681f3Smrgu_box_pixels_to_blocks(struct pipe_box *blocks,
2497ec681f3Smrg                       const struct pipe_box *pixels, enum pipe_format format)
2507ec681f3Smrg{
2517ec681f3Smrg   u_box_3d(
2527ec681f3Smrg         pixels->x / util_format_get_blockwidth(format),
2537ec681f3Smrg         pixels->y / util_format_get_blockheight(format),
2547ec681f3Smrg         pixels->z,
2557ec681f3Smrg         DIV_ROUND_UP(pixels->width, util_format_get_blockwidth(format)),
2567ec681f3Smrg         DIV_ROUND_UP(pixels->height, util_format_get_blockheight(format)),
2577ec681f3Smrg         pixels->depth,
2587ec681f3Smrg         blocks);
2597ec681f3Smrg}
2607ec681f3Smrg
2613464ebd5Sriastradh#endif
262