[PATCH vkd3d 01/10] vkd3d: Rework Vulkan queues initialisation.
Józef Kucia
joseph.kucia at gmail.com
Tue Mar 5 11:16:56 CST 2019
From: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
libs/vkd3d/device.c | 227 ++++++++++++++++++++++++++------------------
1 file changed, 132 insertions(+), 95 deletions(-)
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index c1de98f4a2ba..193a36cb2ee3 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -1097,6 +1097,25 @@ static HRESULT vkd3d_select_physical_device(struct vkd3d_instance *instance,
return S_OK;
}
+/* Vulkan queues */
+enum vkd3d_queue_family
+{
+ VKD3D_QUEUE_FAMILY_DIRECT,
+ VKD3D_QUEUE_FAMILY_COMPUTE,
+ VKD3D_QUEUE_FAMILY_TRANSFER,
+
+ VKD3D_QUEUE_FAMILY_COUNT,
+};
+
+struct vkd3d_device_queue_info
+{
+ unsigned int family_index[VKD3D_QUEUE_FAMILY_COUNT];
+ VkQueueFamilyProperties vk_properties[VKD3D_QUEUE_FAMILY_COUNT];
+
+ unsigned int vk_family_count;
+ VkDeviceQueueCreateInfo vk_queue_create_info[VKD3D_QUEUE_FAMILY_COUNT];
+};
+
static void d3d12_device_destroy_vkd3d_queues(struct d3d12_device *device)
{
if (device->direct_queue)
@@ -1113,31 +1132,33 @@ static void d3d12_device_destroy_vkd3d_queues(struct d3d12_device *device)
}
static HRESULT d3d12_device_create_vkd3d_queues(struct d3d12_device *device,
- const VkQueueFamilyProperties *queue_properties, uint32_t direct_queue_family_index,
- uint32_t compute_queue_family_index, uint32_t copy_queue_family_index)
+ const struct vkd3d_device_queue_info *queue_info)
{
+ uint32_t transfer_family_index = queue_info->family_index[VKD3D_QUEUE_FAMILY_TRANSFER];
+ uint32_t compute_family_index = queue_info->family_index[VKD3D_QUEUE_FAMILY_COMPUTE];
+ uint32_t direct_family_index = queue_info->family_index[VKD3D_QUEUE_FAMILY_DIRECT];
HRESULT hr;
device->direct_queue = NULL;
device->compute_queue = NULL;
device->copy_queue = NULL;
- if (FAILED((hr = vkd3d_queue_create(device, direct_queue_family_index,
- &queue_properties[direct_queue_family_index], &device->direct_queue))))
+ if (FAILED((hr = vkd3d_queue_create(device, direct_family_index,
+ &queue_info->vk_properties[VKD3D_QUEUE_FAMILY_DIRECT], &device->direct_queue))))
goto out_destroy_queues;
- if (compute_queue_family_index == direct_queue_family_index)
+ if (compute_family_index == direct_family_index)
device->compute_queue = device->direct_queue;
- else if (FAILED(hr = vkd3d_queue_create(device, compute_queue_family_index,
- &queue_properties[compute_queue_family_index], &device->compute_queue)))
+ else if (FAILED(hr = vkd3d_queue_create(device, compute_family_index,
+ &queue_info->vk_properties[VKD3D_QUEUE_FAMILY_COMPUTE], &device->compute_queue)))
goto out_destroy_queues;
- if (copy_queue_family_index == direct_queue_family_index)
+ if (transfer_family_index == direct_family_index)
device->copy_queue = device->direct_queue;
- else if (copy_queue_family_index == compute_queue_family_index)
+ else if (transfer_family_index == compute_family_index)
device->copy_queue = device->compute_queue;
- else if (FAILED(hr = vkd3d_queue_create(device, copy_queue_family_index,
- &queue_properties[copy_queue_family_index], &device->copy_queue)))
+ else if (FAILED(hr = vkd3d_queue_create(device, transfer_family_index,
+ &queue_info->vk_properties[VKD3D_QUEUE_FAMILY_TRANSFER], &device->copy_queue)))
goto out_destroy_queues;
return S_OK;
@@ -1147,100 +1168,126 @@ out_destroy_queues:
return hr;
}
-static HRESULT vkd3d_create_vk_device(struct d3d12_device *device,
- const struct vkd3d_device_create_info *create_info)
+static float queue_priorities[] = {1.0f};
+
+static HRESULT vkd3d_select_queues(const struct vkd3d_instance *vkd3d_instance,
+ VkPhysicalDevice physical_device, struct vkd3d_device_queue_info *info)
{
- unsigned int direct_queue_family_index, copy_queue_family_index, compute_queue_family_index;
- const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance->vk_procs;
- VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor_features;
- VkPhysicalDeviceTransformFeedbackFeaturesEXT xfb_features;
- struct vkd3d_vulkan_info *vulkan_info = &device->vk_info;
+ const struct vkd3d_vk_instance_procs *vk_procs = &vkd3d_instance->vk_procs;
VkQueueFamilyProperties *queue_properties = NULL;
VkDeviceQueueCreateInfo *queue_info = NULL;
- VkPhysicalDeviceFeatures2 features2;
- VkPhysicalDevice physical_device;
- VkDeviceCreateInfo device_info;
- uint32_t queue_family_count;
- uint32_t extension_count;
- const char **extensions;
- VkDevice vk_device;
unsigned int i;
- VkResult vr;
- HRESULT hr;
-
- TRACE("device %p, create_info %p.\n", device, create_info);
-
- physical_device = create_info->vk_physical_device;
- if (!physical_device
- && FAILED(hr = vkd3d_select_physical_device(device->vkd3d_instance, &physical_device)))
- return hr;
+ uint32_t count;
- device->vk_physical_device = physical_device;
+ memset(info, 0, sizeof(*info));
+ for (i = 0; i < ARRAY_SIZE(info->family_index); ++i)
+ info->family_index[i] = ~0u;
- /* Create command queues */
- VK_CALL(vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, NULL));
- if (!(queue_properties = vkd3d_calloc(queue_family_count, sizeof(*queue_properties))))
+ VK_CALL(vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &count, NULL));
+ if (!(queue_properties = vkd3d_calloc(count, sizeof(*queue_properties))))
return E_OUTOFMEMORY;
- VK_CALL(vkGetPhysicalDeviceQueueFamilyProperties(physical_device,
- &queue_family_count, queue_properties));
-
- if (!(queue_info = vkd3d_calloc(queue_family_count, sizeof(*queue_info))))
- {
- hr = E_OUTOFMEMORY;
- goto done;
- }
+ VK_CALL(vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &count, queue_properties));
- direct_queue_family_index = ~0u;
- copy_queue_family_index = ~0u;
- compute_queue_family_index = ~0u;
- for (i = 0; i < queue_family_count; ++i)
+ for (i = 0; i < count; ++i)
{
- static float priorities[] = {1.0f};
-
- queue_info[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
- queue_info[i].pNext = NULL;
- queue_info[i].flags = 0;
- queue_info[i].queueFamilyIndex = i;
- queue_info[i].queueCount = 1;
- queue_info[i].pQueuePriorities = priorities;
+ enum vkd3d_queue_family vkd3d_family = VKD3D_QUEUE_FAMILY_COUNT;
if ((queue_properties[i].queueFlags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT))
== (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT))
{
- direct_queue_family_index = i;
- }
- if (queue_properties[i].queueFlags & VK_QUEUE_TRANSFER_BIT)
- {
- copy_queue_family_index = i;
+ vkd3d_family = VKD3D_QUEUE_FAMILY_DIRECT;
}
if ((queue_properties[i].queueFlags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT))
== VK_QUEUE_COMPUTE_BIT)
{
- compute_queue_family_index = i;
+ vkd3d_family = VKD3D_QUEUE_FAMILY_COMPUTE;
}
+ if ((queue_properties[i].queueFlags & ~VK_QUEUE_SPARSE_BINDING_BIT) == VK_QUEUE_TRANSFER_BIT)
+ {
+ vkd3d_family = VKD3D_QUEUE_FAMILY_TRANSFER;
+ }
+
+ if (vkd3d_family == VKD3D_QUEUE_FAMILY_COUNT)
+ continue;
+
+ info->family_index[vkd3d_family] = i;
+ info->vk_properties[vkd3d_family] = queue_properties[i];
+ queue_info = &info->vk_queue_create_info[vkd3d_family];
+
+ queue_info->sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+ queue_info->pNext = NULL;
+ queue_info->flags = 0;
+ queue_info->queueFamilyIndex = i;
+ queue_info->queueCount = 1; /* FIXME: Use multiple queues. */
+ queue_info->pQueuePriorities = queue_priorities;
}
- if (direct_queue_family_index == ~0u)
+ vkd3d_free(queue_properties);
+
+ if (info->family_index[VKD3D_QUEUE_FAMILY_DIRECT] == ~0u)
{
FIXME("Could not find a suitable queue family for a direct command queue.\n");
- hr = E_FAIL;
- goto done;
+ return E_FAIL;
}
- if (copy_queue_family_index == ~0u)
+
+ /* No compute-only queue family, reuse the direct queue family with graphics and compute. */
+ if (info->family_index[VKD3D_QUEUE_FAMILY_COMPUTE] == ~0u)
{
- FIXME("Could not find a suitable queue family for a copy command queue.\n");
- hr = E_FAIL;
- goto done;
+ info->family_index[VKD3D_QUEUE_FAMILY_COMPUTE] = info->family_index[VKD3D_QUEUE_FAMILY_DIRECT];
+ info->vk_properties[VKD3D_QUEUE_FAMILY_COMPUTE] = info->vk_properties[VKD3D_QUEUE_FAMILY_DIRECT];
}
- if (compute_queue_family_index == ~0u)
+ if (info->family_index[VKD3D_QUEUE_FAMILY_TRANSFER] == ~0u)
{
- /* No compute-only queue family, reuse the direct queue family with graphics and compute. */
- compute_queue_family_index = direct_queue_family_index;
+ info->family_index[VKD3D_QUEUE_FAMILY_TRANSFER] = info->family_index[VKD3D_QUEUE_FAMILY_DIRECT];
+ info->vk_properties[VKD3D_QUEUE_FAMILY_TRANSFER] = info->vk_properties[VKD3D_QUEUE_FAMILY_DIRECT];
}
- TRACE("Using queue family %u for direct command queues.\n", direct_queue_family_index);
- TRACE("Using queue family %u for copy command queues.\n", copy_queue_family_index);
- TRACE("Using queue family %u for compute command queues.\n", compute_queue_family_index);
+ /* Compact the array. */
+ info->vk_family_count = 1;
+ for (i = info->vk_family_count; i < ARRAY_SIZE(info->vk_queue_create_info); ++i)
+ {
+ if (info->vk_queue_create_info[i].queueCount)
+ info->vk_queue_create_info[info->vk_family_count++] = info->vk_queue_create_info[i];
+ }
+
+ return S_OK;
+}
+
+static HRESULT vkd3d_create_vk_device(struct d3d12_device *device,
+ const struct vkd3d_device_create_info *create_info)
+{
+ const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance->vk_procs;
+ VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor_features;
+ VkPhysicalDeviceTransformFeedbackFeaturesEXT xfb_features;
+ struct vkd3d_vulkan_info *vulkan_info = &device->vk_info;
+ struct vkd3d_device_queue_info device_queue_info;
+ VkPhysicalDeviceFeatures2 features2;
+ VkPhysicalDevice physical_device;
+ VkDeviceCreateInfo device_info;
+ uint32_t extension_count;
+ const char **extensions;
+ VkDevice vk_device;
+ VkResult vr;
+ HRESULT hr;
+
+ TRACE("device %p, create_info %p.\n", device, create_info);
+
+ physical_device = create_info->vk_physical_device;
+ if (!physical_device
+ && FAILED(hr = vkd3d_select_physical_device(device->vkd3d_instance, &physical_device)))
+ return hr;
+
+ device->vk_physical_device = physical_device;
+
+ if (FAILED(hr = vkd3d_select_queues(device->vkd3d_instance, physical_device, &device_queue_info)))
+ return hr;
+
+ TRACE("Using queue family %u for direct command queues.\n",
+ device_queue_info.family_index[VKD3D_QUEUE_FAMILY_DIRECT]);
+ TRACE("Using queue family %u for compute command queues.\n",
+ device_queue_info.family_index[VKD3D_QUEUE_FAMILY_COMPUTE]);
+ TRACE("Using queue family %u for copy command queues.\n",
+ device_queue_info.family_index[VKD3D_QUEUE_FAMILY_TRANSFER]);
VK_CALL(vkGetPhysicalDeviceMemoryProperties(physical_device, &device->memory_properties));
@@ -1257,20 +1304,17 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device,
VK_CALL(vkGetPhysicalDeviceFeatures(physical_device, &features2.features));
if (FAILED(hr = vkd3d_init_device_caps(device, create_info, &features2, &extension_count)))
- goto done;
+ return hr;
if (!(extensions = vkd3d_calloc(extension_count, sizeof(*extensions))))
- {
- hr = E_OUTOFMEMORY;
- goto done;
- }
+ return E_OUTOFMEMORY;
/* Create device */
device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
device_info.pNext = &vertex_divisor_features;
device_info.flags = 0;
- device_info.queueCreateInfoCount = queue_family_count;
- device_info.pQueueCreateInfos = queue_info;
+ device_info.queueCreateInfoCount = device_queue_info.vk_family_count;
+ device_info.pQueueCreateInfos = device_queue_info.vk_queue_create_info;
device_info.enabledLayerCount = 0;
device_info.ppEnabledLayerNames = NULL;
device_info.enabledExtensionCount = vkd3d_enable_extensions(extensions,
@@ -1286,8 +1330,7 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device,
if (vr < 0)
{
ERR("Failed to create Vulkan device, vr %d.\n", vr);
- hr = hresult_from_vk_result(vr);
- goto done;
+ return hresult_from_vk_result(vr);
}
if (FAILED(hr = vkd3d_load_vk_device_procs(&device->vk_procs, vk_procs, vk_device)))
@@ -1295,26 +1338,20 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device,
ERR("Failed to load device procs, hr %#x.\n", hr);
if (device->vk_procs.vkDestroyDevice)
device->vk_procs.vkDestroyDevice(vk_device, NULL);
- goto done;
+ return hr;
}
device->vk_device = vk_device;
- if (FAILED(hr = d3d12_device_create_vkd3d_queues(device, queue_properties,
- direct_queue_family_index, compute_queue_family_index, copy_queue_family_index)))
+ if (FAILED(hr = d3d12_device_create_vkd3d_queues(device, &device_queue_info)))
{
ERR("Failed to create queues, hr %#x.\n", hr);
device->vk_procs.vkDestroyDevice(vk_device, NULL);
- goto done;
+ return hr;
}
TRACE("Created Vulkan device %p.\n", vk_device);
-done:
- if (queue_properties)
- vkd3d_free(queue_properties);
- if (queue_info)
- vkd3d_free(queue_info);
return hr;
}
--
2.19.2
More information about the wine-devel
mailing list