From: Mathias Fröhlich <[email protected]> In glArrayElement, use the bitmask trick to just walk the enabled vao arrays. This should be about equivalent in execution time to walk the prepare aelt_context list. Finally this will allow us to reduce the _mesa_update_state calls in a few patches.
Signed-off-by: Mathias Fröhlich <[email protected]> --- src/mesa/main/api_arrayelt.c | 78 ++++++++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/src/mesa/main/api_arrayelt.c b/src/mesa/main/api_arrayelt.c index d46c8d14b68..62f1e73ca4c 100644 --- a/src/mesa/main/api_arrayelt.c +++ b/src/mesa/main/api_arrayelt.c @@ -1541,32 +1541,76 @@ _ae_update_state(struct gl_context *ctx) } +static inline attrib_func +func_nv(const struct gl_vertex_format *vformat) +{ + return AttribFuncsNV[vformat->Normalized][vformat->Size-1] + [TYPE_IDX(vformat->Type)]; +} + + +static inline attrib_func +func_arb(const struct gl_vertex_format *vformat) +{ + return AttribFuncsARB[NORM_IDX(vformat)][vformat->Size-1] + [TYPE_IDX(vformat->Type)]; +} + + +static inline const void * +attrib_src(const struct gl_vertex_array_object *vao, + const struct gl_array_attributes *array, GLint elt) +{ + const struct gl_vertex_buffer_binding *binding = + &vao->BufferBinding[array->BufferBindingIndex]; + const GLubyte *src + = ADD_POINTERS(binding->BufferObj->Mappings[MAP_INTERNAL].Pointer, + _mesa_vertex_attrib_address(array, binding)) + + elt * binding->Stride; + return src; +} + + void _mesa_array_element(struct gl_context *ctx, struct _glapi_table *disp, GLint elt) { - const AEcontext *actx = AE_CONTEXT(ctx); + const struct gl_vertex_array_object *vao = ctx->Array.VAO; + GLbitfield mask; - if (actx->dirty_state) - _ae_update_state(ctx); + /* emit conventional arrays elements */ + mask = (VERT_BIT_FF_ALL & ~VERT_BIT_POS) & vao->Enabled; + while (mask) { + const gl_vert_attrib attrib = u_bit_scan(&mask); + const struct gl_array_attributes *array = &vao->VertexAttrib[attrib]; + const void *src = attrib_src(vao, array, elt); + func_nv(&array->Format)(attrib, src); + } /* emit generic attribute elements */ - for (const AEattrib *at = actx->attribs; at->func; at++) { - const GLubyte *src - = ADD_POINTERS(at->binding->BufferObj->Mappings[MAP_INTERNAL].Pointer, - _mesa_vertex_attrib_address(at->array, at->binding)) - + elt * at->binding->Stride; - at->func(at->index, src); + mask = (VERT_BIT_GENERIC_ALL & ~VERT_BIT_GENERIC0) & vao->Enabled; + while (mask) { + const gl_vert_attrib attrib = u_bit_scan(&mask); + const struct gl_array_attributes *array = &vao->VertexAttrib[attrib]; + const void *src = attrib_src(vao, array, elt); + func_arb(&array->Format)(attrib - VERT_ATTRIB_GENERIC0, src); } - /* emit conventional arrays elements */ - for (const AEarray *aa = actx->arrays; aa->offset != -1 ; aa++) { - const GLubyte *src - = ADD_POINTERS(aa->binding->BufferObj->Mappings[MAP_INTERNAL].Pointer, - _mesa_vertex_attrib_address(aa->array, aa->binding)) - + elt * aa->binding->Stride; - CALL_by_offset(disp, (array_func), aa->offset, ((const void *) src)); - } + /* finally, vertex position */ + if (vao->Enabled & VERT_BIT_GENERIC0) { + const gl_vert_attrib attrib = VERT_ATTRIB_GENERIC0; + const struct gl_array_attributes *array = &vao->VertexAttrib[attrib]; + const void *src = attrib_src(vao, array, elt); + /* Use glVertex(v) instead of glVertexAttrib(0, v) to be sure it's + * issued as the last (provoking) attribute). + */ + func_nv(&array->Format)(0, src); + } else if (vao->Enabled & VERT_BIT_POS) { + const gl_vert_attrib attrib = VERT_ATTRIB_POS; + const struct gl_array_attributes *array = &vao->VertexAttrib[attrib]; + const void *src = attrib_src(vao, array, elt); + func_nv(&array->Format)(0, src); + } } -- 2.20.1 _______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
