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