Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vulkan descriptor_count is hardcoded to large number that increases system requirements #189

Open
patowen opened this issue Sep 10, 2024 · 5 comments
Labels
documentation Improvements or additions to documentation

Comments

@patowen
Copy link
Contributor

patowen commented Sep 10, 2024

When trying to play the latest version of Hypermine on my older laptop, I see the following error message:

2024-09-10T23:00:36.823502Z ERROR Validation Error: [ VUID-VkPipelineLayoutCreateInfo-descriptorType-03016 ] | MessageID = 0x56816e61 | vkCreatePipelineLayout():  max per-stage sampler bindings count (1000) exceeds device maxPerStageDescriptorSamplers limit (64). The Vulkan spec states: The total number of descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT bit set with a descriptorType of VK_DESCRIPTOR_TYPE_SAMPLER and VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER accessible to any given shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorSamplers (https://vulkan.lunarg.com/doc/view/1.3.290.0/windows/1.3-extensions/vkspec.html#VUID-VkPipelineLayoutCreateInfo-descriptorType-03016) id=VUID-VkPipelineLayoutCreateInfo-descriptorType-03016 number=1451322977 queue_labels= cmd_labels= objects=
2024-09-10T23:00:36.824037Z ERROR Validation Error: [ VUID-VkPipelineLayoutCreateInfo-descriptorType-06939 ] | MessageID = 0x609f841b | vkCreatePipelineLayout():  max per-stage sampled image bindings count (1000) exceeds device maxPerStageDescriptorSampledImages limit (200). The Vulkan spec states: The total number of descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT bit set with a descriptorType of VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM, VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM, and VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, accessible to any given shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorSampledImages (https://vulkan.lunarg.com/doc/view/1.3.290.0/windows/1.3-extensions/vkspec.html#VUID-VkPipelineLayoutCreateInfo-descriptorType-06939) id=VUID-VkPipelineLayoutCreateInfo-descriptorType-06939 number=1621066779 queue_labels= cmd_labels= objects=
2024-09-10T23:00:36.824638Z ERROR Validation Error: [ VUID-VkPipelineLayoutCreateInfo-descriptorType-03028 ] | MessageID = 0x624a370c | vkCreatePipelineLayout():  sum of sampler bindings among all stages (1000) exceeds device maxDescriptorSetSamplers limit (576). The Vulkan spec states: The total number of descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT bit set with a descriptorType of VK_DESCRIPTOR_TYPE_SAMPLER and VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER accessible across all shader stages and across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxDescriptorSetSamplers (https://vulkan.lunarg.com/doc/view/1.3.290.0/windows/1.3-extensions/vkspec.html#VUID-VkPipelineLayoutCreateInfo-descriptorType-03028) id=VUID-VkPipelineLayoutCreateInfo-descriptorType-03028 number=1649030924 queue_labels= cmd_labels= objects=
2024-09-10T23:00:36.825203Z ERROR Validation Error: [ VUID-VkGraphicsPipelineCreateInfo-layout-01688 ] | MessageID = 0x442e1dd0 | vkCreateGraphicsPipelines(): pCreateInfos[0].pStages[1] VK_SHADER_STAGE_FRAGMENT_BIT exceeds component limit VkPhysicalDeviceLimits::maxPerStageResources (200). The Vulkan spec states: The number of resources in layout accessible to each shader stage that is used by the pipeline must be less than or equal to VkPhysicalDeviceLimits::maxPerStageResources (https://vulkan.lunarg.com/doc/view/1.3.290.0/windows/1.3-extensions/vkspec.html#VUID-VkGraphicsPipelineCreateInfo-layout-01688) id=VUID-VkGraphicsPipelineCreateInfo-layout-01688 number=1143872976 queue_labels= cmd_labels= objects=

I am unable to run the game in this state.

Searching through the yakui code, it looks like the number 1000 is hardcoded in a few places, such as

layout(set = 0, binding = 0) uniform sampler2D textures[1000];

and
descriptor_count: 1000,

This makes yakui's Vulkan code incompatible with some older computers, such as a computer with integrated graphics using an i5-8250U CPU, so I believe it's probably worth fixing.

@LPGhatguy
Copy link
Member

@kanerogers or @Ralith are best equipped to answer this in detail, but choosing 1000 here isn't very high relative to the limits on systems with up-to-date drivers. Many games request tens of thousands of textures in the same way. It's possible that the Vulkan backend should not use combined images and samplers to reach a higher limit on some systems.

The iGPU on your chip, the Intel UHD Graphics 620, has much higher limits based on reports submitted on vulkan.gpuinfo.org. There may be something up with your system drivers, and this would likely also impact some games.

@patowen
Copy link
Contributor Author

patowen commented Sep 11, 2024

When I looked up the link you gave, I see the following lines (among others):

"maxDescriptorSetSamplers": 576,
"maxPerStageDescriptorSamplers": 64,
"maxPerStageResources": 200,

Where did you see the much higher limits?

@kanerogers
Copy link
Collaborator

kanerogers commented Sep 13, 2024

Hi, @patowen!

If you look closely at the validation warning you're receiving (emphasis mine), it may shed some more light on the situation:

2024-09-10T23:00:36.823502Z ERROR Validation Error: [ VUID-VkPipelineLayoutCreateInfo-descriptorType-03016 ] | MessageID = 0x56816e61 | vkCreatePipelineLayout(): max per-stage sampler bindings count (1000) exceeds device maxPerStageDescriptorSamplers limit (64). The Vulkan spec states: The total number of descriptors in descriptor set layouts created without the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT bit set with a descriptorType of VK_DESCRIPTOR_TYPE_SAMPLER and VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER accessible to any given shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorSamplers

As @LPGhatguy noted, it's common practice to have very large numbers of sampler descriptors available on even modest hardware. On some devices such as integrated GPUs, these larger descriptor counts are only available when using the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT. These larger values can be found under Properties -> Extensions -> maxDescriptorSetUpdateAfterBindSampledImages, which for your GPU appears to be 1048576; happily, this is more than enough for yakui. :- )

If you take a look at crates/yakui-vulkan/src/descriptors.rs:46 you'll note that the descriptor layout in question has indeed been created with the VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT bit set.

What might be happening is that your Vulkan Device was not created with the descriptor_binding_sampled_image_update_after_bind enabled. To do this, construct a vk::PhysicalDeviceVulkan12Features struct with descriptor_binding_sampled_image_update_after_bind set to true, and add it to the p_next chain of your vk::DeviceCreateInfo struct, eg.

let mut vulkan_12_features = vk::PhysicalDeviceVulkan12Features::default()
	.descriptor_binding_sampled_image_update_after_bind(true);

let mut device_create_info = vk::DeviceCreateInfo::default()
	.queue_create_infos(std::slice::from_ref(&queue_info))
	.push_next(&mut vulkan_12_features)

If that does not work, I'd suggest the following:

  1. Verify that your drivers are up to date. This might sound trite, but Intel integrated GPUs in particular are notoriously difficult to correctly keep up-to-date. On my Dell laptop I had to separately install the "Intel Arc Centre" to get the correct and up to date drivers.
  2. Run the Vulkan Capacity Viewer (vulkanCapsViewer) and confirm you're able to see the same maxDescriptorSetUpdateAfterBindSampledImages limit.

We do state in the docs that the Vulkan backend requires at least Vulkan 1.2 and a GPU with support for VkPhysicalDeviceDescriptorIndexingFeatures.descriptorBindingPartiallyBound. Given the widespread support for this extension and the significant increase in convenience it grants us, it's very unlikely that we'll relax this requirement.

Please let me know how you go with the above. If you have any further questions or queries, please just let me know.

@patowen
Copy link
Contributor Author

patowen commented Sep 13, 2024

Thanks for the helpful explanation, and sorry for the false alarm! After following your advice, I was able to fix everything. I'll leave this issue open because I believe that descriptor_binding_sampled_image_update_after_bind should be added to the documentation, and there may be other changes you want to make before closing this (although I can't think of any in particular).

I've added more details below in case anyone else encounters my issue:

Hypermine did not have descriptor_binding_sampled_image_update_after_bind enabled. It did have descriptor_binding_partially_bound enabled, but that was it.

I did neglect to test the yakui examples before reporting this bug, which was an error on my part. The example on the current version of yakui does work on my laptop.

Trying your fix initially did not resolve the issue, but it seems like that was due to being on revision 273a4a1, which was before descriptor_binding_sampled_image_update_after_bind was added to the example, so it might have simply been a repeat of the bug fixed by #165.

I neglected to switch to the latest revision before reporting the bug because I assumed I already knew what the issue was and still saw the hardcoded 1000 on the latest revision of the code. I will let this be a lesson not to make too many assumptions. I admittedly was in a bit of a rush when I reported this.

Regarding updating my drivers, that is the one thing I did do before testing again and reporting this, as they were out of date. There were additional errors that had gotten fixed when I updated these drivers, so I appreciate that advice.

@kanerogers
Copy link
Collaborator

Hey, Patrick,

No stress at all!! Vulkan is a harsh mistress. 😄

So glad that you got things working. Thanks so much for bringing this to our attention; you're absolutely right that we should add something in the documentation outlining that the descriptor_binding_sampled_image_update_after_bind feature should be enabled.

Glad that the driver update worked; my uninformed observation is Intel is taking its drivers a bit more seriously with its Arc cards on the market, which should reduce headaches for developers and users alike.

@LPGhatguy LPGhatguy added the documentation Improvements or additions to documentation label Sep 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

3 participants