From e5f133ccc426a197c48a4e88f5377f943f078180 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 13 Apr 2024 22:29:54 -0400 Subject: util: import pipe_box and its helpers We'll use them. There are also new helpers that we'll use. Reviewed-by: Yonggang Luo Part-of: --- src/broadcom/common/v3d_tiling.c | 2 +- src/gallium/auxiliary/meson.build | 1 - src/gallium/auxiliary/postprocess/pp_mlaa.c | 2 +- src/gallium/auxiliary/util/u_box.h | 301 ------------------- src/gallium/auxiliary/util/u_inlines.h | 2 +- src/gallium/auxiliary/util/u_surface_test.cpp | 2 +- src/gallium/auxiliary/util/u_transfer_helper.c | 2 +- src/gallium/drivers/lima/lima_util.c | 3 +- src/gallium/drivers/r300/r300_transfer.c | 2 +- src/gallium/drivers/virgl/virgl_transfer_queue.c | 2 +- src/gallium/frontends/dri/drisw.c | 2 +- src/gallium/frontends/dri/kopper.c | 2 +- src/gallium/frontends/lavapipe/lvp_execute.c | 2 +- src/gallium/frontends/nine/buffer9.c | 2 +- src/gallium/frontends/nine/buffer9.h | 2 +- src/gallium/frontends/nine/indexbuffer9.c | 2 +- src/gallium/frontends/nine/nine_ff.c | 2 +- src/gallium/frontends/nine/nine_state.c | 2 +- src/gallium/frontends/nine/vertexbuffer9.c | 2 +- src/gallium/frontends/osmesa/osmesa.c | 2 +- src/gallium/include/pipe/p_state.h | 18 +- src/mesa/state_tracker/st_cb_copyimage.c | 2 +- src/mesa/state_tracker/st_cb_texture.c | 2 +- src/util/box.h | 359 +++++++++++++++++++++++ src/util/meson.build | 1 + src/util/u_math.h | 6 + 26 files changed, 388 insertions(+), 339 deletions(-) delete mode 100644 src/gallium/auxiliary/util/u_box.h create mode 100644 src/util/box.h (limited to 'src') diff --git a/src/broadcom/common/v3d_tiling.c b/src/broadcom/common/v3d_tiling.c index 5c3e67340f0..5c6413f0db1 100644 --- a/src/broadcom/common/v3d_tiling.c +++ b/src/broadcom/common/v3d_tiling.c @@ -28,7 +28,7 @@ */ #include -#include "util/u_box.h" /* FIXME: avoid include this */ +#include "util/box.h" /* FIXME: avoid include this */ #include "v3d_tiling.h" #include "broadcom/common/v3d_cpu_tiling.h" diff --git a/src/gallium/auxiliary/meson.build b/src/gallium/auxiliary/meson.build index 96b0272c69b..cc9f592894b 100644 --- a/src/gallium/auxiliary/meson.build +++ b/src/gallium/auxiliary/meson.build @@ -211,7 +211,6 @@ files_libgallium = files( 'util/u_blend.h', 'util/u_blitter.c', 'util/u_blitter.h', - 'util/u_box.h', 'util/u_cache.c', 'util/u_cache.h', 'util/u_compute.c', diff --git a/src/gallium/auxiliary/postprocess/pp_mlaa.c b/src/gallium/auxiliary/postprocess/pp_mlaa.c index 8b13efe9dbb..c7f163779e4 100644 --- a/src/gallium/auxiliary/postprocess/pp_mlaa.c +++ b/src/gallium/auxiliary/postprocess/pp_mlaa.c @@ -45,7 +45,7 @@ #include "postprocess/pp_filters.h" #include "postprocess/pp_private.h" -#include "util/u_box.h" +#include "util/box.h" #include "util/u_sampler.h" #include "util/u_inlines.h" #include "util/u_memory.h" diff --git a/src/gallium/auxiliary/util/u_box.h b/src/gallium/auxiliary/util/u_box.h deleted file mode 100644 index 25a91adfdf3..00000000000 --- a/src/gallium/auxiliary/util/u_box.h +++ /dev/null @@ -1,301 +0,0 @@ -#ifndef UTIL_BOX_INLINES_H -#define UTIL_BOX_INLINES_H - -#include "pipe/p_state.h" -#include "util/u_math.h" -#include "util/format/u_format.h" - -static inline void -u_box_1d(unsigned x, unsigned w, struct pipe_box *box) -{ - box->x = x; - box->y = 0; - box->z = 0; - box->width = w; - box->height = 1; - box->depth = 1; -} - -static inline void -u_box_2d(unsigned x,unsigned y, unsigned w, unsigned h, struct pipe_box *box) -{ - box->x = x; - box->y = y; - box->z = 0; - box->width = w; - box->height = h; - box->depth = 1; -} - -static inline void -u_box_origin_2d(unsigned w, unsigned h, struct pipe_box *box) -{ - box->x = 0; - box->y = 0; - box->z = 0; - box->width = w; - box->height = h; - box->depth = 1; -} - -static inline void -u_box_2d_zslice(unsigned x, unsigned y, unsigned z, - unsigned w, unsigned h, struct pipe_box *box) -{ - box->x = x; - box->y = y; - box->z = z; - box->width = w; - box->height = h; - box->depth = 1; -} - -static inline void -u_box_3d(unsigned x, unsigned y, unsigned z, - unsigned w, unsigned h, unsigned d, - struct pipe_box *box) -{ - box->x = x; - box->y = y; - box->z = z; - box->width = w; - box->height = h; - 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. Supports empty width */ -static inline void -u_box_union_1d(struct pipe_box *dst, - const struct pipe_box *a, const struct pipe_box *b) -{ - int x, width; - - if (a->width == 0) { - x = b->x; - width = b->width; - } else if (b->width == 0) { - x = a->x; - width = a->width; - } else { - x = MIN2(a->x, b->x); - width = MAX2(a->x + a->width, b->x + b->width) - x; - } - - dst->x = x; - dst->width = width; -} - -/* Aliasing of @dst permitted. */ -static inline void -u_box_intersect_1d(struct pipe_box *dst, - const struct pipe_box *a, const struct pipe_box *b) -{ - int x; - - x = MAX2(a->x, b->x); - - dst->width = MIN2(a->x + a->width, b->x + b->width) - x; - dst->x = x; - if (dst->width <= 0) { - dst->x = 0; - dst->width = 0; - } -} - -/* 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) -{ - int x, y; - - x = MIN2(a->x, b->x); - y = MIN2(a->y, b->y); - - dst->width = MAX2(a->x + a->width, b->x + b->width) - x; - dst->height = MAX2(a->y + a->height, b->y + b->height) - y; - dst->x = x; - dst->y = 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) -{ - int x, y, z; - - x = MIN2(a->x, b->x); - y = MIN2(a->y, b->y); - z = MIN2(a->z, b->z); - - dst->width = MAX2(a->x + a->width, b->x + b->width) - x; - dst->height = MAX2(a->y + a->height, b->y + b->height) - y; - dst->depth = MAX2(a->z + a->depth, b->z + b->depth) - z; - dst->x = x; - dst->y = y; - dst->z = z; -} - -static inline bool -u_box_test_intersection_1d(const struct pipe_box *a, - const struct pipe_box *b) -{ - int ax[2], bx[2]; - - ax[0] = MIN2(a->x, a->x + a->width); - ax[1] = MAX2(a->x, a->x + a->width - 1); - - bx[0] = MIN2(b->x, b->x + b->width); - bx[1] = MAX2(b->x, b->x + b->width - 1); - - return ax[1] >= bx[0] && bx[1] >= ax[0]; -} - -static inline bool -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 bool -u_box_test_intersection_3d(const struct pipe_box *a, - const struct pipe_box *b) -{ - int ax[2], ay[2], ad[2], bx[2], by[2], bd[2]; - - ax[0] = MIN2(a->x, a->x + a->width); - ax[1] = MAX2(a->x, a->x + a->width - 1); - ay[0] = MIN2(a->y, a->y + a->height); - ay[1] = MAX2(a->y, a->y + a->height - 1); - ad[0] = MIN2(a->z, a->z + a->depth); - ad[1] = MAX2(a->z, a->z + a->depth - 1); - - bx[0] = MIN2(b->x, b->x + b->width); - bx[1] = MAX2(b->x, b->x + b->width - 1); - by[0] = MIN2(b->y, b->y + b->height); - by[1] = MAX2(b->y, b->y + b->height - 1); - bd[0] = MIN2(b->z, b->z + b->depth); - bd[1] = MAX2(b->z, b->z + b->depth - 1); - - return ax[1] >= bx[0] && bx[1] >= ax[0] && - ay[1] >= by[0] && by[1] >= ay[0] && - ad[1] >= bd[0] && bd[1] >= ad[0]; -} - -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); -} - -static inline void -u_box_minify_3d(struct pipe_box *dst, - const struct pipe_box *src, unsigned l) -{ - dst->x = src->x >> l; - dst->y = src->y >> l; - dst->z = src->z >> l; - dst->width = MAX2(src->width >> l, 1); - dst->height = MAX2(src->height >> l, 1); - dst->depth = MAX2(src->depth >> l, 1); -} - -/* Converts a box specified in pixels to an equivalent box specified - * in blocks, where the boxes represent a region-of-interest of an image with - * the given format. This is trivial (a copy) for uncompressed formats. - */ -static inline void -u_box_pixels_to_blocks(struct pipe_box *blocks, - const struct pipe_box *pixels, enum pipe_format format) -{ - u_box_3d( - pixels->x / util_format_get_blockwidth(format), - pixels->y / util_format_get_blockheight(format), - pixels->z, - DIV_ROUND_UP(pixels->width, util_format_get_blockwidth(format)), - DIV_ROUND_UP(pixels->height, util_format_get_blockheight(format)), - pixels->depth, - blocks); -} - -#endif diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h index 7e855e498db..48af214e553 100644 --- a/src/gallium/auxiliary/util/u_inlines.h +++ b/src/gallium/auxiliary/util/u_inlines.h @@ -39,7 +39,7 @@ #include "util/u_debug_describe.h" #include "util/u_debug_refcnt.h" #include "util/u_atomic.h" -#include "util/u_box.h" +#include "util/box.h" #include "util/u_math.h" diff --git a/src/gallium/auxiliary/util/u_surface_test.cpp b/src/gallium/auxiliary/util/u_surface_test.cpp index d647e7fbad9..e0a22315675 100644 --- a/src/gallium/auxiliary/util/u_surface_test.cpp +++ b/src/gallium/auxiliary/util/u_surface_test.cpp @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: MIT */ -#include "u_box.h" +#include "util/box.h" #include "u_surface.h" #include diff --git a/src/gallium/auxiliary/util/u_transfer_helper.c b/src/gallium/auxiliary/util/u_transfer_helper.c index 9d5b7c4b1df..db580e6f513 100644 --- a/src/gallium/auxiliary/util/u_transfer_helper.c +++ b/src/gallium/auxiliary/util/u_transfer_helper.c @@ -23,7 +23,7 @@ #include "pipe/p_screen.h" -#include "util/u_box.h" +#include "util/box.h" #include "util/format/u_format.h" #include "util/format/u_format_zs.h" #include "util/u_inlines.h" diff --git a/src/gallium/drivers/lima/lima_util.c b/src/gallium/drivers/lima/lima_util.c index c88d8393de2..1587ac18f5c 100644 --- a/src/gallium/drivers/lima/lima_util.c +++ b/src/gallium/drivers/lima/lima_util.c @@ -29,7 +29,8 @@ #include "util/u_debug.h" #include "util/u_memory.h" -#include "util/u_box.h" +#include "util/box.h" +#include "pipe/p_state.h" #include "lima_util.h" #include "lima_parser.h" diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c index cf72f9ff727..7ff89303f20 100644 --- a/src/gallium/drivers/r300/r300_transfer.c +++ b/src/gallium/drivers/r300/r300_transfer.c @@ -10,7 +10,7 @@ #include "util/u_memory.h" #include "util/format/u_format.h" -#include "util/u_box.h" +#include "util/box.h" struct r300_transfer { /* Parent class */ diff --git a/src/gallium/drivers/virgl/virgl_transfer_queue.c b/src/gallium/drivers/virgl/virgl_transfer_queue.c index da8255377a8..0adfa07aa90 100644 --- a/src/gallium/drivers/virgl/virgl_transfer_queue.c +++ b/src/gallium/drivers/virgl/virgl_transfer_queue.c @@ -21,7 +21,7 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "util/u_box.h" +#include "util/box.h" #include "util/u_inlines.h" #include "virtio-gpu/virgl_protocol.h" diff --git a/src/gallium/frontends/dri/drisw.c b/src/gallium/frontends/dri/drisw.c index 7c2aae06213..509231a57bd 100644 --- a/src/gallium/frontends/dri/drisw.c +++ b/src/gallium/frontends/dri/drisw.c @@ -31,7 +31,7 @@ #include "util/format/u_format.h" #include "util/u_memory.h" #include "util/u_inlines.h" -#include "util/u_box.h" +#include "util/box.h" #include "pipe/p_context.h" #include "pipe-loader/pipe_loader.h" #include "frontend/drisw_api.h" diff --git a/src/gallium/frontends/dri/kopper.c b/src/gallium/frontends/dri/kopper.c index 3189ccad00a..2ec55b7897c 100644 --- a/src/gallium/frontends/dri/kopper.c +++ b/src/gallium/frontends/dri/kopper.c @@ -26,7 +26,7 @@ #include "util/format/u_format.h" #include "util/u_memory.h" #include "util/u_inlines.h" -#include "util/u_box.h" +#include "util/box.h" #include "util/log.h" #include "pipe/p_context.h" #include "pipe-loader/pipe_loader.h" diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index c02b6745a5e..9a9e187f122 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -36,7 +36,7 @@ #include "util/format/u_format.h" #include "util/u_surface.h" #include "util/u_sampler.h" -#include "util/u_box.h" +#include "util/box.h" #include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" diff --git a/src/gallium/frontends/nine/buffer9.c b/src/gallium/frontends/nine/buffer9.c index 94d40e89d9e..965f29dbb38 100644 --- a/src/gallium/frontends/nine/buffer9.c +++ b/src/gallium/frontends/nine/buffer9.c @@ -16,7 +16,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "util/format/u_formats.h" -#include "util/u_box.h" +#include "util/box.h" #include "util/u_inlines.h" #define DBG_CHANNEL (DBG_INDEXBUFFER|DBG_VERTEXBUFFER) diff --git a/src/gallium/frontends/nine/buffer9.h b/src/gallium/frontends/nine/buffer9.h index a0ebdb7d73b..a78355019aa 100644 --- a/src/gallium/frontends/nine/buffer9.h +++ b/src/gallium/frontends/nine/buffer9.h @@ -15,7 +15,7 @@ #include "pipe/p_defines.h" #include "pipe/p_state.h" #include "util/list.h" -#include "util/u_box.h" +#include "util/box.h" #include "util/u_upload_mgr.h" struct pipe_screen; diff --git a/src/gallium/frontends/nine/indexbuffer9.c b/src/gallium/frontends/nine/indexbuffer9.c index bb7744f8026..e4c50052b04 100644 --- a/src/gallium/frontends/nine/indexbuffer9.c +++ b/src/gallium/frontends/nine/indexbuffer9.c @@ -14,7 +14,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "util/format/u_formats.h" -#include "util/u_box.h" +#include "util/box.h" #define DBG_CHANNEL DBG_INDEXBUFFER diff --git a/src/gallium/frontends/nine/nine_ff.c b/src/gallium/frontends/nine/nine_ff.c index 735406f468c..bd6231eaab3 100644 --- a/src/gallium/frontends/nine/nine_ff.c +++ b/src/gallium/frontends/nine/nine_ff.c @@ -19,7 +19,7 @@ #include "tgsi/tgsi_ureg.h" #include "tgsi/tgsi_dump.h" #include "util/bitscan.h" -#include "util/u_box.h" +#include "util/box.h" #include "util/u_hash_table.h" #include "util/u_upload_mgr.h" diff --git a/src/gallium/frontends/nine/nine_state.c b/src/gallium/frontends/nine/nine_state.c index 4acb9ee3010..3aaff661eb3 100644 --- a/src/gallium/frontends/nine/nine_state.c +++ b/src/gallium/frontends/nine/nine_state.c @@ -25,7 +25,7 @@ #include "util/u_atomic.h" #include "util/u_upload_mgr.h" #include "util/u_math.h" -#include "util/u_box.h" +#include "util/box.h" #include "util/u_simple_shaders.h" #include "util/u_gen_mipmap.h" diff --git a/src/gallium/frontends/nine/vertexbuffer9.c b/src/gallium/frontends/nine/vertexbuffer9.c index b600bd9fc1c..036fce0d38d 100644 --- a/src/gallium/frontends/nine/vertexbuffer9.c +++ b/src/gallium/frontends/nine/vertexbuffer9.c @@ -13,7 +13,7 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "util/format/u_formats.h" -#include "util/u_box.h" +#include "util/box.h" #define DBG_CHANNEL DBG_VERTEXBUFFER diff --git a/src/gallium/frontends/osmesa/osmesa.c b/src/gallium/frontends/osmesa/osmesa.c index 5bf4c5baab9..a25bd800fdc 100644 --- a/src/gallium/frontends/osmesa/osmesa.c +++ b/src/gallium/frontends/osmesa/osmesa.c @@ -70,7 +70,7 @@ #include "pipe/p_state.h" #include "util/u_atomic.h" -#include "util/u_box.h" +#include "util/box.h" #include "util/u_debug.h" #include "util/format/u_format.h" #include "util/u_inlines.h" diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index c20550e8c3b..7e4a57d3c27 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -49,6 +49,7 @@ #include "util/compiler.h" #include "p_defines.h" #include "util/format/u_formats.h" +#include "util/box.h" #ifdef __cplusplus @@ -547,23 +548,6 @@ struct pipe_image_view }; -/** - * Subregion of 1D/2D/3D image resource. - */ -struct pipe_box -{ - /* Only "x" and "width" are used to represent buffer ranges. - * The maximum representable texture size is ANY x ANY x 16K. - */ - int32_t x; - int32_t width; - int32_t y; - int32_t height; - int16_t z; - int16_t depth; -}; - - /** * A memory object/resource such as a vertex buffer or texture. */ diff --git a/src/mesa/state_tracker/st_cb_copyimage.c b/src/mesa/state_tracker/st_cb_copyimage.c index f3ab37fcbdc..bd973b521a8 100644 --- a/src/mesa/state_tracker/st_cb_copyimage.c +++ b/src/mesa/state_tracker/st_cb_copyimage.c @@ -29,7 +29,7 @@ #include "state_tracker/st_texture.h" #include "state_tracker/st_util.h" -#include "util/u_box.h" +#include "util/box.h" #include "util/format/u_format.h" #include "util/u_inlines.h" diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 406f12e1d6a..907efa3acf6 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -80,7 +80,7 @@ #include "util/u_surface.h" #include "util/u_sampler.h" #include "util/u_math.h" -#include "util/u_box.h" +#include "util/box.h" #include "util/u_memory.h" #include "util/u_simple_shaders.h" #include "cso_cache/cso_context.h" diff --git a/src/util/box.h b/src/util/box.h new file mode 100644 index 00000000000..c073101118d --- /dev/null +++ b/src/util/box.h @@ -0,0 +1,359 @@ +#ifndef UTIL_BOX_H +#define UTIL_BOX_H + +#include "util/u_math.h" +#include "util/format/u_format.h" + +/** + * Subregion of 1D/2D/3D image resource. + */ +struct pipe_box +{ + /* Only "x" and "width" are used to represent buffer ranges. + * The maximum representable texture size is ANY x ANY x 16K. + */ + int32_t x; + int32_t width; + int32_t y; + int32_t height; + int16_t z; + int16_t depth; +}; + +static inline void +u_box_1d(unsigned x, unsigned w, struct pipe_box *box) +{ + box->x = x; + box->y = 0; + box->z = 0; + box->width = w; + box->height = 1; + box->depth = 1; +} + +static inline void +u_box_2d(unsigned x,unsigned y, unsigned w, unsigned h, struct pipe_box *box) +{ + box->x = x; + box->y = y; + box->z = 0; + box->width = w; + box->height = h; + box->depth = 1; +} + +static inline void +u_box_origin_2d(unsigned w, unsigned h, struct pipe_box *box) +{ + box->x = 0; + box->y = 0; + box->z = 0; + box->width = w; + box->height = h; + box->depth = 1; +} + +static inline void +u_box_2d_zslice(unsigned x, unsigned y, unsigned z, + unsigned w, unsigned h, struct pipe_box *box) +{ + box->x = x; + box->y = y; + box->z = z; + box->width = w; + box->height = h; + box->depth = 1; +} + +static inline void +u_box_3d(unsigned x, unsigned y, unsigned z, + unsigned w, unsigned h, unsigned d, + struct pipe_box *box) +{ + box->x = x; + box->y = y; + box->z = z; + box->width = w; + box->height = h; + 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. Supports empty width */ +static inline void +u_box_union_1d(struct pipe_box *dst, + const struct pipe_box *a, const struct pipe_box *b) +{ + int x, width; + + if (a->width == 0) { + x = b->x; + width = b->width; + } else if (b->width == 0) { + x = a->x; + width = a->width; + } else { + x = MIN2(a->x, b->x); + width = MAX2(a->x + a->width, b->x + b->width) - x; + } + + dst->x = x; + dst->width = width; +} + +/* Aliasing of @dst permitted. */ +static inline void +u_box_intersect_1d(struct pipe_box *dst, + const struct pipe_box *a, const struct pipe_box *b) +{ + int x; + + x = MAX2(a->x, b->x); + + dst->width = MIN2(a->x + a->width, b->x + b->width) - x; + dst->x = x; + if (dst->width <= 0) { + dst->x = 0; + dst->width = 0; + } +} + +/* 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) +{ + int x, y; + + x = MIN2(a->x, b->x); + y = MIN2(a->y, b->y); + + dst->width = MAX2(a->x + a->width, b->x + b->width) - x; + dst->height = MAX2(a->y + a->height, b->y + b->height) - y; + dst->x = x; + dst->y = 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) +{ + int x, y, z; + + x = MIN2(a->x, b->x); + y = MIN2(a->y, b->y); + z = MIN2(a->z, b->z); + + dst->width = MAX2(a->x + a->width, b->x + b->width) - x; + dst->height = MAX2(a->y + a->height, b->y + b->height) - y; + dst->depth = MAX2(a->z + a->depth, b->z + b->depth) - z; + dst->x = x; + dst->y = y; + dst->z = z; +} + +static inline bool +u_box_test_intersection_1d(const struct pipe_box *a, + const struct pipe_box *b) +{ + int ax[2], bx[2]; + + ax[0] = MIN2(a->x, a->x + a->width); + ax[1] = MAX2(a->x, a->x + a->width - 1); + + bx[0] = MIN2(b->x, b->x + b->width); + bx[1] = MAX2(b->x, b->x + b->width - 1); + + return ax[1] >= bx[0] && bx[1] >= ax[0]; +} + +static inline bool +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 bool +u_box_test_intersection_3d(const struct pipe_box *a, + const struct pipe_box *b) +{ + int ax[2], ay[2], ad[2], bx[2], by[2], bd[2]; + + ax[0] = MIN2(a->x, a->x + a->width); + ax[1] = MAX2(a->x, a->x + a->width - 1); + ay[0] = MIN2(a->y, a->y + a->height); + ay[1] = MAX2(a->y, a->y + a->height - 1); + ad[0] = MIN2(a->z, a->z + a->depth); + ad[1] = MAX2(a->z, a->z + a->depth - 1); + + bx[0] = MIN2(b->x, b->x + b->width); + bx[1] = MAX2(b->x, b->x + b->width - 1); + by[0] = MIN2(b->y, b->y + b->height); + by[1] = MAX2(b->y, b->y + b->height - 1); + bd[0] = MIN2(b->z, b->z + b->depth); + bd[1] = MAX2(b->z, b->z + b->depth - 1); + + return ax[1] >= bx[0] && bx[1] >= ax[0] && + ay[1] >= by[0] && by[1] >= ay[0] && + ad[1] >= bd[0] && bd[1] >= ad[0]; +} + +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); +} + +static inline void +u_box_minify_3d(struct pipe_box *dst, + const struct pipe_box *src, unsigned l) +{ + dst->x = src->x >> l; + dst->y = src->y >> l; + dst->z = src->z >> l; + dst->width = MAX2(src->width >> l, 1); + dst->height = MAX2(src->height >> l, 1); + dst->depth = MAX2(src->depth >> l, 1); +} + +/* Converts a box specified in pixels to an equivalent box specified + * in blocks, where the boxes represent a region-of-interest of an image with + * the given format. This is trivial (a copy) for uncompressed formats. + */ +static inline void +u_box_pixels_to_blocks(struct pipe_box *blocks, + const struct pipe_box *pixels, enum pipe_format format) +{ + u_box_3d( + pixels->x / util_format_get_blockwidth(format), + pixels->y / util_format_get_blockheight(format), + pixels->z, + DIV_ROUND_UP(pixels->width, util_format_get_blockwidth(format)), + DIV_ROUND_UP(pixels->height, util_format_get_blockheight(format)), + pixels->depth, + blocks); +} + +static inline bool +util_is_box_sint16(const struct pipe_box *box) +{ + return util_is_sint16(box->x) && util_is_sint16(box->y) && + util_is_sint16(box->z) && util_is_sint16(box->width) && + util_is_sint16(box->height) && util_is_sint16(box->depth) && + util_is_sint16(box->x + box->width) && + util_is_sint16(box->y + box->height) && + util_is_sint16(box->z + box->depth); +} + +static inline bool +util_is_box_out_of_bounds(const struct pipe_box *src_box, unsigned coord_mask, + unsigned width, unsigned height, unsigned mip_level) +{ + int src_width = u_minify(width, mip_level); + int src_height = u_minify(height, mip_level); + struct pipe_box box = *src_box; + + /* Eliminate negative width/height/depth. */ + if (box.width < 0) { + box.x += box.width; + box.width *= -1; + } + if (box.height < 0) { + box.y += box.height; + box.height *= -1; + } + + bool x_in_bounds = box.x >= 0 && box.x < src_width && + box.x + box.width > 0 && box.x + box.width <= src_width; + bool y_in_bounds = box.y >= 0 && box.y < src_height && + box.y + box.height > 0 && box.y + box.height <= src_height; + + /* Return if the box is not in bounds. */ + if (coord_mask & BITFIELD_BIT(0) && !x_in_bounds) + return true; + if (coord_mask & BITFIELD_BIT(1) && !y_in_bounds) + return true; + + return false; +} + +#endif diff --git a/src/util/meson.build b/src/util/meson.build index 1370213ad45..9f40c44c4e3 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -39,6 +39,7 @@ files_mesa_util = files( 'blend.h', 'blob.c', 'blob.h', + 'box.h', 'build_id.c', 'build_id.h', 'cnd_monotonic.h', diff --git a/src/util/u_math.h b/src/util/u_math.h index 7afe136278f..620e3ec7d21 100644 --- a/src/util/u_math.h +++ b/src/util/u_math.h @@ -819,6 +819,12 @@ util_is_aligned(uintmax_t n, uintmax_t a) return (n & (a - 1)) == 0; } +static inline bool +util_is_sint16(int x) +{ + return x >= INT16_MIN && x <= INT16_MAX; +} + #ifdef __cplusplus } #endif -- cgit v1.2.3