Mesa (master): r300g: use memory pools for buffer_create and get_transfer

Marek Olšák mareko at kemper.freedesktop.org
Mon Jul 19 15:32:25 UTC 2010


Module: Mesa
Branch: master
Commit: 7b31b235d069ab4154bfc4b1eacde6368852aaee
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=7b31b235d069ab4154bfc4b1eacde6368852aaee

Author: Marek Olšák <maraeo at gmail.com>
Date:   Mon Jul 19 14:31:25 2010 +0200

r300g: use memory pools for buffer_create and get_transfer

The improvement in Tremulous: 68.9 fps -> 71.1 fps.

---

 src/gallium/drivers/r300/r300_context.c       |   28 +++++++++
 src/gallium/drivers/r300/r300_context.h       |    2 +
 src/gallium/drivers/r300/r300_screen.c        |    6 ++
 src/gallium/drivers/r300/r300_screen.h        |    9 +++
 src/gallium/drivers/r300/r300_screen_buffer.c |   80 +++++++++++++++++-------
 5 files changed, 101 insertions(+), 24 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 0f7deca..0c06d41 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -36,6 +36,24 @@
 
 #include <inttypes.h>
 
+static void r300_update_num_contexts(struct r300_screen *r300screen,
+                                     int diff)
+{
+    if (diff > 0) {
+        p_atomic_dec(&r300screen->num_contexts);
+
+        if (r300screen->num_contexts > 1)
+            util_mempool_set_thread_safety(&r300screen->pool_buffers,
+                                           UTIL_MEMPOOL_MULTITHREADED);
+    } else {
+        p_atomic_dec(&r300screen->num_contexts);
+
+        if (r300screen->num_contexts <= 1)
+            util_mempool_set_thread_safety(&r300screen->pool_buffers,
+                                           UTIL_MEMPOOL_SINGLETHREADED);
+    }
+}
+
 static void r300_release_referenced_objects(struct r300_context *r300)
 {
     struct pipe_framebuffer_state *fb =
@@ -102,6 +120,8 @@ static void r300_destroy_context(struct pipe_context* context)
 
     r300->rws->cs_destroy(r300->cs);
 
+    util_mempool_destroy(&r300->pool_transfers);
+
     FREE(r300->aa_state.state);
     FREE(r300->blend_color_state.state);
     FREE(r300->clip_state.state);
@@ -121,6 +141,8 @@ static void r300_destroy_context(struct pipe_context* context)
         FREE(r300->vertex_stream_state.state);
     }
     FREE(r300);
+
+    r300_update_num_contexts(r300->screen, -1);
 }
 
 void r300_flush_cb(void *data)
@@ -347,6 +369,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
     if (!r300)
         return NULL;
 
+    r300_update_num_contexts(r300screen, 1);
+
     r300->rws = rws;
     r300->screen = r300screen;
 
@@ -358,6 +382,10 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
 
     r300->cs = rws->cs_create(rws);
 
