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