This looks good. I recommend porting all_varyings_in_vbos from st_draw.c to vbo_all_varyings_in_vbos, because it also takes instanced arrays into account.
Reviewed-by: Marek Olšák <marek.ol...@amd.com> Marek On Sat, Oct 26, 2013 at 7:35 AM, Kenneth Graunke <kenn...@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 by passing the transform feedback > object to the drawing function, counting the number of vertices written > on the GPU, and using draw indirect. This is efficient, but doesn't > always work: > > If vertex data comes from user arrays, then the VBO module needs to > know how many vertices to upload, so we need to synchronously count. > Gallium drivers are currently broken in this case. > > It also doesn't work if primitive restart is done in software. For > normal drawing, vbo_draw_arrays() performs software primitive restart, > splitting the draw call in two. 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. > > On Intel hardware (at least Ivybridge), using the draw indirect approach > is difficult since the hardware counts primitives, rather than vertices, > which requires doing some simple math. So we always use this hook. > > Gallium drivers will likely want to use this hook in some cases, but > want to use the existing draw indirect approach where possible. Hence, > I've added a flag to allow drivers to opt-in to this call. > > v2: Make it possible to implement this hook but only use this path > when necessary (suggested by Marek). > > Cc: Marek Olšák <mar...@gmail.com> > Cc: Eric Anholt <e...@anholt.net> > Signed-off-by: Kenneth Graunke <kenn...@whitecape.org> > --- > src/mesa/drivers/dri/i965/brw_context.c | 2 ++ > src/mesa/main/dd.h | 8 ++++++++ > src/mesa/main/mtypes.h | 6 ++++++ > src/mesa/vbo/vbo_exec_array.c | 10 ++++++++++ > 4 files changed, 26 insertions(+) > > Marek, > > Does this look like what you wanted? I feel a bit silly adding all of this > seeing as the later conditions are totally untested - i965 sets the "always > use this hook" flag, so it short-circuits them, and Gallium drivers don't > yet implement the hook, so they don't hit it either. :) > > But I think this is probably roughly what you're going to want... > > Eric, does this look reasonable? > > Thanks for everything! > > diff --git a/src/mesa/drivers/dri/i965/brw_context.c > b/src/mesa/drivers/dri/i965/brw_context.c > index 90d9be4..623273c 100644 > --- a/src/mesa/drivers/dri/i965/brw_context.c > +++ b/src/mesa/drivers/dri/i965/brw_context.c > @@ -329,6 +329,8 @@ brw_initialize_context_constants(struct brw_context *brw) > ctx->Const.MaxTransformFeedbackSeparateComponents = > BRW_MAX_SOL_BINDINGS / BRW_MAX_SOL_BUFFERS; > > + ctx->Const.AlwaysUseGetTransformFeedbackVertexCount = true; > + > if (brw->gen == 6) { > ctx->Const.MaxSamples = 4; > ctx->Const.MaxColorTextureSamples = 4; > 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/main/mtypes.h b/src/mesa/main/mtypes.h > index 97ed1bd..f5e1f01 100644 > --- a/src/mesa/main/mtypes.h > +++ b/src/mesa/main/mtypes.h > @@ -3131,6 +3131,12 @@ struct gl_constants > */ > GLboolean PrimitiveRestartInSoftware; > > + /** > + * Always use the GetTransformFeedbackVertexCount() driver hook, rather > + * than passing the transform feedback object to the drawing function. > + */ > + GLboolean AlwaysUseGetTransformFeedbackVertexCount; > + > /** GL_ARB_map_buffer_alignment */ > GLuint MinMapBufferAlignment; > > diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c > index 1670409..f25a9de 100644 > --- a/src/mesa/vbo/vbo_exec_array.c > +++ b/src/mesa/vbo/vbo_exec_array.c > @@ -1464,6 +1464,16 @@ vbo_draw_transform_feedback(struct gl_context *ctx, > GLenum mode, > return; > } > > + if (ctx->Driver.GetTransformFeedbackVertexCount && > + (ctx->Const.AlwaysUseGetTransformFeedbackVertexCount || > + (ctx->Const.PrimitiveRestartInSoftware && > + ctx->Array._PrimitiveRestart) || > + !vbo_all_varyings_in_vbos(exec->array.inputs))) { > + GLsizei n = ctx->Driver.GetTransformFeedbackVertexCount(ctx, obj, > stream); > + vbo_draw_arrays(ctx, mode, 0, n, numInstances, 0); > + return; > + } > + > vbo_bind_arrays(ctx); > > /* init most fields to zero */ > -- > 1.8.3.2 > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev