From b37c38c1cada402a258079c6b4e70d5783fb96c5 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Wed, 14 Oct 2015 15:18:49 -0700 Subject: [PATCH] anv: Completely rework descriptor set layouts This patch reworks a bunch of stuff in the way we do descriptor set layouts. Our previous approach had a couple of problems. First, it was based on a misunderstanding of arrays in descriptor sets. Second, it didn't properly handle descriptor sets where some bindings were missing stages. The new apporach should be correct and also makes some operations, particularly those on the hot-path, a bit easier. We use the descriptor set layout for four things: 1) To determine the map from bindings to the actual flattened descriptor set in vkUpdateDescriptorSets(). 2) To determine the descriptor <-> binding table entry mapping to use in anv_cmd_buffer_flush_descriptor_sets(). 3) To determine the mappings of dynamic indices. 4) To determine the (set, binding, array index) -> binding table entry mapping inside of shaders. The new approach is directly taylored towards these operations. --- src/vulkan/anv_cmd_buffer.c | 98 +++++++------- src/vulkan/anv_compiler.cpp | 19 ++- src/vulkan/anv_device.c | 143 ++++++--------------- src/vulkan/anv_nir_apply_dynamic_offsets.c | 10 +- src/vulkan/anv_pipeline.c | 115 ++++++++++++----- src/vulkan/anv_private.h | 52 ++++++-- 6 files changed, 222 insertions(+), 215 deletions(-) diff --git a/src/vulkan/anv_cmd_buffer.c b/src/vulkan/anv_cmd_buffer.c index 28d9dd9d694..718499d60c8 100644 --- a/src/vulkan/anv_cmd_buffer.c +++ b/src/vulkan/anv_cmd_buffer.c @@ -483,7 +483,7 @@ void anv_CmdBindDescriptorSets( cmd_buffer->state.descriptors_dirty |= set_layout->shader_stages; } - if (set_layout->num_dynamic_buffers > 0) { + if (set_layout->dynamic_offset_count > 0) { VkShaderStage s; for_each_bit(s, set_layout->shader_stages) { anv_cmd_buffer_ensure_push_constant_field(cmd_buffer, s, @@ -492,13 +492,13 @@ void anv_CmdBindDescriptorSets( cmd_buffer->state.push_constants[s]->dynamic_offsets + layout->set[firstSet + i].dynamic_offset_start; - memcpy(offsets, pDynamicOffsets + dynamic_slot, - set_layout->num_dynamic_buffers * sizeof(*pDynamicOffsets)); + typed_memcpy(offsets, pDynamicOffsets + dynamic_slot, + set_layout->dynamic_offset_count); } cmd_buffer->state.push_constants_dirty |= set_layout->shader_stages; - dynamic_slot += set_layout->num_dynamic_buffers; + dynamic_slot += set_layout->dynamic_offset_count; } } } @@ -594,41 +594,35 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer, if (layout == NULL) return VK_SUCCESS; - for (uint32_t set = 0; set < layout->num_sets; set++) { - struct anv_descriptor_set_binding *d = &cmd_buffer->state.descriptors[set]; - struct anv_descriptor_set_layout *set_layout = layout->set[set].layout; - struct anv_descriptor_slot *surface_slots = - set_layout->stage[stage].surface_start; - - uint32_t start = bias + layout->set[set].stage[stage].surface_start; - - for (uint32_t b = 0; b < set_layout->stage[stage].surface_count; b++) { - struct anv_descriptor *desc = - &d->set->descriptors[surface_slots[b].index]; - - const struct anv_state *surface_state; - struct anv_bo *bo; - uint32_t bo_offset; - - switch (desc->type) { - case ANV_DESCRIPTOR_TYPE_EMPTY: - case ANV_DESCRIPTOR_TYPE_SAMPLER: - continue; - case ANV_DESCRIPTOR_TYPE_BUFFER_VIEW: - surface_state = &desc->buffer_view->surface_state; - bo = desc->buffer_view->bo; - bo_offset = desc->buffer_view->offset; - break; - case ANV_DESCRIPTOR_TYPE_IMAGE_VIEW: - surface_state = &desc->image_view->nonrt_surface_state; - bo = desc->image_view->bo; - bo_offset = desc->image_view->offset; - break; - } - - bt_map[start + b] = surface_state->offset + state_offset; - add_surface_state_reloc(cmd_buffer, *surface_state, bo, bo_offset); + for (uint32_t s = 0; s < layout->stage[stage].surface_count; s++) { + struct anv_pipeline_binding *binding = + &layout->stage[stage].surface_to_descriptor[s]; + struct anv_descriptor_set *set = + cmd_buffer->state.descriptors[binding->set].set; + struct anv_descriptor *desc = &set->descriptors[binding->offset]; + + const struct anv_state *surface_state; + struct anv_bo *bo; + uint32_t bo_offset; + + switch (desc->type) { + case ANV_DESCRIPTOR_TYPE_EMPTY: + case ANV_DESCRIPTOR_TYPE_SAMPLER: + continue; + case ANV_DESCRIPTOR_TYPE_BUFFER_VIEW: + surface_state = &desc->buffer_view->surface_state; + bo = desc->buffer_view->bo; + bo_offset = desc->buffer_view->offset; + break; + case ANV_DESCRIPTOR_TYPE_IMAGE_VIEW: + surface_state = &desc->image_view->nonrt_surface_state; + bo = desc->image_view->bo; + bo_offset = desc->image_view->offset; + break; } + + bt_map[bias + s] = surface_state->offset + state_offset; + add_surface_state_reloc(cmd_buffer, *surface_state, bo, bo_offset); } return VK_SUCCESS; @@ -656,26 +650,20 @@ anv_cmd_buffer_emit_samplers(struct anv_cmd_buffer *cmd_buffer, if (state->map == NULL) return VK_ERROR_OUT_OF_DEVICE_MEMORY; - for (uint32_t set = 0; set < layout->num_sets; set++) { - struct anv_descriptor_set_binding *d = &cmd_buffer->state.descriptors[set]; - struct anv_descriptor_set_layout *set_layout = layout->set[set].layout; - struct anv_descriptor_slot *sampler_slots = - set_layout->stage[stage].sampler_start; - - uint32_t start = layout->set[set].stage[stage].sampler_start; + for (uint32_t s = 0; s < layout->stage[stage].sampler_count; s++) { + struct anv_pipeline_binding *binding = + &layout->stage[stage].sampler_to_descriptor[s]; + struct anv_descriptor_set *set = + cmd_buffer->state.descriptors[binding->set].set; + struct anv_descriptor *desc = &set->descriptors[binding->offset]; - for (uint32_t b = 0; b < set_layout->stage[stage].sampler_count; b++) { - struct anv_descriptor *desc = - &d->set->descriptors[sampler_slots[b].index]; + if (desc->type != ANV_DESCRIPTOR_TYPE_SAMPLER) + continue; - if (desc->type != ANV_DESCRIPTOR_TYPE_SAMPLER) - continue; + struct anv_sampler *sampler = desc->sampler; - struct anv_sampler *sampler = desc->sampler; - - memcpy(state->map + (start + b) * 16, - sampler->state, sizeof(sampler->state)); - } + memcpy(state->map + (s * 16), + sampler->state, sizeof(sampler->state)); } return VK_SUCCESS; diff --git a/src/vulkan/anv_compiler.cpp b/src/vulkan/anv_compiler.cpp index 759ec7ae4d9..bf931fe886f 100644 --- a/src/vulkan/anv_compiler.cpp +++ b/src/vulkan/anv_compiler.cpp @@ -92,13 +92,20 @@ set_binding_table_layout(struct brw_stage_prog_data *prog_data, k = bias; map = prog_data->map_entries; - for (uint32_t i = 0; i < layout->num_sets; i++) { - prog_data->bind_map[i].index = map; - for (uint32_t j = 0; j < layout->set[i].layout->stage[stage].surface_count; j++) - *map++ = k++; + for (uint32_t set = 0; set < layout->num_sets; set++) { + prog_data->bind_map[set].index = map; + unsigned index_count = 0; + for (uint32_t b = 0; b < layout->set[set].layout->binding_count; b++) { + if (layout->set[set].layout->binding[b].stage[stage].surface_index < 0) + continue; + + unsigned array_size = layout->set[set].layout->binding[b].array_size; + for (uint32_t i = 0; i < array_size; i++) + *map++ = k++; + index_count += array_size; + } - prog_data->bind_map[i].index_count = - layout->set[i].layout->stage[stage].surface_count; + prog_data->bind_map[set].index_count = index_count; } return VK_SUCCESS; diff --git a/src/vulkan/anv_device.c b/src/vulkan/anv_device.c index 9625cc61252..98c1b2334e6 100644 --- a/src/vulkan/anv_device.c +++ b/src/vulkan/anv_device.c @@ -1440,28 +1440,48 @@ VkResult anv_CreateDescriptorSetLayout( { ANV_FROM_HANDLE(anv_device, device, _device); struct anv_descriptor_set_layout *set_layout; + uint32_t s; assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO); + size_t size = sizeof(struct anv_descriptor_set_layout) + + pCreateInfo->count * sizeof(set_layout->binding[0]); + + set_layout = anv_device_alloc(device, size, 8, + VK_SYSTEM_ALLOC_TYPE_API_OBJECT); + if (!set_layout) + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + + set_layout->binding_count = pCreateInfo->count; + set_layout->shader_stages = 0; + set_layout->size = 0; + + /* Initialize all binding_layout entries to -1 */ + memset(set_layout->binding, -1, + pCreateInfo->count * sizeof(set_layout->binding[0])); + uint32_t sampler_count[VK_SHADER_STAGE_NUM] = { 0, }; uint32_t surface_count[VK_SHADER_STAGE_NUM] = { 0, }; - uint32_t num_dynamic_buffers = 0; - uint32_t count = 0; - VkShaderStageFlags stages = 0; - uint32_t s; + uint32_t dynamic_offset_count = 0; + + for (uint32_t b = 0; b < pCreateInfo->count; b++) { + uint32_t array_size = MAX2(1, pCreateInfo->pBinding[b].arraySize); + set_layout->binding[b].array_size = array_size; + set_layout->size += array_size; - for (uint32_t i = 0; i < pCreateInfo->count; i++) { - switch (pCreateInfo->pBinding[i].descriptorType) { + switch (pCreateInfo->pBinding[b].descriptorType) { case VK_DESCRIPTOR_TYPE_SAMPLER: case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - for_each_bit(s, pCreateInfo->pBinding[i].stageFlags) - sampler_count[s] += pCreateInfo->pBinding[i].arraySize; + for_each_bit(s, pCreateInfo->pBinding[b].stageFlags) { + set_layout->binding[b].stage[s].sampler_index = sampler_count[s]; + sampler_count[s] += array_size; + } break; default: break; } - switch (pCreateInfo->pBinding[i].descriptorType) { + switch (pCreateInfo->pBinding[b].descriptorType) { case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: @@ -1472,114 +1492,29 @@ VkResult anv_CreateDescriptorSetLayout( case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: - for_each_bit(s, pCreateInfo->pBinding[i].stageFlags) - surface_count[s] += pCreateInfo->pBinding[i].arraySize; + for_each_bit(s, pCreateInfo->pBinding[b].stageFlags) { + set_layout->binding[b].stage[s].surface_index = surface_count[s]; + surface_count[s] += array_size; + } break; default: break; } - switch (pCreateInfo->pBinding[i].descriptorType) { + switch (pCreateInfo->pBinding[b].descriptorType) { case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - num_dynamic_buffers += pCreateInfo->pBinding[i].arraySize; + set_layout->binding[b].dynamic_offset_index = dynamic_offset_count; + dynamic_offset_count += array_size; break; default: break; } - stages |= pCreateInfo->pBinding[i].stageFlags; - count += pCreateInfo->pBinding[i].arraySize; + set_layout->shader_stages |= pCreateInfo->pBinding[b].stageFlags; } - uint32_t sampler_total = 0; - uint32_t surface_total = 0; - for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) { - sampler_total += sampler_count[s]; - surface_total += surface_count[s]; - } - - size_t size = sizeof(*set_layout) + - (sampler_total + surface_total) * sizeof(set_layout->entries[0]); - set_layout = anv_device_alloc(device, size, 8, - VK_SYSTEM_ALLOC_TYPE_API_OBJECT); - if (!set_layout) - return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); - - set_layout->num_dynamic_buffers = num_dynamic_buffers; - set_layout->count = count; - set_layout->shader_stages = stages; - - struct anv_descriptor_slot *p = set_layout->entries; - struct anv_descriptor_slot *sampler[VK_SHADER_STAGE_NUM]; - struct anv_descriptor_slot *surface[VK_SHADER_STAGE_NUM]; - for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) { - set_layout->stage[s].surface_count = surface_count[s]; - set_layout->stage[s].surface_start = surface[s] = p; - p += surface_count[s]; - set_layout->stage[s].sampler_count = sampler_count[s]; - set_layout->stage[s].sampler_start = sampler[s] = p; - p += sampler_count[s]; - } - - uint32_t descriptor = 0; - int8_t dynamic_slot = 0; - bool is_dynamic; - for (uint32_t i = 0; i < pCreateInfo->count; i++) { - switch (pCreateInfo->pBinding[i].descriptorType) { - case VK_DESCRIPTOR_TYPE_SAMPLER: - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - for_each_bit(s, pCreateInfo->pBinding[i].stageFlags) - for (uint32_t j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) { - sampler[s]->index = descriptor + j; - sampler[s]->dynamic_slot = -1; - sampler[s]++; - } - break; - default: - break; - } - - switch (pCreateInfo->pBinding[i].descriptorType) { - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - is_dynamic = true; - break; - default: - is_dynamic = false; - break; - } - - switch (pCreateInfo->pBinding[i].descriptorType) { - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: - for_each_bit(s, pCreateInfo->pBinding[i].stageFlags) - for (uint32_t j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) { - surface[s]->index = descriptor + j; - if (is_dynamic) - surface[s]->dynamic_slot = dynamic_slot + j; - else - surface[s]->dynamic_slot = -1; - surface[s]++; - } - break; - default: - break; - } - - if (is_dynamic) - dynamic_slot += pCreateInfo->pBinding[i].arraySize; - - descriptor += pCreateInfo->pBinding[i].arraySize; - } + set_layout->dynamic_offset_count = dynamic_offset_count; *pSetLayout = anv_descriptor_set_layout_to_handle(set_layout); @@ -1627,7 +1562,7 @@ anv_descriptor_set_create(struct anv_device *device, struct anv_descriptor_set **out_set) { struct anv_descriptor_set *set; - size_t size = sizeof(*set) + layout->count * sizeof(set->descriptors[0]); + size_t size = sizeof(*set) + layout->size * sizeof(set->descriptors[0]); set = anv_device_alloc(device, size, 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT); if (!set) diff --git a/src/vulkan/anv_nir_apply_dynamic_offsets.c b/src/vulkan/anv_nir_apply_dynamic_offsets.c index 1f6c64a9e02..9d29c3c23ea 100644 --- a/src/vulkan/anv_nir_apply_dynamic_offsets.c +++ b/src/vulkan/anv_nir_apply_dynamic_offsets.c @@ -39,7 +39,6 @@ apply_dynamic_offsets_block(nir_block *block, void *void_state) { struct apply_dynamic_offsets_state *state = void_state; struct anv_descriptor_set_layout *set_layout; - const struct anv_descriptor_slot *slot; nir_foreach_instr_safe(block, instr) { if (instr->type != nir_instr_type_intrinsic) @@ -69,19 +68,18 @@ apply_dynamic_offsets_block(nir_block *block, void *void_state) } set_layout = state->layout->set[set].layout; - slot = &set_layout->stage[state->stage].surface_start[binding]; - if (slot->dynamic_slot < 0) + if (set_layout->binding[binding].dynamic_offset_index < 0) continue; - uint32_t dynamic_index = state->layout->set[set].dynamic_offset_start + - slot->dynamic_slot; + uint32_t index = state->layout->set[set].dynamic_offset_start + + set_layout->binding[binding].dynamic_offset_index; state->builder.cursor = nir_before_instr(&intrin->instr); nir_intrinsic_instr *offset_load = nir_intrinsic_instr_create(state->shader, nir_intrinsic_load_uniform); offset_load->num_components = 1; - offset_load->const_index[0] = state->indices_start + dynamic_index; + offset_load->const_index[0] = state->indices_start + index; offset_load->const_index[1] = 0; nir_ssa_dest_init(&offset_load->instr, &offset_load->dest, 1, NULL); nir_builder_instr_insert(&state->builder, &offset_load->instr); diff --git a/src/vulkan/anv_pipeline.c b/src/vulkan/anv_pipeline.c index 75f640154cc..84e023c781a 100644 --- a/src/vulkan/anv_pipeline.c +++ b/src/vulkan/anv_pipeline.c @@ -458,48 +458,101 @@ VkResult anv_CreatePipelineLayout( VkPipelineLayout* pPipelineLayout) { ANV_FROM_HANDLE(anv_device, device, _device); - struct anv_pipeline_layout *layout; + struct anv_pipeline_layout l, *layout; assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO); - layout = anv_device_alloc(device, sizeof(*layout), 8, - VK_SYSTEM_ALLOC_TYPE_API_OBJECT); - if (layout == NULL) - return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + l.num_sets = pCreateInfo->descriptorSetCount; + + unsigned dynamic_offset_count = 0; + + memset(l.stage, 0, sizeof(l.stage)); + for (uint32_t set = 0; set < pCreateInfo->descriptorSetCount; set++) { + ANV_FROM_HANDLE(anv_descriptor_set_layout, set_layout, + pCreateInfo->pSetLayouts[set]); + l.set[set].layout = set_layout; + + l.set[set].dynamic_offset_start = dynamic_offset_count; + for (uint32_t b = 0; b < set_layout->binding_count; b++) { + if (set_layout->binding[b].dynamic_offset_index >= 0) + dynamic_offset_count += set_layout->binding[b].array_size; + } + + for (VkShaderStage s = 0; s < VK_SHADER_STAGE_NUM; s++) { + l.set[set].stage[s].surface_start = l.stage[s].surface_count; + l.set[set].stage[s].sampler_start = l.stage[s].sampler_count; + + for (uint32_t b = 0; b < set_layout->binding_count; b++) { + unsigned array_size = set_layout->binding[b].array_size; - layout->num_sets = pCreateInfo->descriptorSetCount; + if (set_layout->binding[b].stage[s].surface_index >= 0) { + l.stage[s].surface_count += array_size; - uint32_t surface_start[VK_SHADER_STAGE_NUM] = { 0, }; - uint32_t sampler_start[VK_SHADER_STAGE_NUM] = { 0, }; + if (set_layout->binding[b].dynamic_offset_index >= 0) + l.stage[s].has_dynamic_offsets = true; + } - for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) { - layout->stage[s].has_dynamic_offsets = false; - layout->stage[s].surface_count = 0; - layout->stage[s].sampler_count = 0; + if (set_layout->binding[b].stage[s].sampler_index >= 0) + l.stage[s].sampler_count += array_size; + } + } } - uint32_t num_dynamic_offsets = 0; - for (uint32_t i = 0; i < pCreateInfo->descriptorSetCount; i++) { - ANV_FROM_HANDLE(anv_descriptor_set_layout, set_layout, - pCreateInfo->pSetLayouts[i]); - - layout->set[i].layout = set_layout; - layout->set[i].dynamic_offset_start = num_dynamic_offsets; - num_dynamic_offsets += set_layout->num_dynamic_buffers; - for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) { - if (set_layout->num_dynamic_buffers > 0) - layout->stage[s].has_dynamic_offsets = true; - - layout->set[i].stage[s].surface_start = surface_start[s]; - surface_start[s] += set_layout->stage[s].surface_count; - layout->set[i].stage[s].sampler_start = sampler_start[s]; - sampler_start[s] += set_layout->stage[s].sampler_count; - - layout->stage[s].surface_count += set_layout->stage[s].surface_count; - layout->stage[s].sampler_count += set_layout->stage[s].sampler_count; + unsigned num_bindings = 0; + for (VkShaderStage s = 0; s < VK_SHADER_STAGE_NUM; s++) + num_bindings += l.stage[s].surface_count + l.stage[s].sampler_count; + + size_t size = sizeof(*layout) + num_bindings * sizeof(layout->entries[0]); + + layout = anv_device_alloc(device, size, 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT); + if (layout == NULL) + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + + /* Now we can actually build our surface and sampler maps */ + struct anv_pipeline_binding *entry = layout->entries; + for (VkShaderStage s = 0; s < VK_SHADER_STAGE_NUM; s++) { + l.stage[s].surface_to_descriptor = entry; + entry += l.stage[s].surface_count; + l.stage[s].sampler_to_descriptor = entry; + entry += l.stage[s].sampler_count; + + int surface = 0; + int sampler = 0; + for (uint32_t set = 0; set < pCreateInfo->descriptorSetCount; set++) { + struct anv_descriptor_set_layout *set_layout = l.set[set].layout; + + unsigned set_offset = 0; + for (uint32_t b = 0; b < set_layout->binding_count; b++) { + unsigned array_size = set_layout->binding[b].array_size; + + if (set_layout->binding[b].stage[s].surface_index >= 0) { + assert(surface == l.set[set].stage[s].surface_start + + set_layout->binding[b].stage[s].surface_index); + for (unsigned i = 0; i < array_size; i++) { + l.stage[s].surface_to_descriptor[surface + i].set = set; + l.stage[s].surface_to_descriptor[surface + i].offset = set_offset + i; + } + surface += array_size; + } + + if (set_layout->binding[b].stage[s].sampler_index >= 0) { + assert(sampler == l.set[set].stage[s].sampler_start + + set_layout->binding[b].stage[s].sampler_index); + for (unsigned i = 0; i < array_size; i++) { + l.stage[s].sampler_to_descriptor[sampler + i].set = set; + l.stage[s].sampler_to_descriptor[sampler + i].offset = set_offset + i; + } + sampler += array_size; + } + + set_offset += array_size; + } } } + /* Finally, we're done setting it up, copy into the allocated version */ + *layout = l; + *pPipelineLayout = anv_pipeline_layout_to_handle(layout); return VK_SUCCESS; diff --git a/src/vulkan/anv_private.h b/src/vulkan/anv_private.h index 6bc781fa072..523e6dfa747 100644 --- a/src/vulkan/anv_private.h +++ b/src/vulkan/anv_private.h @@ -660,23 +660,37 @@ struct anv_device_memory { void * map; }; -struct anv_descriptor_slot { - int8_t dynamic_slot; - uint8_t index; -}; +struct anv_descriptor_set_binding_layout { + /* Number of array elements in this binding */ + uint16_t array_size; + + /* Index into the dynamic state array for a dynamic buffer */ + int16_t dynamic_offset_index; -struct anv_descriptor_set_layout { struct { - uint32_t surface_count; - struct anv_descriptor_slot *surface_start; - uint32_t sampler_count; - struct anv_descriptor_slot *sampler_start; + /* Index into the binding table for the associated surface */ + int16_t surface_index; + + /* Index into the sampler table for the associated sampler */ + int16_t sampler_index; } stage[VK_SHADER_STAGE_NUM]; +}; + +struct anv_descriptor_set_layout { + /* Number of bindings in this descriptor set */ + uint16_t binding_count; + + /* Total size of the descriptor set with room for all array entries */ + uint16_t size; + + /* Shader stages affected by this descriptor set */ + uint16_t shader_stages; + + /* Number of dynamic offsets used by this descriptor set */ + uint16_t dynamic_offset_count; - uint32_t count; - uint32_t num_dynamic_buffers; - VkShaderStageFlags shader_stages; - struct anv_descriptor_slot entries[0]; + /* Don't use this directly */ + struct anv_descriptor_set_binding_layout binding[0]; }; enum anv_descriptor_type { @@ -718,6 +732,14 @@ anv_descriptor_set_destroy(struct anv_device *device, #define MAX_DYNAMIC_BUFFERS 16 #define MAX_IMAGES 8 +struct anv_pipeline_binding { + /* The descriptor set this surface corresponds to */ + uint16_t set; + + /* Offset into the descriptor set */ + uint16_t offset; +}; + struct anv_pipeline_layout { struct { struct anv_descriptor_set_layout *layout; @@ -733,8 +755,12 @@ struct anv_pipeline_layout { struct { bool has_dynamic_offsets; uint32_t surface_count; + struct anv_pipeline_binding *surface_to_descriptor; uint32_t sampler_count; + struct anv_pipeline_binding *sampler_to_descriptor; } stage[VK_SHADER_STAGE_NUM]; + + struct anv_pipeline_binding entries[0]; }; struct anv_buffer { -- 2.30.2