r300g: use memory pools for buffer_create and get_transfer
The improvement in Tremulous: 68.9 fps -> 71.1 fps.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user