+    util_mempool_create(&r300->pool_transfers,
+                        sizeof(struct pipe_transfer), 64,
+                        UTIL_MEMPOOL_SINGLETHREADED);
+
     if (!r300screen->caps.has_tcl) {
         /* Create a Draw. This is used for SW TCL. */
         r300->draw = draw_create(&r300->context);
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index d2b8aa1..b9c96d5 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -539,6 +539,8 @@ struct r300_context {
     struct u_upload_mgr *upload_vb;
     struct u_upload_mgr *upload_ib;
 
+    struct util_mempool pool_transfers;
+
     /* Stat counter. */
     uint64_t flush_counter;
 };
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index f28b055..9c73ffc 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -345,6 +345,8 @@ static void r300_destroy_screen(struct pipe_screen* pscreen)
     struct r300_screen* r300screen = r300_screen(pscreen);
     struct r300_winsys_screen *rws = r300_winsys_screen(pscreen);
 
+    util_mempool_destroy(&r300screen->pool_buffers);
+
     if (rws)
       rws->destroy(rws);
 
@@ -400,6 +402,10 @@ struct pipe_screen* r300_screen_create(struct r300_winsys_screen *rws)
     r300_init_debug(r300screen);
     r300_parse_chipset(&r300screen->caps);
 
+    util_mempool_create(&r300screen->pool_buffers,
+                        sizeof(struct r300_buffer), 64,
+                        UTIL_MEMPOOL_SINGLETHREADED);
+
     r300screen->rws = rws;
     r300screen->screen.winsys = (struct pipe_winsys*)rws;
     r300screen->screen.destroy = r300_destroy_screen;
diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h
index 5827023..edc494f 100644
--- a/src/gallium/drivers/r300/r300_screen.h
+++ b/src/gallium/drivers/r300/r300_screen.h
@@ -28,6 +28,8 @@
 
 #include "r300_chipset.h"
 
+#include "util/u_mempool.h"
+
 #include <stdio.h>
 
 struct r300_winsys_screen;
@@ -41,8 +43,15 @@ struct r300_screen {
     /* Chipset capabilities */
     struct r300_capabilities caps;
 
+    /* Memory pools. */
+    struct util_mempool pool_buffers;
+
     /** Combination of DBG_xxx flags */
     unsigned debug;
+
+    /* The number of created contexts to know whether we have multiple
+     * contexts or not. */
+    int num_contexts;
 };
 
 
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c
index b19b5b5..37a080b 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.c
+++ b/src/gallium/drivers/r300/r300_screen_buffer.c
@@ -136,7 +136,39 @@ static void r300_buffer_destroy(struct pipe_screen *screen,
     if (rbuf->buf)
         rws->buffer_reference(rws, &rbuf->buf, NULL);
 
-    FREE(rbuf);
+    util_mempool_free(&r300screen->pool_buffers, rbuf);
+}
+
+static struct pipe_transfer*
+r300_default_get_transfer(struct pipe_context *context,
+                          struct pipe_resource *resource,
+                          struct pipe_subresource sr,
+                          unsigned usage,
+                          const struct pipe_box *box)
+{
+   struct r300_context *r300 = r300_context(context);
+   struct pipe_transfer *transfer =
+         util_mempool_malloc(&r300->pool_transfers);
+
+   transfer->resource = resource;
+   transfer->sr = sr;
+   transfer->usage = usage;
+   transfer->box = *box;
+   transfer->stride = 0;
+   transfer->slice_stride = 0;
+   transfer->data = NULL;
+
+   /* Note strides are zero, this is ok for buffers, but not for
+    * textures 2d & higher at least.
+    */
+   return transfer;
+}
+
+static void r300_default_transfer_destroy(struct pipe_context *pipe,
+                                          struct pipe_transfer *transfer)
+{
+   struct r300_context *r300 = r300_context(pipe);
+   util_mempool_free(&r300->pool_transfers, transfer);
 }
 
 static void *
@@ -236,14 +268,14 @@ static void r300_buffer_transfer_unmap( struct pipe_context *pipe,
 struct u_resource_vtbl r300_buffer_vtbl = 
 {
    u_default_resource_get_handle,      /* get_handle */
-   r300_buffer_destroy,		     /* resource_destroy */
-   r300_buffer_is_referenced_by_cs,  /* is_buffer_referenced */
-   u_default_get_transfer,	     /* get_transfer */
-   u_default_transfer_destroy,	     /* transfer_destroy */
-   r300_buffer_transfer_map,	     /* transfer_map */
+   r300_buffer_destroy,                /* resource_destroy */
+   r300_buffer_is_referenced_by_cs,    /* is_buffer_referenced */
+   r300_default_get_transfer,          /* get_transfer */
+   r300_default_transfer_destroy,      /* transfer_destroy */
+   r300_buffer_transfer_map,           /* transfer_map */
    r300_buffer_transfer_flush_region,  /* transfer_flush_region */
-   r300_buffer_transfer_unmap,	     /* transfer_unmap */
-   u_default_transfer_inline_write   /* transfer_inline_write */
+   r300_buffer_transfer_unmap,         /* transfer_unmap */
+   u_default_transfer_inline_write     /* transfer_inline_write */
 };
 
 struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
@@ -253,9 +285,7 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
     struct r300_buffer *rbuf;
     unsigned alignment = 16;
 
-    rbuf = CALLOC_STRUCT(r300_buffer);
-    if (!rbuf)
-	goto error1;
+    rbuf = util_mempool_malloc(&r300screen->pool_buffers);
 
     rbuf->magic = R300_BUFFER_MAGIC;
 
@@ -264,6 +294,10 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
     pipe_reference_init(&rbuf->b.b.reference, 1);
     rbuf->b.b.screen = screen;
     rbuf->domain = R300_DOMAIN_GTT;
+    rbuf->num_ranges = 0;
+    rbuf->buf = NULL;
+    rbuf->constant_buffer = NULL;
+    rbuf->user_buffer = NULL;
 
     /* Alloc constant buffers in RAM. */
     if (templ->bind & PIPE_BIND_CONSTANT_BUFFER) {
@@ -277,14 +311,12 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
                                        rbuf->b.b.bind, rbuf->b.b.usage,
                                        rbuf->domain);
 
-    if (!rbuf->buf)
-	goto error2;
+    if (!rbuf->buf) {
+        util_mempool_free(&r300screen->pool_buffers, rbuf);
+        return NULL;
+    }
 
     return &rbuf->b.b;
-error2:
-    FREE(rbuf);
-error1:
-    return NULL;
 }
 
 struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
@@ -292,28 +324,28 @@ struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
 					      unsigned bytes,
 					      unsigned bind)
 {
+    struct r300_screen *r300screen = r300_screen(screen);
     struct r300_buffer *rbuf;
 
-    rbuf = CALLOC_STRUCT(r300_buffer);
-    if (!rbuf)
-	goto no_rbuf;
+    rbuf = util_mempool_malloc(&r300screen->pool_buffers);
 
     rbuf->magic = R300_BUFFER_MAGIC;
 
     pipe_reference_init(&rbuf->b.b.reference, 1);
     rbuf->b.vtbl = &r300_buffer_vtbl;
     rbuf->b.b.screen = screen;
+    rbuf->b.b.target = PIPE_BUFFER;
     rbuf->b.b.format = PIPE_FORMAT_R8_UNORM;
     rbuf->b.b.usage = PIPE_USAGE_IMMUTABLE;
     rbuf->b.b.bind = bind;
     rbuf->b.b.width0 = bytes;
     rbuf->b.b.height0 = 1;
     rbuf->b.b.depth0 = 1;
+    rbuf->b.b.flags = 0;
     rbuf->domain = R300_DOMAIN_GTT;
-
+    rbuf->num_ranges = 0;
+    rbuf->buf = NULL;
+    rbuf->constant_buffer = NULL;
     rbuf->user_buffer = ptr;
     return &rbuf->b.b;
-
-no_rbuf:
-    return NULL;
 }




More information about the mesa-commit mailing list