gallium/auxiliary: add contained and rect checks (v6)
v3: thanks to Brian, improved coding style, also glennk helped spot few things (unsigned -> int, two constify) v4: thanks Ilia improved function, dropped u_box_clip_3d v5: incorporated rest of Gregor proposed changes,clean ups v6: u_box_clip_2d simplify proposed by Ilia Mirkin Acked-by: Jose Fonseca <jfonseca@vmware.com> Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu> Reviewed-by: Marek Olšák <marek.olsak@amd.com> Signed-off-by: David Heidelberg <david@ixit.cz>
This commit is contained in:
parent
cb49132166
commit
7d2573b537
|
@ -2,6 +2,7 @@
|
|||
#define UTIL_BOX_INLINES_H
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
static INLINE
|
||||
void u_box_1d( unsigned x,
|
||||
|
@ -77,4 +78,121 @@ void u_box_3d( unsigned x,
|
|||
box->depth = d;
|
||||
}
|
||||
|
||||
/* Clips @dst to width @w and height @h.
|
||||
* Returns -1 if the resulting box would be empty (then @dst is left unchanged).
|
||||
* 0 if nothing has been reduced.
|
||||
* 1 if width has been reduced.
|
||||
* 2 if height has been reduced.
|
||||
* 3 if both width and height have been reduced.
|
||||
* Aliasing permitted.
|
||||
*/
|
||||
static INLINE int
|
||||
u_box_clip_2d(struct pipe_box *dst,
|
||||
const struct pipe_box *box, int w, int h)
|
||||
{
|
||||
unsigned i;
|
||||
int a[2], b[2], dim[2];
|
||||
int *start, *end;
|
||||
int res = 0;
|
||||
|
||||
if (!box->width || !box->height)
|
||||
return -1;
|
||||
dim[0] = w;
|
||||
dim[1] = h;
|
||||
a[0] = box->x;
|
||||
a[1] = box->y;
|
||||
b[0] = box->x + box->width;
|
||||
b[1] = box->y + box->height;
|
||||
|
||||
for (i = 0; i < 2; ++i) {
|
||||
start = (a[i] <= b[i]) ? &a[i] : &b[i];
|
||||
end = (a[i] <= b[i]) ? &b[i] : &a[i];
|
||||
|
||||
if (*end < 0 || *start >= dim[i])
|
||||
return -1;
|
||||
if (*start < 0) {
|
||||
*start = 0;
|
||||
res |= (1 << i);
|
||||
}
|
||||
if (*end > dim[i]) {
|
||||
*end = dim[i];
|
||||
res |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
if (res) {
|
||||
dst->x = a[0];
|
||||
dst->y = a[1];
|
||||
dst->width = b[0] - a[0];
|
||||
dst->height = b[1] - a[1];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static INLINE int64_t
|
||||
u_box_volume_3d(const struct pipe_box *box)
|
||||
{
|
||||
return (int64_t)box->width * box->height * box->depth;
|
||||
}
|
||||
|
||||
/* Aliasing of @dst permitted. */
|
||||
static INLINE void
|
||||
u_box_union_2d(struct pipe_box *dst,
|
||||
const struct pipe_box *a, const struct pipe_box *b)
|
||||
{
|
||||
dst->x = MIN2(a->x, b->x);
|
||||
dst->y = MIN2(a->y, b->y);
|
||||
|
||||
dst->width = MAX2(a->x + a->width, b->x + b->width) - dst->x;
|
||||
dst->height = MAX2(a->y + a->height, b->y + b->height) - dst->y;
|
||||
}
|
||||
|
||||
/* Aliasing of @dst permitted. */
|
||||
static INLINE void
|
||||
u_box_union_3d(struct pipe_box *dst,
|
||||
const struct pipe_box *a, const struct pipe_box *b)
|
||||
{
|
||||
dst->x = MIN2(a->x, b->x);
|
||||
dst->y = MIN2(a->y, b->y);
|
||||
dst->z = MIN2(a->z, b->z);
|
||||
|
||||
dst->width = MAX2(a->x + a->width, b->x + b->width) - dst->x;
|
||||
dst->height = MAX2(a->y + a->height, b->y + b->height) - dst->y;
|
||||
dst->depth = MAX2(a->z + a->depth, b->z + b->depth) - dst->z;
|
||||
}
|
||||
|
||||
static INLINE boolean
|
||||
u_box_test_intersection_2d(const struct pipe_box *a,
|
||||
const struct pipe_box *b)
|
||||
{
|
||||
unsigned i;
|
||||
int a_l[2], a_r[2], b_l[2], b_r[2];
|
||||
|
||||
a_l[0] = MIN2(a->x, a->x + a->width);
|
||||
a_r[0] = MAX2(a->x, a->x + a->width);
|
||||
a_l[1] = MIN2(a->y, a->y + a->height);
|
||||
a_r[1] = MAX2(a->y, a->y + a->height);
|
||||
|
||||
b_l[0] = MIN2(b->x, b->x + b->width);
|
||||
b_r[0] = MAX2(b->x, b->x + b->width);
|
||||
b_l[1] = MIN2(b->y, b->y + b->height);
|
||||
b_r[1] = MAX2(b->y, b->y + b->height);
|
||||
|
||||
for (i = 0; i < 2; ++i) {
|
||||
if (a_l[i] > b_r[i] || a_r[i] < b_l[i])
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
u_box_minify_2d(struct pipe_box *dst,
|
||||
const struct pipe_box *src, unsigned l)
|
||||
{
|
||||
dst->x = src->x >> l;
|
||||
dst->y = src->y >> l;
|
||||
dst->width = MAX2(src->width >> l, 1);
|
||||
dst->height = MAX2(src->height >> l, 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#define U_RECT_H
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -67,6 +68,12 @@ u_rect_find_intersection(const struct u_rect *a,
|
|||
}
|
||||
|
||||
|
||||
static INLINE int
|
||||
u_rect_area(const struct u_rect *r)
|
||||
{
|
||||
return (r->x1 - r->x0) * (r->y1 - r->y0);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
u_rect_possible_intersection(const struct u_rect *a,
|
||||
struct u_rect *b)
|
||||
|
@ -79,6 +86,17 @@ u_rect_possible_intersection(const struct u_rect *a,
|
|||
}
|
||||
}
|
||||
|
||||
/* Set @d to a rectangle that covers both @a and @b.
|
||||
*/
|
||||
static INLINE void
|
||||
u_rect_union(struct u_rect *d, const struct u_rect *a, const struct u_rect *b)
|
||||
{
|
||||
d->x0 = MIN2(a->x0, b->x0);
|
||||
d->y0 = MIN2(a->y0, b->y0);
|
||||
d->x1 = MAX2(a->x1, b->x1);
|
||||
d->y1 = MAX2(a->y1, b->y1);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue