[Mesa-dev] [PATCH 05/23] radeonsi: simplify setting the DONE bit for PS exports

Nicolai Hähnle nhaehnle at gmail.com
Wed Jan 6 06:56:47 PST 2016


Patches 1-5 are

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

On 06.01.2016 07:41, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> First find out what the last export is and simply set the DONE bit there.
> ---
>   src/gallium/drivers/radeonsi/si_shader.c        | 126 ++++++++++--------------
>   src/gallium/drivers/radeonsi/si_state_shaders.c |   2 +-
>   2 files changed, 55 insertions(+), 73 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
> index 85113c0..8441fb4 100644
> --- a/src/gallium/drivers/radeonsi/si_shader.c
> +++ b/src/gallium/drivers/radeonsi/si_shader.c
> @@ -2109,10 +2109,36 @@ static void si_llvm_emit_fs_epilogue(struct lp_build_tgsi_context * bld_base)
>   	struct tgsi_shader_info *info = &shader->selector->info;
>   	LLVMBuilderRef builder = base->gallivm->builder;
>   	LLVMValueRef args[9];
> -	LLVMValueRef last_args[9] = { 0 };
>   	int depth_index = -1, stencil_index = -1, samplemask_index = -1;
> +	int last_color_export = -1;
>   	int i;
>
> +	/* If there are no outputs, add a dummy export. */
> +	if (!info->num_outputs) {
> +		args[0] = lp_build_const_int32(base->gallivm, 0x0); /* enabled channels */
> +		args[1] = uint->one; /* whether the EXEC mask is valid */
> +		args[2] = uint->one; /* DONE bit */
> +		args[3] = lp_build_const_int32(base->gallivm, V_008DFC_SQ_EXP_MRT);
> +		args[4] = uint->zero; /* COMPR flag (0 = 32-bit export) */
> +		args[5] = uint->zero; /* R */
> +		args[6] = uint->zero; /* G */
> +		args[7] = uint->zero; /* B */
> +		args[8] = uint->zero; /* A */
> +
> +		lp_build_intrinsic(base->gallivm->builder, "llvm.SI.export",
> +				   LLVMVoidTypeInContext(base->gallivm->context),
> +				   args, 9, 0);
> +		return;
> +	}
> +
> +	/* Determine the last export. If MRTZ is present, it's always last.
> +	 * Otherwise, find the last color export.
> +	 */
> +	if (!info->writes_z && !info->writes_stencil && !info->writes_samplemask)
> +		for (i = 0; i < info->num_outputs; i++)
> +			if (info->output_semantic_name[i] == TGSI_SEMANTIC_COLOR)
> +				last_color_export = i;
> +
>   	for (i = 0; i < info->num_outputs; i++) {
>   		unsigned semantic_name = info->output_semantic_name[i];
>   		unsigned semantic_index = info->output_semantic_index[i];
> @@ -2157,56 +2183,48 @@ static void si_llvm_emit_fs_epilogue(struct lp_build_tgsi_context * bld_base)
>
>   			break;
>   		default:
> -			target = 0;
>   			fprintf(stderr,
>   				"Warning: SI unhandled fs output type:%d\n",
>   				semantic_name);
> +			continue;
>   		}
>
> -		si_llvm_init_export_args_load(bld_base,
> -					      si_shader_ctx->radeon_bld.soa.outputs[i],
> -					      target, args);
> -
> -		if (semantic_name == TGSI_SEMANTIC_COLOR) {
> -			/* If there is an export instruction waiting to be emitted, do so now. */
> -			if (last_args[0]) {
> -				lp_build_intrinsic(base->gallivm->builder,
> -						   "llvm.SI.export",
> +		/* If last_cbuf > 0, FS_COLOR0_WRITES_ALL_CBUFS is true. */
> +		if (semantic_index == 0 &&
> +		    si_shader_ctx->shader->key.ps.last_cbuf > 0) {
> +			for (int c = 1; c <= si_shader_ctx->shader->key.ps.last_cbuf; c++) {
> +				si_llvm_init_export_args_load(bld_base,
> +							      si_shader_ctx->radeon_bld.soa.outputs[i],
> +							      V_008DFC_SQ_EXP_MRT + c, args);
> +				lp_build_intrinsic(base->gallivm->builder, "llvm.SI.export",
>   						   LLVMVoidTypeInContext(base->gallivm->context),
> -						   last_args, 9, 0);
> +						   args, 9, 0);
>   			}
> +		}
>
> -			/* This instruction will be emitted at the end of the shader. */
> -			memcpy(last_args, args, sizeof(args));
> -
> -			/* If last_cbuf > 0, FS_COLOR0_WRITES_ALL_CBUFS is true. */
> -			if (semantic_index == 0 &&
> -			    si_shader_ctx->shader->key.ps.last_cbuf > 0) {
> -				for (int c = 1; c <= si_shader_ctx->shader->key.ps.last_cbuf; c++) {
> -					si_llvm_init_export_args_load(bld_base,
> -								      si_shader_ctx->radeon_bld.soa.outputs[i],
> -								      V_008DFC_SQ_EXP_MRT + c, args);
> -					lp_build_intrinsic(base->gallivm->builder,
> -							   "llvm.SI.export",
> -							   LLVMVoidTypeInContext(base->gallivm->context),
> -							   args, 9, 0);
> -				}
> -			}
> -		} else {
> -			lp_build_intrinsic(base->gallivm->builder,
> -					   "llvm.SI.export",
> -					   LLVMVoidTypeInContext(base->gallivm->context),
> -					   args, 9, 0);
> +		si_llvm_init_export_args_load(bld_base,
> +					      si_shader_ctx->radeon_bld.soa.outputs[i],
> +					      target, args);
> +		if (last_color_export == i) {
> +			args[1] = uint->one; /* whether the EXEC mask is valid */
> +			args[2] = uint->one; /* DONE bit */
>   		}
> +		lp_build_intrinsic(base->gallivm->builder, "llvm.SI.export",
> +				   LLVMVoidTypeInContext(base->gallivm->context),
> +				   args, 9, 0);
>   	}
>
>   	if (depth_index >= 0 || stencil_index >= 0 || samplemask_index >= 0) {
>   		LLVMValueRef out_ptr;
>   		unsigned mask = 0;
>
> +		args[1] = uint->one; /* whether the EXEC mask is valid */
> +		args[2] = uint->one; /* DONE bit */
> +
>   		/* Specify the target we are exporting */
>   		args[3] = lp_build_const_int32(base->gallivm, V_008DFC_SQ_EXP_MRTZ);
>
> +		args[4] = uint->zero; /* COMP flag */
>   		args[5] = base->zero; /* R, depth */
>   		args[6] = base->zero; /* G, stencil test value[0:7], stencil op value[8:15] */
>   		args[7] = base->zero; /* B, sample mask */
> @@ -2239,46 +2257,10 @@ static void si_llvm_emit_fs_epilogue(struct lp_build_tgsi_context * bld_base)
>   		/* Specify which components to enable */
>   		args[0] = lp_build_const_int32(base->gallivm, mask);
>
> -		args[1] =
> -		args[2] =
> -		args[4] = uint->zero;
> -
> -		if (last_args[0])
> -			lp_build_intrinsic(base->gallivm->builder,
> -					   "llvm.SI.export",
> -					   LLVMVoidTypeInContext(base->gallivm->context),
> -					   args, 9, 0);
> -		else
> -			memcpy(last_args, args, sizeof(args));
> -	}
> -
> -	if (!last_args[0]) {
> -		/* Specify which components to enable */
> -		last_args[0] = lp_build_const_int32(base->gallivm, 0x0);
> -
> -		/* Specify the target we are exporting */
> -		last_args[3] = lp_build_const_int32(base->gallivm, V_008DFC_SQ_EXP_MRT);
> -
> -		/* Set COMPR flag to zero to export data as 32-bit */
> -		last_args[4] = uint->zero;
> -
> -		/* dummy bits */
> -		last_args[5]= uint->zero;
> -		last_args[6]= uint->zero;
> -		last_args[7]= uint->zero;
> -		last_args[8]= uint->zero;
> +		lp_build_intrinsic(base->gallivm->builder, "llvm.SI.export",
> +				   LLVMVoidTypeInContext(base->gallivm->context),
> +				   args, 9, 0);
>   	}
> -
> -	/* Specify whether the EXEC mask represents the valid mask */
> -	last_args[1] = uint->one;
> -
> -	/* Specify that this is the last export */
> -	last_args[2] = lp_build_const_int32(base->gallivm, 1);
> -
> -	lp_build_intrinsic(base->gallivm->builder,
> -			   "llvm.SI.export",
> -			   LLVMVoidTypeInContext(base->gallivm->context),
> -			   last_args, 9, 0);
>   }
>
>   static void build_tex_intrinsic(const struct lp_build_tgsi_action * action,
> diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
> index b08b035f..68ba7ec 100644
> --- a/src/gallium/drivers/radeonsi/si_state_shaders.c
> +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
> @@ -428,7 +428,7 @@ static void si_shader_ps(struct si_shader *shader)
>   	colors_written = info->colors_written;
>   	export_16bpc = shader->key.ps.export_16bpc;
>
> -	if (info->colors_written == 0x0) {
> +	if (!info->num_outputs) {
>   		colors_written = 0x1; /* dummy export */
>   		export_16bpc = 0;
>   	} else if (info->colors_written == 0x1 &&
>


More information about the mesa-dev mailing list