summaryrefslogtreecommitdiff
path: root/src/amd
diff options
context:
space:
mode:
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>2018-04-09 23:16:55 +0200
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>2018-04-18 22:56:54 +0200
commitd02bbde1a8e6b96ca3b2e0d160c966dcb63d6c16 (patch)
treef4c1e7b22dcc9c99f4e8615b69aff1a129feee49 /src/amd
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 <samuel.pitoiset@gmail.com>
Diffstat (limited to 'src/amd')
-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 0915f5c355..1100ca182b 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;
}