[Mesa-dev] [PATCH 09/13] gallium/radeon: subclass threaded_transfer

Nicolai Hähnle nhaehnle at gmail.com
Thu May 11 18:42:32 UTC 2017


On 11.05.2017 00:45, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> ---
>  src/gallium/drivers/radeon/r600_buffer_common.c | 22 ++++++++++-----------
>  src/gallium/drivers/radeon/r600_pipe_common.h   |  2 +-
>  src/gallium/drivers/radeon/r600_texture.c       | 26 ++++++++++++-------------
>  3 files changed, 25 insertions(+), 25 deletions(-)
>
> diff --git a/src/gallium/drivers/radeon/r600_buffer_common.c b/src/gallium/drivers/radeon/r600_buffer_common.c
> index b57632e..0c6fa66 100644
> --- a/src/gallium/drivers/radeon/r600_buffer_common.c
> +++ b/src/gallium/drivers/radeon/r600_buffer_common.c
> @@ -293,30 +293,31 @@ static void *r600_buffer_get_transfer(struct pipe_context *ctx,
>  				      unsigned offset)
>  {
>  	struct r600_common_context *rctx = (struct r600_common_context*)ctx;
>  	struct r600_transfer *transfer;
>
>  	if (usage & TC_TRANSFER_MAP_THREADED_UNSYNC)
>  		transfer = slab_alloc(&rctx->pool_transfers_unsync);
>  	else
>  		transfer = slab_alloc(&rctx->pool_transfers);
>
> -	transfer->transfer.resource = NULL;
> -	pipe_resource_reference(&transfer->transfer.resource, resource);
> -	transfer->transfer.level = 0;
> -	transfer->transfer.usage = usage;
> -	transfer->transfer.box = *box;
> -	transfer->transfer.stride = 0;
> -	transfer->transfer.layer_stride = 0;
> +	transfer->b.b.resource = NULL;
> +	pipe_resource_reference(&transfer->b.b.resource, resource);
> +	transfer->b.b.level = 0;
> +	transfer->b.b.usage = usage;
> +	transfer->b.b.box = *box;
> +	transfer->b.b.stride = 0;
> +	transfer->b.b.layer_stride = 0;
> +	transfer->b.staging = NULL;
>  	transfer->offset = offset;
>  	transfer->staging = staging;
> -	*ptransfer = &transfer->transfer;
> +	*ptransfer = &transfer->b.b;
>  	return data;
>  }
>
>  static bool r600_can_dma_copy_buffer(struct r600_common_context *rctx,
>  				     unsigned dstx, unsigned srcx, unsigned size)
>  {
>  	bool dword_aligned = !(dstx % 4) && !(srcx % 4) && !(size % 4);
>
>  	return rctx->screen->has_cp_dma ||
>  	       (dword_aligned && (rctx->dma.cs ||
> @@ -505,23 +506,22 @@ static void r600_buffer_flush_region(struct pipe_context *ctx,
>  static void r600_buffer_transfer_unmap(struct pipe_context *ctx,
>  				       struct pipe_transfer *transfer)
>  {
>  	struct r600_common_context *rctx = (struct r600_common_context*)ctx;
>  	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
>
>  	if (transfer->usage & PIPE_TRANSFER_WRITE &&
>  	    !(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT))
>  		r600_buffer_do_flush_region(ctx, transfer, &transfer->box);
>
> -	if (rtransfer->staging)
> -		r600_resource_reference(&rtransfer->staging, NULL);
> -
> +	r600_resource_reference(&rtransfer->staging, NULL);
> +	pipe_resource_reference(&rtransfer->b.staging, NULL);

Can we get here with rtransfer->b.staging != NULL? The way I understand 
it, those transfers will be completely handled in the threaded_context. 
In that case, it'd be better to replace this by an assert.

Cheers,
Nicolai


>  	pipe_resource_reference(&transfer->resource, NULL);
>
>  	/* Don't use pool_transfers_unsync. We are always in the driver
>  	 * thread. */
>  	slab_free(&rctx->pool_transfers, transfer);
>  }
>
>  void r600_buffer_subdata(struct pipe_context *ctx,
>  			 struct pipe_resource *buffer,
>  			 unsigned usage, unsigned offset,
> diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
> index 3449786..a694b97 100644
> --- a/src/gallium/drivers/radeon/r600_pipe_common.h
> +++ b/src/gallium/drivers/radeon/r600_pipe_common.h
> @@ -177,21 +177,21 @@ struct r600_resource {
>  	 * an index buffer. The reason is that VGT DMA index fetching doesn't
>  	 * use TC L2.
>  	 */
>  	bool				TC_L2_dirty;
>
>  	/* Whether the resource has been exported via resource_get_handle. */
>  	unsigned			external_usage; /* PIPE_HANDLE_USAGE_* */
>  };
>
>  struct r600_transfer {
> -	struct pipe_transfer		transfer;
> +	struct threaded_transfer	b;
>  	struct r600_resource		*staging;
>  	unsigned			offset;
>  };
>
>  struct r600_fmask_info {
>  	uint64_t offset;
>  	uint64_t size;
>  	unsigned alignment;
>  	unsigned pitch_in_pixels;
>  	unsigned bank_height;
> diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
> index 3bcf966..4d72b86 100644
> --- a/src/gallium/drivers/radeon/r600_texture.c
> +++ b/src/gallium/drivers/radeon/r600_texture.c
> @@ -1641,24 +1641,24 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx,
>  							usage, box))
>  				r600_texture_invalidate_storage(rctx, rtex);
>  			else
>  				use_staging_texture = true;
>  		}
>  	}
>
>  	trans = CALLOC_STRUCT(r600_transfer);
>  	if (!trans)
>  		return NULL;
> -	pipe_resource_reference(&trans->transfer.resource, texture);
> -	trans->transfer.level = level;
> -	trans->transfer.usage = usage;
> -	trans->transfer.box = *box;
> +	pipe_resource_reference(&trans->b.b.resource, texture);
> +	trans->b.b.level = level;
> +	trans->b.b.usage = usage;
> +	trans->b.b.box = *box;
>
>  	if (rtex->is_depth) {
>  		struct r600_texture *staging_depth;
>
>  		if (rtex->resource.b.b.nr_samples > 1) {
>  			/* MSAA depth buffers need to be converted to single sample buffers.
>  			 *
>  			 * Mapping MSAA depth buffers can occur if ReadPixels is called
>  			 * with a multisample GLX visual.
>  			 *
> @@ -1686,40 +1686,40 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx,
>  				}
>
>  				r600_copy_region_with_blit(ctx, temp, 0, 0, 0, 0, texture, level, box);
>  				rctx->blit_decompress_depth(ctx, (struct r600_texture*)temp, staging_depth,
>  							    0, 0, 0, box->depth, 0, 0);
>  				pipe_resource_reference(&temp, NULL);
>  			}
>
>  			/* Just get the strides. */
>  			r600_texture_get_offset(rctx->screen, staging_depth, level, NULL,
> -						&trans->transfer.stride,
> -						&trans->transfer.layer_stride);
> +						&trans->b.b.stride,
> +						&trans->b.b.layer_stride);
>  		} else {
>  			/* XXX: only readback the rectangle which is being mapped? */
>  			/* XXX: when discard is true, no need to read back from depth texture */
>  			if (!r600_init_flushed_depth_texture(ctx, texture, &staging_depth)) {
>  				R600_ERR("failed to create temporary texture to hold untiled copy\n");
>  				FREE(trans);
>  				return NULL;
>  			}
>
>  			rctx->blit_decompress_depth(ctx, rtex, staging_depth,
>  						    level, level,
>  						    box->z, box->z + box->depth - 1,
>  						    0, 0);
>
>  			offset = r600_texture_get_offset(rctx->screen, staging_depth,
>  							 level, box,
> -							 &trans->transfer.stride,
> -							 &trans->transfer.layer_stride);
> +							 &trans->b.b.stride,
> +							 &trans->b.b.layer_stride);
>  		}
>
>  		trans->staging = (struct r600_resource*)staging_depth;
>  		buf = trans->staging;
>  	} else if (use_staging_texture) {
>  		struct pipe_resource resource;
>  		struct r600_texture *staging;
>
>  		r600_init_temp_resource_from_box(&resource, texture, box, level,
>  						 R600_RESOURCE_FLAG_TRANSFER);
> @@ -1730,44 +1730,44 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx,
>  		staging = (struct r600_texture*)ctx->screen->resource_create(ctx->screen, &resource);
>  		if (!staging) {
>  			R600_ERR("failed to create temporary texture to hold untiled copy\n");
>  			FREE(trans);
>  			return NULL;
>  		}
>  		trans->staging = &staging->resource;
>
>  		/* Just get the strides. */
>  		r600_texture_get_offset(rctx->screen, staging, 0, NULL,
> -					&trans->transfer.stride,
> -					&trans->transfer.layer_stride);
> +					&trans->b.b.stride,
> +					&trans->b.b.layer_stride);
>
>  		if (usage & PIPE_TRANSFER_READ)
>  			r600_copy_to_staging_texture(ctx, trans);
>  		else
>  			usage |= PIPE_TRANSFER_UNSYNCHRONIZED;
>
>  		buf = trans->staging;
>  	} else {
>  		/* the resource is mapped directly */
>  		offset = r600_texture_get_offset(rctx->screen, rtex, level, box,
> -						 &trans->transfer.stride,
> -						 &trans->transfer.layer_stride);
> +						 &trans->b.b.stride,
> +						 &trans->b.b.layer_stride);
>  		buf = &rtex->resource;
>  	}
>
>  	if (!(map = r600_buffer_map_sync_with_rings(rctx, buf, usage))) {
>  		r600_resource_reference(&trans->staging, NULL);
>  		FREE(trans);
>  		return NULL;
>  	}
>
> -	*ptransfer = &trans->transfer;
> +	*ptransfer = &trans->b.b;
>  	return map + offset;
>  }
>
>  static void r600_texture_transfer_unmap(struct pipe_context *ctx,
>  					struct pipe_transfer* transfer)
>  {
>  	struct r600_common_context *rctx = (struct r600_common_context*)ctx;
>  	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
>  	struct pipe_resource *texture = transfer->resource;
>  	struct r600_texture *rtex = (struct r600_texture*)texture;
>


-- 
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.


More information about the mesa-dev mailing list