[Mesa-dev] [PATCH] r600g,radeonsi: set domains in one place; put DRI2 tiled textures in VRAM

Christian König deathsimple at vodafone.de
Tue Feb 4 20:45:53 CET 2014


Am 04.02.2014 20:42, schrieb Marek Olšák:
> From: Marek Olšák <marek.olsak at amd.com>
>
> This is a rework of "r600g,radeonsi: force VRAM placement for DRI2 buffers".
> It mainly consolidates the code determining resource placements. It also takes
> Prime into account.
> ---
>   src/gallium/drivers/r600/r600_state_common.c    |  4 +-
>   src/gallium/drivers/radeon/r600_buffer_common.c | 72 +++++++++++++++----------
>   src/gallium/drivers/radeon/r600_pipe_common.h   |  3 +-
>   src/gallium/drivers/radeon/r600_texture.c       | 11 ++--
>   src/gallium/drivers/radeonsi/si_descriptors.c   |  4 +-
>   5 files changed, 54 insertions(+), 40 deletions(-)
>
> diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
> index d8fab10..c1d7e29 100644
> --- a/src/gallium/drivers/r600/r600_state_common.c
> +++ b/src/gallium/drivers/r600/r600_state_common.c
> @@ -2082,8 +2082,8 @@ static void r600_invalidate_buffer(struct pipe_context *ctx, struct pipe_resourc
>   	pb_reference(&rbuffer->buf, NULL);
>   
>   	/* Create a new one in the same pipe_resource. */
> -	r600_init_resource(&rctx->screen->b, rbuffer, rbuffer->b.b.width0, alignment,
> -			   TRUE, rbuffer->b.b.usage);
> +	r600_init_resource(&rctx->screen->b, rbuffer, rbuffer->b.b.width0,
> +			   alignment, TRUE);
>   
>   	/* We changed the buffer, now we need to bind it where the old one was bound. */
>   	/* Vertex buffers. */
> diff --git a/src/gallium/drivers/radeon/r600_buffer_common.c b/src/gallium/drivers/radeon/r600_buffer_common.c
> index 2077228..466630e 100644
> --- a/src/gallium/drivers/radeon/r600_buffer_common.c
> +++ b/src/gallium/drivers/radeon/r600_buffer_common.c
> @@ -100,45 +100,56 @@ void *r600_buffer_map_sync_with_rings(struct r600_common_context *ctx,
>   	return ctx->ws->buffer_map(resource->cs_buf, NULL, usage);
>   }
>   
> +void r600_set_resource_placement(struct r600_resource *res)
> +{
> +	if (res->b.b.target == PIPE_BUFFER) {
> +		/* Buffer placement is determined from the usage flag directly. */
> +		switch (res->b.b.usage) {
> +		case PIPE_USAGE_IMMUTABLE:
> +		case PIPE_USAGE_DEFAULT:
> +		case PIPE_USAGE_STATIC:
> +		default:
> +			/* Not listing GTT here improves performance in some apps. */
> +			res->domains = RADEON_DOMAIN_VRAM;
> +			break;
> +		case PIPE_USAGE_DYNAMIC:
> +		case PIPE_USAGE_STREAM:
> +		case PIPE_USAGE_STAGING:
> +			/* These resources participate in transfers, i.e. are used
> +			 * for uploads and downloads from regular resources. */
> +			res->domains = RADEON_DOMAIN_GTT;
> +			break;
> +		}
> +	} else {
> +		/* Texture placement is determined from the tiling mode,
> +		 * which was determined from the usage flags. */
> +		struct r600_texture *rtex = (struct r600_texture*)rtex;
> +
> +		if (rtex->surface.level[0].mode >= RADEON_SURF_MODE_1D) {
> +			/* Tiled textures are unmappable. Always put them in VRAM. */
> +			res->domains = RADEON_DOMAIN_VRAM;
> +		} else {
> +			/* Linear textures should be in GTT for Prime and texture
> +			 * transfers. Also, why would anyone want to have a linear
> +			 * texture in VRAM? */

VCE doesn't supports tilling and you still want the resource to be in VRAM.

Christian.

> +			res->domains = RADEON_DOMAIN_GTT;
> +		}
> +	}
> +}
> +
>   bool r600_init_resource(struct r600_common_screen *rscreen,
>   			struct r600_resource *res,
>   			unsigned size, unsigned alignment,
> -			bool use_reusable_pool, unsigned usage)
> +			bool use_reusable_pool)
>   {
> -	uint32_t initial_domain, domains;
> -
> -	switch(usage) {
> -	case PIPE_USAGE_STAGING:
> -	case PIPE_USAGE_DYNAMIC:
> -	case PIPE_USAGE_STREAM:
> -		/* These resources participate in transfers, i.e. are used
> -		 * for uploads and downloads from regular resources.
> -		 * We generate them internally for some transfers.
> -		 */
> -		initial_domain = RADEON_DOMAIN_GTT;
> -		domains = RADEON_DOMAIN_GTT;
> -		break;
> -	case PIPE_USAGE_DEFAULT:
> -	case PIPE_USAGE_STATIC:
> -	case PIPE_USAGE_IMMUTABLE:
> -	default:
> -		/* Don't list GTT here, because the memory manager would put some
> -		 * resources to GTT no matter what the initial domain is.
> -		 * Not listing GTT in the domains improves performance a lot. */
> -		initial_domain = RADEON_DOMAIN_VRAM;
> -		domains = RADEON_DOMAIN_VRAM;
> -		break;
> -	}
> -
>   	res->buf = rscreen->ws->buffer_create(rscreen->ws, size, alignment,
>                                                 use_reusable_pool,
> -                                              initial_domain);
> +                                              res->domains);
>   	if (!res->buf) {
>   		return false;
>   	}
>   
>   	res->cs_buf = rscreen->ws->buffer_get_cs_handle(res->buf);
> -	res->domains = domains;
>   	util_range_set_empty(&res->valid_buffer_range);
>   
>   	if (rscreen->debug_flags & DBG_VM && res->b.b.target == PIPE_BUFFER) {
> @@ -327,7 +338,10 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
>   	rbuffer->b.vtbl = &r600_buffer_vtbl;
>   	util_range_init(&rbuffer->valid_buffer_range);
>   
> -	if (!r600_init_resource(rscreen, rbuffer, templ->width0, alignment, TRUE, templ->usage)) {
> +	/* Must be set before creating the buffer. */
> +	r600_set_resource_placement(rbuffer);
> +
> +	if (!r600_init_resource(rscreen, rbuffer, templ->width0, alignment, TRUE)) {
>   		FREE(rbuffer);
>   		return NULL;
>   	}
> diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
> index 9fdfdfd..97c5d6e 100644
> --- a/src/gallium/drivers/radeon/r600_pipe_common.h
> +++ b/src/gallium/drivers/radeon/r600_pipe_common.h
> @@ -318,10 +318,11 @@ boolean r600_rings_is_buffer_referenced(struct r600_common_context *ctx,
>   void *r600_buffer_map_sync_with_rings(struct r600_common_context *ctx,
>                                         struct r600_resource *resource,
>                                         unsigned usage);
> +void r600_set_resource_placement(struct r600_resource *res);
>   bool r600_init_resource(struct r600_common_screen *rscreen,
>   			struct r600_resource *res,
>   			unsigned size, unsigned alignment,
> -			bool use_reusable_pool, unsigned usage);
> +			bool use_reusable_pool);
>   struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
>   					 const struct pipe_resource *templ,
>   					 unsigned alignment);
> diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
> index 878b26f..e05375d 100644
> --- a/src/gallium/drivers/radeon/r600_texture.c
> +++ b/src/gallium/drivers/radeon/r600_texture.c
> @@ -614,20 +614,19 @@ r600_texture_create_object(struct pipe_screen *screen,
>   		}
>   	}
>   
> +	/* Must be set before creating the buffer. */
> +	r600_set_resource_placement(resource);
> +
>   	/* Now create the backing buffer. */
>   	if (!buf) {
> -		unsigned base_align = rtex->surface.bo_alignment;
> -		unsigned usage = rtex->surface.level[0].mode >= RADEON_SURF_MODE_1D ?
> -					 PIPE_USAGE_STATIC : base->usage;
> -
> -		if (!r600_init_resource(rscreen, resource, rtex->size, base_align, FALSE, usage)) {
> +		if (!r600_init_resource(rscreen, resource, rtex->size,
> +					rtex->surface.bo_alignment, FALSE)) {
>   			FREE(rtex);
>   			return NULL;
>   		}
>   	} else {
>   		resource->buf = buf;
>   		resource->cs_buf = rscreen->ws->buffer_get_cs_handle(buf);
> -		resource->domains = RADEON_DOMAIN_GTT | RADEON_DOMAIN_VRAM;
>   	}
>   
>   	if (rtex->cmask.size) {
> diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
> index 9078c6c..f717371 100644
> --- a/src/gallium/drivers/radeonsi/si_descriptors.c
> +++ b/src/gallium/drivers/radeonsi/si_descriptors.c
> @@ -706,8 +706,8 @@ static void si_invalidate_buffer(struct pipe_context *ctx, struct pipe_resource
>   	pb_reference(&rbuffer->buf, NULL);
>   
>   	/* Create a new one in the same pipe_resource. */
> -	r600_init_resource(&sctx->screen->b, rbuffer, rbuffer->b.b.width0, alignment,
> -			   TRUE, rbuffer->b.b.usage);
> +	r600_init_resource(&sctx->screen->b, rbuffer, rbuffer->b.b.width0,
> +			   alignment, TRUE);
>   
>   	/* We changed the buffer, now we need to bind it where the old one
>   	 * was bound. This consists of 2 things:



More information about the mesa-dev mailing list