Mesa (main): venus: add VN_CS_ENCODER_STORAGE_SHMEM_POOL for VkCommandBuffer

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Dec 15 19:12:29 UTC 2021


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

Author: Chia-I Wu <olvaffe at gmail.com>
Date:   Wed Dec  8 15:55:12 2021 -0800

venus: add VN_CS_ENCODER_STORAGE_SHMEM_POOL for VkCommandBuffer

It suballocates from a shmem pool owned by vn_instance.  The goals are
to speed up shmem allocations for VkCommandBuffer and to reduce the
number of BOs.  Both are crucial when shmems are HOST3D BOs, because
they require roundtrips to the renderer to allocate and they take up KVM
memslots.

Signed-off-by: Chia-I Wu <olvaffe at gmail.com>
Reviewed-by: Ryan Neph <ryanneph at google.com>
Reviewed-by: Yiwei Zhang <zzyiwei at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14179>

---

 src/virtio/vulkan/vn_command_buffer.c |  2 +-
 src/virtio/vulkan/vn_cs.c             | 49 +++++++++++++++++++++++++++++------
 src/virtio/vulkan/vn_cs.h             |  2 ++
 src/virtio/vulkan/vn_instance.c       |  8 ++++++
 src/virtio/vulkan/vn_instance.h       | 21 +++++++++++++++
 5 files changed, 73 insertions(+), 9 deletions(-)

diff --git a/src/virtio/vulkan/vn_command_buffer.c b/src/virtio/vulkan/vn_command_buffer.c
index 7909795384d..5f90343e831 100644
--- a/src/virtio/vulkan/vn_command_buffer.c
+++ b/src/virtio/vulkan/vn_command_buffer.c
@@ -561,7 +561,7 @@ vn_AllocateCommandBuffers(VkDevice device,
 
       cmd->state = VN_COMMAND_BUFFER_STATE_INITIAL;
       vn_cs_encoder_init(&cmd->cs, dev->instance,
-                         VN_CS_ENCODER_STORAGE_SHMEM_ARRAY, 16 * 1024);
+                         VN_CS_ENCODER_STORAGE_SHMEM_POOL, 16 * 1024);
 
       VkCommandBuffer cmd_handle = vn_command_buffer_to_handle(cmd);
       pCommandBuffers[i] = cmd_handle;
diff --git a/src/virtio/vulkan/vn_cs.c b/src/virtio/vulkan/vn_cs.c
index 9dc5c71c50c..66e93aa74a1 100644
--- a/src/virtio/vulkan/vn_cs.c
+++ b/src/virtio/vulkan/vn_cs.c
@@ -70,6 +70,23 @@ vn_cs_encoder_commit_buffer(struct vn_cs_encoder *enc)
 static void
 vn_cs_encoder_gc_buffers(struct vn_cs_encoder *enc)
 {
+   /* when the shmem pool is used, no need to cache the shmem in cs */
+   if (enc->storage_type == VN_CS_ENCODER_STORAGE_SHMEM_POOL) {
+      for (uint32_t i = 0; i < enc->buffer_count; i++) {
+         vn_renderer_shmem_unref(enc->instance->renderer,
+                                 enc->buffers[i].shmem);
+      }
+
+      enc->buffer_count = 0;
+      enc->total_committed_size = 0;
+      enc->current_buffer_size = 0;
+
+      enc->cur = NULL;
+      enc->end = NULL;
+
+      return;
+   }
+
    /* free all but the current buffer */
    assert(enc->buffer_count);
    struct vn_cs_encoder_buffer *cur_buf =
@@ -180,22 +197,37 @@ vn_cs_encoder_reserve_internal(struct vn_cs_encoder *enc, size_t size)
    if (likely(enc->buffer_count)) {
       vn_cs_encoder_commit_buffer(enc);
 
-      /* TODO better strategy to grow buffer size */
-      const struct vn_cs_encoder_buffer *cur_buf =
-         &enc->buffers[enc->buffer_count - 1];
-      if (cur_buf->offset)
-         buf_size = next_buffer_size(0, enc->current_buffer_size, size);
+      if (enc->storage_type == VN_CS_ENCODER_STORAGE_SHMEM_ARRAY) {
+         /* if the current buffer is reused from the last vn_cs_encoder_reset
+          * (i.e., offset != 0), do not double the size
+          *
+          * TODO better strategy to grow buffer size
+          */
+         const struct vn_cs_encoder_buffer *cur_buf =
+            &enc->buffers[enc->buffer_count - 1];
+         if (cur_buf->offset)
+            buf_size = next_buffer_size(0, enc->current_buffer_size, size);
+      }
    }
 
    if (!buf_size) {
+      /* double the size */
       buf_size = next_buffer_size(enc->current_buffer_size,
                                   enc->min_buffer_size, size);
       if (!buf_size)
          return false;
    }
 
-   struct vn_renderer_shmem *shmem =
-      vn_renderer_shmem_create(enc->instance->renderer, buf_size);
+   struct vn_renderer_shmem *shmem;
+   size_t buf_offset;
+   if (enc->storage_type == VN_CS_ENCODER_STORAGE_SHMEM_ARRAY) {
+      shmem = vn_renderer_shmem_create(enc->instance->renderer, buf_size);
+      buf_offset = 0;
+   } else {
+      assert(enc->storage_type == VN_CS_ENCODER_STORAGE_SHMEM_POOL);
+      shmem =
+         vn_instance_cs_shmem_alloc(enc->instance, buf_size, &buf_offset);
+   }
    if (!shmem)
       return false;
 
@@ -206,7 +238,8 @@ vn_cs_encoder_reserve_internal(struct vn_cs_encoder *enc, size_t size)
       return false;
    }
 
