From 0a7602b938893e1b04a01ca8680376cbeec053ab Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 26 Dec 2011 14:43:07 -0700 Subject: [PATCH] vbo: signal _NEW_ARRAY when transitioning between glBegin/End, glDrawArrays This fixes a regression seen with the isosurf demo when switching between glBegin/End and glDrawArrays (do it several times). The problem was the driver wasn't getting _NEW_ARRAY when the arrays were subtly changed: (vertex3f, normal3f) vs. (normal3f, vertex3f). This patch fixes that by signaling _NEW_ARRAY whenever we transition between glBegin/End and glDrawArrays mode and display lists. The patch also fixes up the initialization of the map_vp_none[] array to stop putting strange values in the last five elements of the array. v2: remove DRAW_ELEMENTS, don't distinguish between glDrawArrays and glDrawElements v3: add DRAW_DISPLAY_LIST for the display list case, just to be safe. Reviewed-by: Mathias Froehlich Tested-by: Mathias Froehlich --- src/mesa/vbo/vbo_context.c | 11 ++++------- src/mesa/vbo/vbo_exec.h | 36 +++++++++++++++++++++++++++++++++++ src/mesa/vbo/vbo_exec_api.c | 2 ++ src/mesa/vbo/vbo_exec_array.c | 4 ++++ src/mesa/vbo/vbo_save_draw.c | 3 +++ 5 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c index b2e6bbc12fb..d83f2fd23a5 100644 --- a/src/mesa/vbo/vbo_context.c +++ b/src/mesa/vbo/vbo_context.c @@ -176,17 +176,14 @@ GLboolean _vbo_CreateContext( struct gl_context *ctx ) { GLuint i; - /* When no vertex program, pull in the material attributes in - * the generic range. - */ - for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) + /* identity mapping */ + for (i = 0; i < Elements(vbo->map_vp_none); i++) vbo->map_vp_none[i] = i; + /* map material attribs to generic slots */ for (i = 0; i < NR_MAT_ATTRIBS; i++) vbo->map_vp_none[VERT_ATTRIB_GENERIC(i)] = VBO_ATTRIB_MAT_FRONT_AMBIENT + i; - for (i = NR_MAT_ATTRIBS; i < VERT_ATTRIB_GENERIC_MAX; i++) - vbo->map_vp_none[VERT_ATTRIB_GENERIC(i)] = i; - + for (i = 0; i < Elements(vbo->map_vp_arb); i++) vbo->map_vp_arb[i] = i; } diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h index cfed8e86dc0..e85798da4c4 100644 --- a/src/mesa/vbo/vbo_exec.h +++ b/src/mesa/vbo/vbo_exec.h @@ -78,12 +78,26 @@ struct vbo_exec_copied_vtx { }; +/** Used to signal when transitioning from one kind of drawing method + * to another. + */ +enum draw_method +{ + DRAW_NONE, /**< Initial value only */ + DRAW_BEGIN_END, + DRAW_DISPLAY_LIST, + DRAW_ARRAYS +}; + + struct vbo_exec_context { struct gl_context *ctx; GLvertexformat vtxfmt; GLvertexformat vtxfmt_noop; + enum draw_method last_draw_method; + struct { struct gl_buffer_object *bufferobj; @@ -164,6 +178,28 @@ void vbo_exec_array_destroy( struct vbo_exec_context *exec ); void vbo_exec_vtx_init( struct vbo_exec_context *exec ); void vbo_exec_vtx_destroy( struct vbo_exec_context *exec ); + +/** + * This is called by glBegin, glDrawArrays and glDrawElements (and + * variations of those calls). When we transition from immediate mode + * drawing to array drawing we need to invalidate the array state. + * + * glBegin/End builds vertex arrays. Those arrays may look identical + * to glDrawArrays arrays except that the position of the elements may + * be different. For example, arrays of (position3v, normal3f) vs. arrays + * of (normal3f, position3f). So we need to make sure we notify drivers + * that arrays may be changing. + */ +static inline void +vbo_draw_method(struct vbo_exec_context *exec, enum draw_method method) +{ + if (exec->last_draw_method != method) { + exec->ctx->NewState |= _NEW_ARRAY; + exec->last_draw_method = method; + } +} + + #if FEATURE_beginend void vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap ); diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index 4be016925c9..cb5f9ae522b 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -701,6 +701,8 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode ) return; } + vbo_draw_method(exec, DRAW_BEGIN_END); + if (ctx->Driver.PrepareExecBegin) ctx->Driver.PrepareExecBegin(ctx); diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index a6e41e9c5e5..6ffdff330d7 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -558,6 +558,8 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, vbo_bind_arrays(ctx); + vbo_draw_method(exec, DRAW_ARRAYS); + /* Again... because we may have changed the bitmask of per-vertex varying * attributes. If we regenerate the fixed-function vertex program now * we may be able to prune down the number of vertex attributes which we @@ -773,6 +775,8 @@ vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, vbo_bind_arrays( ctx ); + vbo_draw_method(exec, DRAW_ARRAYS); + /* check for dirty state again */ if (ctx->NewState) _mesa_update_state( ctx ); diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index fa93ca48f43..9f0290561e8 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -248,6 +248,7 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data) const struct vbo_save_vertex_list *node = (const struct vbo_save_vertex_list *) data; struct vbo_save_context *save = &vbo_context(ctx)->save; + struct vbo_exec_context *exec = &vbo_context(ctx)->exec; FLUSH_CURRENT(ctx, 0); @@ -286,6 +287,8 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data) vbo_bind_vertex_list( ctx, node ); + vbo_draw_method(exec, DRAW_DISPLAY_LIST); + /* Again... */ if (ctx->NewState) -- 2.30.2