[Mesa-dev] [PATCH 18/19] radeonsi: use DDX/DDY directly in si_llvm_emit_ddxy_interp

Nicolai Hähnle nhaehnle at gmail.com
Tue Oct 4 09:45:47 UTC 2016


On 02.10.2016 23:09, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> We can finally do this, because the opcodes are scalar now.
> ---
>  src/gallium/drivers/radeonsi/si_shader.c | 56 ++++----------------------------
>  1 file changed, 7 insertions(+), 49 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
> index c150ae4..7844ebd 100644
> --- a/src/gallium/drivers/radeonsi/si_shader.c
> +++ b/src/gallium/drivers/radeonsi/si_shader.c
> @@ -5067,70 +5067,28 @@ static void si_llvm_emit_ddxy(
>   * this takes an I,J coordinate pair,
>   * and works out the X and Y derivatives.
>   * it returns DDX(I), DDX(J), DDY(I), DDY(J).
>   */
>  static LLVMValueRef si_llvm_emit_ddxy_interp(
>  	struct lp_build_tgsi_context *bld_base,
>  	LLVMValueRef interp_ij)
>  {
>  	struct si_shader_context *ctx = si_shader_context(bld_base);
>  	struct gallivm_state *gallivm = bld_base->base.gallivm;
> -	LLVMValueRef store_ptr, load_ptr_x, load_ptr_y, load_ptr_ddx, load_ptr_ddy, temp, temp2;
> -	LLVMValueRef tl, tr, bl, result[4], thread_id;
> -	unsigned c;
> -
> -	thread_id = get_thread_id(ctx);
> -	store_ptr = build_gep0(ctx, ctx->lds, thread_id);
> -
> -	temp = LLVMBuildAnd(gallivm->builder, thread_id,
> -			    lp_build_const_int32(gallivm, TID_MASK_LEFT), "");
> -
> -	temp2 = LLVMBuildAnd(gallivm->builder, thread_id,
> -			     lp_build_const_int32(gallivm, TID_MASK_TOP), "");
> -
> -	load_ptr_x = build_gep0(ctx, ctx->lds, temp);
> -
> -	load_ptr_y = build_gep0(ctx, ctx->lds, temp2);
> -
> -	load_ptr_ddx = build_gep0(ctx, ctx->lds,
> -				  LLVMBuildAdd(gallivm->builder, temp,
> -					       lp_build_const_int32(gallivm, 1), ""));
> -
> -	load_ptr_ddy = build_gep0(ctx, ctx->lds,
> -				  LLVMBuildAdd(gallivm->builder, temp2,
> -					       lp_build_const_int32(gallivm, 2), ""));
> -
> -	for (c = 0; c < 2; ++c) {
> -		LLVMValueRef store_val;
> -		LLVMValueRef c_ll = lp_build_const_int32(gallivm, c);
> -
> -		store_val = LLVMBuildExtractElement(gallivm->builder,
> -						    interp_ij, c_ll, "");
> -		LLVMBuildStore(gallivm->builder,
> -			       store_val,
> -			       store_ptr);
> -
> -		tl = LLVMBuildLoad(gallivm->builder, load_ptr_x, "");
> -		tl = LLVMBuildBitCast(gallivm->builder, tl, ctx->f32, "");
> -
> -		tr = LLVMBuildLoad(gallivm->builder, load_ptr_ddx, "");
> -		tr = LLVMBuildBitCast(gallivm->builder, tr, ctx->f32, "");
> -
> -		result[c] = LLVMBuildFSub(gallivm->builder, tr, tl, "");
> -
> -		tl = LLVMBuildLoad(gallivm->builder, load_ptr_y, "");
> -		tl = LLVMBuildBitCast(gallivm->builder, tl, ctx->f32, "");
> -
> -		bl = LLVMBuildLoad(gallivm->builder, load_ptr_ddy, "");
> -		bl = LLVMBuildBitCast(gallivm->builder, bl, ctx->f32, "");
> +	LLVMValueRef result[4], a;
> +	unsigned i;
>
> -		result[c + 2] = LLVMBuildFSub(gallivm->builder, bl, tl, "");
> +	for (i = 0; i < 2; i++) {
> +		a = LLVMBuildExtractElement(gallivm->builder, interp_ij,
> +					    LLVMConstInt(ctx->i32, i, 0), "");
> +		result[i] = lp_build_emit_llvm_unary(bld_base, TGSI_OPCODE_DDX, a);
> +		result[2+i] = lp_build_emit_llvm_unary(bld_base, TGSI_OPCODE_DDY, a);

I wonder if these shouldn't be DDX/Y_FINE. Though this way, the code's 
behavior is preserved. Either way, patches 9-18:

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

>  	}
>
>  	return lp_build_gather_values(gallivm, result, 4);
>  }
>
>  static void interp_fetch_args(
>  	struct lp_build_tgsi_context *bld_base,
>  	struct lp_build_emit_data *emit_data)
>  {
>  	struct si_shader_context *ctx = si_shader_context(bld_base);
>


More information about the mesa-dev mailing list