[Mesa-dev] [PATCH 3/3] radv: Handle GFX9 merged shaders in radv_flush_constants()

Bas Nieuwenhuizen bas at basnieuwenhuizen.nl
Thu May 31 20:15:52 UTC 2018


On Thu, May 31, 2018 at 5:44 PM, Alex Smith <asmith at feralinteractive.com> wrote:
> This was not previously handled correctly. For example,
> push_constant_stages might only contain MESA_SHADER_VERTEX because
> only that stage was changed by CmdPushConstants or
> CmdBindDescriptorSets.
>
> In that case, if vertex has been merged with tess control, then the
> push constant address wouldn't be updated since
> pipeline->shaders[MESA_SHADER_VERTEX] would be NULL.
>
> Use radv_get_shader() instead of getting the shader directly so that
> we get the right shader if merged. Also, skip emitting the address
> redundantly - if two merged stages are set in push_constant_stages
> this change would have made the address get emitted twice.
>
> Signed-off-by: Alex Smith <asmith at feralinteractive.com>
> Cc: "18.1" <mesa-stable at lists.freedesktop.org>
> ---
>  src/amd/vulkan/radv_cmd_buffer.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
> index da9591b9a5..c6a2d6c5b9 100644
> --- a/src/amd/vulkan/radv_cmd_buffer.c
> +++ b/src/amd/vulkan/radv_cmd_buffer.c
> @@ -1585,6 +1585,7 @@ radv_flush_constants(struct radv_cmd_buffer *cmd_buffer,
>                                          ? cmd_buffer->state.compute_pipeline
>                                          : cmd_buffer->state.pipeline;
>         struct radv_pipeline_layout *layout = pipeline->layout;
> +       struct radv_shader_variant *shader, *prev_shader;
>         unsigned offset;
>         void *ptr;
>         uint64_t va;
> @@ -1609,11 +1610,17 @@ radv_flush_constants(struct radv_cmd_buffer *cmd_buffer,
>         MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer->device->ws,
>                                                            cmd_buffer->cs, MESA_SHADER_STAGES * 4);
>
> +       prev_shader = NULL;
>         radv_foreach_stage(stage, stages) {
> -               if (pipeline->shaders[stage]) {
> +               shader = radv_get_shader(pipeline, stage);
> +
> +               /* Avoid redundantly emitting the address for merged stages. */
> +               if (shader && shader != prev_shader) {
>                         radv_emit_userdata_address(cmd_buffer, pipeline, stage,
>                                                    AC_UD_PUSH_CONSTANTS, va);
>                 }
> +
> +               prev_shader = shader;

This emits the same shader twice if we have a geometry shader and a
vertex shader but no tessellation shaders in cases were the stage mask
is larger than needed and includes the tessellation stages. On the
iteration for the tess shaders, prev_shader will be reset to NULL, and
hence when we visit the geometry shader we will emit the constants
again.

I think this should be solved by moving the prev_shader update within
the if statement.

With that, this series is

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

Thanks a lot!


>         }
>
>         cmd_buffer->push_constant_stages &= ~stages;
> --
> 2.14.3
>
> _______________________________________________
> 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