[Mesa-dev] [PATCH 1/6] radeonsi: load streamout buffer descriptors before use

Nicolai Hähnle nhaehnle at gmail.com
Tue Sep 13 17:59:54 UTC 2016


On 13.09.2016 19:13, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> ---
>  src/gallium/drivers/radeonsi/si_shader.c | 67 ++++++++++++++++----------------
>  1 file changed, 34 insertions(+), 33 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
> index be6fae7..b9ad4be 100644
> --- a/src/gallium/drivers/radeonsi/si_shader.c
> +++ b/src/gallium/drivers/radeonsi/si_shader.c
> @@ -105,21 +105,20 @@ struct si_shader_context
>  	unsigned uniform_md_kind;
>  	LLVMValueRef empty_md;
>
>  	LLVMValueRef const_buffers[SI_NUM_CONST_BUFFERS];
>  	LLVMValueRef lds;
>  	LLVMValueRef shader_buffers[SI_NUM_SHADER_BUFFERS];
>  	LLVMValueRef sampler_views[SI_NUM_SAMPLERS];
>  	LLVMValueRef sampler_states[SI_NUM_SAMPLERS];
>  	LLVMValueRef fmasks[SI_NUM_SAMPLERS];
>  	LLVMValueRef images[SI_NUM_IMAGES];
> -	LLVMValueRef so_buffers[4];
>  	LLVMValueRef esgs_ring;
>  	LLVMValueRef gsvs_ring[4];
>  	LLVMValueRef gs_next_vertex[4];
>  	LLVMValueRef return_value;
>
>  	LLVMTypeRef voidt;
>  	LLVMTypeRef i1;
>  	LLVMTypeRef i8;
>  	LLVMTypeRef i32;
>  	LLVMTypeRef i64;
> @@ -2253,31 +2252,64 @@ static void si_dump_streamout(struct pipe_stream_output_info *so)
>  			i, so->output[i].output_buffer,
>  			so->output[i].dst_offset, so->output[i].dst_offset + so->output[i].num_components - 1,
>  			so->output[i].register_index,
>  			mask & 1 ? "x" : "",
>  		        mask & 2 ? "y" : "",
>  		        mask & 4 ? "z" : "",
>  		        mask & 8 ? "w" : "");
>  	}
>  }
>
> +static void load_streamout_descriptors(struct si_shader_context *ctx,
> +				       LLVMValueRef so_buffers[4])
> +{
> +	struct lp_build_tgsi_context *bld_base = &ctx->radeon_bld.soa.bld_base;
> +	struct gallivm_state *gallivm = bld_base->base.gallivm;
> +	unsigned i;
> +
> +	/* Streamout can only be used if the shader is compiled as VS. */
> +	if (!ctx->shader->selector->so.num_outputs ||
> +	    (ctx->type == PIPE_SHADER_VERTEX &&
> +	     (ctx->shader->key.vs.as_es ||
> +	      ctx->shader->key.vs.as_ls)) ||
> +	    (ctx->type == PIPE_SHADER_TESS_EVAL &&
> +	     ctx->shader->key.tes.as_es))
> +		return;

This should probably be an assertion now.

Cheers
Nicolai

> +
> +	LLVMValueRef buf_ptr = LLVMGetParam(ctx->radeon_bld.main_fn,
> +					    SI_PARAM_RW_BUFFERS);
> +
> +	/* Load the resources, we rely on the code sinking to do the rest */
> +	for (i = 0; i < 4; ++i) {
> +		if (ctx->shader->selector->so.stride[i]) {
> +			LLVMValueRef offset = lp_build_const_int32(gallivm,
> +								   SI_VS_STREAMOUT_BUF0 + i);
> +
> +			so_buffers[i] = build_indexed_load_const(ctx, buf_ptr, offset);
> +		}
> +	}
> +}
> +
>  /* On SI, the vertex shader is responsible for writing streamout data
>   * to buffers. */
>  static void si_llvm_emit_streamout(struct si_shader_context *ctx,
>  				   struct si_shader_output_values *outputs,
>  				   unsigned noutput)
>  {
>  	struct pipe_stream_output_info *so = &ctx->shader->selector->so;
>  	struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
>  	LLVMBuilderRef builder = gallivm->builder;
>  	int i, j;
>  	struct lp_build_if_state if_ctx;
> +	LLVMValueRef so_buffers[4];
> +
> +	load_streamout_descriptors(ctx, so_buffers);
>
>  	/* Get bits [22:16], i.e. (so_param >> 16) & 127; */
>  	LLVMValueRef so_vtx_count =
>  		unpack_param(ctx, ctx->param_streamout_config, 16, 7);
>
>  	LLVMValueRef tid = get_thread_id(ctx);
>
>  	/* can_emit = tid < so_vtx_count; */
>  	LLVMValueRef can_emit =
>  		LLVMBuildICmp(builder, LLVMIntULT, tid, so_vtx_count, "");
> @@ -2359,21 +2391,21 @@ static void si_llvm_emit_streamout(struct si_shader_context *ctx,
>  				}
>  				break;
>  			}
>
>  			LLVMValueRef can_emit_stream =
>  				LLVMBuildICmp(builder, LLVMIntEQ,
>  					      stream_id,
>  					      lp_build_const_int32(gallivm, stream), "");
>
>  			lp_build_if(&if_ctx_stream, gallivm, can_emit_stream);
> -			build_tbuffer_store_dwords(ctx, ctx->so_buffers[buf_idx],
> +			build_tbuffer_store_dwords(ctx, so_buffers[buf_idx],
>  						   vdata, num_comps,
>  						   so_write_offset[buf_idx],
>  						   LLVMConstInt(ctx->i32, 0, 0),
>  						   so->output[i].dst_offset*4);
>  			lp_build_endif(&if_ctx_stream);
>  		}
>  	}
>  	lp_build_endif(&if_ctx);
>  }
>
> @@ -5917,49 +5949,20 @@ static void preload_images(struct si_shader_context *ctx)
>  						 lp_build_const_int32(gallivm, i));
>
>  		if (info->images_writemask & (1 << i) &&
>  		    !(info->images_buffers & (1 << i)))
>  			rsrc = force_dcc_off(ctx, rsrc);
>
>  		ctx->images[i] = rsrc;
>  	}
>  }
>
> -static void preload_streamout_buffers(struct si_shader_context *ctx)
> -{
> -	struct lp_build_tgsi_context *bld_base = &ctx->radeon_bld.soa.bld_base;
> -	struct gallivm_state *gallivm = bld_base->base.gallivm;
> -	unsigned i;
> -
> -	/* Streamout can only be used if the shader is compiled as VS. */
> -	if (!ctx->shader->selector->so.num_outputs ||
> -	    (ctx->type == PIPE_SHADER_VERTEX &&
> -	     (ctx->shader->key.vs.as_es ||
> -	      ctx->shader->key.vs.as_ls)) ||
> -	    (ctx->type == PIPE_SHADER_TESS_EVAL &&
> -	     ctx->shader->key.tes.as_es))
> -		return;
> -
> -	LLVMValueRef buf_ptr = LLVMGetParam(ctx->radeon_bld.main_fn,
> -					    SI_PARAM_RW_BUFFERS);
> -
> -	/* Load the resources, we rely on the code sinking to do the rest */
> -	for (i = 0; i < 4; ++i) {
> -		if (ctx->shader->selector->so.stride[i]) {
> -			LLVMValueRef offset = lp_build_const_int32(gallivm,
> -								   SI_VS_STREAMOUT_BUF0 + i);
> -
> -			ctx->so_buffers[i] = build_indexed_load_const(ctx, buf_ptr, offset);
> -		}
> -	}
> -}
> -
>  /**
>   * Load ESGS and GSVS ring buffer resource descriptors and save the variables
>   * for later use.
>   */
>  static void preload_ring_buffers(struct si_shader_context *ctx)
>  {
>  	struct gallivm_state *gallivm =
>  		ctx->radeon_bld.soa.bld_base.base.gallivm;
>
>  	LLVMValueRef buf_ptr = LLVMGetParam(ctx->radeon_bld.main_fn,
> @@ -6490,21 +6493,20 @@ static int si_generate_gs_copy_shader(struct si_screen *sscreen,
>  	int i, r;
>
>  	outputs = MALLOC(gsinfo->num_outputs * sizeof(outputs[0]));
>
>  	si_init_shader_ctx(ctx, sscreen, ctx->shader, ctx->tm);
>  	ctx->type = PIPE_SHADER_VERTEX;
>  	ctx->is_gs_copy_shader = true;
>
>  	create_meta_data(ctx);
>  	create_function(ctx);
> -	preload_streamout_buffers(ctx);
>  	preload_ring_buffers(ctx);
>
>  	args[0] = ctx->gsvs_ring[0];
>  	args[1] = lp_build_mul_imm(uint,
>  				   LLVMGetParam(ctx->radeon_bld.main_fn,
>  						ctx->param_vertex_id),
>  				   4);
>  	args[3] = uint->zero;
>  	args[4] = uint->one;  /* OFFEN */
>  	args[5] = uint->zero; /* IDXEN */
> @@ -6792,21 +6794,20 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
>  		assert(!"Unsupported shader type");
>  		return -1;
>  	}
>
>  	create_meta_data(&ctx);
>  	create_function(&ctx);
>  	preload_constants(&ctx);
>  	preload_shader_buffers(&ctx);
>  	preload_samplers(&ctx);
>  	preload_images(&ctx);
> -	preload_streamout_buffers(&ctx);
>  	preload_ring_buffers(&ctx);
>
>  	if (ctx.is_monolithic && sel->type == PIPE_SHADER_FRAGMENT &&
>  	    shader->key.ps.prolog.poly_stipple) {
>  		LLVMValueRef list = LLVMGetParam(ctx.radeon_bld.main_fn,
>  						 SI_PARAM_RW_BUFFERS);
>  		si_llvm_emit_polygon_stipple(&ctx, list,
>  					     SI_PARAM_POS_FIXED_PT);
>  	}
>
>


More information about the mesa-dev mailing list