Mesa (main): venus: pre-initialize device groups

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Aug 31 21:04:14 UTC 2021


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

Author: Chia-I Wu <olvaffe at gmail.com>
Date:   Sat Aug 28 20:40:33 2021 -0700

venus: pre-initialize device groups

We don't need to worry about how vkEnumeratePhysicalDeviceGroups is
called (props is NULL, props is non-NULL but count is 0, etc.) this way.
It also allows us to fix up VkPhysicalDeviceGroupProperties easily.

v2: let the for-loop increment (Yiwei)

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

---

 src/virtio/vulkan/vn_instance.c        |   1 +
 src/virtio/vulkan/vn_instance.h        |   2 +
 src/virtio/vulkan/vn_physical_device.c | 177 ++++++++++++++++++++-------------
 3 files changed, 111 insertions(+), 69 deletions(-)

diff --git a/src/virtio/vulkan/vn_instance.c b/src/virtio/vulkan/vn_instance.c
index 4f3bda48fdf..54efb8e4272 100644
--- a/src/virtio/vulkan/vn_instance.c
+++ b/src/virtio/vulkan/vn_instance.c
@@ -779,6 +779,7 @@ vn_DestroyInstance(VkInstance _instance,
       return;
 
    if (instance->physical_devices) {
+      vk_free(alloc, instance->physical_device_groups);
       for (uint32_t i = 0; i < instance->physical_device_count; i++)
          vn_physical_device_fini(&instance->physical_devices[i]);
       vk_free(alloc, instance->physical_devices);
diff --git a/src/virtio/vulkan/vn_instance.h b/src/virtio/vulkan/vn_instance.h
index c1903fed746..6c49489b961 100644
--- a/src/virtio/vulkan/vn_instance.h
+++ b/src/virtio/vulkan/vn_instance.h
@@ -74,6 +74,8 @@ struct vn_instance {
    mtx_t physical_device_mutex;
    struct vn_physical_device *physical_devices;
    uint32_t physical_device_count;
+   VkPhysicalDeviceGroupProperties *physical_device_groups;
+   uint32_t physical_device_group_count;
 
    /* XXX staged features to be merged to core venus protocol */
    VkVenusExperimentalFeatures100000MESA experimental;
diff --git a/src/virtio/vulkan/vn_physical_device.c b/src/virtio/vulkan/vn_physical_device.c
index 491a02c0bf8..14b40f2dfff 100644
--- a/src/virtio/vulkan/vn_physical_device.c
+++ b/src/virtio/vulkan/vn_physical_device.c
@@ -25,17 +25,6 @@
                    offsetof(__typeof__(tbl), ext)) -                         \
     (tbl).extensions)
 
-static struct vn_physical_device *
-vn_instance_find_physical_device(struct vn_instance *instance,
-                                 vn_object_id id)
-{
-   for (uint32_t i = 0; i < instance->physical_device_count; i++) {
-      if (instance->physical_devices[i].base.id == id)
-         return &instance->physical_devices[i];
-   }
-   return NULL;
-}
-
 static void
 vn_physical_device_init_features(struct vn_physical_device *physical_dev)
 {
@@ -1162,10 +1151,101 @@ vn_physical_device_fini(struct vn_physical_device *physical_dev)
    vn_physical_device_base_fini(&physical_dev->base);
 }
 
+static struct vn_physical_device *
+find_physical_device(struct vn_physical_device *physical_devs,
+                     uint32_t count,
+                     vn_object_id id)
+{
+   for (uint32_t i = 0; i < count; i++) {
+      if (physical_devs[i].base.id == id)
+         return &physical_devs[i];
+   }
+   return NULL;
+}
+
+static VkResult
+vn_instance_enumerate_physical_device_groups_locked(
+   struct vn_instance *instance,
+   struct vn_physical_device *physical_devs,
+   uint32_t physical_dev_count)
+{
+   VkInstance instance_handle = vn_instance_to_handle(instance);
+   const VkAllocationCallbacks *alloc = &instance->base.base.alloc;
+   VkResult result;
+
+   uint32_t count;
+   result = vn_call_vkEnumeratePhysicalDeviceGroups(instance, instance_handle,
+                                                    &count, NULL);
+   if (result != VK_SUCCESS)
+      return result;
+
+   VkPhysicalDeviceGroupProperties *groups =
+      vk_alloc(alloc, sizeof(*groups) * count, VN_DEFAULT_ALIGN,
+               VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+   if (!groups)
+      return VK_ERROR_OUT_OF_HOST_MEMORY;
+
+   /* VkPhysicalDeviceGroupProperties::physicalDevices is treated as an input
+    * by the encoder.  Each VkPhysicalDevice must point to a valid object.
+    * Each object must have id 0 as well, which is interpreted as a query by
+    * the renderer.
+    */
+   struct vn_physical_device_base *temp_objs =
+      vk_zalloc(alloc, sizeof(*temp_objs) * VK_MAX_DEVICE_GROUP_SIZE * count,
+                VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+   if (!temp_objs) {
+      vk_free(alloc, groups);
+      return VK_ERROR_OUT_OF_HOST_MEMORY;
+   }
+
+   for (uint32_t i = 0; i < count; i++) {
+      VkPhysicalDeviceGroupProperties *group = &groups[i];
+      group->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
+      group->pNext = NULL;
+      for (uint32_t j = 0; j < VK_MAX_DEVICE_GROUP_SIZE; j++) {
+         struct vn_physical_device_base *temp_obj =
+            &temp_objs[VK_MAX_DEVICE_GROUP_SIZE * i + j];
+         temp_obj->base.base.type = VK_OBJECT_TYPE_PHYSICAL_DEVICE;
+         group->physicalDevices[j] = (VkPhysicalDevice)temp_obj;
+      }
+   }
+
+   result = vn_call_vkEnumeratePhysicalDeviceGroups(instance, instance_handle,
+                                                    &count, groups);
+   if (result != VK_SUCCESS) {
+      vk_free(alloc, groups);
+      vk_free(alloc, temp_objs);
+      return result;
+   }
+
+   /* fix VkPhysicalDeviceGroupProperties::physicalDevices to point to
+    * physical_devs
+    */
+   for (uint32_t i = 0; i < count; i++) {
+      VkPhysicalDeviceGroupProperties *group = &groups[i];
+
+      for (uint32_t j = 0; j < group->physicalDeviceCount; j++) {
+         struct vn_physical_device_base *temp_obj =
+            (struct vn_physical_device_base *)group->physicalDevices[j];
+         struct vn_physical_device *physical_dev = find_physical_device(
+            physical_devs, physical_dev_count, temp_obj->id);
+
+         group->physicalDevices[j] =
+            vn_physical_device_to_handle(physical_dev);
+      }
+   }
+
+   vk_free(alloc, temp_objs);
+
+   instance->physical_device_groups = groups;
+   instance->physical_device_group_count = count;
+
+   return VK_SUCCESS;
+}
+
 static VkResult
 vn_instance_enumerate_physical_devices(struct vn_instance *instance)
 {
-   /* TODO cache device group info here as well */
    const VkAllocationCallbacks *alloc = &instance->base.base.alloc;
    struct vn_physical_device *physical_devs = NULL;
    VkResult result;
@@ -1244,6 +1324,15 @@ vn_instance_enumerate_physical_devices(struct vn_instance *instance)
    if (!count)
       goto out;
 
+   result = vn_instance_enumerate_physical_device_groups_locked(
+      instance, physical_devs, count);
+   if (result != VK_SUCCESS) {
+      for (uint32_t i = 0; i < count; i++)
+         vn_physical_device_fini(&physical_devs[i]);
+      count = 0;
+      goto out;
+   }
+
    instance->physical_devices = physical_devs;
    instance->physical_device_count = count;
 
@@ -1289,70 +1378,20 @@ vn_EnumeratePhysicalDeviceGroups(
    VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties)
 {
    struct vn_instance *instance = vn_instance_from_handle(_instance);
-   const VkAllocationCallbacks *alloc = &instance->base.base.alloc;
-   struct vn_physical_device_base *dummy = NULL;
-   VkResult result;
 
-   result = vn_instance_enumerate_physical_devices(instance);
+   VkResult result = vn_instance_enumerate_physical_devices(instance);
    if (result != VK_SUCCESS)
       return vn_error(instance, result);
 
-   if (pPhysicalDeviceGroupProperties && *pPhysicalDeviceGroupCount == 0)
-      return instance->physical_device_count ? VK_INCOMPLETE : VK_SUCCESS;
-
-   /* make sure VkPhysicalDevice point to objects, as they are considered
-    * inputs by the encoder
-    */
-   if (pPhysicalDeviceGroupProperties) {
-      const uint32_t count = *pPhysicalDeviceGroupCount;
-      const size_t size = sizeof(*dummy) * VK_MAX_DEVICE_GROUP_SIZE * count;
-
-      dummy = vk_zalloc(alloc, size, VN_DEFAULT_ALIGN,
-                        VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
-      if (!dummy)
-         return vn_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
-
-      for (uint32_t i = 0; i < count; i++) {
-         VkPhysicalDeviceGroupProperties *props =
-            &pPhysicalDeviceGroupProperties[i];
-
-         for (uint32_t j = 0; j < VK_MAX_DEVICE_GROUP_SIZE; j++) {
-            struct vn_physical_device_base *obj =
-               &dummy[VK_MAX_DEVICE_GROUP_SIZE * i + j];
-            obj->base.base.type = VK_OBJECT_TYPE_PHYSICAL_DEVICE;
-            props->physicalDevices[j] = (VkPhysicalDevice)obj;
-         }
-      }
-   }
-
-   result = vn_call_vkEnumeratePhysicalDeviceGroups(
-      instance, _instance, pPhysicalDeviceGroupCount,
-      pPhysicalDeviceGroupProperties);
-   if (result != VK_SUCCESS) {
-      if (dummy)
-         vk_free(alloc, dummy);
-      return vn_error(instance, result);
-   }
-
-   if (pPhysicalDeviceGroupProperties) {
-      for (uint32_t i = 0; i < *pPhysicalDeviceGroupCount; i++) {
-         VkPhysicalDeviceGroupProperties *props =
-            &pPhysicalDeviceGroupProperties[i];
-         for (uint32_t j = 0; j < props->physicalDeviceCount; j++) {
-            const vn_object_id id =
-               dummy[VK_MAX_DEVICE_GROUP_SIZE * i + j].id;
-            struct vn_physical_device *physical_dev =
-               vn_instance_find_physical_device(instance, id);
-            props->physicalDevices[j] =
-               vn_physical_device_to_handle(physical_dev);
-         }
+   VK_OUTARRAY_MAKE(out, pPhysicalDeviceGroupProperties,
+                    pPhysicalDeviceGroupCount);
+   for (uint32_t i = 0; i < instance->physical_device_group_count; i++) {
+      vk_outarray_append(&out, props) {
+         *props = instance->physical_device_groups[i];
       }
    }
 
-   if (dummy)
-      vk_free(alloc, dummy);
-
-   return VK_SUCCESS;
+   return vk_outarray_status(&out);
 }
 
 VkResult



More information about the mesa-commit mailing list