summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2010-07-19 14:31:25 +0200
committerMarek Olšák <[email protected]>2010-07-19 17:12:11 +0200
commit7b31b235d069ab4154bfc4b1eacde6368852aaee (patch)
treefce58f29a6ab87184c2518349568a8eacb171e74 /src/gallium/drivers
parentad44b775e30b2740d25bb8330c9e8879f1ec5533 (diff)
r300g: use memory pools for buffer_create and get_transfer
The improvement in Tremulous: 68.9 fps -> 71.1 fps.
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/r300/r300_context.c28
-rw-r--r--src/gallium/drivers/r300/r300_context.h2
-rw-r--r--src/gallium/drivers/r300/r300_screen.c6
-rw-r--r--src/gallium/drivers/r300/r300_screen.h9
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.c80
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 0f7deca2826..0c06d41f4a4 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 d2b8aa10284..b9c96d5bdd8 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 f28b05506e3..9c73ffc09b2 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 58270230e1d..edc494ff6ca 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 b19b5b5cce8..37a080ba48b 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;
}