[Mesa-dev] [PATCH 4/6] gallium/radeon: add state setup for a separate DCC buffer

Nicolai Hähnle nhaehnle at gmail.com
Fri Jun 24 11:10:35 UTC 2016


I remember there was a plausible reason to have a dcc_offset instead of 
just a dcc_address (though I keep forgetting it), but maybe it's time to 
change that now?

Either way, patches 1-4 & 6 are

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>

On 22.06.2016 20:29, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> ---
>   src/gallium/drivers/radeon/r600_pipe_common.h |  8 ++++++++
>   src/gallium/drivers/radeon/r600_texture.c     | 18 +++++++++++++++---
>   src/gallium/drivers/radeonsi/si_descriptors.c | 11 ++++++++++-
>   src/gallium/drivers/radeonsi/si_state.c       |  9 ++++++++-
>   4 files changed, 41 insertions(+), 5 deletions(-)
>
> diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
> index c0e4282..92cba13 100644
> --- a/src/gallium/drivers/radeon/r600_pipe_common.h
> +++ b/src/gallium/drivers/radeon/r600_pipe_common.h
> @@ -265,6 +265,14 @@ struct r600_texture {
>
>   	bool				non_disp_tiling; /* R600-Cayman only */
>
> +	/* Whether the texture is a displayable back buffer and needs DCC
> +	 * decompression, which is expensive. Therefore, it's enabled only
> +	 * if statistics suggest that it will pay off and it's allocated
> +	 * separately. Limited to target == 2D and last_level == 0. If enabled,
> +	 * dcc_offset contains the absolute GPUVM address, not the relative one.
> +	 */
> +	struct r600_resource		*dcc_separate_buffer;
> +
>   	/* Counter that should be non-zero if the texture is bound to a
>   	 * framebuffer. Implemented in radeonsi only.
>   	 */
> diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
> index 4053a75..23be5ed 100644
> --- a/src/gallium/drivers/radeon/r600_texture.c
> +++ b/src/gallium/drivers/radeon/r600_texture.c
> @@ -387,6 +387,8 @@ static bool r600_texture_discard_dcc(struct r600_common_screen *rscreen,
>   	if (!r600_can_disable_dcc(rtex))
>   		return false;
>
> +	assert(rtex->dcc_separate_buffer == NULL);
> +
>   	/* Disable DCC. */
>   	rtex->dcc_offset = 0;
>
> @@ -564,6 +566,7 @@ static void r600_texture_destroy(struct pipe_screen *screen,
>   	    pipe_resource_reference((struct pipe_resource**)&rtex->cmask_buffer, NULL);
>   	}
>   	pb_reference(&resource->buf, NULL);
> +	r600_resource_reference(&rtex->dcc_separate_buffer, NULL);
>   	FREE(rtex);
>   }
>
> @@ -1800,12 +1803,21 @@ void vi_dcc_clear_level(struct r600_common_context *rctx,
>   			struct r600_texture *rtex,
>   			unsigned level, unsigned clear_value)
>   {
> -	struct pipe_resource *dcc_buffer = &rtex->resource.b.b;
> -	uint64_t dcc_offset = rtex->dcc_offset +
> -			      rtex->surface.level[level].dcc_offset;
> +	struct pipe_resource *dcc_buffer;
> +	uint64_t dcc_offset;
>
>   	assert(rtex->dcc_offset && rtex->surface.level[level].dcc_enabled);
>
> +	if (rtex->dcc_separate_buffer) {
> +		dcc_buffer = &rtex->dcc_separate_buffer->b.b;
> +		dcc_offset = 0;
> +	} else {
> +		dcc_buffer = &rtex->resource.b.b;
> +		dcc_offset = rtex->dcc_offset;
> +	}
> +
> +	dcc_offset += rtex->surface.level[level].dcc_offset;
> +
>   	rctx->clear_buffer(&rctx->b, dcc_buffer, dcc_offset,
>   			   rtex->surface.level[level].dcc_fast_clear_size,
>   			   clear_value, R600_COHERENCY_CB_META);
> diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
> index e95556b..0bdeb04 100644
> --- a/src/gallium/drivers/radeonsi/si_descriptors.c
> +++ b/src/gallium/drivers/radeonsi/si_descriptors.c
> @@ -304,6 +304,15 @@ static void si_sampler_view_add_buffer(struct si_context *sctx,
>
>   	radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx, rres, usage,
>   				  r600_get_sampler_view_priority(rres));
> +
> +	if (resource->target != PIPE_BUFFER) {
> +		struct r600_texture *rtex = (struct r600_texture*)resource;
> +
> +		if (rtex->dcc_separate_buffer)
> +			radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
> +						  rtex->dcc_separate_buffer, usage,
> +						  RADEON_PRIO_DCC);
> +	}
>   }
>
>   static void si_sampler_views_begin_new_cs(struct si_context *sctx,
> @@ -352,7 +361,7 @@ void si_set_mutable_tex_desc_fields(struct r600_texture *tex,
>
>   	if (tex->dcc_offset && tex->surface.level[first_level].dcc_enabled) {
>   		state[6] |= S_008F28_COMPRESSION_EN(1);
> -		state[7] = (tex->resource.gpu_address +
> +		state[7] = ((!tex->dcc_separate_buffer ? tex->resource.gpu_address : 0) +
>   			    tex->dcc_offset +
>   			    base_level_info->dcc_offset) >> 8;
>   	}
> diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
> index ccd9f860..492a670 100644
> --- a/src/gallium/drivers/radeonsi/si_state.c
> +++ b/src/gallium/drivers/radeonsi/si_state.c
> @@ -2418,6 +2418,12 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
>   				RADEON_PRIO_CMASK);
>   		}
>
> +		if (tex->dcc_separate_buffer)
> +			radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
> +						  tex->dcc_separate_buffer,
> +						  RADEON_USAGE_READWRITE,
> +						  RADEON_PRIO_DCC);
> +
>   		/* Compute mutable surface parameters. */
>   		pitch_tile_max = cb->level_info->nblk_x / 8 - 1;
>   		slice_tile_max = cb->level_info->nblk_x *
> @@ -2474,7 +2480,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom
>   		radeon_emit(cs, tex->color_clear_value[1]);	/* R_028C90_CB_COLOR0_CLEAR_WORD1 */
>
>   		if (sctx->b.chip_class >= VI) /* R_028C94_CB_COLOR0_DCC_BASE */
> -			radeon_emit(cs, (tex->resource.gpu_address +
> +			radeon_emit(cs, ((!tex->dcc_separate_buffer ? tex->resource.gpu_address : 0) +
>   					 tex->dcc_offset +
>   				         tex->surface.level[cb->base.u.tex.level].dcc_offset) >> 8);
>   	}
> @@ -3433,6 +3439,7 @@ static void si_query_opaque_metadata(struct r600_common_screen *rscreen,
>   	if (rscreen->info.drm_major != 3)
>   		return;
>
> +	assert(rtex->dcc_separate_buffer == NULL);
>   	assert(rtex->fmask.size == 0);
>
>   	/* Metadata image format format version 1:
>


More information about the mesa-dev mailing list