Mesa (master): zink: cache bufferviews

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Mar 16 14:57:42 UTC 2021


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

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Tue Oct 27 10:40:27 2020 -0400

zink: cache bufferviews

we can cache bufferviews just like we do surfaces, so let's do that

Reviewed-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9543>

---

 src/gallium/drivers/zink/zink_batch.c   |  4 +--
 src/gallium/drivers/zink/zink_context.c | 50 ++++++++++++++++++++++-----------
 src/gallium/drivers/zink/zink_context.h | 11 ++++----
 src/gallium/drivers/zink/zink_screen.c  | 14 +++++++++
 src/gallium/drivers/zink/zink_screen.h  |  2 ++
 5 files changed, 57 insertions(+), 24 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c
index b5814888364..4422815c555 100644
--- a/src/gallium/drivers/zink/zink_batch.c
+++ b/src/gallium/drivers/zink/zink_batch.c
@@ -40,7 +40,7 @@ zink_reset_batch(struct zink_context *ctx, struct zink_batch *batch)
       sampler_view->batch_uses &= ~BITFIELD_BIT(batch->batch_id);
       if (sampler_view->base.target == PIPE_BUFFER) {
          struct zink_buffer_view *buffer_view = sampler_view->buffer_view;
-         zink_buffer_view_reference(ctx, &buffer_view, NULL);
+         zink_buffer_view_reference(screen, &buffer_view, NULL);
       } else {
          struct zink_surface *surface = sampler_view->image_view;
          pipe_surface_reference((struct pipe_surface**)&surface, NULL);
@@ -58,7 +58,7 @@ zink_reset_batch(struct zink_context *ctx, struct zink_batch *batch)
    set_foreach(batch->bufferviews, entry) {
       struct zink_buffer_view *buffer_view = (struct zink_buffer_view *)entry->key;
       buffer_view->batch_uses &= ~BITFIELD64_BIT(batch->batch_id);
-      zink_buffer_view_reference(ctx, &buffer_view, NULL);
+      zink_buffer_view_reference(screen, &buffer_view, NULL);
       _mesa_set_remove(batch->bufferviews, entry);
    }
 
diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index 7296694f019..3d8c53da12f 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -557,7 +557,7 @@ static struct zink_buffer_view *
 get_buffer_view(struct zink_context *ctx, struct zink_resource *res, enum pipe_format format, uint32_t offset, uint32_t range)
 {
    struct zink_screen *screen = zink_screen(ctx->base.screen);
-   struct zink_buffer_view *buffer_view;
+   struct zink_buffer_view *buffer_view = NULL;
    VkBufferViewCreateInfo bvci = {};
    bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
    bvci.buffer = res->obj->buffer;
@@ -567,17 +567,28 @@ get_buffer_view(struct zink_context *ctx, struct zink_resource *res, enum pipe_f
    bvci.range = range;
 
    uint32_t hash = hash_bufferview(&bvci);
-   VkBufferView view;
-   if (vkCreateBufferView(screen->dev, &bvci, NULL, &view) != VK_SUCCESS)
-      return NULL;
-   buffer_view = CALLOC_STRUCT(zink_buffer_view);
-   if (!buffer_view) {
-      vkDestroyBufferView(screen->dev, view, NULL);
-      return NULL;
-   }
-   pipe_reference_init(&buffer_view->reference, 1);
-   buffer_view->buffer_view = view;
-   buffer_view->hash = hash;
+   simple_mtx_lock(&screen->bufferview_mtx);
+   struct hash_entry *he = _mesa_hash_table_search_pre_hashed(&screen->bufferview_cache, hash, &bvci);
+   if (he) {
+      buffer_view = he->data;
+      p_atomic_inc(&buffer_view->reference.count);
+   } else {
+      VkBufferView view;
+      if (vkCreateBufferView(screen->dev, &bvci, NULL, &view) != VK_SUCCESS)
+         goto out;
+      buffer_view = CALLOC_STRUCT(zink_buffer_view);
+      if (!buffer_view) {
+         vkDestroyBufferView(screen->dev, view, NULL);
+         goto out;
+      }
+      pipe_reference_init(&buffer_view->reference, 1);
+      buffer_view->bvci = bvci;
+      buffer_view->buffer_view = view;
+      buffer_view->hash = hash;
+      _mesa_hash_table_insert_pre_hashed(&screen->bufferview_cache, hash, &buffer_view->bvci, buffer_view);
+   }
+out:
+   simple_mtx_unlock(&screen->bufferview_mtx);
    return buffer_view;
 }
 
@@ -646,9 +657,14 @@ zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres,
 }
 
 void
-zink_destroy_buffer_view(struct zink_context *ctx, struct zink_buffer_view *buffer_view)
-{
-   vkDestroyBufferView(zink_screen(ctx->base.screen)->dev, buffer_view->buffer_view, NULL);
+zink_destroy_buffer_view(struct zink_screen *screen, struct zink_buffer_view *buffer_view)
+{
+   simple_mtx_lock(&screen->bufferview_mtx);
+   struct hash_entry *he = _mesa_hash_table_search_pre_hashed(&screen->bufferview_cache, buffer_view->hash, &buffer_view->bvci);
+   assert(he);
+   _mesa_hash_table_remove(&screen->bufferview_cache, he);
+   simple_mtx_unlock(&screen->bufferview_mtx);
+   vkDestroyBufferView(screen->dev, buffer_view->buffer_view, NULL);
    FREE(buffer_view);
 }
 
@@ -659,7 +675,7 @@ zink_sampler_view_destroy(struct pipe_context *pctx,
    struct zink_sampler_view *view = zink_sampler_view(pview);
    zink_descriptor_set_refs_clear(&view->desc_set_refs, view);
    if (pview->texture->target == PIPE_BUFFER)
-      zink_buffer_view_reference(zink_context(pctx), &view->buffer_view, NULL);
+      zink_buffer_view_reference(zink_screen(pctx->screen), &view->buffer_view, NULL);
    else {
       struct pipe_surface *psurf = &view->image_view->base;
       pipe_surface_reference(&psurf, NULL);
@@ -883,7 +899,7 @@ unbind_shader_image(struct zink_context *ctx, enum pipe_shader_type stage, unsig
 
    zink_descriptor_set_refs_clear(&image_view->desc_set_refs, image_view);
    if (image_view->base.resource->target == PIPE_BUFFER)
-      zink_buffer_view_reference(ctx, &image_view->buffer_view, NULL);
+      zink_buffer_view_reference(zink_screen(ctx->base.screen), &image_view->buffer_view, NULL);
    else
       pipe_surface_reference((struct pipe_surface**)&image_view->surface, NULL);
    pipe_resource_reference(&image_view->base.resource, NULL);
diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h
index 943fb0d6d29..80b6bd3c208 100644
--- a/src/gallium/drivers/zink/zink_context.h
+++ b/src/gallium/drivers/zink/zink_context.h
@@ -76,6 +76,7 @@ struct zink_sampler_state {
 
 struct zink_buffer_view {
    struct pipe_reference reference;
+   VkBufferViewCreateInfo bvci;
    VkBufferView buffer_view;
    uint32_t hash;
    uint32_t batch_uses;
@@ -342,21 +343,21 @@ zink_copy_image_buffer(struct zink_context *ctx, struct zink_batch *batch, struc
                        unsigned src_level, const struct pipe_box *src_box, enum pipe_map_flags map_flags);
 
 void
-zink_destroy_buffer_view(struct zink_context *ctx, struct zink_buffer_view *buffer_view);
+zink_destroy_buffer_view(struct zink_screen *screen, struct zink_buffer_view *buffer_view);
 
 void
 debug_describe_zink_buffer_view(char *buf, const struct zink_buffer_view *ptr);
 
 static inline void
-zink_buffer_view_reference(struct zink_context *ctx,
-                             struct zink_buffer_view **dst,
-                             struct zink_buffer_view *src)
+zink_buffer_view_reference(struct zink_screen *screen,
+                           struct zink_buffer_view **dst,
+                           struct zink_buffer_view *src)
 {
    struct zink_buffer_view *old_dst = dst ? *dst : NULL;
 
    if (pipe_reference_described(old_dst ? &old_dst->reference : NULL, &src->reference,
                                 (debug_reference_descriptor)debug_describe_zink_buffer_view))
-      zink_destroy_buffer_view(ctx, old_dst);
+      zink_destroy_buffer_view(screen, old_dst);
    if (dst) *dst = src;
 }
 
diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c
index e4fc26e2924..ddd22b96cc1 100644
--- a/src/gallium/drivers/zink/zink_screen.c
+++ b/src/gallium/drivers/zink/zink_screen.c
@@ -89,6 +89,12 @@ equals_ivci(const void *a, const void *b)
    return memcmp(a, b, sizeof(VkImageViewCreateInfo)) == 0;
 }
 
+static bool
+equals_bvci(const void *a, const void *b)
+{
+   return memcmp(a, b, sizeof(VkBufferViewCreateInfo)) == 0;
+}
+
 static VkDeviceSize
 get_video_mem(struct zink_screen *screen)
 {
@@ -858,7 +864,13 @@ zink_destroy_screen(struct pipe_screen *pscreen)
       pipe_surface_reference(&psurf, NULL);
    }
 
+   hash_table_foreach(&screen->bufferview_cache, entry) {
+      struct zink_buffer_view *bv = (struct zink_buffer_view*)entry->data;
+      zink_buffer_view_reference(screen, &bv, NULL);
+   }
+
    simple_mtx_destroy(&screen->surface_mtx);
+   simple_mtx_destroy(&screen->bufferview_mtx);
 
    u_transfer_helper_destroy(pscreen->transfer_helper);
    zink_screen_update_pipeline_cache(screen);
@@ -1387,8 +1399,10 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
    screen->total_mem = get_video_mem(screen);
 
    simple_mtx_init(&screen->surface_mtx, mtx_plain);
+   simple_mtx_init(&screen->bufferview_mtx, mtx_plain);
 
    _mesa_hash_table_init(&screen->surface_cache, screen, NULL, equals_ivci);
+   _mesa_hash_table_init(&screen->bufferview_cache, screen, NULL, equals_bvci);
 
    return screen;
 
diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h
index d791c3545a7..86da45db501 100644
--- a/src/gallium/drivers/zink/zink_screen.h
+++ b/src/gallium/drivers/zink/zink_screen.h
@@ -56,6 +56,8 @@ struct zink_screen {
 
    struct hash_table surface_cache;
    simple_mtx_t surface_mtx;
+   struct hash_table bufferview_cache;
+   simple_mtx_t bufferview_mtx;
 
    struct slab_parent_pool transfer_pool;
    VkPipelineCache pipeline_cache;



More information about the mesa-commit mailing list