[Mesa-dev] [PATCH] vbo: optimize some display list drawing (v2)
Ian Romanick
idr at freedesktop.org
Tue Jan 16 17:33:02 UTC 2018
Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>
On 01/15/2018 11:37 AM, Brian Paul wrote:
> The vbo_save_vertex_list structure records one or more glBegin/End
> primitives which all have the same vertex format.
>
> To draw these primitives, we setup the vertex array state, then
> issue the drawing command. Before, the 'start' vertex was typically
> zero and we used the vertex array pointer to indicate where the
> vertex data starts.
>
> This patch checks if the vertex buffer offset is an exact multiple of
> the vertex size. If so, that means we can use zero-based vertex array
> pointers and use the draw's start value to indicate where the vertex
> data starts.
>
> This means a series of display list drawing commands may have
> identical vertex array state. This will get filtered out by the
> Gallium CSO module so we can issue a tight series of drawing commands
> without state changes to the device.
>
> Note that this also works for a series of glCallList commands (not
> just one list that contains multiple glBegin/End pairs).
>
> No Piglit or conform changes.
>
> v2: minor fixes suggested by Ian.
> ---
> src/mesa/vbo/vbo_save.h | 14 ++++++++++++++
> src/mesa/vbo/vbo_save_api.c | 14 ++++++++++++++
> src/mesa/vbo/vbo_save_draw.c | 12 ++++++++++++
> 3 files changed, 40 insertions(+)
>
> diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h
> index 9d13e0a..274d667 100644
> --- a/src/mesa/vbo/vbo_save.h
> +++ b/src/mesa/vbo/vbo_save.h
> @@ -86,6 +86,20 @@ struct vbo_save_vertex_list {
> struct vbo_save_primitive_store *prim_store;
> };
>
> +
> +/**
> + * Is the vertex lists's buffer offset an exact multiple of the
> + * vertex size (in bytes)? This is used to check for a vertex array /
> + * drawing optimization.
> + */
> +static inline bool
> +aligned_vertex_buffer_offset(const struct vbo_save_vertex_list *node)
> +{
> + unsigned vertex_size = node->vertex_size * sizeof(GLfloat); /* in bytes */
> + return vertex_size != 0 && node->buffer_offset % vertex_size == 0;
> +}
> +
> +
> /* These buffers should be a reasonable size to support upload to
> * hardware. Current vbo implementation will re-upload on any
> * changes, so don't make too big or apps which dynamically create
> diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c
> index 42d883f..1c57544 100644
> --- a/src/mesa/vbo/vbo_save_api.c
> +++ b/src/mesa/vbo/vbo_save_api.c
> @@ -546,6 +546,20 @@ compile_vertex_list(struct gl_context *ctx)
> save->prim_store = alloc_prim_store();
> }
>
> + /*
> + * If the vertex buffer offset is a multiple of the vertex size,
> + * we can use the _mesa_prim::start value to indicate where the
> + * vertices starts, instead of the buffer offset. Also see the
> + * bind_vertex_list() function.
> + */
> + if (aligned_vertex_buffer_offset(node)) {
> + const unsigned start_offset =
> + node->buffer_offset / (node->vertex_size * sizeof(GLfloat));
> + for (unsigned i = 0; i < save->prim_count; i++) {
> + save->prims[i].start += start_offset;
> + }
> + }
> +
> /* Reset our structures for the next run of vertices:
> */
> reset_counters(ctx);
> diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c
> index 1694a04..b63a9a8 100644
> --- a/src/mesa/vbo/vbo_save_draw.c
> +++ b/src/mesa/vbo/vbo_save_draw.c
> @@ -146,6 +146,18 @@ bind_vertex_list(struct gl_context *ctx,
> memcpy(node_attrsz, node->attrsz, sizeof(node->attrsz));
> memcpy(node_attrtype, node->attrtype, sizeof(node->attrtype));
>
> + if (aligned_vertex_buffer_offset(node)) {
> + /* The vertex size is an exact multiple of the buffer offset.
> + * This means that we can use zero-based vertex attribute pointers
> + * and specify the start of the primitive with the _mesa_prim::start
> + * field. This results in issuing several draw calls with identical
> + * vertex attribute information. This can result in fewer state
> + * changes in drivers. In particular, the Gallium CSO module will
> + * filter out redundant vertex buffer changes.
> + */
> + buffer_offset = 0;
> + }
> +
> /* Install the default (ie Current) attributes first, then overlay
> * all active ones.
> */
>
More information about the mesa-dev
mailing list