From f039c86aacb19dcd91d9cc448923028a441d9ff6 Mon Sep 17 00:00:00 2001
From: Conor McCarthy <cmccarthy@codeweavers.com>
Date: Mon, 8 May 2023 14:47:07 +1000
Subject: [PATCH] vkd3d: Create smaller UAV-only descriptor pools in the
 allocator if Vulkan-backed heaps are enabled.

In this case d3d12_command_allocator_allocate_descriptor_set() is
only called for clearing UAVs. This helps on platforms with limited
descriptor maximum counts.
---
 libs/vkd3d/command.c       |  2 +-
 libs/vkd3d/device.c        | 23 ++++++++++++++++++++---
 libs/vkd3d/vkd3d_private.h |  1 +
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index dd5c78a4d2..32439eec7e 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -1437,7 +1437,7 @@ 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(device->vk_pool_sizes);
+        pool_desc.poolSizeCount = device->vk_pool_count;
         pool_desc.pPoolSizes = device->vk_pool_sizes;
         if ((vr = VK_CALL(vkCreateDescriptorPool(vk_device, &pool_desc, NULL, &vk_pool))) < 0)
         {
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index 93274bc959..4263dcf418 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -19,6 +19,8 @@
 #include "vkd3d_private.h"
 #include "vkd3d_version.h"
 
+#define VKD3D_MAX_UAV_CLEAR_DESCRIPTORS_PER_TYPE 256u
+
 struct vkd3d_struct
 {
     enum vkd3d_structure_type type;
@@ -2393,9 +2395,23 @@ 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)
+static void device_init_descriptor_pool_sizes(struct d3d12_device *device)
 {
+    const struct vkd3d_device_descriptor_limits *limits = &device->vk_info.descriptor_limits;
+    VkDescriptorPoolSize *pool_sizes = device->vk_pool_sizes;
+
+    if (device->use_vk_heaps)
+    {
+        pool_sizes[0].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
+        pool_sizes[0].descriptorCount = min(limits->storage_image_max_descriptors,
+                VKD3D_MAX_UAV_CLEAR_DESCRIPTORS_PER_TYPE);
+        pool_sizes[1].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
+        pool_sizes[1].descriptorCount = pool_sizes[0].descriptorCount;
+        device->vk_pool_count = 2;
+        return;
+    }
+
+    assert(ARRAY_SIZE(device->vk_pool_sizes) >= 6);
     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);
@@ -2412,6 +2428,7 @@ static void vkd3d_init_descriptor_pool_sizes(VkDescriptorPoolSize *pool_sizes,
     pool_sizes[5].type = VK_DESCRIPTOR_TYPE_SAMPLER;
     pool_sizes[5].descriptorCount = min(limits->sampler_max_descriptors,
             VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE);
+    device->vk_pool_count = 6;
 };
 
 static void vkd3d_desc_object_cache_init(struct vkd3d_desc_object_cache *cache, size_t size)
@@ -4000,7 +4017,7 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
     vkd3d_desc_object_cache_init(&device->view_desc_cache, sizeof(struct vkd3d_view));
     vkd3d_desc_object_cache_init(&device->cbuffer_desc_cache, sizeof(struct vkd3d_cbuffer_desc));
 
-    vkd3d_init_descriptor_pool_sizes(device->vk_pool_sizes, &device->vk_info.descriptor_limits);
+    device_init_descriptor_pool_sizes(device);
 
     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 79474414a0..b015075443 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -1666,6 +1666,7 @@ struct d3d12_device
     struct vkd3d_uav_clear_state uav_clear_state;
 
     VkDescriptorPoolSize vk_pool_sizes[VKD3D_DESCRIPTOR_POOL_COUNT];
+    unsigned int vk_pool_count;
     struct vkd3d_vk_descriptor_heap_layout vk_descriptor_heap_layouts[VKD3D_SET_INDEX_COUNT];
     bool use_vk_heaps;
 };
-- 
GitLab