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 8static inline void 9u_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 19static inline void 20u_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 30static inline void 31u_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 41static inline void 42u_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 53static inline void 54u_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 */ 74static inline int 75u_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 117static inline int64_t 118u_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 */ 124static inline void 125u_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. */ 146static inline void 147u_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. */ 163static inline void 164u_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. */ 179static inline void 180u_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 197static inline boolean 198u_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 221static inline void 222u_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 231static inline void 232u_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 */ 247static inline void 248u_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