[Mesa-dev] [PATCH] st/mesa: cleanup and fix primitive restart for indirect draws

Marek Olšák maraeo at gmail.com
Fri Oct 21 09:38:13 UTC 2016


Reviewed-by: Marek Olšák <marek.olsak at amd.com>

Marek

On Fri, Oct 21, 2016 at 10:18 AM, Nicolai Hähnle <nhaehnle at gmail.com> wrote:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
>
> There are three intended functional changes here:
>
> 1. OpenGL 4.5 clarifies that primitive restart should only apply with index
>    buffers, so make that change explicit in the indirect draw path.
>
> 2. Make PrimitiveRestartFixedIndex work with indirect draws.
>
> 3. The change where primitive_restart is only set when the restart index can
>    actually have an effect (based on the size of indices) is also applied for
>    indirect draws.
>
> Cc: 13.0 <mesa-stable at lists.freedesktop.org>
> ---
>  src/mesa/state_tracker/st_draw.c | 45 +++++++++++++++++++++++++---------------
>  1 file changed, 28 insertions(+), 17 deletions(-)
>
> diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
> index 5dcaff0..e9f25b6 100644
> --- a/src/mesa/state_tracker/st_draw.c
> +++ b/src/mesa/state_tracker/st_draw.c
> @@ -120,20 +120,44 @@ setup_index_buffer(struct st_context *st,
>        /* indices are in user space memory */
>        ibuffer->user_buffer = ib->ptr;
>     }
>
>     cso_set_index_buffer(st->cso_context, ibuffer);
>     return TRUE;
>  }
>
>
>  /**
> + * Set the restart index.
> + */
> +static void
> +setup_primitive_restart(struct gl_context *ctx,
> +                        const struct _mesa_index_buffer *ib,
> +                        struct pipe_draw_info *info)
> +{
> +   if (ctx->Array._PrimitiveRestart) {
> +      info->restart_index = _mesa_primitive_restart_index(ctx, ib->type);
> +
> +      /* Enable primitive restart only when the restart index can have an
> +       * effect. This is required for correctness in radeonsi VI support.
> +       * Other hardware may also benefit from taking a faster, non-restart path
> +       * when possible.
> +       */
> +      if ((ib->type == GL_UNSIGNED_INT) ||
> +          (ib->type == GL_UNSIGNED_SHORT && info->restart_index <= 0xffff) ||
> +          (ib->type == GL_UNSIGNED_BYTE && info->restart_index <= 0xff))
> +         info->primitive_restart = true;
> +   }
> +}
> +
> +
> +/**
>   * Translate OpenGL primtive type (GL_POINTS, GL_TRIANGLE_STRIP, etc) to
>   * the corresponding Gallium type.
>   */
>  static unsigned
>  translate_prim(const struct gl_context *ctx, unsigned prim)
>  {
>     /* GL prims should match Gallium prims, spot-check a few */
>     STATIC_ASSERT(GL_POINTS == PIPE_PRIM_POINTS);
>     STATIC_ASSERT(GL_QUADS == PIPE_PRIM_QUADS);
>     STATIC_ASSERT(GL_TRIANGLE_STRIP_ADJACENCY == PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY);
> @@ -198,33 +222,21 @@ st_draw_vbo(struct gl_context *ctx,
>
>        info.indexed = TRUE;
>        if (min_index != ~0U && max_index != ~0U) {
>           info.min_index = min_index;
>           info.max_index = max_index;
>        }
>
>        /* The VBO module handles restart for the non-indexed GLDrawArrays
>         * so we only set these fields for indexed drawing:
>         */
> -      if (ctx->Array._PrimitiveRestart) {
> -         info.restart_index = _mesa_primitive_restart_index(ctx, ib->type);
> -
> -         /* Enable primitive restart only when the restart index can have an
> -          * effect. This is required for correctness in radeonsi VI support,
> -          * though other hardware may also benefit from taking a faster,
> -          * non-restart path when possible.
> -          */
> -         if ((ibuffer.index_size >= 4) ||
> -             (ibuffer.index_size >= 2 && info.restart_index <= 0xffff) ||
> -             (info.restart_index <= 0xff))
> -            info.primitive_restart = true;
> -      }
> +      setup_primitive_restart(ctx, ib, &info);
>     }
>     else {
>        /* Transform feedback drawing is always non-indexed. */
>        /* Set info.count_from_stream_output. */
>        if (tfb_vertcount) {
>           if (!st_transform_feedback_draw_init(tfb_vertcount, stream, &info))
>              return;
>        }
>     }
>
> @@ -303,31 +315,30 @@ st_indirect_draw_vbo(struct gl_context *ctx,
>
>     if (ib) {
>        if (!setup_index_buffer(st, ib, &ibuffer)) {
>           _mesa_error(ctx, GL_OUT_OF_MEMORY, "gl%sDrawElementsIndirect%s",
>                       (draw_count > 1) ? "Multi" : "",
>                       indirect_params ? "CountARB" : "");
>           return;
>        }
>
>        info.indexed = TRUE;
> +
> +      /* Primitive restart is not handled by the VBO module in this case. */
> +      setup_primitive_restart(ctx, ib, &info);
>     }
>
>     info.mode = translate_prim(ctx, mode);
>     info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices;
>     info.indirect = st_buffer_object(indirect_data)->buffer;
>     info.indirect_offset = indirect_offset;
>
> -   /* Primitive restart is not handled by the VBO module in this case. */
> -   info.primitive_restart = ctx->Array._PrimitiveRestart;
> -   info.restart_index = ctx->Array.RestartIndex;
> -
>     if (ST_DEBUG & DEBUG_DRAW) {
>        debug_printf("st/draw indirect: mode %s drawcount %d indexed %d\n",
>                     u_prim_name(info.mode),
>                     draw_count,
>                     info.indexed);
>     }
>
>     if (!st->has_multi_draw_indirect) {
>        int i;
>
> --
> 2.7.4
>
> _______________________________________________
> 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