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