v2: Drop a memset by using zalloc (Jason) Decouple vulkan descriptors from the underlying binding table (Jason)
Signed-off-by: Lionel Landwerlin <lionel.g.landwer...@intel.com> --- src/intel/vulkan/anv_descriptor_set.c | 24 ++++++++- src/intel/vulkan/anv_nir_apply_pipeline_layout.c | 66 ++++++++++++++---------- src/intel/vulkan/anv_private.h | 22 ++++++++ src/intel/vulkan/genX_cmd_buffer.c | 17 +++--- src/intel/vulkan/genX_state.c | 2 + 5 files changed, 97 insertions(+), 34 deletions(-) diff --git a/src/intel/vulkan/anv_descriptor_set.c b/src/intel/vulkan/anv_descriptor_set.c index 84077982307..704693e227f 100644 --- a/src/intel/vulkan/anv_descriptor_set.c +++ b/src/intel/vulkan/anv_descriptor_set.c @@ -35,6 +35,21 @@ * Descriptor set layouts. */ +static uint32_t +layout_binding_get_hw_binding_size(const VkDescriptorSetLayoutBinding *binding) +{ + if (binding->pImmutableSamplers == NULL) + return binding->descriptorCount; + + uint32_t immutable_sampler_count = 0; + for (uint32_t i = 0; i < binding->descriptorCount; i++) { + ANV_FROM_HANDLE(anv_sampler, sampler, binding->pImmutableSamplers[i]); + immutable_sampler_count += sampler->n_planes; + } + + return immutable_sampler_count; +} + VkResult anv_CreateDescriptorSetLayout( VkDevice _device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, @@ -75,6 +90,7 @@ VkResult anv_CreateDescriptorSetLayout( set_layout->binding[b].array_size = 0; set_layout->binding[b].immutable_samplers = NULL; + set_layout->binding[b].hw_binding_size = 0; } /* Initialize all samplers to 0 */ @@ -108,8 +124,13 @@ VkResult anv_CreateDescriptorSetLayout( set_layout->binding[b].type = binding->descriptorType; #endif set_layout->binding[b].array_size = binding->descriptorCount; + set_layout->binding[b].hw_binding_size = + layout_binding_get_hw_binding_size(binding); set_layout->binding[b].descriptor_index = set_layout->size; + set_layout->binding[b].hw_binding_index = set_layout->hw_size; + set_layout->size += binding->descriptorCount; + set_layout->hw_size += set_layout->binding[b].hw_binding_size; switch (binding->descriptorType) { case VK_DESCRIPTOR_TYPE_SAMPLER: @@ -323,6 +344,8 @@ VkResult anv_CreateDescriptorPool( case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: buffer_count += pCreateInfo->pPoolSizes[i].descriptorCount; + /* Fallthrough */ + default: descriptor_count += pCreateInfo->pPoolSizes[i].descriptorCount; break; @@ -612,7 +635,6 @@ anv_descriptor_set_write_image_view(struct anv_descriptor_set *set, sampler = bind_layout->immutable_samplers ? bind_layout->immutable_samplers[element] : sampler; - *desc = (struct anv_descriptor) { .type = type, .layout = info->imageLayout, diff --git a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c index 67bcf5e29ef..428cfdf42d1 100644 --- a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c +++ b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c @@ -130,7 +130,7 @@ lower_res_index_intrinsic(nir_intrinsic_instr *intrin, static void lower_tex_deref(nir_tex_instr *tex, nir_deref_var *deref, - unsigned *const_index, unsigned array_size, + unsigned *const_index, unsigned hw_binding_size, nir_tex_src_type src_type, struct apply_pipeline_layout_state *state) { @@ -146,7 +146,7 @@ lower_tex_deref(nir_tex_instr *tex, nir_deref_var *deref, nir_ssa_for_src(b, deref_array->indirect, 1)); if (state->add_bounds_checks) - index = nir_umin(b, index, nir_imm_int(b, array_size - 1)); + index = nir_umin(b, index, nir_imm_int(b, hw_binding_size - 1)); nir_tex_src *new_srcs = rzalloc_array(tex, nir_tex_src, tex->num_srcs + 1); @@ -167,7 +167,7 @@ lower_tex_deref(nir_tex_instr *tex, nir_deref_var *deref, nir_src_for_ssa(index)); tex->num_srcs++; } else { - *const_index += MIN2(deref_array->base_offset, array_size - 1); + *const_index += MIN2(deref_array->base_offset, hw_binding_size - 1); } } } @@ -196,19 +196,18 @@ lower_tex(nir_tex_instr *tex, struct apply_pipeline_layout_state *state) unsigned set = tex->texture->var->data.descriptor_set; unsigned binding = tex->texture->var->data.binding; - unsigned array_size = - state->layout->set[set].layout->binding[binding].array_size; + unsigned hw_binding_size = + state->layout->set[set].layout->binding[binding].hw_binding_size; tex->texture_index = state->set[set].surface_offsets[binding]; - lower_tex_deref(tex, tex->texture, &tex->texture_index, array_size, + lower_tex_deref(tex, tex->texture, &tex->texture_index, hw_binding_size, nir_tex_src_texture_offset, state); if (tex->sampler) { unsigned set = tex->sampler->var->data.descriptor_set; unsigned binding = tex->sampler->var->data.binding; - unsigned array_size = - state->layout->set[set].layout->binding[binding].array_size; - tex->sampler_index = state->set[set].sampler_offsets[binding]; - lower_tex_deref(tex, tex->sampler, &tex->sampler_index, array_size, + unsigned hw_binding_size = + state->layout->set[set].layout->binding[binding].hw_binding_size; + lower_tex_deref(tex, tex->sampler, &tex->sampler_index, hw_binding_size, nir_tex_src_sampler_offset, state); } @@ -300,9 +299,9 @@ anv_nir_apply_pipeline_layout(struct anv_pipeline *pipeline, BITSET_FOREACH_SET(b, _tmp, state.set[set].used, set_layout->binding_count) { if (set_layout->binding[b].stage[shader->stage].surface_index >= 0) - map->surface_count += set_layout->binding[b].array_size; + map->surface_count += set_layout->binding[b].hw_binding_size; if (set_layout->binding[b].stage[shader->stage].sampler_index >= 0) - map->sampler_count += set_layout->binding[b].array_size; + map->sampler_count += set_layout->binding[b].hw_binding_size; if (set_layout->binding[b].stage[shader->stage].image_index >= 0) map->image_count += set_layout->binding[b].array_size; } @@ -317,31 +316,44 @@ anv_nir_apply_pipeline_layout(struct anv_pipeline *pipeline, BITSET_WORD b, _tmp; BITSET_FOREACH_SET(b, _tmp, state.set[set].used, set_layout->binding_count) { - unsigned array_size = set_layout->binding[b].array_size; + struct anv_descriptor_set_binding_layout *binding = + &set_layout->binding[b]; - if (set_layout->binding[b].stage[shader->stage].surface_index >= 0) { + if (binding->stage[shader->stage].surface_index >= 0) { state.set[set].surface_offsets[b] = surface; - for (unsigned i = 0; i < array_size; i++) { - map->surface_to_descriptor[surface + i].set = set; - map->surface_to_descriptor[surface + i].binding = b; - map->surface_to_descriptor[surface + i].index = i; + for (unsigned i = 0; i < binding->array_size; i++) { + struct anv_sampler *sampler = binding->immutable_samplers ? + binding->immutable_samplers[i] : NULL; + uint8_t planes = sampler ? sampler->n_planes : 1; + for (uint8_t p = 0; p < planes; p++) { + map->surface_to_descriptor[surface + i + p].set = set; + map->surface_to_descriptor[surface + i + p].binding = b; + map->surface_to_descriptor[surface + i + p].index = i; + map->surface_to_descriptor[surface + i + p].plane = p; + } } - surface += array_size; + surface += binding->hw_binding_size; } - if (set_layout->binding[b].stage[shader->stage].sampler_index >= 0) { + if (binding->stage[shader->stage].sampler_index >= 0) { state.set[set].sampler_offsets[b] = sampler; - for (unsigned i = 0; i < array_size; i++) { - map->sampler_to_descriptor[sampler + i].set = set; - map->sampler_to_descriptor[sampler + i].binding = b; - map->sampler_to_descriptor[sampler + i].index = i; + for (unsigned i = 0; i < binding->array_size; i++) { + struct anv_sampler *anv_sampler = binding->immutable_samplers ? + binding->immutable_samplers[i] : NULL; + uint8_t planes = anv_sampler ? anv_sampler->n_planes : 1; + for (uint8_t p = 0; p < planes; p++) { + map->sampler_to_descriptor[sampler + i + p].set = set; + map->sampler_to_descriptor[sampler + i + p].binding = b; + map->sampler_to_descriptor[sampler + i + p].index = i; + map->surface_to_descriptor[surface + i + p].plane = p; + } } - sampler += array_size; + sampler += binding->hw_binding_size; } - if (set_layout->binding[b].stage[shader->stage].image_index >= 0) { + if (binding->stage[shader->stage].image_index >= 0) { state.set[set].image_offsets[b] = image; - image += array_size; + image += binding->array_size; } } } diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 77ae7bb14dd..c2ce8ee43f7 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -1197,6 +1197,19 @@ struct anv_descriptor_set_binding_layout { int16_t image_index; } stage[MESA_SHADER_STAGES]; + /* Index into the dynamic state array for a dynamic buffer */ + int16_t hw_dynamic_offset_index; + + /* Index into the flattend hardware binding table (might differ from + * descriptor_index because of mutliplanar surfaces) + */ + uint16_t hw_binding_index; + + /* Number of hardware binding to used in this binding (might differ from + * array_size because of multiplanar surfaces) + */ + uint16_t hw_binding_size; + /* Immutable samplers (or NULL if no immutable samplers) */ struct anv_sampler **immutable_samplers; }; @@ -1208,6 +1221,11 @@ struct anv_descriptor_set_layout { /* Total size of the descriptor set with room for all array entries */ uint16_t size; + /* Total size of the hardware binding table (might differ from size because + * of multiplanar surfaces) + */ + uint16_t hw_size; + /* Shader stages affected by this descriptor set */ uint16_t shader_stages; @@ -1385,6 +1403,9 @@ struct anv_pipeline_binding { /* Index in the binding */ uint32_t index; + /* Plane in the binding index */ + uint8_t plane; + /* Input attachment index (relative to the subpass) */ uint8_t input_attachment_index; @@ -2541,6 +2562,7 @@ void anv_fill_buffer_surface_state(struct anv_device *device, struct anv_sampler { uint32_t state[4]; + uint32_t n_planes; }; struct anv_framebuffer { diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 35593990198..367fddcf02a 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -1505,8 +1505,7 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer, uint32_t bo_offset = cmd_buffer->state.num_workgroups_offset; struct anv_state surface_state; - surface_state = - anv_cmd_buffer_alloc_surface_state(cmd_buffer); + surface_state = anv_cmd_buffer_alloc_surface_state(cmd_buffer); const enum isl_format format = anv_isl_format_for_descriptor_type(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); @@ -1532,7 +1531,6 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer, uint32_t image = 0; for (uint32_t s = 0; s < map->surface_count; s++) { struct anv_pipeline_binding *binding = &map->surface_to_descriptor[s]; - struct anv_state surface_state; if (binding->set == ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS) { @@ -1722,7 +1720,8 @@ emit_samplers(struct anv_cmd_buffer *cmd_buffer, if (state->map == NULL) return VK_ERROR_OUT_OF_DEVICE_MEMORY; - for (uint32_t s = 0; s < map->sampler_count; s++) { + uint32_t s = 0; + while (s < map->sampler_count) { struct anv_pipeline_binding *binding = &map->sampler_to_descriptor[s]; struct anv_descriptor_set *set = cmd_buffer->state.descriptors[binding->set]; @@ -1730,19 +1729,25 @@ emit_samplers(struct anv_cmd_buffer *cmd_buffer, struct anv_descriptor *desc = &set->descriptors[offset + binding->index]; if (desc->type != VK_DESCRIPTOR_TYPE_SAMPLER && - desc->type != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) + desc->type != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) { + s += 1; continue; + } struct anv_sampler *sampler = desc->sampler; /* This can happen if we have an unfilled slot since TYPE_SAMPLER * happens to be zero. */ - if (sampler == NULL) + if (sampler == NULL) { + s += 1; continue; + } memcpy(state->map + (s * 16), sampler->state, sizeof(sampler->state)); + + s += sampler->n_planes; } anv_state_flush(cmd_buffer->device, *state); diff --git a/src/intel/vulkan/genX_state.c b/src/intel/vulkan/genX_state.c index d016aff4a54..81570825a54 100644 --- a/src/intel/vulkan/genX_state.c +++ b/src/intel/vulkan/genX_state.c @@ -171,6 +171,8 @@ VkResult genX(CreateSampler)( if (!sampler) return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + sampler->n_planes = 1; + uint32_t border_color_offset = device->border_colors.offset + pCreateInfo->borderColor * 64; -- 2.14.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev