From 7a5ddd29c2e44ea8513f9c106f60e7d126c1afee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Thu, 4 Jan 2024 18:44:07 -0500 Subject: [PATCH] mesa: don't use the slow VAO path except for drivers that want to use it The fast path is the only focus of optimizations, so let's stop using the slow one if the fast path is allowed. Only display lists with drivers lacking draw_vertex_state use it, and drivers not exposing PIPE_CAP_ALLOW_DYNAMIC_VAO_FASTPATH use it. This changes gl_constants::AllowDynamicVAOFastPath to UseVAOFastPath because it's no longer turned on/off dynamically, but only one of them is always used per VAO. It also removes the IsDynamic and NumUpdates fields of VAOs. Reviewed-By: Mike Blumenkrantz Part-of: --- src/mesa/main/arrayobj.c | 13 +++---------- src/mesa/main/arrayobj.h | 3 ++- src/mesa/main/consts_exts.h | 7 +++++-- src/mesa/main/mtypes.h | 14 -------------- src/mesa/main/varray.c | 12 +++++++----- src/mesa/state_tracker/st_atom_array.cpp | 18 ++++++++++-------- src/mesa/state_tracker/st_cb_rasterpos.c | 4 ++-- src/mesa/state_tracker/st_extensions.c | 2 +- src/mesa/vbo/vbo_save_api.c | 2 +- 9 files changed, 31 insertions(+), 44 deletions(-) diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index 32e0a194592..e96aaabc91e 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -515,9 +515,10 @@ compute_vbo_offset_range(const struct gl_vertex_array_object *vao, */ void _mesa_update_vao_derived_arrays(struct gl_context *ctx, - struct gl_vertex_array_object *vao) + struct gl_vertex_array_object *vao, + bool display_list) { - assert(!vao->IsDynamic); + assert(display_list || !ctx->Const.UseVAOFastPath); /* Make sure we do not run into problems with shared objects */ assert(!vao->SharedAndImmutable); @@ -543,14 +544,6 @@ _mesa_update_vao_derived_arrays(struct gl_context *ctx, /* VBO array bits. */ const GLbitfield vbos = vao->VertexAttribBufferMask; - /* More than 4 updates turn the VAO to dynamic. */ - if (ctx->Const.AllowDynamicVAOFastPath && ++vao->NumUpdates > 4) { - vao->IsDynamic = true; - /* IsDynamic changes how vertex elements map to vertex buffers. */ - ctx->Array.NewVertexElements = true; - return; - } - /* Walk those enabled arrays that have a real vbo attached */ GLbitfield mask = enabled; while (mask) { diff --git a/src/mesa/main/arrayobj.h b/src/mesa/main/arrayobj.h index 87c86b5a148..279d7ec2a9a 100644 --- a/src/mesa/main/arrayobj.h +++ b/src/mesa/main/arrayobj.h @@ -89,7 +89,8 @@ _mesa_initialize_vao(struct gl_context *ctx, extern void _mesa_update_vao_derived_arrays(struct gl_context *ctx, - struct gl_vertex_array_object *vao); + struct gl_vertex_array_object *vao, + bool display_list); extern void _mesa_vao_map_arrays(struct gl_context *ctx, struct gl_vertex_array_object *vao, diff --git a/src/mesa/main/consts_exts.h b/src/mesa/main/consts_exts.h index 6cc973a7175..8510ebde5b9 100644 --- a/src/mesa/main/consts_exts.h +++ b/src/mesa/main/consts_exts.h @@ -973,8 +973,11 @@ struct gl_constants /** Whether out-of-order draw (Begin/End) optimizations are allowed. */ bool AllowDrawOutOfOrder; - /** Whether to allow the fast path for frequently updated VAOs. */ - bool AllowDynamicVAOFastPath; + /** Whether to force the fast path for binding VAOs. It has much lower + * overhead due to not spending CPU cycles on trying to find interleaved + * vertex attribs and binding them. + */ + bool UseVAOFastPath; /** Whether the driver can support primitive restart with a fixed index. * This is essentially a subset of NV_primitive_restart with enough support diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 15ca47ff6b4..aed3440470f 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1630,14 +1630,6 @@ struct gl_vertex_array_object */ GLboolean EverBound; - /** - * Whether the VAO is changed by the application so often that some of - * the derived fields are not updated at all to decrease overhead. - * Also, interleaved arrays are not detected, because it's too expensive - * to do that before every draw call. - */ - bool IsDynamic; - /** * Marked to true if the object is shared between contexts and immutable. * Then reference counting is done using atomics and thread safe. @@ -1645,12 +1637,6 @@ struct gl_vertex_array_object */ bool SharedAndImmutable; - /** - * Number of updates that were done by the application. This is used to - * decide whether the VAO is static or dynamic. - */ - unsigned NumUpdates; - /** Vertex attribute arrays */ struct gl_array_attributes VertexAttrib[VERT_ATTRIB_MAX]; diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 25229537ee5..19d3251a5e9 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -304,10 +304,10 @@ _mesa_bind_vertex_buffer(struct gl_context *ctx, if (vao->Enabled & binding->_BoundArrays) { ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS; - /* Non-dynamic VAOs merge vertex buffers, which affects vertex elements. - * stride changes also require new vertex elements + /* The slow path merges vertex buffers, which affects vertex elements. + * Stride changes also require new vertex elements. */ - if (!vao->IsDynamic || stride_changed) + if (!ctx->Const.UseVAOFastPath || stride_changed) ctx->Array.NewVertexElements = true; } @@ -1123,8 +1123,10 @@ update_array(struct gl_context *ctx, if (vao->Enabled & VERT_BIT(attrib)) { ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS; - /* Non-dynamic VAOs merge vertex buffers, which affects vertex elements. */ - if (!vao->IsDynamic) + /* The slow path merges vertex buffers, which affects vertex + * elements. + */ + if (!ctx->Const.UseVAOFastPath) ctx->Array.NewVertexElements = true; } diff --git a/src/mesa/state_tracker/st_atom_array.cpp b/src/mesa/state_tracker/st_atom_array.cpp index 53c620100a7..3197e0b6206 100644 --- a/src/mesa/state_tracker/st_atom_array.cpp +++ b/src/mesa/state_tracker/st_atom_array.cpp @@ -82,10 +82,11 @@ setup_arrays(struct gl_context *ctx, const GLbitfield inputs_read, GLbitfield mask, struct cso_velems_state *velements, - struct pipe_vertex_buffer *vbuffer, unsigned *num_vbuffers) + struct pipe_vertex_buffer *vbuffer, unsigned *num_vbuffers, + bool use_vao_fast_path) { - /* Process attribute array data. */ - if (vao->IsDynamic) { + /* Set up enabled vertex arrays. */ + if (use_vao_fast_path) { const GLubyte *attribute_map = _mesa_vao_attribute_map[vao->_AttributeMapMode]; @@ -183,7 +184,7 @@ st_setup_arrays(struct st_context *st, (ctx, ctx->Array._DrawVAO, vp->Base.DualSlotInputs, vp_variant->vert_attrib_mask, vp_variant->vert_attrib_mask & enabled_arrays, - velements, vbuffer, num_vbuffers); + velements, vbuffer, num_vbuffers, ctx->Const.UseVAOFastPath); } /* ALWAYS_INLINE helps the compiler realize that most of the parameters are @@ -323,7 +324,8 @@ st_update_array_templ(struct st_context *st, /* Setup arrays */ setup_arrays (ctx, ctx->Array._DrawVAO, dual_slot_inputs, inputs_read, - inputs_read & enabled_arrays, &velements, vbuffer, &num_vbuffers); + inputs_read & enabled_arrays, &velements, vbuffer, &num_vbuffers, + ctx->Const.UseVAOFastPath); /* _NEW_CURRENT_ATTRIB */ /* Setup zero-stride attribs. */ @@ -362,8 +364,8 @@ st_update_array_impl(struct st_context *st) assert(vao->_EnabledWithMapMode == _mesa_vao_enable_to_vp_inputs(vao->_AttributeMapMode, vao->Enabled)); - if (!vao->IsDynamic && !vao->SharedAndImmutable) - _mesa_update_vao_derived_arrays(ctx, vao); + if (!ctx->Const.UseVAOFastPath && !vao->SharedAndImmutable) + _mesa_update_vao_derived_arrays(ctx, vao, false); _mesa_get_derived_vao_masks(ctx, enabled_arrays, &enabled_user_arrays, &nonzero_divisor_arrays); @@ -410,7 +412,7 @@ st_create_gallium_vertex_state(struct gl_context *ctx, setup_arrays (ctx, vao, dual_slot_inputs, inputs_read, inputs_read, &velements, - vbuffer, &num_vbuffers); + vbuffer, &num_vbuffers, false); if (num_vbuffers != 1) { assert(!"this should never happen with display lists"); diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c index fe8ec093f8c..e249d6c5b11 100644 --- a/src/mesa/state_tracker/st_cb_rasterpos.c +++ b/src/mesa/state_tracker/st_cb_rasterpos.c @@ -263,8 +263,8 @@ st_RasterPos(struct gl_context *ctx, const GLfloat v[4]) rs->VAO->VertexAttrib[VERT_ATTRIB_POS].Ptr = (GLubyte *) v; ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS; - /* Non-dynamic VAOs merge vertex buffers, which changes vertex elements. */ - if (!rs->VAO->IsDynamic) { + /* The slow path merges vertex buffers, which changes vertex elements. */ + if (!ctx->Const.UseVAOFastPath) { ctx->Array.NewVertexElements = true; } diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 91d593dfc90..17f2c74460b 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -606,7 +606,7 @@ void st_init_limits(struct pipe_screen *screen, c->VertexBufferOffsetIsInt32 = screen->get_param(screen, PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET); - c->AllowDynamicVAOFastPath = + c->UseVAOFastPath = screen->get_param(screen, PIPE_CAP_ALLOW_DYNAMIC_VAO_FASTPATH); c->glBeginEndBufferSize = diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index d013fac32f2..583f79e09dd 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -389,7 +389,7 @@ update_vao(struct gl_context *ctx, assert((vao_enabled & ~(*vao)->VertexAttribBufferMask) == 0); /* Finalize and freeze the VAO */ - _mesa_update_vao_derived_arrays(ctx, *vao); + _mesa_update_vao_derived_arrays(ctx, *vao, true); (*vao)->SharedAndImmutable = true; }