u_vbuf: override draw_vbo
authorMarek Olšák <maraeo@gmail.com>
Sat, 31 Mar 2012 12:52:35 +0000 (14:52 +0200)
committerMarek Olšák <maraeo@gmail.com>
Mon, 23 Apr 2012 23:39:21 +0000 (01:39 +0200)
src/gallium/auxiliary/util/u_vbuf.c
src/gallium/auxiliary/util/u_vbuf.h
src/gallium/drivers/r300/r300_render.c
src/gallium/drivers/r600/r600_state_common.c

index f3ba89f6717ab70512f525d6f221323f0a773f54..b63de487c3f6df1e6a2373ae95706677a748d631 100644 (file)
@@ -76,6 +76,7 @@ struct u_vbuf_priv {
     * There are no user buffers. */
    struct pipe_vertex_buffer real_vertex_buffer[PIPE_MAX_ATTRIBS];
    int nr_real_vertex_buffers;
+   boolean vertex_buffers_dirty;
 
    /* The index buffer. */
    struct pipe_index_buffer index_buffer;
@@ -109,6 +110,8 @@ struct u_vbuf_priv {
                                           const struct pipe_vertex_element *);
    void (*driver_bind_vertex_elements_state)(struct pipe_context *, void *);
    void (*driver_delete_vertex_elements_state)(struct pipe_context *, void *);
+   void (*driver_draw_vbo)(struct pipe_context *pipe,
+                           const struct pipe_draw_info *info);
 };
 
 static void u_vbuf_init_format_caps(struct u_vbuf_priv *mgr)
@@ -744,11 +747,7 @@ static void u_vbuf_set_vertex_buffers(struct pipe_context *pipe,
 
    mgr->b.nr_vertex_buffers = count;
    mgr->nr_real_vertex_buffers = count;
-
-   if (!mgr->any_user_vbs && !mgr->incompatible_vb_layout) {
-      mgr->driver_set_vertex_buffers(pipe, mgr->nr_real_vertex_buffers,
-                                     mgr->real_vertex_buffer);
-   }
+   mgr->vertex_buffers_dirty = TRUE;
 }
 
 static void u_vbuf_set_index_buffer(struct pipe_context *pipe,
@@ -1067,17 +1066,26 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
    }
 }
 
-void u_vbuf_draw_begin(struct u_vbuf *mgrb,
-                       struct pipe_draw_info *info)
+static void u_vbuf_draw_vbo(struct pipe_context *pipe,
+                            const struct pipe_draw_info *info)
 {
-   struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb;
+   struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw;
    int start_vertex, min_index;
    unsigned num_vertices;
    bool unroll_indices = false;
 
+   /* Normal draw. No fallback and no user buffers. */
    if (!mgr->incompatible_vb_layout &&
        !mgr->ve->incompatible_layout &&
        !mgr->any_user_vbs) {
+      /* Set vertex buffers if needed. */
+      if (mgr->vertex_buffers_dirty) {
+         mgr->driver_set_vertex_buffers(pipe, mgr->nr_real_vertex_buffers,
+                                        mgr->real_vertex_buffer);
+         mgr->vertex_buffers_dirty = FALSE;
+      }
+
+      mgr->driver_draw_vbo(pipe, info);
       return;
    }
 
@@ -1164,25 +1172,26 @@ void u_vbuf_draw_begin(struct u_vbuf *mgrb,
    }
    */
 
-   if (unroll_indices) {
-      info->indexed = FALSE;
-      info->index_bias = 0;
-      info->min_index = 0;
-      info->max_index = info->count - 1;
-      info->start = 0;
-   }
-
    mgr->driver_set_vertex_buffers(mgr->pipe, mgr->nr_real_vertex_buffers,
                                   mgr->real_vertex_buffer);
-}
 
