[Mesa-dev] [PATCH 3/3] radv: emit shader descriptor pointers consecutively

Bas Nieuwenhuizen bas at basnieuwenhuizen.nl
Mon May 28 10:27:21 UTC 2018


Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>

for the series.

On Fri, May 25, 2018 at 2:59 PM, Samuel Pitoiset
<samuel.pitoiset at gmail.com> wrote:
> This reduces the number of SET_SH_REG packets which are emitted
> for applications that use more than one descriptor set per stage.
>
> We should be able to emit more SET_SH_REG packets consecutively
> (like push constants and vertex buffers for the vertex stage),
> but this will be improved later.
>
> Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
> ---
>  src/amd/vulkan/radv_cmd_buffer.c | 104 +++++++++++++++++--------------
>  1 file changed, 57 insertions(+), 47 deletions(-)
>
> diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
> index 5ab577b4c5..206d9b7fad 100644
> --- a/src/amd/vulkan/radv_cmd_buffer.c
> +++ b/src/amd/vulkan/radv_cmd_buffer.c
> @@ -594,6 +594,46 @@ radv_emit_userdata_address(struct radv_cmd_buffer *cmd_buffer,
>                                  base_reg + loc->sgpr_idx * 4, va, false);
>  }
>
> +static void
> +radv_emit_descriptor_pointers(struct radv_cmd_buffer *cmd_buffer,
> +                             struct radv_pipeline *pipeline,
> +                             struct radv_descriptor_state *descriptors_state,
> +                             gl_shader_stage stage)
> +{
> +       struct radv_device *device = cmd_buffer->device;
> +       struct radeon_winsys_cs *cs = cmd_buffer->cs;
> +       uint32_t sh_base = pipeline->user_data_0[stage];
> +       struct radv_userdata_locations *locs =
> +               &pipeline->shaders[stage]->info.user_sgprs_locs;
> +       unsigned mask;
> +
> +       mask = descriptors_state->dirty & descriptors_state->valid;
> +
> +       for (int i = 0; i < MAX_SETS; i++) {
> +               struct radv_userdata_info *loc = &locs->descriptor_sets[i];
> +               if (loc->sgpr_idx != -1 && !loc->indirect)
> +                       continue;
> +               mask &= ~(1 << i);
> +       }
> +
> +       while (mask) {
> +               int start, count;
> +
> +               u_bit_scan_consecutive_range(&mask, &start, &count);
> +
> +               struct radv_userdata_info *loc = &locs->descriptor_sets[start];
> +               unsigned sh_offset = sh_base + loc->sgpr_idx * 4;
> +
> +               radv_emit_shader_pointer_head(cs, sh_offset, count, true);
> +               for (int i = 0; i < count; i++) {
> +                       struct radv_descriptor_set *set =
> +                               descriptors_state->sets[start + i];
> +
> +                       radv_emit_shader_pointer_body(device, cs, set->va, true);
> +               }
> +       }
> +}
> +
>  static void
>  radv_update_multisample_state(struct radv_cmd_buffer *cmd_buffer,
>                               struct radv_pipeline *pipeline)
> @@ -1429,47 +1469,6 @@ radv_cmd_buffer_flush_dynamic_state(struct radv_cmd_buffer *cmd_buffer)
>         cmd_buffer->state.dirty &= ~states;
>  }
>
> -static void
> -emit_stage_descriptor_set_userdata(struct radv_cmd_buffer *cmd_buffer,
> -                                  struct radv_pipeline *pipeline,
> -                                  int idx,
> -                                  uint64_t va,
> -                                  gl_shader_stage stage)
> -{
> -       struct radv_userdata_info *desc_set_loc = &pipeline->shaders[stage]->info.user_sgprs_locs.descriptor_sets[idx];
> -       uint32_t base_reg = pipeline->user_data_0[stage];
> -
> -       if (desc_set_loc->sgpr_idx == -1 || desc_set_loc->indirect)
> -               return;
> -
> -       assert(!desc_set_loc->indirect);
> -       assert(desc_set_loc->num_sgprs == (HAVE_32BIT_POINTERS ? 1 : 2));
> -
> -       radv_emit_shader_pointer(cmd_buffer->device, cmd_buffer->cs,
> -                                base_reg + desc_set_loc->sgpr_idx * 4, va, false);
> -}
> -
> -static void
> -radv_emit_descriptor_set_userdata(struct radv_cmd_buffer *cmd_buffer,
> -                                 VkShaderStageFlags stages,
> -                                 struct radv_descriptor_set *set,
> -                                 unsigned idx)
> -{
> -       if (cmd_buffer->state.pipeline) {
> -               radv_foreach_stage(stage, stages) {
> -                       if (cmd_buffer->state.pipeline->shaders[stage])
> -                               emit_stage_descriptor_set_userdata(cmd_buffer, cmd_buffer->state.pipeline,
> -                                                                  idx, set->va,
> -                                                                  stage);
> -               }
> -       }
> -
> -       if (cmd_buffer->state.compute_pipeline && (stages & VK_SHADER_STAGE_COMPUTE_BIT))
> -               emit_stage_descriptor_set_userdata(cmd_buffer, cmd_buffer->state.compute_pipeline,
> -                                                  idx, set->va,
> -                                                  MESA_SHADER_COMPUTE);
> -}
> -
>  static void
>  radv_flush_push_descriptors(struct radv_cmd_buffer *cmd_buffer,
>                             VkPipelineBindPoint bind_point)
> @@ -1551,7 +1550,6 @@ radv_flush_descriptors(struct radv_cmd_buffer *cmd_buffer,
>                                          VK_PIPELINE_BIND_POINT_GRAPHICS;
>         struct radv_descriptor_state *descriptors_state =
>                 radv_get_descriptors_state(cmd_buffer, bind_point);
> -       unsigned i;
>
>         if (!descriptors_state->dirty)
>                 return;
> @@ -1568,13 +1566,25 @@ radv_flush_descriptors(struct radv_cmd_buffer *cmd_buffer,
>                                                            cmd_buffer->cs,
>                                                            MAX_SETS * MESA_SHADER_STAGES * 4);
>
> -       for_each_bit(i, descriptors_state->dirty) {
> -               struct radv_descriptor_set *set = descriptors_state->sets[i];
> -               if (!(descriptors_state->valid & (1u << i)))
> -                       continue;
> +       if (cmd_buffer->state.pipeline) {
> +               radv_foreach_stage(stage, stages) {
> +                       if (!cmd_buffer->state.pipeline->shaders[stage])
> +                               continue;
>
> -               radv_emit_descriptor_set_userdata(cmd_buffer, stages, set, i);
> +                       radv_emit_descriptor_pointers(cmd_buffer,
> +                                                     cmd_buffer->state.pipeline,
> +                                                     descriptors_state, stage);
> +               }
>         }
> +
> +       if (cmd_buffer->state.compute_pipeline &&
> +           (stages & VK_SHADER_STAGE_COMPUTE_BIT)) {
> +               radv_emit_descriptor_pointers(cmd_buffer,
> +                                             cmd_buffer->state.compute_pipeline,
> +                                             descriptors_state,
> +                                             MESA_SHADER_COMPUTE);
> +       }
> +
>         descriptors_state->dirty = 0;
>         descriptors_state->push_dirty = false;
>
> --
> 2.17.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list