-   vn_cs_encoder_add_buffer(enc, shmem, 0, shmem->mmap_ptr, buf_size);
+   vn_cs_encoder_add_buffer(enc, shmem, buf_offset,
+                            shmem->mmap_ptr + buf_offset, buf_size);
    enc->current_buffer_size = buf_size;
    enc->current_buffer_roundtrip = roundtrip;
 
diff --git a/src/virtio/vulkan/vn_cs.h b/src/virtio/vulkan/vn_cs.h
index 3bd8c05f978..989b0f5d433 100644
--- a/src/virtio/vulkan/vn_cs.h
+++ b/src/virtio/vulkan/vn_cs.h
@@ -40,6 +40,8 @@ enum vn_cs_encoder_storage_type {
    VN_CS_ENCODER_STORAGE_POINTER,
    /* an array of dynamically allocated shmems */
    VN_CS_ENCODER_STORAGE_SHMEM_ARRAY,
+   /* same as above, but shmems are suballocated from a pool */
+   VN_CS_ENCODER_STORAGE_SHMEM_POOL,
 };
 
 struct vn_cs_encoder_buffer {
diff --git a/src/virtio/vulkan/vn_instance.c b/src/virtio/vulkan/vn_instance.c
index 96ce612c2eb..bf27631cdde 100644
--- a/src/virtio/vulkan/vn_instance.c
+++ b/src/virtio/vulkan/vn_instance.c
@@ -711,6 +711,7 @@ vn_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
    }
 
    mtx_init(&instance->physical_device.mutex, mtx_plain);
+   mtx_init(&instance->cs_shmem.mutex, mtx_plain);
 
    if (!vn_icd_supports_api_version(
           instance->base.base.app_info.api_version)) {
@@ -742,6 +743,9 @@ vn_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
    if (result != VK_SUCCESS)
       goto fail;
 
+   vn_renderer_shmem_pool_init(instance->renderer, &instance->cs_shmem.pool,
+                               8u << 20);
+
    VkInstanceCreateInfo local_create_info = *pCreateInfo;
    local_create_info.ppEnabledExtensionNames = NULL;
    local_create_info.enabledExtensionCount = 0;
@@ -804,6 +808,7 @@ fail:
       vn_renderer_destroy(instance->renderer, alloc);
 
    mtx_destroy(&instance->physical_device.mutex);
+   mtx_destroy(&instance->cs_shmem.mutex);
 
    vn_instance_base_fini(&instance->base);
    vk_free(alloc, instance);
@@ -832,6 +837,9 @@ vn_DestroyInstance(VkInstance _instance,
 
    vn_call_vkDestroyInstance(instance, _instance, NULL);
 
+   vn_renderer_shmem_pool_fini(instance->renderer, &instance->cs_shmem.pool);
+   mtx_destroy(&instance->cs_shmem.mutex);
+
    uint32_t destroy_ring_data[4];
    struct vn_cs_encoder local_enc = VN_CS_ENCODER_INITIALIZER_LOCAL(
       destroy_ring_data, sizeof(destroy_ring_data));
diff --git a/src/virtio/vulkan/vn_instance.h b/src/virtio/vulkan/vn_instance.h
index 800554961b9..a0cbc98d608 100644
--- a/src/virtio/vulkan/vn_instance.h
+++ b/src/virtio/vulkan/vn_instance.h
@@ -70,6 +70,12 @@ struct vn_instance {
    uint32_t renderer_api_version;
    uint32_t renderer_version;
 
+   /* for VN_CS_ENCODER_STORAGE_SHMEM_POOL */
+   struct {
+      mtx_t mutex;
+      struct vn_renderer_shmem_pool pool;
+   } cs_shmem;
+
    struct {
       mtx_t mutex;
       bool initialized;
@@ -152,4 +158,19 @@ vn_instance_free_command_reply(struct vn_instance *instance,
    vn_renderer_shmem_unref(instance->renderer, submit->reply_shmem);
 }
 
+static inline struct vn_renderer_shmem *
+vn_instance_cs_shmem_alloc(struct vn_instance *instance,
+                           size_t size,
+                           size_t *out_offset)
+{
+   struct vn_renderer_shmem *shmem;
+
+   mtx_lock(&instance->cs_shmem.mutex);
+   shmem = vn_renderer_shmem_pool_alloc(
+      instance->renderer, &instance->cs_shmem.pool, size, out_offset);
+   mtx_unlock(&instance->cs_shmem.mutex);
+
+   return shmem;
+}
+
 #endif /* VN_INSTANCE_H */



More information about the mesa-commit mailing list