Mesa (main): venus: add vn_feedback_pool backed by coherent buffer (part 1)

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jun 16 19:06:12 UTC 2022


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

Author: Yiwei Zhang <zzyiwei at chromium.org>
Date:   Thu May 19 06:36:03 2022 +0000

venus: add vn_feedback_pool backed by coherent buffer (part 1)

Implemented:
- vn_feedback_pool_init
- vn_feedback_pool_fini

Signed-off-by: Yiwei Zhang <zzyiwei at chromium.org>
Reviewed-by: Ryan Neph <ryanneph at google.com>
Reviewed-by: Chad Versace <chadversary at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16731>

---

 src/virtio/vulkan/meson.build   |   1 +
 src/virtio/vulkan/vn_feedback.c | 177 ++++++++++++++++++++++++++++++++++++++++
 src/virtio/vulkan/vn_feedback.h |  33 ++++++++
 3 files changed, 211 insertions(+)

diff --git a/src/virtio/vulkan/meson.build b/src/virtio/vulkan/meson.build
index 712a466c1b4..346c4da8d47 100644
--- a/src/virtio/vulkan/meson.build
+++ b/src/virtio/vulkan/meson.build
@@ -56,6 +56,7 @@ libvn_files = files(
   'vn_descriptor_set.c',
   'vn_device.c',
   'vn_device_memory.c',
+  'vn_feedback.c',
   'vn_icd.c',
   'vn_image.c',
   'vn_instance.c',
diff --git a/src/virtio/vulkan/vn_feedback.c b/src/virtio/vulkan/vn_feedback.c
new file mode 100644
index 00000000000..bb7d6927a10
--- /dev/null
+++ b/src/virtio/vulkan/vn_feedback.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2022 Google LLC
+ * SPDX-License-Identifier: MIT
+ */
+
+#include "vn_feedback.h"
+
+#include "vn_device.h"
+#include "vn_physical_device.h"
+
+/* coherent buffer with bound and mapped memory */
+struct vn_feedback_buffer {
+   VkBuffer buffer;
+   VkDeviceMemory memory;
+   void *data;
+
+   struct list_head head;
+};
+
+static uint32_t
+vn_get_memory_type_index(const VkPhysicalDeviceMemoryProperties *mem_props,
+                         uint32_t mem_type_bits,
+                         VkMemoryPropertyFlags required_mem_flags)
+{
+   u_foreach_bit(mem_type_index, mem_type_bits)
+   {
+      assert(mem_type_index < mem_props->memoryTypeCount);
+      if ((mem_props->memoryTypes[mem_type_index].propertyFlags &
+           required_mem_flags) == required_mem_flags)
+         return mem_type_index;
+   }
+
+   return UINT32_MAX;
+}
+
+static VkResult
+vn_feedback_buffer_create(struct vn_device *dev,
+                          uint32_t size,
+                          const VkAllocationCallbacks *alloc,
+                          struct vn_feedback_buffer **out_feedback_buf)
+{
+   const bool exclusive = dev->queue_family_count == 1;
+   const VkPhysicalDeviceMemoryProperties *mem_props =
+      &dev->physical_device->memory_properties.memoryProperties;
+   VkDevice dev_handle = vn_device_to_handle(dev);
+   struct vn_feedback_buffer *feedback_buf;
+   VkResult result;
+
+   feedback_buf = vk_zalloc(alloc, sizeof(*feedback_buf), VN_DEFAULT_ALIGN,
+                            VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   if (!feedback_buf)
+      return VK_ERROR_OUT_OF_HOST_MEMORY;
+
+   /* use concurrent to avoid explicit queue family ownership transfer for
+    * device created with queues from multiple queue families
+    */
+   const VkBufferCreateInfo buf_create_info = {
+      .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
+      .size = size,
+      .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT,
+      .sharingMode =
+         exclusive ? VK_SHARING_MODE_EXCLUSIVE : VK_SHARING_MODE_CONCURRENT,
+      /* below favors the current venus protocol */
+      .queueFamilyIndexCount = exclusive ? 0 : dev->queue_family_count,
+      .pQueueFamilyIndices = exclusive ? NULL : dev->queue_families,
+   };
+   result = vn_CreateBuffer(dev_handle, &buf_create_info, alloc,
+                            &feedback_buf->buffer);
+   if (result != VK_SUCCESS)
+      goto out_free_feedback_buf;
+
+   struct vn_buffer *buf = vn_buffer_from_handle(feedback_buf->buffer);
+   const VkMemoryRequirements *mem_req =
+      &buf->requirements.memory.memoryRequirements;
+   const uint32_t mem_type_index =
+      vn_get_memory_type_index(mem_props, mem_req->memoryTypeBits,
+                               VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
+   if (mem_type_index >= mem_props->memoryTypeCount) {
+      result = VK_ERROR_INITIALIZATION_FAILED;
+      goto out_destroy_buffer;
+   }
+
+   const VkMemoryAllocateInfo mem_alloc_info = {
+      .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+      .allocationSize = mem_req->size,
+      .memoryTypeIndex = mem_type_index,
+   };
+   result = vn_AllocateMemory(dev_handle, &mem_alloc_info, alloc,
+                              &feedback_buf->memory);
+   if (result != VK_SUCCESS)
+      goto out_destroy_buffer;
+
+   const VkBindBufferMemoryInfo bind_info = {
+      .sType = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
+      .buffer = feedback_buf->buffer,
+      .memory = feedback_buf->memory,
+      .memoryOffset = 0,
+   };
+   result = vn_BindBufferMemory2(dev_handle, 1, &bind_info);
+   if (result != VK_SUCCESS)
+      goto out_free_memory;
+
+   result = vn_MapMemory(dev_handle, feedback_buf->memory, 0, VK_WHOLE_SIZE,
+                         0, &feedback_buf->data);
+   if (result != VK_SUCCESS)
+      goto out_free_memory;
+
+   *out_feedback_buf = feedback_buf;
+
+   return VK_SUCCESS;
+
+out_free_memory:
+   vn_FreeMemory(dev_handle, feedback_buf->memory, alloc);
+
+out_destroy_buffer:
+   vn_DestroyBuffer(dev_handle, feedback_buf->buffer, alloc);
+
+out_free_feedback_buf:
+   vk_free(alloc, feedback_buf);
+
+   return result;
+}
+
+static void
+vn_feedback_buffer_destroy(struct vn_device *dev,
+                           struct vn_feedback_buffer *feedback_buf,
+                           const VkAllocationCallbacks *alloc)
+{
+   VkDevice dev_handle = vn_device_to_handle(dev);
+
+   vn_UnmapMemory(dev_handle, feedback_buf->memory);
+   vn_FreeMemory(dev_handle, feedback_buf->memory, alloc);
+   vn_DestroyBuffer(dev_handle, feedback_buf->buffer, alloc);
+   vk_free(alloc, feedback_buf);
+}
+
+static VkResult
+vn_feedback_pool_grow(struct vn_feedback_pool *pool)
+{
+   VN_TRACE_FUNC();
+   struct vn_feedback_buffer *feedback_buf = NULL;
+   VkResult result;
+
+   result = vn_feedback_buffer_create(pool->device, pool->size, pool->alloc,
+                                      &feedback_buf);
+   if (result != VK_SUCCESS)
+      return result;
+
+   pool->used = 0;
+
+   list_add(&feedback_buf->head, &pool->feedback_buffers);
+
+   return VK_SUCCESS;
+}
+
+VkResult
+vn_feedback_pool_init(struct vn_device *dev,
+                      struct vn_feedback_pool *pool,
+                      uint32_t size,
+                      const VkAllocationCallbacks *alloc)
+{
+   pool->device = dev;
+   pool->alloc = alloc;
+   pool->size = size;
+   pool->used = size;
+   list_inithead(&pool->feedback_buffers);
+
+   return vn_feedback_pool_grow(pool);
+}
+
+void
+vn_feedback_pool_fini(struct vn_feedback_pool *pool)
+{
+   list_for_each_entry_safe(struct vn_feedback_buffer, feedback_buf,
+                            &pool->feedback_buffers, head)
+      vn_feedback_buffer_destroy(pool->device, feedback_buf, pool->alloc);
+}
diff --git a/src/virtio/vulkan/vn_feedback.h b/src/virtio/vulkan/vn_feedback.h
new file mode 100644
index 00000000000..1120a7e5195
--- /dev/null
+++ b/src/virtio/vulkan/vn_feedback.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2022 Google LLC
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef VN_FEEDBACK_H
+#define VN_FEEDBACK_H
+
+#include "vn_common.h"
+
+struct vn_feedback_pool {
+   struct vn_device *device;
+   const VkAllocationCallbacks *alloc;
+
+   /* size in bytes of the feedback buffer */
+   uint32_t size;
+   /* size in bytes used of the active feedback buffer */
+   uint32_t used;
+
+   /* first entry is the active feedback buffer */
+   struct list_head feedback_buffers;
+};
+
+VkResult
+vn_feedback_pool_init(struct vn_device *dev,
+                      struct vn_feedback_pool *pool,
+                      uint32_t size,
+                      const VkAllocationCallbacks *alloc);
+
+void
+vn_feedback_pool_fini(struct vn_feedback_pool *pool);
+
+#endif /* VN_FEEDBACK_H */



More information about the mesa-commit mailing list