aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2020-03-21 22:15:20 -0400
committerMarge Bot <[email protected]>2020-04-30 22:01:55 +0000
commiteb04db734429971ddc240ba9dc6726a991cc0a14 (patch)
tree65109b6589ddda1180ae501405f3671f8638dee4 /src/mesa
parentbeb02a781ca9a4918b7ac777aab65cc31338ee87 (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/mesa')
-rw-r--r--src/mesa/main/arrayobj.c7
-rw-r--r--src/mesa/main/arrayobj.h4
-rw-r--r--src/mesa/main/attrib.c158
-rw-r--r--src/mesa/main/mtypes.h14
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 */