Conor McCarthy : vkd3d: Use device descriptor limits when creating descriptor pools.

Alexandre Julliard julliard at winehq.org
Mon Feb 21 15:58:07 CST 2022


Module: vkd3d
Branch: master
Commit: 65e353d5df50f28760b3c0bc999ea1c11aee2fec
URL:    https://source.winehq.org/git/vkd3d.git/?a=commit;h=65e353d5df50f28760b3c0bc999ea1c11aee2fec

Author: Conor McCarthy <cmccarthy at codeweavers.com>
Date:   Tue Feb 22 01:18:57 2022 +1000

vkd3d: Use device descriptor limits when creating descriptor pools.

Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 libs/vkd3d/command.c       | 13 ++-----------
 libs/vkd3d/device.c        | 36 ++++++++++++++++++++++++++++++++++++
 libs/vkd3d/vkd3d_private.h | 20 ++++++++++++++++++++
 3 files changed, 58 insertions(+), 11 deletions(-)

diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index 61e1810..e7375fb 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -1351,15 +1351,6 @@ static bool d3d12_command_allocator_add_transfer_buffer(struct d3d12_command_all
 static VkDescriptorPool d3d12_command_allocator_allocate_descriptor_pool(
         struct d3d12_command_allocator *allocator)
 {
-    static const VkDescriptorPoolSize pool_sizes[] =
-    {
-        {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1024},
-        {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1024},
-        {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1024},
-        {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1024},
-        {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1024},
-        {VK_DESCRIPTOR_TYPE_SAMPLER, 1024},
-    };
     struct d3d12_device *device = allocator->device;
     const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
     struct VkDescriptorPoolCreateInfo pool_desc;
@@ -1379,8 +1370,8 @@ static VkDescriptorPool d3d12_command_allocator_allocate_descriptor_pool(
         pool_desc.pNext = NULL;
         pool_desc.flags = 0;
         pool_desc.maxSets = 512;
-        pool_desc.poolSizeCount = ARRAY_SIZE(pool_sizes);
-        pool_desc.pPoolSizes = pool_sizes;
+        pool_desc.poolSizeCount = ARRAY_SIZE(device->vk_pool_sizes);
+        pool_desc.pPoolSizes = device->vk_pool_sizes;
         if ((vr = VK_CALL(vkCreateDescriptorPool(vk_device, &pool_desc, NULL, &vk_pool))) < 0)
         {
             ERR("Failed to create descriptor pool, vr %d.\n", vr);
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index 3360fd6..59fa9af 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -1277,6 +1277,16 @@ static void vkd3d_init_feature_level(struct vkd3d_vulkan_info *vk_info,
     TRACE("Max feature level: %#x.\n", vk_info->max_feature_level);
 }
 
+static void vkd3d_device_descriptor_limits_init(struct vkd3d_device_descriptor_limits *limits,
+        const VkPhysicalDeviceLimits *device_limits)
+{
+    limits->uniform_buffer_max_descriptors = device_limits->maxDescriptorSetUniformBuffers;
+    limits->sampled_image_max_descriptors = device_limits->maxDescriptorSetSampledImages;
+    limits->storage_buffer_max_descriptors = device_limits->maxDescriptorSetStorageBuffers;
+    limits->storage_image_max_descriptors = device_limits->maxDescriptorSetStorageImages;
+    limits->sampler_max_descriptors = min(device_limits->maxDescriptorSetSamplers, VKD3D_MAX_DESCRIPTOR_SET_SAMPLERS);
+}
+
 static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
         const struct vkd3d_device_create_info *create_info,
         struct vkd3d_physical_device_info *physical_device_info,
@@ -1504,6 +1514,9 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
         features->robustBufferAccess = VK_FALSE;
     }
 
+    vkd3d_device_descriptor_limits_init(&vulkan_info->descriptor_limits,
+            &physical_device_info->properties2.properties.limits);
+
     return S_OK;
 }
 
@@ -2419,6 +2432,27 @@ static void vkd3d_time_domains_init(struct d3d12_device *device)
         WARN("Found no acceptable host time domain. Calibrated timestamps will not be available.\n");
 }
 
+static void vkd3d_init_descriptor_pool_sizes(VkDescriptorPoolSize *pool_sizes,
+        const struct vkd3d_device_descriptor_limits *limits)
+{
+    pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    pool_sizes[0].descriptorCount = min(limits->uniform_buffer_max_descriptors,
+            VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE);
+    pool_sizes[1].type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
+    pool_sizes[1].descriptorCount = min(limits->sampled_image_max_descriptors,
+            VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE);
+    pool_sizes[2].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
+    pool_sizes[2].descriptorCount = pool_sizes[1].descriptorCount;
+    pool_sizes[3].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
+    pool_sizes[3].descriptorCount = min(limits->storage_image_max_descriptors,
+            VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE);
+    pool_sizes[4].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
+    pool_sizes[4].descriptorCount = pool_sizes[3].descriptorCount;
+    pool_sizes[5].type = VK_DESCRIPTOR_TYPE_SAMPLER;
+    pool_sizes[5].descriptorCount = min(limits->sampler_max_descriptors,
+            VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE);
+};
+
 /* ID3D12Device */
 static inline struct d3d12_device *impl_from_ID3D12Device(ID3D12Device *iface)
 {
@@ -3979,6 +4013,8 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
     for (i = 0; i < ARRAY_SIZE(device->desc_mutex); ++i)
         vkd3d_mutex_init(&device->desc_mutex[i]);
 
+    vkd3d_init_descriptor_pool_sizes(device->vk_pool_sizes, &device->vk_info.descriptor_limits);
+
     if ((device->parent = create_info->parent))
         IUnknown_AddRef(device->parent);
 
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 67989c1..ca7a3f2 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -62,6 +62,12 @@
 #define VKD3D_MAX_SHADER_STAGES           5u
 #define VKD3D_MAX_VK_SYNC_OBJECTS         4u
 #define VKD3D_MAX_DESCRIPTOR_SETS        64u
+/* D3D12 binding tier 3 has a limit of 2048 samplers. */
+#define VKD3D_MAX_DESCRIPTOR_SET_SAMPLERS 2048u
+/* The main limitation here is the simple descriptor pool recycling scheme
+ * requiring each pool to contain all descriptor types used by vkd3d. Limit
+ * this number to prevent excessive pool memory use. */
+#define VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE (16 * 1024u)
 
 struct d3d12_command_list;
 struct d3d12_device;
@@ -95,6 +101,15 @@ HRESULT hresult_from_errno(int rc);
 HRESULT hresult_from_vk_result(VkResult vr);
 HRESULT hresult_from_vkd3d_result(int vkd3d_result);
 
+struct vkd3d_device_descriptor_limits
+{
+    unsigned int uniform_buffer_max_descriptors;
+    unsigned int sampled_image_max_descriptors;
+    unsigned int storage_buffer_max_descriptors;
+    unsigned int storage_image_max_descriptors;
+    unsigned int sampler_max_descriptors;
+};
+
 struct vkd3d_vulkan_info
 {
     /* KHR instance extensions */
@@ -130,6 +145,7 @@ struct vkd3d_vulkan_info
 
     VkPhysicalDeviceLimits device_limits;
     VkPhysicalDeviceSparseProperties sparse_properties;
+    struct vkd3d_device_descriptor_limits descriptor_limits;
 
     VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT texel_buffer_alignment_properties;
 
@@ -1299,6 +1315,8 @@ struct vkd3d_uav_clear_state
 HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d3d12_device *device);
 void vkd3d_uav_clear_state_cleanup(struct vkd3d_uav_clear_state *state, struct d3d12_device *device);
 
+#define VKD3D_DESCRIPTOR_POOL_COUNT 6
+
 /* ID3D12Device */
 struct d3d12_device
 {
@@ -1352,6 +1370,8 @@ struct d3d12_device
     const struct vkd3d_format_compatibility_list *format_compatibility_lists;
     struct vkd3d_null_resources null_resources;
     struct vkd3d_uav_clear_state uav_clear_state;
+
+    VkDescriptorPoolSize vk_pool_sizes[VKD3D_DESCRIPTOR_POOL_COUNT];
 };
 
 HRESULT d3d12_device_create(struct vkd3d_instance *instance,




More information about the wine-cvs mailing list