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

Kenneth Graunke kenneth at whitecape.org
Fri Oct 18 08:09:34 CEST 2013

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.

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,
+   if (ctx->Driver.GetTransformFeedbackVertexCount) {
+      GLsizei n = ctx->Driver.GetTransformFeedbackVertexCount(ctx, obj, stream);
+      vbo_draw_arrays(ctx, mode, 0, n, numInstances, 0);
+      return;
+   }
    /* init most fields to zero */

More information about the mesa-dev mailing list