mesa: Keep track of the last looked-up VAO

This saves the cost of repeated hash table lookups when the same
vertex array object is referenced in a sequence of calls such as:

    glVertexArrayAttribFormat(vao, ...);
    glVertexArrayAttribBinding(vao, ...);
    glEnableVertexArrayAttrib(vao, ...);
    ...

Note that VAO's are container objects that are not shared between
contexts.

Reviewed-by: Laura Ekstrand <laura@jlekstrand.net>
This commit is contained in:
Fredrik Höglund 2015-03-02 18:25:45 +01:00
parent 2830c2fbeb
commit 6c37acfbed
2 changed files with 27 additions and 13 deletions

View File

@ -100,20 +100,28 @@ _mesa_lookup_vao_err(struct gl_context *ctx, GLuint id, const char *caller)
return ctx->Array.DefaultVAO; return ctx->Array.DefaultVAO;
} else { } else {
struct gl_vertex_array_object *vao = struct gl_vertex_array_object *vao;
(struct gl_vertex_array_object *)
_mesa_HashLookup(ctx->Array.Objects, id);
/* The ARB_direct_state_access specification says: if (ctx->Array.LastLookedUpVAO &&
* ctx->Array.LastLookedUpVAO->Name == id) {
* "An INVALID_OPERATION error is generated if <vaobj> is not vao = ctx->Array.LastLookedUpVAO;
* [compatibility profile: zero or] the name of an existing } else {
* vertex array object." vao = (struct gl_vertex_array_object *)
*/ _mesa_HashLookup(ctx->Array.Objects, id);
if (!vao || !vao->EverBound) {
_mesa_error(ctx, GL_INVALID_OPERATION, /* The ARB_direct_state_access specification says:
"%s(non-existent vaobj=%u)", caller, id); *
return NULL; * "An INVALID_OPERATION error is generated if <vaobj> is not
* [compatibility profile: zero or] the name of an existing
* vertex array object."
*/
if (!vao || !vao->EverBound) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(non-existent vaobj=%u)", caller, id);
return NULL;
}
_mesa_reference_vao(ctx, &ctx->Array.LastLookedUpVAO, vao);
} }
return vao; return vao;
@ -517,6 +525,9 @@ _mesa_DeleteVertexArrays(GLsizei n, const GLuint *ids)
/* The ID is immediately freed for re-use */ /* The ID is immediately freed for re-use */
remove_array_object(ctx, obj); remove_array_object(ctx, obj);
if (ctx->Array.LastLookedUpVAO == obj)
_mesa_reference_vao(ctx, &ctx->Array.LastLookedUpVAO, NULL);
/* Unreference the array object. /* Unreference the array object.
* If refcount hits zero, the object will be deleted. * If refcount hits zero, the object will be deleted.
*/ */

View File

@ -1674,6 +1674,9 @@ struct gl_array_attrib
/** The default vertex array object */ /** The default vertex array object */
struct gl_vertex_array_object *DefaultVAO; struct gl_vertex_array_object *DefaultVAO;
/** The last VAO accessed by a DSA function */
struct gl_vertex_array_object *LastLookedUpVAO;
/** Array objects (GL_ARB/APPLE_vertex_array_object) */ /** Array objects (GL_ARB/APPLE_vertex_array_object) */
struct _mesa_HashTable *Objects; struct _mesa_HashTable *Objects;