st/mesa: move the logic of all_varyings_in_vbos into st_update_array
authorMarek Olšák <marek.olsak@amd.com>
Mon, 8 May 2017 00:15:08 +0000 (02:15 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 10 May 2017 17:29:08 +0000 (19:29 +0200)
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

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/mesa/state_tracker/st_atom_array.c
src/mesa/state_tracker/st_context.h
src/mesa/state_tracker/st_draw.c

index 1327a196eff96b4db615d8330a717b2ef0272449..c7467eb20b7198b9b8b5bb9b12a77a8103f9c679 100644 (file)
@@ -555,6 +555,9 @@ setup_interleaved_attribs(struct st_context *st,
       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,
@@ -647,6 +650,9 @@ setup_non_interleaved_attribs(struct st_context *st,
             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;
          }
       }
 
@@ -681,6 +687,7 @@ void st_update_array(struct st_context *st)
    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)
index 68fd9b9d3d280a4e5a87a9f478e81c628b136876..520cd8d4623e5685a4ae507d905730afe1c1d268 100644 (file)
@@ -120,7 +120,7 @@ struct st_context
     * 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.
index 15c5b80f2912108ba325854fbcbb358f6e21c351..019001fd6f27263f6fc7dfd27e672a0005937dd2 100644 (file)
 #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.
  */
@@ -161,7 +142,6 @@ st_draw_vbo(struct gl_context *ctx,
 {
    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;
 
@@ -180,10 +160,10 @@ st_draw_vbo(struct gl_context *ctx,
       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;