[Mesa-dev] [PATCH 51/61] radeonsi: add reference counting for shader selectors

Nicolai Hähnle nhaehnle at gmail.com
Fri Apr 28 11:49:38 UTC 2017


On 24.04.2017 10:45, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> The 2nd shader of merged shaders should take a reference of the 1st shader.
> The next commit will do that.
> ---
>  src/gallium/drivers/radeonsi/si_shader.h        |  1 +
>  src/gallium/drivers/radeonsi/si_state_shaders.c | 27 ++++++++++++++++++++++---
>  2 files changed, 25 insertions(+), 3 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
> index 4fb79e6..514bb3c 100644
> --- a/src/gallium/drivers/radeonsi/si_shader.h
> +++ b/src/gallium/drivers/radeonsi/si_shader.h
> @@ -240,20 +240,21 @@ struct si_compiler_ctx_state {
>  	struct pipe_debug_callback	debug;
>
>  	/* Used for creating the log string for gallium/ddebug. */
>  	bool				is_debug_context;
>  };
>
>  /* A shader selector is a gallium CSO and contains shader variants and
>   * binaries for one TGSI program. This can be shared by multiple contexts.
>   */
>  struct si_shader_selector {
> +	struct pipe_reference	reference;
>  	struct si_screen	*screen;
>  	struct util_queue_fence ready;
>  	struct si_compiler_ctx_state compiler_ctx_state;
>
>  	mtx_t		mutex;
>  	struct si_shader	*first_variant; /* immutable after the first variant */
>  	struct si_shader	*last_variant; /* mutable */
>
>  	/* The compiled TGSI shader expecting a prolog and/or epilog (not
>  	 * uploaded to a buffer).
> diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
> index d496d4a..c5fa01d 100644
> --- a/src/gallium/drivers/radeonsi/si_state_shaders.c
> +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
> @@ -1496,20 +1496,33 @@ static bool si_check_missing_main_part(struct si_screen *sscreen,
>  					   main_part, false,
>  					   &compiler_state->debug) != 0) {
>  			FREE(main_part);
>  			return false;
>  		}
>  		*mainp = main_part;
>  	}
>  	return true;
>  }
>
> +static void si_destroy_shader_selector(struct si_context *sctx,
> +				       struct si_shader_selector *sel);
> +
> +static void si_shader_selector_reference(struct si_context *sctx,
> +					 struct si_shader_selector **dst,
> +					 struct si_shader_selector *src)
> +{
> +	if (pipe_reference(&(*dst)->reference, &src->reference))
> +		si_destroy_shader_selector(sctx, *dst);
> +
> +	*dst = src;
> +}
> +
>  /* Select the hw shader variant depending on the current state. */
>  static int si_shader_select_with_key(struct si_screen *sscreen,
>  				     struct si_shader_ctx_state *state,
>  				     struct si_compiler_ctx_state *compiler_state,
>  				     struct si_shader_key *key,
>  				     int thread_index)
>  {
>  	struct si_shader_selector *sel = state->cso;
>  	struct si_shader *current = state->current;
>  	struct si_shader *iter, *shader = NULL;
> @@ -1878,20 +1891,21 @@ static void *si_create_shader_selector(struct pipe_context *ctx,
>  				       const struct pipe_shader_state *state)
>  {
>  	struct si_screen *sscreen = (struct si_screen *)ctx->screen;
>  	struct si_context *sctx = (struct si_context*)ctx;
>  	struct si_shader_selector *sel = CALLOC_STRUCT(si_shader_selector);
>  	int i;
>
>  	if (!sel)
>  		return NULL;
>
> +	sel->reference.count = 1;

pipe_reference_init

Cheers,
Nicolai


>  	sel->screen = sscreen;
>  	sel->compiler_ctx_state.tm = sctx->tm;
>  	sel->compiler_ctx_state.debug = sctx->b.debug;
>  	sel->compiler_ctx_state.is_debug_context = sctx->is_debug;
>  	sel->tokens = tgsi_dup_tokens(state->tokens);
>  	if (!sel->tokens) {
>  		FREE(sel);
>  		return NULL;
>  	}
>
> @@ -2227,24 +2241,23 @@ static void si_delete_shader(struct si_context *sctx, struct si_shader *shader)
>  		case PIPE_SHADER_FRAGMENT:
>  			si_pm4_delete_state(sctx, ps, shader->pm4);
>  			break;
>  		}
>  	}
>
>  	si_shader_destroy(shader);
>  	free(shader);
>  }
>
> -static void si_delete_shader_selector(struct pipe_context *ctx, void *state)
> +static void si_destroy_shader_selector(struct si_context *sctx,
> +				       struct si_shader_selector *sel)
>  {
> -	struct si_context *sctx = (struct si_context *)ctx;
> -	struct si_shader_selector *sel = (struct si_shader_selector *)state;
>  	struct si_shader *p = sel->first_variant, *c;
>  	struct si_shader_ctx_state *current_shader[SI_NUM_SHADERS] = {
>  		[PIPE_SHADER_VERTEX] = &sctx->vs_shader,
>  		[PIPE_SHADER_TESS_CTRL] = &sctx->tcs_shader,
>  		[PIPE_SHADER_TESS_EVAL] = &sctx->tes_shader,
>  		[PIPE_SHADER_GEOMETRY] = &sctx->gs_shader,
>  		[PIPE_SHADER_FRAGMENT] = &sctx->ps_shader,
>  	};
>
>  	util_queue_fence_wait(&sel->ready);
> @@ -2268,20 +2281,28 @@ static void si_delete_shader_selector(struct pipe_context *ctx, void *state)
>  		si_delete_shader(sctx, sel->main_shader_part_es);
>  	if (sel->gs_copy_shader)
>  		si_delete_shader(sctx, sel->gs_copy_shader);
>
>  	util_queue_fence_destroy(&sel->ready);
>  	mtx_destroy(&sel->mutex);
>  	free(sel->tokens);
>  	free(sel);
>  }
>
> +static void si_delete_shader_selector(struct pipe_context *ctx, void *state)
> +{
> +	struct si_context *sctx = (struct si_context *)ctx;
> +	struct si_shader_selector *sel = (struct si_shader_selector *)state;
> +
> +	si_shader_selector_reference(sctx, &sel, NULL);
> +}
> +
>  static unsigned si_get_ps_input_cntl(struct si_context *sctx,
>  				     struct si_shader *vs, unsigned name,
>  				     unsigned index, unsigned interpolate)
>  {
>  	struct tgsi_shader_info *vsinfo = &vs->selector->info;
>  	unsigned j, offset, ps_input_cntl = 0;
>
>  	if (interpolate == TGSI_INTERPOLATE_CONSTANT ||
>  	    (interpolate == TGSI_INTERPOLATE_COLOR && sctx->flatshade))
>  		ps_input_cntl |= S_028644_FLAT_SHADE(1);
>


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


More information about the mesa-dev mailing list