From: Emma Anholt Date: Thu, 17 Jun 2021 16:33:24 +0000 (-0700) Subject: gallium/util: Introduce a helper for finding whole-resource blits. X-Git-Tag: upstream/21.2.3~1583 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=447b6f60a6902e07ca034e0ebf667e76cde93ec6;p=platform%2Fupstream%2Fmesa.git 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 Part-of: --- diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h index 958b117..cd6e935 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) {