From 7b31b235d069ab4154bfc4b1eacde6368852aaee Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Mon, 19 Jul 2010 14:31:25 +0200 Subject: [PATCH] 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 +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..b9c96d5b 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 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; } -- 2.7.4