Module: Mesa
Branch: main
Commit: 7411264ca6758293349ba8730165eade8b8235b0
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=7411264ca6758293349ba8730165eade8b8235b0

Author: Mike Blumenkrantz <[email protected]>
Date:   Thu Mar  2 12:12:32 2023 -0500

zink: add a dynamic render version of clear_texture hook

this avoids the (sizable) overhead of going through the previous path
with set_frame_buffer state et al, instead just firing off a quick
begin+end rendering with a clear

it's also easily reorderable

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21906>

---

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

diff --git a/src/gallium/drivers/zink/zink_clear.c 
b/src/gallium/drivers/zink/zink_clear.c
index 8d675777cbe..39ac5c4a7ec 100644
--- a/src/gallium/drivers/zink/zink_clear.c
+++ b/src/gallium/drivers/zink/zink_clear.c
@@ -436,6 +436,87 @@ set_clear_fb(struct pipe_context *pctx, struct 
pipe_surface *psurf, struct pipe_
    pctx->set_framebuffer_state(pctx, &fb_state);
 }
 
+void
+zink_clear_texture_dynamic(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);
+
+   bool full_clear = 0 <= box->x && u_minify(pres->width0, level) >= box->x + 
box->width &&
+                     0 <= box->y && u_minify(pres->height0, level) >= box->y + 
box->height &&
+                     0 <= box->z && u_minify(pres->target == PIPE_TEXTURE_3D ? 
pres->depth0 : pres->array_size, level) >= box->z + box->depth;
+
+   struct pipe_surface *surf = create_clear_surface(pctx, pres, level, box);
+
+   VkRenderingAttachmentInfo att = {0};
+   att.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
+   att.imageView = zink_csurface(surf)->image_view;
+   att.imageLayout = res->aspect & VK_IMAGE_ASPECT_COLOR_BIT ? 
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : 
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+   att.loadOp = full_clear ? VK_ATTACHMENT_LOAD_OP_CLEAR : 
VK_ATTACHMENT_LOAD_OP_LOAD;
+   att.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+
+   VkRenderingInfo info = {0};
+   info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
+   info.renderArea.offset.x = box->x;
+   info.renderArea.offset.y = box->y;
+   info.renderArea.extent.width = box->width;
+   info.renderArea.extent.height = box->height;
+   info.layerCount = MAX2(box->depth, 1);
+
+   union pipe_color_union color;
+   float depth = 0.0;
+   uint8_t stencil = 0;
+   if (res->aspect & VK_IMAGE_ASPECT_COLOR_BIT) {
+      util_format_unpack_rgba(pres->format, color.ui, data, 1);
+   } else {
+      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);
+   }
+
+   zink_blit_barriers(ctx, NULL, res, full_clear);
+   VkCommandBuffer cmdbuf = zink_get_cmdbuf(ctx, NULL, res);
+   if (cmdbuf == ctx->batch.state->cmdbuf && ctx->batch.in_rp)
+      zink_batch_no_rp(ctx);
+
+   if (res->aspect & VK_IMAGE_ASPECT_COLOR_BIT) {
+      memcpy(&att.clearValue, &color, sizeof(float) * 4);
+      info.colorAttachmentCount = 1;
+      info.pColorAttachments = &att;
+   } else {
+      att.clearValue.depthStencil.depth = depth;
+      att.clearValue.depthStencil.stencil = stencil;
+      if (res->aspect & VK_IMAGE_ASPECT_DEPTH_BIT)
+         info.pDepthAttachment = &att;
+      if (res->aspect & VK_IMAGE_ASPECT_STENCIL_BIT)
+         info.pStencilAttachment = &att;
+   }
+   VKCTX(CmdBeginRendering)(cmdbuf, &info);
+   if (!full_clear) {
+      VkClearRect rect;
+      rect.rect = info.renderArea;
+      rect.baseArrayLayer = box->z;
+      rect.layerCount = box->depth;
+
+      VkClearAttachment clear_att;
+      clear_att.aspectMask = res->aspect;
+      clear_att.colorAttachment = 0;
+      clear_att.clearValue = att.clearValue;
+
+      VKCTX(CmdClearAttachments)(cmdbuf, 1, &clear_att, 1, &rect);
+   }
+   VKCTX(CmdEndRendering)(cmdbuf);
+   zink_batch_reference_resource_rw(&ctx->batch, res, true);
+   /* this will never destroy the surface */
+   pipe_surface_reference(&surf, NULL);
+}
+
 void
 zink_clear_texture(struct pipe_context *pctx,
                    struct pipe_resource *pres,
diff --git a/src/gallium/drivers/zink/zink_clear.h 
b/src/gallium/drivers/zink/zink_clear.h
index b1f4b18ff01..eb17f15f544 100644
--- a/src/gallium/drivers/zink/zink_clear.h
+++ b/src/gallium/drivers/zink/zink_clear.h
@@ -40,6 +40,12 @@ zink_clear_texture(struct pipe_context *ctx,
                    const struct pipe_box *box,
                    const void *data);
 void
+zink_clear_texture_dynamic(struct pipe_context *ctx,
+                           struct pipe_resource *p_res,
+                           unsigned level,
+                           const struct pipe_box *box,
+                           const void *data);
+void
 zink_clear_buffer(struct pipe_context *pctx,
                   struct pipe_resource *pres,
                   unsigned offset,
diff --git a/src/gallium/drivers/zink/zink_context.c 
b/src/gallium/drivers/zink/zink_context.c
index b59bd107b5c..552b8ef5757 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -5316,7 +5316,7 @@ zink_context_create(struct pipe_screen *pscreen, void 
*priv, unsigned flags)
    ctx->gfx_pipeline_state.sample_mask = UINT32_MAX;
 
    ctx->base.clear = zink_clear;
-   ctx->base.clear_texture = zink_clear_texture;
+   ctx->base.clear_texture = screen->info.have_KHR_dynamic_rendering ? 
zink_clear_texture_dynamic : zink_clear_texture;
    ctx->base.clear_buffer = zink_clear_buffer;
    ctx->base.clear_render_target = zink_clear_render_target;
    ctx->base.clear_depth_stencil = zink_clear_depth_stencil;

Reply via email to