summaryrefslogtreecommitdiff
path: root/src/gallium
diff options
context:
space:
mode:
authorEmma Anholt <emma@anholt.net>2021-06-17 09:33:24 -0700
committerMarge Bot <eric+marge@anholt.net>2021-06-21 20:48:21 +0000
commit447b6f60a6902e07ca034e0ebf667e76cde93ec6 (patch)
tree0cd1fcb9ce1612d40a3e27f151c1f4aa8006f2c0 /src/gallium
parent9ce44dc9bc6bfbd88639e4ebeb16680d35585088 (diff)
gallium/util: Introduce a helper for finding whole-resource blits.
This can be useful for tilers to discard previous rendering to a buffer instead of reloading before drawing all the pixels. Reviewed-by: Rob Clark <robdclark@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11455>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/util/u_inlines.h47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h
index 958b117ddc3..cd6e9351352 100644
--- a/src/gallium/auxiliary/util/u_inlines.h
+++ b/src/gallium/auxiliary/util/u_inlines.h
@@ -34,6 +34,7 @@
#include "pipe/p_state.h"
#include "pipe/p_screen.h"
#include "util/compiler.h"
+#include "util/format/u_format.h"
#include "util/u_debug.h"
#include "util/u_debug_describe.h"
#include "util/u_debug_refcnt.h"
@@ -781,6 +782,52 @@ util_texrange_covers_whole_level(const struct pipe_resource *tex,
depth == util_num_layers(tex, level);
}
+/**
+ * Returns true if the blit will fully initialize all pixels in the resource.
+ */
+static inline bool
+util_blit_covers_whole_resource(const struct pipe_blit_info *info)
+{
+ /* No conditional rendering or scissoring. (We assume that the caller would
+ * have dropped any redundant scissoring)
+ */
+ if (info->scissor_enable || info->window_rectangle_include || info->render_condition_enable || info->alpha_blend)
+ return false;
+
+ const struct pipe_resource *dst = info->dst.resource;
+ /* A single blit can't initialize a miptree. */
+ if (dst->last_level != 0)
+ return false;
+
+ assert(info->dst.level == 0);
+
+ /* Make sure the dst box covers the whole resource. */
+ if (!(util_texrange_covers_whole_level(dst, 0,
+ 0, 0, 0,
+ info->dst.box.width, info->dst.box.height, info->dst.box.depth))) {
+ return false;
+ }
+
+ /* Make sure the mask actually updates all the channels present in the dst format. */
+ if (info->mask & PIPE_MASK_RGBA) {
+ if ((info->mask & PIPE_MASK_RGBA) != PIPE_MASK_RGBA)
+ return false;
+ }
+
+ if (info->mask & PIPE_MASK_ZS) {
+ const struct util_format_description *format_desc = util_format_description(info->dst.format);
+ uint32_t dst_has = 0;
+ if (util_format_has_depth(format_desc))
+ dst_has |= PIPE_MASK_Z;
+ if (util_format_has_stencil(format_desc))
+ dst_has |= PIPE_MASK_S;
+ if (dst_has & ~(info->mask & PIPE_MASK_ZS))
+ return false;
+ }
+
+ return true;
+}
+
static inline bool
util_logicop_reads_dest(enum pipe_logicop op)
{