From 77cd629b34f67b7035ae9c167ce1fedefe75ce32 Mon Sep 17 00:00:00 2001 From: Mel Henning Date: Thu, 16 Oct 2025 16:30:13 -0400 Subject: [PATCH] nvk: Really fix maxVariableDescriptorCount w/ iub I didn't test "nvk: Fix maxVariableDescriptorCount with iub" as thoroughly as I should have and it regressed dEQP-VK.api.maintenance3_check.descriptor_set because we were then violating the requirement that maxPerSetDescriptors describes a limit that's guaranteed to be supported (and reported as supported in GetDescriptorSetLayoutSupport). That commit was also based on a misreading of nvk_nir_lower_descriptors.c where I thought that the end offset of an inline uniform block needed to be less than the size of a UBO. That is not the case - on closer inspection that code gracefully falls back to placing IUBs in globablmem if necessary. So, we can afford to be less strict about our IUB sizing and only require that IUBs follow the existing limit imposed by maxInlineUniformBlockSize. Fixes: ff7f785f09ce ("nvk: Fix maxVariableDescriptorCount with iub") Reviewed-by: Faith Ekstrand Part-of: --- .../vulkan/nvk_descriptor_set_layout.c | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/nouveau/vulkan/nvk_descriptor_set_layout.c b/src/nouveau/vulkan/nvk_descriptor_set_layout.c index 402bca2c4a8..c99562b170e 100644 --- a/src/nouveau/vulkan/nvk_descriptor_set_layout.c +++ b/src/nouveau/vulkan/nvk_descriptor_set_layout.c @@ -474,9 +474,6 @@ nvk_GetDescriptorSetLayoutSupport(VkDevice device, assert(stride <= UINT8_MAX); assert(util_is_power_of_two_nonzero(alignment)); - variable_is_inline_uniform_block = - binding->descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK; - if (flags & VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT) { /* From the Vulkan 1.3.256 spec: * @@ -486,6 +483,9 @@ nvk_GetDescriptorSetLayoutSupport(VkDevice device, */ variable_count = MAX2(1, binding->descriptorCount); variable_stride = stride; + + variable_is_inline_uniform_block = + binding->descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK; } else { /* Since we're aligning to the maximum and since this is just a * check for whether or not the max buffer size is big enough, we @@ -507,8 +507,6 @@ nvk_GetDescriptorSetLayoutSupport(VkDevice device, if (pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR) max_buffer_size = NVK_MAX_PUSH_DESCRIPTORS * nvk_max_descriptor_size(&pdev->info); - else if (variable_is_inline_uniform_block) - max_buffer_size = NVK_MAX_INLINE_UNIFORM_BLOCK_SIZE; else max_buffer_size = NVK_MAX_DESCRIPTOR_SET_SIZE; @@ -519,12 +517,21 @@ nvk_GetDescriptorSetLayoutSupport(VkDevice device, switch (ext->sType) { case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT: { VkDescriptorSetVariableDescriptorCountLayoutSupport *vs = (void *)ext; + uint32_t max_var_count; + if (variable_stride > 0) { - vs->maxVariableDescriptorCount = + max_var_count = (max_buffer_size - non_variable_size) / variable_stride; } else { - vs->maxVariableDescriptorCount = 0; + max_var_count = 0; } + + if (variable_is_inline_uniform_block) { + max_var_count = + MIN2(max_var_count, NVK_MAX_INLINE_UNIFORM_BLOCK_SIZE); + } + + vs->maxVariableDescriptorCount = max_var_count; break; }