[Mesa-dev] [PATCH 6/9] mesa: Add a new GetTransformFeedbackVertexCount() driver hook.

Marek Olšák maraeo at gmail.com
Tue Oct 22 13:30:32 CEST 2013


On Fri, Oct 18, 2013 at 8:09 AM, Kenneth Graunke <kenneth at whitecape.org> wrote:
> DrawTransformFeedback() needs to obtain the number of vertices written
> to a particular stream during the last Begin/EndTransformFeedback block.
> The new driver hook returns exactly that information.
>
> Gallium drivers already implement this functionality by passing the
> transform feedback object to the drawing function.  I prefer to avoid
> this for two reasons:
>
> 1. Complexity:
>
> Normally, the drawing function takes an array of _mesa_prim objects,
> each of which specifies a vertex count.  If tfb_vertcount != NULL,
> however, there will only be one _mesa_prim object with an invalid
> vertex count (of 1), so it needs to be ignored.
>
> Since the _mesa_prim pointers are const, you can't even override it to
> the proper value; you need to pass around extra "ignore that, here's
> the real count" parameters.
>
> The drawing function is already terribly complicated, so I don't want to
> make it even more complicated.

I don't understand this. Are you saying that the software emulation of
the feature is always better because of complexity the real
hardware-accelerated solution would have?

>
> 2. Primitive restart:
>
> vbo_draw_arrays() performs software primitive restart, splitting a draw
> call in two when necessary.  vbo_draw_transform_feedback() currently
> doesn't because it has no idea how many vertices need to be drawn.  The
> new driver hook gives it that information, allowing us to reuse the
> existing vbo_draw_arrays() code to do everything right.
>
> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> ---
>  src/mesa/main/dd.h            | 8 ++++++++
>  src/mesa/vbo/vbo_exec_array.c | 6 ++++++
>  2 files changed, 14 insertions(+)
>
> diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
> index 29469ce..11d5a9e 100644
> --- a/src/mesa/main/dd.h
> +++ b/src/mesa/main/dd.h
> @@ -843,6 +843,14 @@ struct dd_function_table {
>                                     struct gl_transform_feedback_object *obj);
>
>     /**
> +    * Return the number of vertices written to a stream during the last
> +    * Begin/EndTransformFeedback block.
> +    */
> +   GLsizei (*GetTransformFeedbackVertexCount)(struct gl_context *ctx,
> +                                              struct gl_transform_feedback_object *obj,
> +                                              GLuint stream);
> +
> +   /**
>      * \name GL_NV_texture_barrier interface
>      */
>     void (*TextureBarrier)(struct gl_context *ctx);
> diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
> index 1670409..11bb76a 100644
> --- a/src/mesa/vbo/vbo_exec_array.c
> +++ b/src/mesa/vbo/vbo_exec_array.c
> @@ -1464,6 +1464,12 @@ vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
>        return;
>     }
>
> +   if (ctx->Driver.GetTransformFeedbackVertexCount) {
> +      GLsizei n = ctx->Driver.GetTransformFeedbackVertexCount(ctx, obj, stream);
> +      vbo_draw_arrays(ctx, mode, 0, n, numInstances, 0);
> +      return;
> +   }

As you mentioned, the only issue is with primitive restart, so why is
this done even if primitive restart is disabled? Drivers which will
have to implement this just to make e.g. non-VBO vertex uploads work
will suffer from the CPU-GPU synchronization this code forces.

Marek


More information about the mesa-dev mailing list