From 239c88e8d3ccdf28845505d614b947176449c74c Mon Sep 17 00:00:00 2001 From: Giovanni Mascellani Date: Fri, 22 Nov 2024 12:33:31 +0100 Subject: [PATCH] vkd3d: Do not use more than a few million descriptors in Vulkan heap set layouts. Currently, when using Vulkan heaps, we create descriptor set layouts with as many descriptors as allowed by the Vulkan implementation limits. For some implementations this can mean hundreds of millions of descriptors or more, which is wasteful, given that even on the best resource binding tier Direct3D 12 applications should not expect to have more than a million usable descriptors. Recently this began being a problem, because since Mesa 24.2.7 the Intel driver advertises more than 200 million descriptors, but pipeline compilation takes linear RAM in the number of descriptors declared in the pipeline layout. This means that compiling even a simple shader requires 10-20 GB of RAM. In order to avoid using too much memory, with this commit we clamp the number of descriptors declared in the set layouts to how many we actually need to guarantee tier 3 resource binding support. --- libs/vkd3d/device.c | 25 +++++++++++++++---------- libs/vkd3d/vkd3d_private.h | 5 +++++ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 7958a51a..7b491805 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -1473,16 +1473,21 @@ static void vkd3d_device_vk_heaps_descriptor_limits_init(struct vkd3d_device_des uav_divisor = properties->maxDescriptorSetUpdateAfterBindSampledImages >= (3u << 20) ? 3 : 2; } - limits->uniform_buffer_max_descriptors = min(properties->maxDescriptorSetUpdateAfterBindUniformBuffers, - properties->maxPerStageDescriptorUpdateAfterBindUniformBuffers - root_provision); - limits->sampled_image_max_descriptors = min(properties->maxDescriptorSetUpdateAfterBindSampledImages, - properties->maxPerStageDescriptorUpdateAfterBindSampledImages / srv_divisor - root_provision); - limits->storage_buffer_max_descriptors = min(properties->maxDescriptorSetUpdateAfterBindStorageBuffers, - properties->maxPerStageDescriptorUpdateAfterBindStorageBuffers - root_provision); - limits->storage_image_max_descriptors = min(properties->maxDescriptorSetUpdateAfterBindStorageImages, - properties->maxPerStageDescriptorUpdateAfterBindStorageImages / uav_divisor - root_provision); - limits->sampler_max_descriptors = min(properties->maxDescriptorSetUpdateAfterBindSamplers, - properties->maxPerStageDescriptorUpdateAfterBindSamplers - root_provision); + limits->uniform_buffer_max_descriptors = min(min(properties->maxDescriptorSetUpdateAfterBindUniformBuffers, + properties->maxPerStageDescriptorUpdateAfterBindUniformBuffers - root_provision), + VKD3D_MAX_DESCRIPTOR_SET_CBVS_SRVS_UAVS); + limits->sampled_image_max_descriptors = min(min(properties->maxDescriptorSetUpdateAfterBindSampledImages, + properties->maxPerStageDescriptorUpdateAfterBindSampledImages / srv_divisor - root_provision), + VKD3D_MAX_DESCRIPTOR_SET_CBVS_SRVS_UAVS); + limits->storage_buffer_max_descriptors = min(min(properties->maxDescriptorSetUpdateAfterBindStorageBuffers, + properties->maxPerStageDescriptorUpdateAfterBindStorageBuffers - root_provision), + VKD3D_MAX_DESCRIPTOR_SET_CBVS_SRVS_UAVS); + limits->storage_image_max_descriptors = min(min(properties->maxDescriptorSetUpdateAfterBindStorageImages, + properties->maxPerStageDescriptorUpdateAfterBindStorageImages / uav_divisor - root_provision), + VKD3D_MAX_DESCRIPTOR_SET_CBVS_SRVS_UAVS); + limits->sampler_max_descriptors = min(min(properties->maxDescriptorSetUpdateAfterBindSamplers, + properties->maxPerStageDescriptorUpdateAfterBindSamplers - root_provision), + VKD3D_MAX_DESCRIPTOR_SET_CBVS_SRVS_UAVS); limits->sampler_max_descriptors = min(limits->sampler_max_descriptors, VKD3D_MAX_DESCRIPTOR_SET_SAMPLERS); } diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index b7517855..3f5783e5 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -58,6 +58,11 @@ #define VKD3D_MAX_VK_SYNC_OBJECTS 4u #define VKD3D_MAX_DEVICE_BLOCKED_QUEUES 16u #define VKD3D_MAX_DESCRIPTOR_SETS 64u +/* Direct3D 12 binding tier 3 has a limit of "1,000,000+" CBVs, SRVs and UAVs. + * I am not sure what the "+" is supposed to mean: it probably hints that + * implementations may have an even higher limit, but that's pretty obvious, + * that table is for guaranteed minimum limits. */ +#define VKD3D_MAX_DESCRIPTOR_SET_CBVS_SRVS_UAVS 1000000u /* D3D12 binding tier 3 has a limit of 2048 samplers. */ #define VKD3D_MAX_DESCRIPTOR_SET_SAMPLERS 2048u #define VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE (16 * 1024u)