diff options
| author | Marek Olšák <maraeo@gmail.com> | 2011-02-08 17:30:39 +0100 | 
|---|---|---|
| committer | Marek Olšák <maraeo@gmail.com> | 2011-02-08 17:30:39 +0100 | 
| commit | f0b202ec73855bd9e1b29909c8ac90393043cb8b (patch) | |
| tree | cfd0394b33568a3edf731a5f4c3f1fba17c8bb37 | |
| parent | b541a3c4c0a125087fa9e1e0d35db019c36fb0e9 (diff) | |
r600g: slab-allocate buffer and transfer structures
| -rw-r--r-- | src/gallium/drivers/r600/r600_buffer.c | 48 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_pipe.c | 40 | ||||
| -rw-r--r-- | src/gallium/drivers/r600/r600_pipe.h | 7 | 
3 files changed, 85 insertions, 10 deletions
| diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index 7483a5292b..2a427839fd 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -42,13 +42,14 @@  static void r600_buffer_destroy(struct pipe_screen *screen,  				struct pipe_resource *buf)  { +	struct r600_screen *rscreen = (struct r600_screen*)screen;  	struct r600_resource_buffer *rbuffer = r600_buffer(buf);  	if (rbuffer->r.bo) {  		r600_bo_reference((struct radeon*)screen->winsys, &rbuffer->r.bo, NULL);  	}  	rbuffer->r.bo = NULL; -	FREE(rbuffer); +	util_slab_free(&rscreen->pool_buffers, rbuffer);  }  static unsigned r600_buffer_is_referenced_by_cs(struct pipe_context *context, @@ -59,6 +60,29 @@ static unsigned r600_buffer_is_referenced_by_cs(struct pipe_context *context,  	return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;  } +static struct pipe_transfer *r600_get_transfer(struct pipe_context *ctx, +					       struct pipe_resource *resource, +					       unsigned level, +					       unsigned usage, +					       const struct pipe_box *box) +{ +	struct r600_pipe_context *rctx = (struct r600_pipe_context*)ctx; +	struct pipe_transfer *transfer = util_slab_alloc(&rctx->pool_transfers); + +	transfer->resource = resource; +	transfer->level = level; +	transfer->usage = usage; +	transfer->box = *box; +	transfer->stride = 0; +	transfer->layer_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 *r600_buffer_transfer_map(struct pipe_context *pipe,  				      struct pipe_transfer *transfer)  { @@ -100,13 +124,21 @@ static void r600_buffer_transfer_flush_region(struct pipe_context *pipe,  {  } +static void r600_transfer_destroy(struct pipe_context *ctx, +				  struct pipe_transfer *transfer) +{ +	struct r600_pipe_context *rctx = (struct r600_pipe_context*)ctx; +	util_slab_free(&rctx->pool_transfers, transfer); +} + +  static const struct u_resource_vtbl r600_buffer_vtbl =  {  	u_default_resource_get_handle,		/* get_handle */  	r600_buffer_destroy,			/* resource_destroy */  	r600_buffer_is_referenced_by_cs,	/* is_buffer_referenced */ -	u_default_get_transfer,			/* get_transfer */ -	u_default_transfer_destroy,		/* transfer_destroy */ +	r600_get_transfer,			/* get_transfer */ +	r600_transfer_destroy,			/* transfer_destroy */  	r600_buffer_transfer_map,		/* transfer_map */  	r600_buffer_transfer_flush_region,	/* transfer_flush_region */  	r600_buffer_transfer_unmap,		/* transfer_unmap */ @@ -116,14 +148,13 @@ static const struct u_resource_vtbl r600_buffer_vtbl =  struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,  					 const struct pipe_resource *templ)  { +	struct r600_screen *rscreen = (struct r600_screen*)screen;  	struct r600_resource_buffer *rbuffer;  	struct r600_bo *bo;  	/* XXX We probably want a different alignment for buffers and textures. */  	unsigned alignment = 4096; -	rbuffer = CALLOC_STRUCT(r600_resource_buffer); -	if (rbuffer == NULL) -		return NULL; +	rbuffer = util_slab_alloc(&rscreen->pool_buffers);  	rbuffer->magic = R600_BUFFER_MAGIC;  	rbuffer->r.b.b.b = *templ; @@ -151,11 +182,10 @@ struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,  					      void *ptr, unsigned bytes,  					      unsigned bind)  { +	struct r600_screen *rscreen = (struct r600_screen*)screen;  	struct r600_resource_buffer *rbuffer; -	rbuffer = CALLOC_STRUCT(r600_resource_buffer); -	if (rbuffer == NULL) -		return NULL; +	rbuffer = util_slab_alloc(&rscreen->pool_buffers);  	rbuffer->magic = R600_BUFFER_MAGIC;  	pipe_reference_init(&rbuffer->r.b.b.b.reference, 1); diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index a7c19b0927..f9e8e76d24 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -75,6 +75,26 @@ static void r600_flush(struct pipe_context *ctx, unsigned flags,  	u_upload_flush(rctx->vbuf_mgr->uploader);  } +static void r600_update_num_contexts(struct r600_screen *rscreen, +                                     int diff) +{ +	pipe_mutex_lock(rscreen->mutex_num_contexts); +	if (diff > 0) { +		rscreen->num_contexts++; + +		if (rscreen->num_contexts > 1) +			util_slab_set_thread_safety(&rscreen->pool_buffers, +						    UTIL_SLAB_MULTITHREADED); +	} else { +		rscreen->num_contexts--; + +		if (rscreen->num_contexts <= 1) +			util_slab_set_thread_safety(&rscreen->pool_buffers, +						    UTIL_SLAB_SINGLETHREADED); +	} +	pipe_mutex_unlock(rscreen->mutex_num_contexts); +} +  static void r600_destroy_context(struct pipe_context *context)  {  	struct r600_pipe_context *rctx = (struct r600_pipe_context *)context; @@ -90,6 +110,9 @@ static void r600_destroy_context(struct pipe_context *context)  	}  	u_vbuf_mgr_destroy(rctx->vbuf_mgr); +	util_slab_destroy(&rctx->pool_transfers); + +	r600_update_num_contexts(rctx->screen, -1);  	FREE(rctx);  } @@ -102,6 +125,9 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void  	if (rctx == NULL)  		return NULL; + +	r600_update_num_contexts(rscreen, 1); +  	rctx->context.winsys = rscreen->screen.winsys;  	rctx->context.screen = screen;  	rctx->context.priv = priv; @@ -161,6 +187,10 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void  		return NULL;  	} +	util_slab_create(&rctx->pool_transfers, +			 sizeof(struct pipe_transfer), 64, +			 UTIL_SLAB_SINGLETHREADED); +  	rctx->vbuf_mgr = u_vbuf_mgr_create(&rctx->context, 1024 * 1024, 256,  					   PIPE_BIND_VERTEX_BUFFER |  					   PIPE_BIND_INDEX_BUFFER | @@ -173,7 +203,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void  	rctx->blitter = util_blitter_create(&rctx->context);  	if (rctx->blitter == NULL) { -		FREE(rctx); +		r600_destroy_context(&rctx->context);  		return NULL;  	} @@ -444,6 +474,8 @@ static void r600_destroy_screen(struct pipe_screen* pscreen)  	radeon_decref(rscreen->radeon); +	util_slab_destroy(&rscreen->pool_buffers); +	pipe_mutex_destroy(rscreen->mutex_num_contexts);  	FREE(rscreen);  } @@ -471,5 +503,11 @@ struct pipe_screen *r600_screen_create(struct radeon *radeon)  	rscreen->tiling_info = r600_get_tiling_info(radeon); +	util_slab_create(&rscreen->pool_buffers, +			 sizeof(struct r600_resource_buffer), 64, +			 UTIL_SLAB_SINGLETHREADED); + +	pipe_mutex_init(rscreen->mutex_num_contexts); +  	return &rscreen->screen;  } diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 71d9647508..8dc1f4ad5c 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -30,6 +30,7 @@  #include <pipe/p_screen.h>  #include <pipe/p_context.h>  #include <util/u_math.h> +#include "util/u_slab.h"  #include "util/u_vbuf_mgr.h"  #include "r600.h"  #include "r600_public.h" @@ -64,6 +65,11 @@ struct r600_screen {  	struct pipe_screen		screen;  	struct radeon			*radeon;  	struct r600_tiling_info		*tiling_info; +	struct util_slab_mempool	pool_buffers; +	unsigned			num_contexts; + +	/* for thread-safe write accessing to num_contexts */ +	pipe_mutex			mutex_num_contexts;  };  struct r600_pipe_sampler_view { @@ -152,6 +158,7 @@ struct r600_pipe_context {  	struct r600_textures_info	ps_samplers;  	struct u_vbuf_mgr		*vbuf_mgr; +	struct util_slab_mempool	pool_transfers;  	bool				blit;  }; | 
