[Mesa-dev] [PATCH 7/8] gallium/radeon: implement PIPE_CAP_INVALIDATE_BUFFER

Fredrik Höglund fredrik at kde.org
Tue Jan 12 10:41:07 PST 2016


On Tuesday 12 January 2016, Nicolai Hähnle wrote:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
> 
> ---
>  src/gallium/drivers/r600/r600_pipe.c            |  2 +-
>  src/gallium/drivers/radeon/r600_buffer_common.c | 23 ++++++++++++++++-------
>  src/gallium/drivers/radeon/r600_pipe_common.c   |  1 +
>  src/gallium/drivers/radeon/r600_pipe_common.h   |  3 +++
>  src/gallium/drivers/radeonsi/si_pipe.c          |  2 +-
>  5 files changed, 22 insertions(+), 9 deletions(-)
> 
> diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
> index a8805f6..569f77c 100644
> --- a/src/gallium/drivers/r600/r600_pipe.c
> +++ b/src/gallium/drivers/r600/r600_pipe.c
> @@ -278,6 +278,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
>  	case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
>  	case PIPE_CAP_TGSI_TXQS:
>  	case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
> +	case PIPE_CAP_INVALIDATE_BUFFER:
>  		return 1;
>  
>  	case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
> @@ -355,7 +356,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
>  	case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
>  	case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
>  	case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
> -	case PIPE_CAP_INVALIDATE_BUFFER:
>  		return 0;
>  
>  	case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
> diff --git a/src/gallium/drivers/radeon/r600_buffer_common.c b/src/gallium/drivers/radeon/r600_buffer_common.c
> index aeb9a20..09755e0 100644
> --- a/src/gallium/drivers/radeon/r600_buffer_common.c
> +++ b/src/gallium/drivers/radeon/r600_buffer_common.c
> @@ -209,6 +209,21 @@ static void r600_buffer_destroy(struct pipe_screen *screen,
>  	FREE(rbuffer);
>  }
>  
> +void r600_invalidate_resource(struct pipe_context *ctx,
> +			      struct pipe_resource *resource)
> +{
> +	struct r600_common_context *rctx = (struct r600_common_context*)ctx;
> +        struct r600_resource *rbuffer = r600_resource(resource);
> +
> +	/* Check if mapping this buffer would cause waiting for the GPU. */
> +	if (r600_rings_is_buffer_referenced(rctx, rbuffer->buf, RADEON_USAGE_READWRITE) ||
> +	    !rctx->ws->buffer_wait(rbuffer->buf, 0, RADEON_USAGE_READWRITE)) {
> +		rctx->invalidate_buffer(&rctx->b, &rbuffer->b.b);
> +	} else {
> +		util_range_set_empty(&rbuffer->valid_buffer_range);
> +	}

This implementation does not exactly comply with the specification.

The point of InvalidateBuffer is to tell the driver that it may discard the
contents of the buffer if, for example, the buffer needs to be evicted.

Calling InvalidateBuffer is not equivalent to calling MapBufferRange
with GL_MAP_INVALIDATE_BUFFER_BIT, since the former should invalidate
the buffer regardless of whether it is busy or not.

> +}
> +
>  static void *r600_buffer_get_transfer(struct pipe_context *ctx,
>  				      struct pipe_resource *resource,
>                                        unsigned level,
> @@ -276,13 +291,7 @@ static void *r600_buffer_transfer_map(struct pipe_context *ctx,
>  	    !(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
>  		assert(usage & PIPE_TRANSFER_WRITE);
>  
> -		/* Check if mapping this buffer would cause waiting for the GPU. */
> -		if (r600_rings_is_buffer_referenced(rctx, rbuffer->buf, RADEON_USAGE_READWRITE) ||
> -		    !rctx->ws->buffer_wait(rbuffer->buf, 0, RADEON_USAGE_READWRITE)) {
> -			rctx->invalidate_buffer(&rctx->b, &rbuffer->b.b);
> -		} else {
> -			util_range_set_empty(&rbuffer->valid_buffer_range);
> -		}
> +		r600_invalidate_resource(ctx, resource);
>  
>  		/* At this point, the buffer is always idle. */
>  		usage |= PIPE_TRANSFER_UNSYNCHRONIZED;
> diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c
> index 52c365e..e926f56 100644
> --- a/src/gallium/drivers/radeon/r600_pipe_common.c
> +++ b/src/gallium/drivers/radeon/r600_pipe_common.c
> @@ -257,6 +257,7 @@ bool r600_common_context_init(struct r600_common_context *rctx,
>  	else
>  		rctx->max_db = 4;
>  
> +	rctx->b.invalidate_resource = r600_invalidate_resource;
>  	rctx->b.transfer_map = u_transfer_map_vtbl;
>  	rctx->b.transfer_flush_region = u_transfer_flush_region_vtbl;
>  	rctx->b.transfer_unmap = u_transfer_unmap_vtbl;
> diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
> index 68b50a9..27f6e98 100644
> --- a/src/gallium/drivers/radeon/r600_pipe_common.h
> +++ b/src/gallium/drivers/radeon/r600_pipe_common.h
> @@ -500,6 +500,9 @@ struct pipe_resource *
>  r600_buffer_from_user_memory(struct pipe_screen *screen,
>  			     const struct pipe_resource *templ,
>  			     void *user_memory);
> +void
> +r600_invalidate_resource(struct pipe_context *ctx,
> +			 struct pipe_resource *resource);
>  
>  /* r600_common_pipe.c */
>  void r600_draw_rectangle(struct blitter_context *blitter,
> diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
> index 512f939..fd4bda9 100644
> --- a/src/gallium/drivers/radeonsi/si_pipe.c
> +++ b/src/gallium/drivers/radeonsi/si_pipe.c
> @@ -301,6 +301,7 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
>  	case PIPE_CAP_TGSI_TXQS:
>  	case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
>  	case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
> +	case PIPE_CAP_INVALIDATE_BUFFER:
>  		return 1;
>  
>  	case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
> @@ -347,7 +348,6 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
>  	case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
>  	case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
>  	case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
> -	case PIPE_CAP_INVALIDATE_BUFFER:
>  		return 0;
>  
>  	case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
> 



More information about the mesa-dev mailing list