[Mesa-dev] [PATCH v5 08/16] anv/apply_pipeline_layout: Prepare for multi-planar images

Jason Ekstrand jason at jlekstrand.net
Fri Oct 6 14:52:03 UTC 2017


On Fri, Oct 6, 2017 at 6:31 AM, Lionel Landwerlin <
lionel.g.landwerlin at intel.com> wrote:

> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
> Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>
> ---
>  src/intel/vulkan/anv_descriptor_set.c            |  13 +++
>  src/intel/vulkan/anv_nir_apply_pipeline_layout.c | 113
> ++++++++++++++++++-----
>  src/intel/vulkan/anv_private.h                   |   7 ++
>  src/intel/vulkan/genX_state.c                    |   2 +
>  4 files changed, 113 insertions(+), 22 deletions(-)
>
> diff --git a/src/intel/vulkan/anv_descriptor_set.c b/src/intel/vulkan/anv_
> descriptor_set.c
> index 84077982307..629c041eedf 100644
> --- a/src/intel/vulkan/anv_descriptor_set.c
> +++ b/src/intel/vulkan/anv_descriptor_set.c
> @@ -400,6 +400,19 @@ anv_descriptor_set_layout_size(const struct
> anv_descriptor_set_layout *layout)
>        layout->buffer_count * sizeof(struct anv_buffer_view);
>  }
>
> +size_t
> +anv_descriptor_set_binding_layout_get_hw_size(const struct
> anv_descriptor_set_binding_layout *binding)
> +{
> +   if (!binding->immutable_samplers)
> +      return binding->array_size;
> +
> +   uint32_t total_plane_count = 0;
> +   for (uint32_t i = 0; i < binding->array_size; i++)
> +      total_plane_count += binding->immutable_samplers[i]->n_planes;
> +
> +   return total_plane_count;
> +}
> +
>  struct surface_state_free_list_entry {
>     void *next;
>     struct anv_state state;
> diff --git a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c
> b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c
> index 67bcf5e29ef..02323fba31a 100644
> --- a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c
> +++ b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c
> @@ -131,7 +131,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,
> -                nir_tex_src_type src_type,
> +                nir_tex_src_type src_type, bool allow_indirect,
>                  struct apply_pipeline_layout_state *state)
>  {
>     nir_builder *b = &state->builder;
> @@ -141,6 +141,15 @@ lower_tex_deref(nir_tex_instr *tex, nir_deref_var
> *deref,
>        nir_deref_array *deref_array = nir_deref_as_array(deref->
> deref.child);
>
>        if (deref_array->deref_array_type == nir_deref_array_type_indirect)
> {
> +         /* From VK_KHR_sampler_ycbcr_conversion:
> +          *
> +          * If sampler Y’CBCR conversion is enabled, the combined image
> +          * sampler must be indexed only by constant integral expressions
> when
> +          * aggregated into arrays in shader code, irrespective of the
> +          * shaderSampledImageArrayDynamicIndexing feature.
> +          */
> +         assert(allow_indirect);
> +
>           nir_ssa_def *index =
>              nir_iadd(b, nir_imm_int(b, deref_array->base_offset),
>                          nir_ssa_for_src(b, deref_array->indirect, 1));
> @@ -186,6 +195,46 @@ cleanup_tex_deref(nir_tex_instr *tex, nir_deref_var
> *deref)
>     nir_instr_rewrite_src(&tex->instr, &deref_array->indirect,
> NIR_SRC_INIT);
>  }
>
> +static bool
> +has_tex_src_plane(nir_tex_instr *tex)
> +{
> +   for (unsigned i = 0; i < tex->num_srcs; i++) {
> +      if (tex->src[i].src_type == nir_tex_src_plane)
> +         return true;
> +   }
> +
> +   return false;
> +}
> +
> +static uint32_t
> +extract_tex_src_plane(nir_tex_instr *tex)
> +{
> +   nir_tex_src *new_srcs = rzalloc_array(tex, nir_tex_src, tex->num_srcs
> - 1);
> +   unsigned plane = 0;
> +
> +   for (unsigned i = 0, w = 0; i < tex->num_srcs; i++) {
> +      if (tex->src[i].src_type == nir_tex_src_plane) {
> +         nir_const_value *const_plane =
> +            nir_src_as_const_value(tex->src[i].src);
> +
> +         /* Our color conversion lowering pass should only ever insert
> +          * constants. */
> +         assert(const_plane);
> +         plane = const_plane->u32[0];
>

As I mentioned on IRC today, we need to do

nir_instr_rewrite_src(&tex->instr, &tex->src[i].src, NIR_SRC_INIT);

here to get rid of the reference that he source carries to the load_const
SSA def.  Sorry that's not terribly intuitive.


> +      } else {
> +         new_srcs[w].src_type = tex->src[i].src_type;
> +         nir_instr_move_src(&tex->instr, &new_srcs[w].src,
> &tex->src[i].src);
> +         w++;
> +      }
> +   }
> +
> +   ralloc_free(tex->src);
> +   tex->src = new_srcs;
> +   tex->num_srcs--;
> +
> +   return plane;
> +}
> +
>  static void
>  lower_tex(nir_tex_instr *tex, struct apply_pipeline_layout_state *state)
>  {
> @@ -198,9 +247,13 @@ lower_tex(nir_tex_instr *tex, struct
> apply_pipeline_layout_state *state)
>     unsigned binding = tex->texture->var->data.binding;
>     unsigned array_size =
>        state->layout->set[set].layout->binding[binding].array_size;
> +   bool has_plane = has_tex_src_plane(tex);
> +   unsigned plane = has_plane ? extract_tex_src_plane(tex) : 0;
> +
>     tex->texture_index = state->set[set].surface_offsets[binding];
>     lower_tex_deref(tex, tex->texture, &tex->texture_index, array_size,
> -                   nir_tex_src_texture_offset, state);
> +                   nir_tex_src_texture_offset, !has_plane, state);
> +   tex->texture_index += plane;
>
>     if (tex->sampler) {
>        unsigned set = tex->sampler->var->data.descriptor_set;
> @@ -209,7 +262,8 @@ lower_tex(nir_tex_instr *tex, struct
> apply_pipeline_layout_state *state)
>           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,
> -                      nir_tex_src_sampler_offset, state);
> +                      nir_tex_src_sampler_offset, !has_plane, state);
> +      tex->sampler_index += plane;
>     }
>
>     /* The backend only ever uses this to mark used surfaces.  We don't
> care
> @@ -299,10 +353,14 @@ 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) {
> -         if (set_layout->binding[b].stage[shader->stage].surface_index
> >= 0)
> -            map->surface_count += set_layout->binding[b].array_size;
> -         if (set_layout->binding[b].stage[shader->stage].sampler_index
> >= 0)
> -            map->sampler_count += set_layout->binding[b].array_size;
> +         if (set_layout->binding[b].stage[shader->stage].surface_index
> >= 0) {
> +            map->surface_count +=
> +               anv_descriptor_set_binding_layout_get_hw_size(&set_
> layout->binding[b]);
> +         }
> +         if (set_layout->binding[b].stage[shader->stage].sampler_index
> >= 0) {
> +            map->sampler_count +=
> +               anv_descriptor_set_binding_layout_get_hw_size(&set_
> layout->binding[b]);
> +         }
>           if (set_layout->binding[b].stage[shader->stage].image_index >=
> 0)
>              map->image_count += set_layout->binding[b].array_size;
>        }
> @@ -317,31 +375,42 @@ 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;
> +            struct anv_sampler **samplers = binding->immutable_samplers;
> +            for (unsigned i = 0; i < binding->array_size; i++) {
> +               uint8_t planes = samplers ? samplers[i]->n_planes : 1;
> +               for (uint8_t p = 0; p < planes; p++) {
> +                  map->surface_to_descriptor[surface].set = set;
> +                  map->surface_to_descriptor[surface].binding = b;
> +                  map->surface_to_descriptor[surface].index = i;
> +                  map->surface_to_descriptor[surface].plane = p;
> +                  surface++;
> +               }
>              }
> -            surface += array_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;
> +            struct anv_sampler **samplers = binding->immutable_samplers;
> +            for (unsigned i = 0; i < binding->array_size; i++) {
> +               uint8_t planes = samplers ? samplers[i]->n_planes : 1;
> +               for (uint8_t p = 0; p < planes; p++) {
> +                  map->sampler_to_descriptor[sampler].set = set;
> +                  map->sampler_to_descriptor[sampler].binding = b;
> +                  map->sampler_to_descriptor[sampler].index = i;
> +                  map->sampler_to_descriptor[sampler].plane = p;
> +                  sampler++;
> +               }
>              }
> -            sampler += array_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 36aa86141fc..ff1b1cc8a80 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -1323,6 +1323,9 @@ struct anv_descriptor_update_template {
>     struct anv_descriptor_template_entry entries[0];
>  };
>
> +size_t
> +anv_descriptor_set_binding_layout_get_hw_size(const struct
> anv_descriptor_set_binding_layout *binding);
> +
>  size_t
>  anv_descriptor_set_layout_size(const struct anv_descriptor_set_layout
> *layout);
>
> @@ -1385,6 +1388,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;
>
> @@ -2540,6 +2546,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_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 at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20171006/92b8eb8a/attachment-0001.html>


More information about the mesa-dev mailing list