diff options
Diffstat (limited to 'src/mesa/tnl')
-rw-r--r-- | src/mesa/tnl/t_save_loopback.c | 125 | ||||
-rw-r--r-- | src/mesa/tnl/t_save_playback.c | 9 |
2 files changed, 88 insertions, 46 deletions
diff --git a/src/mesa/tnl/t_save_loopback.c b/src/mesa/tnl/t_save_loopback.c index 0798203c4bf..b496a784c35 100644 --- a/src/mesa/tnl/t_save_loopback.c +++ b/src/mesa/tnl/t_save_loopback.c @@ -41,6 +41,9 @@ * glVertex() * ... lots of vertices ... * glEnd() + * + * or: + * glDrawArrays(...) * * and then tries to execute it like this: * @@ -58,7 +61,7 @@ * usage. * * Further, replaying degenerately-called lists in this fashion is - * probably no worse than the replay using opcodes. + * probably still faster than the replay using opcodes. */ typedef void (*attr_func)( GLcontext *ctx, GLint target, const GLfloat * ); @@ -174,6 +177,82 @@ struct loopback_attr { attr_func func; }; +/* Don't emit ends and begins on wrapped primitives. Don't replay + * wrapped vertices. If we get here, it's probably because the the + * precalculated wrapping is wrong. + */ +static void loopback_prim( GLcontext *ctx, + struct tnl_vertex_list *list, GLuint i, + struct loopback_attr *la, GLuint nr ) +{ + struct tnl_prim *prim = &list->prim[i]; + GLint begin = prim->start; + GLint end = begin + prim->count; + GLfloat *data; + GLint j, k; + + if (prim->mode & PRIM_BEGIN) { + glBegin( prim->mode & PRIM_MODE_MASK ); + } else { + assert(i == 0); + assert(begin == 0); + begin += list->wrap_count; + } + + data = list->buffer + begin * list->vertex_size; + + for (j = begin ; j < end ; j++) { + GLfloat *tmp = data + la[0].sz; + + for (k = 1 ; k < nr ; k++) { + la[k].func( ctx, la[k].target, tmp ); + tmp += la[k].sz; + } + + /* Fire the vertex + */ + la[0].func( ctx, VERT_ATTRIB_POS, data ); + data = tmp; + } + + if (prim->mode & PRIM_END) { + glEnd(); + } + else { + assert (i == list->prim_count-1); + } +} + +/* Primitives generated by DrawArrays/DrawElements/Rectf may be + * caught here. If there is no primitive in progress, execute them + * normally, otherwise need to track and discard the generated + * primitives. + */ +static void loopback_weak_prim( GLcontext *ctx, + struct tnl_vertex_list *list, GLuint i, + struct loopback_attr *la, GLuint nr ) +{ + if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) + loopback_prim( ctx, list, i, la, nr ); + else { + struct tnl_prim *prim = &list->prim[i]; + + /* Use the prim_weak flag to ensure that if this primitive + * wraps, we don't mistake future vertex_lists for part of the + * surrounding primitive. + * + * While this flag is set, we are simply disposing of data + * generated by an operation now known to be a noop. + */ + if (prim->mode & PRIM_BEGIN) + ctx->Driver.CurrentExecPrimitive |= PRIM_WEAK; + if (prim->mode & PRIM_END) + ctx->Driver.CurrentExecPrimitive &= ~PRIM_WEAK; + } +} + + + void _tnl_loopback_vertex_list( GLcontext *ctx, struct tnl_vertex_list *list ) { struct loopback_attr la[_TNL_ATTRIB_MAX]; @@ -213,46 +292,10 @@ void _tnl_loopback_vertex_list( GLcontext *ctx, struct tnl_vertex_list *list ) nr++; } - /* Don't emit ends and begins on wrapped primitives. Don't replay - * wrapped vertices. If we get here, it's probably because the the - * precalculated wrapping is wrong. - */ for (i = 0 ; i < list->prim_count ; i++) { - struct tnl_prim *prim = &list->prim[i]; - GLint begin = prim->start; - GLint end = begin + prim->count; - GLfloat *data; - GLint j, k; - - if (prim->mode & PRIM_BEGIN) { - glBegin( prim->mode & PRIM_MODE_MASK ); - } else { - assert(i == 0); - assert(begin == 0); - begin += list->wrap_count; - } - - data = list->buffer + begin * list->vertex_size; - - for (j = begin ; j < end ; j++) { - GLfloat *tmp = data + la[0].sz; - - for (k = 1 ; k < nr ; k++) { - la[k].func( ctx, la[k].target, tmp ); - tmp += la[k].sz; - } - - /* Fire the vertex - */ - la[0].func( ctx, VERT_ATTRIB_POS, data ); - data = tmp; - } - - if (prim->mode & PRIM_END) { - glEnd(); - } - else { - assert (i == list->prim_count-1); - } + if (list->prim[i].mode & PRIM_WEAK) + loopback_weak_prim( ctx, list, i, la, nr ); + else + loopback_prim( ctx, list, i, la, nr ); } } diff --git a/src/mesa/tnl/t_save_playback.c b/src/mesa/tnl/t_save_playback.c index 34225807db2..78e6c661598 100644 --- a/src/mesa/tnl/t_save_playback.c +++ b/src/mesa/tnl/t_save_playback.c @@ -65,9 +65,6 @@ static void _tnl_bind_vertex_list( GLcontext *ctx, VB->PrimitiveCount = node->prim_count; VB->Elts = NULL; VB->NormalLengthPtr = NULL; - VB->ColorPtr[1] = NULL; - VB->SecondaryColorPtr[1] = NULL; - VB->IndexPtr[1] = NULL; for (attr = 0; attr <= _TNL_ATTRIB_INDEX; attr++) { if (node->attrsz[attr]) { @@ -108,8 +105,11 @@ static void _tnl_bind_vertex_list( GLcontext *ctx, VB->ObjPtr = VB->AttribPtr[_TNL_ATTRIB_POS]; VB->NormalPtr = VB->AttribPtr[_TNL_ATTRIB_NORMAL]; VB->ColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR0]; + VB->ColorPtr[1] = 0; VB->IndexPtr[0] = VB->AttribPtr[_TNL_ATTRIB_INDEX]; + VB->IndexPtr[1] = 0; VB->SecondaryColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR1]; + VB->SecondaryColorPtr[1] = 0; for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]; @@ -179,8 +179,7 @@ void _tnl_playback_vertex_list( GLcontext *ctx, void *data ) * includes operations such as glBegin or glDrawArrays. */ _mesa_error( ctx, GL_INVALID_OPERATION, "displaylist recursive begin"); - if (!(node->prim[0].mode & PRIM_WEAK)) - _tnl_loopback_vertex_list( ctx, data ); + _tnl_loopback_vertex_list( ctx, data ); return; } else if (node->dangling_attr_ref) { |