diff options
author | Marek Olšák <[email protected]> | 2020-03-21 22:15:20 -0400 |
---|---|---|
committer | Marge Bot <[email protected]> | 2020-04-30 22:01:55 +0000 |
commit | eb04db734429971ddc240ba9dc6726a991cc0a14 (patch) | |
tree | 65109b6589ddda1180ae501405f3671f8638dee4 /src | |
parent | beb02a781ca9a4918b7ac777aab65cc31338ee87 (diff) |
mesa: optimize glPush/PopClientAttrib by removing malloc overhead
just declare all structures needed by the stack in gl_context.
This improves performance by 5.6% in the game "torcs". FPS: 101.01 -> 106.73
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4314>
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/main/arrayobj.c | 7 | ||||
-rw-r--r-- | src/mesa/main/arrayobj.h | 4 | ||||
-rw-r--r-- | src/mesa/main/attrib.c | 158 | ||||
-rw-r--r-- | src/mesa/main/mtypes.h | 14 |
4 files changed, 46 insertions, 137 deletions
diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index dd410c345cc..3ebcedea4e9 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -304,8 +304,9 @@ _mesa_lookup_vao_err(struct gl_context *ctx, GLuint id, * to any buffer objects (VBOs). * This is done just prior to array object destruction. */ -static void -unbind_array_object_vbos(struct gl_context *ctx, struct gl_vertex_array_object *obj) +void +_mesa_unbind_array_object_vbos(struct gl_context *ctx, + struct gl_vertex_array_object *obj) { GLuint i; @@ -333,7 +334,7 @@ _mesa_new_vao(struct gl_context *ctx, GLuint name) void _mesa_delete_vao(struct gl_context *ctx, struct gl_vertex_array_object *obj) { - unbind_array_object_vbos(ctx, obj); + _mesa_unbind_array_object_vbos(ctx, obj); _mesa_reference_buffer_object(ctx, &obj->IndexBufferObj, NULL); free(obj->Label); free(obj); diff --git a/src/mesa/main/arrayobj.h b/src/mesa/main/arrayobj.h index 94e22348248..9da996014de 100644 --- a/src/mesa/main/arrayobj.h +++ b/src/mesa/main/arrayobj.h @@ -57,6 +57,10 @@ extern struct gl_vertex_array_object * _mesa_new_vao(struct gl_context *ctx, GLuint name); extern void +_mesa_unbind_array_object_vbos(struct gl_context *ctx, + struct gl_vertex_array_object *obj); + +extern void _mesa_delete_vao(struct gl_context *ctx, struct gl_vertex_array_object *obj); extern void diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index e3df99b0396..74c449bfbcb 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -1690,47 +1690,11 @@ restore_array_attrib(struct gl_context *ctx, } } -/** - * init/alloc the fields of 'attrib'. - * Needs to the init part matching free_array_attrib_data below. - */ -static bool -init_array_attrib_data(struct gl_context *ctx, - struct gl_array_attrib *attrib) -{ - /* Get a non driver gl_vertex_array_object. */ - attrib->VAO = MALLOC_STRUCT(gl_vertex_array_object); - - if (attrib->VAO == NULL) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); - return false; - } - - _mesa_initialize_vao(ctx, attrib->VAO, 0); - return true; -} - -/** - * Free/unreference the fields of 'attrib' but don't delete it (that's - * done later in the calling code). - * Needs to the cleanup part matching init_array_attrib_data above. - */ -static void -free_array_attrib_data(struct gl_context *ctx, - struct gl_array_attrib *attrib) -{ - /* We use a non driver array object, so don't just unref since we would - * end up using the drivers DeleteArrayObject function for deletion. */ - _mesa_delete_vao(ctx, attrib->VAO); - attrib->VAO = 0; - _mesa_reference_buffer_object(ctx, &attrib->ArrayBufferObj, NULL); -} - void GLAPIENTRY _mesa_PushClientAttrib(GLbitfield mask) { - struct gl_attrib_node *head; + struct gl_client_attrib_node *head; GET_CURRENT_CONTEXT(ctx); @@ -1739,81 +1703,29 @@ _mesa_PushClientAttrib(GLbitfield mask) return; } - /* Build linked list of attribute nodes which save all attribute - * groups specified by the mask. - */ - head = NULL; + head = &ctx->ClientAttribStack[ctx->ClientAttribStackDepth]; + head->Mask = mask; if (mask & GL_CLIENT_PIXEL_STORE_BIT) { - struct gl_pixelstore_attrib *attr; - /* packing attribs */ - attr = CALLOC_STRUCT(gl_pixelstore_attrib); - if (attr == NULL) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); - goto end; - } - if (save_attrib_data(&head, GL_CLIENT_PACK_BIT, attr)) { - copy_pixelstore(ctx, attr, &ctx->Pack); - } - else { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); - free(attr); - goto end; - } - - /* unpacking attribs */ - attr = CALLOC_STRUCT(gl_pixelstore_attrib); - if (attr == NULL) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); - goto end; - } - - if (save_attrib_data(&head, GL_CLIENT_UNPACK_BIT, attr)) { - copy_pixelstore(ctx, attr, &ctx->Unpack); - } - else { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); - free(attr); - goto end; - } + copy_pixelstore(ctx, &head->Pack, &ctx->Pack); + copy_pixelstore(ctx, &head->Unpack, &ctx->Unpack); } if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) { - struct gl_array_attrib *attr; - attr = CALLOC_STRUCT(gl_array_attrib); - if (attr == NULL) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); - goto end; - } - - if (!init_array_attrib_data(ctx, attr)) { - free(attr); - goto end; - } - - if (save_attrib_data(&head, GL_CLIENT_VERTEX_ARRAY_BIT, attr)) { - save_array_attrib(ctx, attr, &ctx->Array); - } - else { - free_array_attrib_data(ctx, attr); - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib"); - free(attr); - /* goto to keep safe from possible later changes */ - goto end; - } - } -end: - if (head != NULL) { - ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head; - ctx->ClientAttribStackDepth++; + _mesa_initialize_vao(ctx, &head->VAO, 0); + /* Use the VAO declared within the node instead of allocating it. */ + head->Array.VAO = &head->VAO; + save_array_attrib(ctx, &head->Array, &ctx->Array); } + + ctx->ClientAttribStackDepth++; } void GLAPIENTRY _mesa_PopClientAttrib(void) { - struct gl_attrib_node *node, *next; + struct gl_client_attrib_node *head; GET_CURRENT_CONTEXT(ctx); FLUSH_VERTICES(ctx, 0); @@ -1824,41 +1736,21 @@ _mesa_PopClientAttrib(void) } ctx->ClientAttribStackDepth--; - node = ctx->ClientAttribStack[ctx->ClientAttribStackDepth]; + head = &ctx->ClientAttribStack[ctx->ClientAttribStackDepth]; - while (node) { - switch (node->kind) { - case GL_CLIENT_PACK_BIT: - { - struct gl_pixelstore_attrib *store = - (struct gl_pixelstore_attrib *) node->data; - copy_pixelstore(ctx, &ctx->Pack, store); - _mesa_reference_buffer_object(ctx, &store->BufferObj, NULL); - } - break; - case GL_CLIENT_UNPACK_BIT: - { - struct gl_pixelstore_attrib *store = - (struct gl_pixelstore_attrib *) node->data; - copy_pixelstore(ctx, &ctx->Unpack, store); - _mesa_reference_buffer_object(ctx, &store->BufferObj, NULL); - } - break; - case GL_CLIENT_VERTEX_ARRAY_BIT: { - struct gl_array_attrib * attr = - (struct gl_array_attrib *) node->data; - restore_array_attrib(ctx, &ctx->Array, attr); - free_array_attrib_data(ctx, attr); - break; - } - default: - unreachable("Bad attrib flag in PopClientAttrib"); - } + if (head->Mask & GL_CLIENT_PIXEL_STORE_BIT) { + copy_pixelstore(ctx, &ctx->Pack, &head->Pack); + _mesa_reference_buffer_object(ctx, &head->Pack.BufferObj, NULL); + + copy_pixelstore(ctx, &ctx->Unpack, &head->Unpack); + _mesa_reference_buffer_object(ctx, &head->Unpack.BufferObj, NULL); + } - next = node->next; - free(node->data); - free(node); - node = next; + if (head->Mask & GL_CLIENT_VERTEX_ARRAY_BIT) { + restore_array_attrib(ctx, &ctx->Array, &head->Array); + _mesa_unbind_array_object_vbos(ctx, &head->VAO); + _mesa_reference_buffer_object(ctx, &head->VAO.IndexBufferObj, NULL); + _mesa_reference_buffer_object(ctx, &head->Array.ArrayBufferObj, NULL); } } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 0a50e929986..5bb6ac58be4 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -4831,6 +4831,18 @@ struct gl_semaphore_object }; /** + * One element of the client attrib stack. + */ +struct gl_client_attrib_node +{ + GLbitfield Mask; + struct gl_array_attrib Array; + struct gl_vertex_array_object VAO; + struct gl_pixelstore_attrib Pack; + struct gl_pixelstore_attrib Unpack; +}; + +/** * Mesa rendering context. * * This is the central context data structure for Mesa. Almost all @@ -4968,7 +4980,7 @@ struct gl_context /** \name Client attribute stack */ /*@{*/ GLuint ClientAttribStackDepth; - struct gl_attrib_node *ClientAttribStack[MAX_CLIENT_ATTRIB_STACK_DEPTH]; + struct gl_client_attrib_node ClientAttribStack[MAX_CLIENT_ATTRIB_STACK_DEPTH]; /*@}*/ /** \name Client attribute groups */ |