r300g: avoid stall in no-tcl drawing when mapping vbo
authorDave Airlie <airlied@redhat.com>
Mon, 23 Aug 2010 10:28:02 +0000 (20:28 +1000)
committerDave Airlie <airlied@redhat.com>
Mon, 23 Aug 2010 10:31:21 +0000 (20:31 +1000)
the current code reuses the same vbo over and over, however after a flush
we'd stall and wait for mapping on the vbo when we should just fire and forget.

On a gears test this brings me from ~620 to ~750 on my rv530 in swtcl mode.

Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_flush.c
src/gallium/drivers/r300/r300_render.c

index 6fa7f47..030bb23 100644 (file)
@@ -449,6 +449,7 @@ struct r300_context {
     struct r300_screen *screen;
     /* Draw module. Used mostly for SW TCL. */
     struct draw_context* draw;
+    size_t draw_vbo_size;
     /* Accelerated blit support. */
     struct blitter_context* blitter;
     /* Stencil two-sided reference value fallback. */
@@ -649,6 +650,9 @@ void r300_translate_index_buffer(struct r300_context *r300,
 /* r300_render_stencilref.c */
 void r300_plug_in_stencil_ref_fallback(struct r300_context *r300);
 
+/* r300 render */
+void r300_draw_flush_vbuf(struct r300_context *r300);
+
 /* r300_state.c */
 enum r300_fb_state_change {
     R300_CHANGED_FB_STATE = 0,
index fe182b6..f00707b 100644 (file)
@@ -43,6 +43,8 @@ static void r300_flush(struct pipe_context* pipe,
     u_upload_flush(r300->upload_vb);
     u_upload_flush(r300->upload_ib);
 
+    if (r300->draw)
+       r300_draw_flush_vbuf(r300);
     if (r300->dirty_hw) {
         r300_emit_hyperz_end(r300);
         r300_emit_query_end(r300);
index 86b11ca..7344705 100644 (file)
@@ -726,8 +726,6 @@ struct r300_render {
     unsigned hwprim;
 
     /* VBO */
-    struct pipe_resource* vbo;
-    size_t vbo_size;
     size_t vbo_offset;
     size_t vbo_max_used;
     void * vbo_ptr;
@@ -759,31 +757,31 @@ static boolean r300_render_allocate_vertices(struct vbuf_render* render,
     struct pipe_screen* screen = r300->context.screen;
     size_t size = (size_t)vertex_size * (size_t)count;
 
-    if (size + r300render->vbo_offset > r300render->vbo_size)
+    if (size + r300render->vbo_offset > r300->draw_vbo_size)
     {
-        pipe_resource_reference(&r300->vbo, NULL);
-        r300render->vbo = pipe_buffer_create(screen,
-                                             PIPE_BIND_VERTEX_BUFFER,
-                                             R300_MAX_DRAW_VBO_SIZE);
+       pipe_resource_reference(&r300->vbo, NULL);
+        r300->vbo = pipe_buffer_create(screen,
+                                      PIPE_BIND_VERTEX_BUFFER,
+                                      R300_MAX_DRAW_VBO_SIZE);
         r300render->vbo_offset = 0;
-        r300render->vbo_size = R300_MAX_DRAW_VBO_SIZE;
+        r300->draw_vbo_size = R300_MAX_DRAW_VBO_SIZE;
     }
 
     r300render->vertex_size = vertex_size;
-    r300->vbo = r300render->vbo;
     r300->vbo_offset = r300render->vbo_offset;
 
-    return (r300render->vbo) ? TRUE : FALSE;
+    return (r300->vbo) ? TRUE : FALSE;
 }
 
 static void* r300_render_map_vertices(struct vbuf_render* render)
 {
     struct r300_render* r300render = r300_render(render);
+    struct r300_context* r300 = r300render->r300;
 
     assert(!r300render->vbo_transfer);
 
     r300render->vbo_ptr = pipe_buffer_map(&r300render->r300->context,
-                                         r300render->vbo,
+                                         r300->vbo,
                                           PIPE_TRANSFER_WRITE,
                                          &r300render->vbo_transfer);
 
@@ -798,12 +796,13 @@ static void r300_render_unmap_vertices(struct vbuf_render* render,
 {
     struct r300_render* r300render = r300_render(render);
     struct pipe_context* context = &r300render->r300->context;
+    struct r300_context* r300 = r300render->r300;
 
     assert(r300render->vbo_transfer);
 
     r300render->vbo_max_used = MAX2(r300render->vbo_max_used,
                                     r300render->vertex_size * (max + 1));
-    pipe_buffer_unmap(context, r300render->vbo, r300render->vbo_transfer);
+    pipe_buffer_unmap(context, r300->vbo, r300render->vbo_transfer);
 
     r300render->vbo_transfer = NULL;
 }
@@ -880,7 +879,7 @@ static void r300_render_draw_elements(struct vbuf_render* render,
     struct r300_context* r300 = r300render->r300;
     int i;
     unsigned end_cs_dwords;
-    unsigned max_index = (r300render->vbo_size - r300render->vbo_offset) /
+    unsigned max_index = (r300->draw_vbo_size - r300render->vbo_offset) /
                          (r300render->r300->vertex_info.size * 4) - 1;
     unsigned short_count;
     unsigned free_dwords;
@@ -956,8 +955,6 @@ static struct vbuf_render* r300_render_create(struct r300_context* r300)
     r300render->base.release_vertices = r300_render_release_vertices;
     r300render->base.destroy = r300_render_destroy;
 
-    r300render->vbo = NULL;
-    r300render->vbo_size = 0;
     r300render->vbo_offset = 0;
 
     return &r300render->base;
@@ -986,6 +983,14 @@ struct draw_stage* r300_draw_stage(struct r300_context* r300)
     return stage;
 }
 
+void r300_draw_flush_vbuf(struct r300_context *r300)
+{
+    struct r300_render *r300render;
+
+    pipe_resource_reference(&r300->vbo, NULL);
+    r300->draw_vbo_size = 0;
+}
+
 /****************************************************************************
  *                         End of SW TCL functions                          *
  ***************************************************************************/