summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBas Nieuwenhuizen <[email protected]>2018-04-09 23:16:55 +0200
committerBas Nieuwenhuizen <[email protected]>2018-04-18 22:56:54 +0200
commitd02bbde1a8e6b96ca3b2e0d160c966dcb63d6c16 (patch)
treef4c1e7b22dcc9c99f4e8615b69aff1a129feee49
parentab6cadd3ecc7fbdd9079808b407674e0b19c52f0 (diff)
radv: Use sorted bindings for set layout creation.
Previously we did not care about havin the set storage in order, but for variable descriptor count we want the highest binding at the end of the storage. Reviewed-by: Samuel Pitoiset <[email protected]>
-rw-r--r--src/amd/vulkan/radv_descriptor_set.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/src/amd/vulkan/radv_descriptor_set.c b/src/amd/vulkan/radv_descriptor_set.c
index 0915f5c3552..1100ca182b1 100644
--- a/src/amd/vulkan/radv_descriptor_set.c
+++ b/src/amd/vulkan/radv_descriptor_set.c
@@ -45,6 +45,27 @@ static bool has_equal_immutable_samplers(const VkSampler *samplers, uint32_t cou
return true;
}
+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(count * sizeof(VkDescriptorSetLayoutBinding));
+ if (!sorted_bindings)
+ return NULL;
+
+ memcpy(sorted_bindings, bindings, count * sizeof(VkDescriptorSetLayoutBinding));
+
+ qsort(sorted_bindings, count, sizeof(VkDescriptorSetLayoutBinding), binding_compare);
+
+ return sorted_bindings;
+}
+
VkResult radv_CreateDescriptorSetLayout(
VkDevice _device,
const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
@@ -78,6 +99,13 @@ VkResult radv_CreateDescriptorSetLayout(
/* We just allocate all the samplers at the end of the struct */
uint32_t *samplers = (uint32_t*)&set_layout->binding[max_binding + 1];
+ VkDescriptorSetLayoutBinding *bindings = create_sorted_bindings(pCreateInfo->pBindings,
+ pCreateInfo->bindingCount);
+ if (!bindings) {
+ vk_free2(&device->alloc, pAllocator, set_layout);
+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+ }
+
set_layout->binding_count = max_binding + 1;
set_layout->shader_stages = 0;
set_layout->dynamic_shader_stages = 0;
@@ -89,7 +117,7 @@ VkResult radv_CreateDescriptorSetLayout(
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;
uint32_t alignment;
@@ -163,6 +191,8 @@ VkResult radv_CreateDescriptorSetLayout(
set_layout->shader_stages |= binding->stageFlags;
}
+ free(bindings);
+
set_layout->dynamic_offset_count = dynamic_offset_count;
*pSetLayout = radv_descriptor_set_layout_to_handle(set_layout);
@@ -188,10 +218,17 @@ void radv_GetDescriptorSetLayoutSupport(VkDevice device,
const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
VkDescriptorSetLayoutSupport* pSupport)
{
+ VkDescriptorSetLayoutBinding *bindings = create_sorted_bindings(pCreateInfo->pBindings,
+ pCreateInfo->bindingCount);
+ if (!bindings) {
+ pSupport->supported = false;
+ return;
+ }
+
bool supported = true;
uint64_t size = 0;
for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) {
- const VkDescriptorSetLayoutBinding *binding = &pCreateInfo->pBindings[i];
+ const VkDescriptorSetLayoutBinding *binding = bindings + i;
if (binding->descriptorCount == 0)
continue;
@@ -244,6 +281,8 @@ void radv_GetDescriptorSetLayoutSupport(VkDevice device,
size += binding->descriptorCount * descriptor_size;
}
+ free(bindings);
+
pSupport->supported = supported;
}