[Mesa-dev] [PATCH 3/3] st/mesa: move the logic of all_varyings_in_vbos into st_update_array
Nicolai Hähnle
nhaehnle at gmail.com
Mon May 8 19:08:30 UTC 2017
On 08.05.2017 19:09, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> The function was pretty slow. This brings a substantial decrease in draw
> call overhead when min/max index bounds are not needed:
>
> Before: DrawElements (1 VBO) w/ no state change: 5.75 million
> After: DrawElements (1 VBO) w/ no state change: 7.03 million
Nice improvement! Series is
Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
> ---
> src/mesa/state_tracker/st_atom_array.c | 7 +++++++
> src/mesa/state_tracker/st_context.h | 2 +-
> src/mesa/state_tracker/st_draw.c | 28 ++++------------------------
> 3 files changed, 12 insertions(+), 25 deletions(-)
>
> diff --git a/src/mesa/state_tracker/st_atom_array.c b/src/mesa/state_tracker/st_atom_array.c
> index 1327a19..c7467eb 100644
> --- a/src/mesa/state_tracker/st_atom_array.c
> +++ b/src/mesa/state_tracker/st_atom_array.c
> @@ -548,20 +548,23 @@ setup_interleaved_attribs(struct st_context *st,
> vbuffer.is_user_buffer = false;
> vbuffer.buffer_offset = pointer_to_offset(low_addr);
> vbuffer.stride = stride;
> }
> else {
> /* all interleaved arrays in user memory */
> vbuffer.buffer.user = low_addr;
> vbuffer.is_user_buffer = !!low_addr; /* if NULL, then unbind */
> vbuffer.buffer_offset = 0;
> vbuffer.stride = stride;
> +
> + if (low_addr)
> + st->draw_needs_minmax_index = true;
> }
>
> set_vertex_attribs(st, &vbuffer, num_inputs ? 1 : 0,
> velements, num_inputs);
> }
>
> /**
> * Set up a separate pipe_vertex_buffer and pipe_vertex_element for each
> * vertex attribute.
> * \param vbuffer returns vertex buffer info
> @@ -640,20 +643,23 @@ setup_non_interleaved_attribs(struct st_context *st,
> st->pipe->stream_uploader,
> 0, size, alignment, ptr,
> &vbuffer[bufidx].buffer_offset,
> &vbuffer[bufidx].buffer.resource);
> unref_buffers |= 1u << bufidx;
> } else {
> assert(array->Ptr);
> vbuffer[bufidx].buffer.user = array->Ptr;
> vbuffer[bufidx].is_user_buffer = true;
> vbuffer[bufidx].buffer_offset = 0;
> +
> + if (!array->InstanceDivisor)
> + st->draw_needs_minmax_index = true;
> }
> }
>
> /* common-case setup */
> vbuffer[bufidx].stride = stride; /* in bytes */
>
> src_format = st_pipe_vertex_format(array->Type,
> array->Size,
> array->Format,
> array->Normalized,
> @@ -674,20 +680,21 @@ setup_non_interleaved_attribs(struct st_context *st,
> }
>
> void st_update_array(struct st_context *st)
> {
> struct gl_context *ctx = st->ctx;
> const struct gl_vertex_array **arrays = ctx->Array._DrawArrays;
> const struct st_vertex_program *vp;
> unsigned num_inputs;
>
> st->vertex_array_out_of_memory = FALSE;
> + st->draw_needs_minmax_index = false;
>
> /* No drawing has been done yet, so do nothing. */
> if (!arrays)
> return;
>
> /* vertex program validation must be done before this */
> vp = st->vp;
> num_inputs = st->vp_variant->num_inputs;
>
> if (is_interleaved_arrays(vp, arrays, num_inputs))
> diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
> index 68fd9b9..520cd8d 100644
> --- a/src/mesa/state_tracker/st_context.h
> +++ b/src/mesa/state_tracker/st_context.h
> @@ -113,21 +113,21 @@ struct st_context
> */
> boolean shader_has_one_variant[MESA_SHADER_STAGES];
>
> boolean needs_texcoord_semantic;
> boolean apply_texture_swizzle_to_border_color;
>
> /* On old libGL's for linux we need to invalidate the drawables
> * on glViewpport calls, this is set via a option.
> */
> boolean invalidate_on_gl_viewport;
> -
> + boolean draw_needs_minmax_index;
> boolean vertex_array_out_of_memory;
>
> /* Some state is contained in constant objects.
> * Other state is just parameter values.
> */
> struct {
> struct pipe_blend_state blend;
> struct pipe_depth_stencil_alpha_state depth_stencil;
> struct pipe_rasterizer_state rasterizer;
> struct pipe_sampler_state samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
> diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
> index 15c5b80..019001f 100644
> --- a/src/mesa/state_tracker/st_draw.c
> +++ b/src/mesa/state_tracker/st_draw.c
> @@ -60,39 +60,20 @@
> #include "util/u_inlines.h"
> #include "util/u_format.h"
> #include "util/u_prim.h"
> #include "util/u_draw.h"
> #include "util/u_upload_mgr.h"
> #include "draw/draw_context.h"
> #include "cso_cache/cso_context.h"
>
>
> /**
> - * This is very similar to vbo_all_varyings_in_vbos() but we are
> - * only interested in per-vertex data. See bug 38626.
> - */
> -static GLboolean
> -all_varyings_in_vbos(const struct gl_vertex_array *arrays[])
> -{
> - GLuint i;
> -
> - for (i = 0; i < VERT_ATTRIB_MAX; i++)
> - if (arrays[i]->StrideB &&
> - !arrays[i]->InstanceDivisor &&
> - !_mesa_is_bufferobj(arrays[i]->BufferObj))
> - return GL_FALSE;
> -
> - return GL_TRUE;
> -}
> -
> -
> -/**
> * Set the restart index.
> */
> static void
> setup_primitive_restart(struct gl_context *ctx, struct pipe_draw_info *info)
> {
> if (ctx->Array._PrimitiveRestart) {
> unsigned index_size = info->index_size;
>
> info->restart_index =
> _mesa_primitive_restart_index(ctx, index_size);
> @@ -154,43 +135,42 @@ st_draw_vbo(struct gl_context *ctx,
> const struct _mesa_index_buffer *ib,
> GLboolean index_bounds_valid,
> GLuint min_index,
> GLuint max_index,
> struct gl_transform_feedback_object *tfb_vertcount,
> unsigned stream,
> struct gl_buffer_object *indirect)
> {
> struct st_context *st = st_context(ctx);
> struct pipe_draw_info info;
> - const struct gl_vertex_array **arrays = ctx->Array._DrawArrays;
> unsigned i;
> unsigned start = 0;
>
> prepare_draw(st, ctx);
>
> if (st->vertex_array_out_of_memory)
> return;
>
> /* Initialize pipe_draw_info. */
> info.primitive_restart = false;
> info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices;
> info.indirect = NULL;
> info.count_from_stream_output = NULL;
>
> if (ib) {
> struct gl_buffer_object *bufobj = ib->obj;
>
> /* Get index bounds for user buffers. */
> - if (!index_bounds_valid)
> - if (!all_varyings_in_vbos(arrays))
> - vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index,
> - nr_prims);
> + if (!index_bounds_valid && st->draw_needs_minmax_index) {
> + vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index,
> + nr_prims);
> + }
>
> info.index_size = ib->index_size;
> info.min_index = min_index;
> info.max_index = max_index;
>
> if (_mesa_is_bufferobj(bufobj)) {
> /* indices are in a real VBO */
> info.has_user_indices = false;
> info.index.resource = st_buffer_object(bufobj)->buffer;
> start = pointer_to_offset(ib->ptr) / info.index_size;
>
--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
More information about the mesa-dev
mailing list