Mesa (master): zink: add a pipe_context::clear_texture hook

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jan 15 16:46:10 UTC 2021


Module: Mesa
Branch: master
Commit: 622f8f6ed57bb32cb6b1014e4f8c7be2a58a5bd3
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=622f8f6ed57bb32cb6b1014e4f8c7be2a58a5bd3

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Thu Aug 13 17:23:51 2020 -0400

zink: add a pipe_context::clear_texture hook

there's a lot going on here, but the gist of it is:
* if we're not in a renderpass, use the no_rp clear helpers
* if we're in a renderpass, use our lord and savior u_blitter with a temporary
  surface that we create just for the blit

Reviewed-by: Adam Jackson <ajax at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8512>

---

 src/gallium/drivers/zink/zink_clear.c   | 73 ++++++++++++++++++++++++++++++++-
 src/gallium/drivers/zink/zink_context.c |  2 +
 src/gallium/drivers/zink/zink_context.h |  6 +++
 3 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/zink/zink_clear.c b/src/gallium/drivers/zink/zink_clear.c
index ad85a7079ee..daa60558e00 100644
--- a/src/gallium/drivers/zink/zink_clear.c
+++ b/src/gallium/drivers/zink/zink_clear.c
@@ -23,10 +23,15 @@
 
 #include "zink_context.h"
 #include "zink_resource.h"
+#include "zink_screen.h"
+
+#include "util/u_blitter.h"
 #include "util/format/u_format.h"
-#include "util/u_framebuffer.h"
 #include "util/format_srgb.h"
+#include "util/u_framebuffer.h"
+#include "util/u_inlines.h"
 #include "util/u_rect.h"
+#include "util/u_surface.h"
 
 static inline bool
 check_3d_layers(struct pipe_surface *psurf)
@@ -230,3 +235,69 @@ zink_clear(struct pipe_context *pctx,
                      fb->zsbuf->u.tex.last_layer - fb->zsbuf->u.tex.first_layer + 1);
    }
 }
+
+static struct pipe_surface *
+create_clear_surface(struct pipe_context *pctx, struct pipe_resource *pres, unsigned level, const struct pipe_box *box)
+{
+   struct pipe_surface tmpl = {{0}};
+
+   tmpl.format = pres->format;
+   tmpl.u.tex.first_layer = box->z;
+   tmpl.u.tex.last_layer = box->z + box->depth - 1;
+   tmpl.u.tex.level = level;
+   return pctx->create_surface(pctx, pres, &tmpl);
+}
+
+void
+zink_clear_texture(struct pipe_context *pctx,
+                   struct pipe_resource *pres,
+                   unsigned level,
+                   const struct pipe_box *box,
+                   const void *data)
+{
+   struct zink_context *ctx = zink_context(pctx);
+   struct zink_resource *res = zink_resource(pres);
+   struct pipe_screen *pscreen = pctx->screen;
+   struct u_rect region = {box->x, box->x + box->width, box->y, box->y + box->height};
+   bool needs_rp = clear_needs_rp(pres->width0, pres->height0, &region) || ctx->render_condition_active;
+   struct zink_batch *batch = zink_curr_batch(ctx);
+   struct pipe_surface *surf = NULL;
+
+   if (res->aspect & VK_IMAGE_ASPECT_COLOR_BIT) {
+      union pipe_color_union color;
+
+      util_format_unpack_rgba(pres->format, color.ui, data, 1);
+
+      if (pscreen->is_format_supported(pscreen, pres->format, pres->target, 0, 0,
+                                      PIPE_BIND_RENDER_TARGET) && !needs_rp && !batch->in_rp) {
+         clear_color_no_rp(batch, res, &color, level, box->z, box->depth);
+      } else {
+         surf = create_clear_surface(pctx, pres, level, box);
+         zink_blit_begin(ctx, ZINK_BLIT_SAVE_FB | ZINK_BLIT_SAVE_FS);
+         util_clear_render_target(pctx, surf, &color, box->x, box->y, box->width, box->height);
+      }
+   } else {
+      float depth = 0.0;
+      uint8_t stencil = 0;
+
+      if (res->aspect & VK_IMAGE_ASPECT_DEPTH_BIT)
+         util_format_unpack_z_float(pres->format, &depth, data, 1);
+
+      if (res->aspect & VK_IMAGE_ASPECT_STENCIL_BIT)
+         util_format_unpack_s_8uint(pres->format, &stencil, data, 1);
+
+      if (!needs_rp && !batch->in_rp)
+         clear_zs_no_rp(batch, res, res->aspect, depth, stencil, level, box->z, box->depth);
+      else {
+         unsigned flags = 0;
+         if (res->aspect & VK_IMAGE_ASPECT_DEPTH_BIT)
+            flags |= PIPE_CLEAR_DEPTH;
+         if (res->aspect & VK_IMAGE_ASPECT_STENCIL_BIT)
+            flags |= PIPE_CLEAR_STENCIL;
+         surf = create_clear_surface(pctx, pres, level, box);
+         zink_blit_begin(ctx, ZINK_BLIT_SAVE_FB | ZINK_BLIT_SAVE_FS);
+         util_blitter_clear_depth_stencil(ctx->blitter, surf, flags, depth, stencil, box->x, box->y, box->width, box->height);
+      }
+   }
+   pipe_surface_reference(&surf, NULL);
+}
diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index 340b77b2315..4e938d1c369 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -1293,6 +1293,8 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
    ctx->base.set_sample_mask = zink_set_sample_mask;
 
    ctx->base.clear = zink_clear;
+   ctx->base.clear_texture = zink_clear_texture;
+
    ctx->base.draw_vbo = zink_draw_vbo;
    ctx->base.flush = zink_flush;
 
diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h
index 273b223a955..7b83aa147af 100644
--- a/src/gallium/drivers/zink/zink_context.h
+++ b/src/gallium/drivers/zink/zink_context.h
@@ -210,6 +210,12 @@ zink_clear(struct pipe_context *pctx,
            const struct pipe_scissor_state *scissor_state,
            const union pipe_color_union *pcolor,
            double depth, unsigned stencil);
+void
+zink_clear_texture(struct pipe_context *ctx,
+                   struct pipe_resource *p_res,
+                   unsigned level,
+                   const struct pipe_box *box,
+                   const void *data);
 
 void
 zink_draw_vbo(struct pipe_context *pctx,



More information about the mesa-commit mailing list