Mesa (main): zink: add a pipe_context::clear_buffer hook
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri May 7 17:10:57 UTC 2021
Module: Mesa
Branch: main
Commit: 91bd4fc6139f46fea63e0e22381f5d4ca5d78bdc
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=91bd4fc6139f46fea63e0e22381f5d4ca5d78bdc
Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date: Thu May 6 10:44:21 2021 -0400
zink: add a pipe_context::clear_buffer hook
Reviewed-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10679>
---
src/gallium/drivers/zink/zink_clear.c | 41 +++++++++++++++++++++++++++++++++
src/gallium/drivers/zink/zink_clear.h | 8 ++++++-
src/gallium/drivers/zink/zink_context.c | 1 +
3 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/src/gallium/drivers/zink/zink_clear.c b/src/gallium/drivers/zink/zink_clear.c
index d28aa9f7ab0..96f5aaf7b91 100644
--- a/src/gallium/drivers/zink/zink_clear.c
+++ b/src/gallium/drivers/zink/zink_clear.c
@@ -409,6 +409,47 @@ zink_clear_texture(struct pipe_context *pctx,
pipe_surface_reference(&surf, NULL);
}
+void
+zink_clear_buffer(struct pipe_context *pctx,
+ struct pipe_resource *pres,
+ unsigned offset,
+ unsigned size,
+ const void *clear_value,
+ int clear_value_size)
+{
+ struct zink_context *ctx = zink_context(pctx);
+ struct zink_resource *res = zink_resource(pres);
+
+ if (offset % 4 == 0 && size % 4 == 0 && clear_value_size == sizeof(uint32_t)) {
+ /*
+ - dstOffset is the byte offset into the buffer at which to start filling,
+ and must be a multiple of 4.
+
+ - size is the number of bytes to fill, and must be either a multiple of 4,
+ or VK_WHOLE_SIZE to fill the range from offset to the end of the buffer
+ */
+ struct zink_batch *batch = zink_batch_no_rp(ctx);
+ zink_batch_reference_resource_rw(batch, res, true);
+ util_range_add(&res->base.b, &res->valid_buffer_range, offset, offset + size);
+ vkCmdFillBuffer(batch->state->cmdbuf, res->obj->buffer, offset, size, *(uint32_t*)clear_value);
+ return;
+ }
+ struct pipe_transfer *xfer;
+ uint8_t *map = pipe_buffer_map_range(pctx, pres, offset, size,
+ PIPE_MAP_WRITE | PIPE_MAP_ONCE | PIPE_MAP_DISCARD_RANGE, &xfer);
+ if (!map)
+ return;
+ unsigned rem = size % clear_value_size;
+ uint8_t *ptr = map;
+ for (unsigned i = 0; i < (size - rem) / clear_value_size; i++) {
+ memcpy(ptr, clear_value, clear_value_size);
+ ptr += clear_value_size;
+ }
+ if (rem)
+ memcpy(map + size - rem, clear_value, rem);
+ pipe_buffer_unmap(pctx, xfer);
+}
+
bool
zink_fb_clear_needs_explicit(struct zink_framebuffer_clear *fb_clear)
{
diff --git a/src/gallium/drivers/zink/zink_clear.h b/src/gallium/drivers/zink/zink_clear.h
index b32c03ba6c7..2eb81273cde 100644
--- a/src/gallium/drivers/zink/zink_clear.h
+++ b/src/gallium/drivers/zink/zink_clear.h
@@ -65,7 +65,13 @@ zink_clear_texture(struct pipe_context *ctx,
unsigned level,
const struct pipe_box *box,
const void *data);
-
+void
+zink_clear_buffer(struct pipe_context *pctx,
+ struct pipe_resource *pres,
+ unsigned offset,
+ unsigned size,
+ const void *clear_value,
+ int clear_value_size);
bool
zink_fb_clear_needs_explicit(struct zink_framebuffer_clear *fb_clear);
diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index 3e11ee6ef38..41b0872e4b8 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -2574,6 +2574,7 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
ctx->base.clear = zink_clear;
ctx->base.clear_texture = zink_clear_texture;
+ ctx->base.clear_buffer = zink_clear_buffer;
ctx->base.draw_vbo = zink_draw_vbo;
ctx->base.launch_grid = zink_launch_grid;
More information about the mesa-commit
mailing list