From abc724e440ea1809c7c53cee42a99b68afbb1b11 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 3 Mar 2021 06:50:00 +1000 Subject: [PATCH] lavapipe: sort bindings before creating descriptor set This ensures the dynamic offsets are correct Fixes: b38879f8c5f5 ("vallium: initial import of the vulkan frontend") Reviewed-By: Mike Blumenkrantz Part-of: --- .../frontends/lavapipe/lvp_descriptor_set.c | 33 ++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/gallium/frontends/lavapipe/lvp_descriptor_set.c b/src/gallium/frontends/lavapipe/lvp_descriptor_set.c index 1df9a12..daf177b 100644 --- a/src/gallium/frontends/lavapipe/lvp_descriptor_set.c +++ b/src/gallium/frontends/lavapipe/lvp_descriptor_set.c @@ -25,6 +25,28 @@ #include "vk_util.h" #include "u_math.h" +static int binding_compare(const void* av, const void *bv) +{ + const VkDescriptorSetLayoutBinding *a = (const VkDescriptorSetLayoutBinding*)av; + const VkDescriptorSetLayoutBinding *b = (const VkDescriptorSetLayoutBinding*)bv; + + return (a->binding < b->binding) ? -1 : (a->binding > b->binding) ? 1 : 0; +} + +static VkDescriptorSetLayoutBinding * +create_sorted_bindings(const VkDescriptorSetLayoutBinding *bindings, unsigned count) { + VkDescriptorSetLayoutBinding *sorted_bindings = malloc(MAX2(count * sizeof(VkDescriptorSetLayoutBinding), 1)); + if (!sorted_bindings) + return NULL; + + if (count) { + memcpy(sorted_bindings, bindings, count * sizeof(VkDescriptorSetLayoutBinding)); + qsort(sorted_bindings, count, sizeof(VkDescriptorSetLayoutBinding), binding_compare); + } + + return sorted_bindings; +} + VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateDescriptorSetLayout( VkDevice _device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, @@ -64,10 +86,17 @@ VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateDescriptorSetLayout( set_layout->shader_stages = 0; set_layout->size = 0; - uint32_t dynamic_offset_count = 0; + VkDescriptorSetLayoutBinding *bindings = create_sorted_bindings(pCreateInfo->pBindings, + pCreateInfo->bindingCount); + if (!bindings) { + vk_object_base_finish(&set_layout->base); + vk_free2(&device->vk.alloc, pAllocator, set_layout); + return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); + } + uint32_t dynamic_offset_count = 0; for (uint32_t j = 0; j < pCreateInfo->bindingCount; j++) { - const VkDescriptorSetLayoutBinding *binding = &pCreateInfo->pBindings[j]; + const VkDescriptorSetLayoutBinding *binding = bindings + j; uint32_t b = binding->binding; set_layout->binding[b].array_size = binding->descriptorCount; -- 2.7.4