-void u_vbuf_draw_end(struct u_vbuf *mgrb)
-{
-   struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb;
+   if (unlikely(unroll_indices)) {
+      struct pipe_draw_info new_info = *info;
+      new_info.indexed = FALSE;
+      new_info.index_bias = 0;
+      new_info.min_index = 0;
+      new_info.max_index = info->count - 1;
+      new_info.start = 0;
+
+      mgr->driver_draw_vbo(pipe, &new_info);
+   } else {
+      mgr->driver_draw_vbo(pipe, info);
+   }
 
    if (mgr->fallback_ve) {
       u_vbuf_translate_end(mgr);
    }
+   mgr->vertex_buffers_dirty = TRUE;
 }
 
 static void u_vbuf_install(struct u_vbuf_priv *mgr)
@@ -1198,9 +1207,12 @@ static void u_vbuf_install(struct u_vbuf_priv *mgr)
    mgr->driver_bind_vertex_elements_state = pipe->bind_vertex_elements_state;
    mgr->driver_delete_vertex_elements_state =
       pipe->delete_vertex_elements_state;
+   mgr->driver_draw_vbo = pipe->draw_vbo;
+
    pipe->set_index_buffer = u_vbuf_set_index_buffer;
    pipe->set_vertex_buffers = u_vbuf_set_vertex_buffers;
    pipe->create_vertex_elements_state = u_vbuf_create_vertex_elements;
    pipe->bind_vertex_elements_state = u_vbuf_bind_vertex_elements;
    pipe->delete_vertex_elements_state = u_vbuf_delete_vertex_elements;
+   pipe->draw_vbo = u_vbuf_draw_vbo;
 }
index 99b97a2b09c6065fc067cd364dde2a02bfadca7d..4f3235b7ca9978a4bbed8c13426ca78b99d4654a 100644 (file)
@@ -98,13 +98,8 @@ u_vbuf_create(struct pipe_context *pipe,
 
 void u_vbuf_destroy(struct u_vbuf *mgr);
 
-void u_vbuf_draw_begin(struct u_vbuf *mgr,
-                       struct pipe_draw_info *info);
-
 unsigned u_vbuf_draw_max_vertex_count(struct u_vbuf *mgr);
 
-void u_vbuf_draw_end(struct u_vbuf *mgr);
-
 
 static INLINE struct u_vbuf_resource *u_vbuf_resource(struct pipe_resource *r)
 {
index 84162bfa638a387c4eb18b58dd5e2491ef7dfbfb..c0f5687d80ac79fa1999b204a87dc32eba08923a 100644 (file)
@@ -754,7 +754,6 @@ static void r300_draw_vbo(struct pipe_context* pipe,
     }
 
     r300_update_derived_state(r300);
-    u_vbuf_draw_begin(r300->vbuf_mgr, &info);
 
     /* Draw. */
     if (info.indexed) {
@@ -763,7 +762,7 @@ static void r300_draw_vbo(struct pipe_context* pipe,
         if (!max_count) {
            fprintf(stderr, "r300: Skipping a draw command. There is a buffer "
                    " which is too small to be used for rendering.\n");
-           goto done;
+           return;
         }
 
         if (max_count == ~0) {
@@ -795,9 +794,6 @@ static void r300_draw_vbo(struct pipe_context* pipe,
             r300_draw_arrays_instanced(r300, &info);
         }
     }
-
-done:
-    u_vbuf_draw_end(r300->vbuf_mgr);
 }
 
 /****************************************************************************
index a6fb6b81d833172f144286458430e5d6f5487373..6c02ed544c48b80323d9bb07817343098722ce3d 100644 (file)
@@ -761,7 +761,6 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
        r600_update_derived_state(rctx);
 
        /* Update vertex buffers. */
-       u_vbuf_draw_begin(rctx->vbuf_mgr, &info);
        if (rctx->vertex_buffers_dirty) {
                r600_inval_vertex_cache(rctx);
                rctx->vertex_buffer_state.num_dw = (rctx->chip_class >= EVERGREEN ? 12 : 10) *
@@ -902,7 +901,6 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
        }
 
        pipe_resource_reference(&ib.buffer, NULL);
-       u_vbuf_draw_end(rctx->vbuf_mgr);
 }
 
 void _r600_pipe_state_add_reg_bo(struct r600_context *ctx,