[Mesa-dev] [PATCH v2 07/12] ac/radeonsi: add lookup_interp_param and load_sample_position to the abi

Timothy Arceri tarceri at itsqueeze.com
Tue Jan 30 03:55:33 UTC 2018


The will enable the interpolateAt builtins to work on the radeonsi
nir backend.

Reviewed-by: Marek Olšák <marek.olsak at amd.com>
---
 src/amd/common/ac_nir_to_llvm.c          | 64 +++++++++++++++++---------------
 src/amd/common/ac_shader_abi.h           |  7 ++++
 src/gallium/drivers/radeonsi/si_shader.c |  2 +
 3 files changed, 44 insertions(+), 29 deletions(-)

diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index e4963dc359..fd5989389b 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -3975,9 +3975,11 @@ static LLVMValueRef visit_var_atomic(struct nir_to_llvm_context *ctx,
 	return result;
 }
 
-static LLVMValueRef lookup_interp_param(struct nir_to_llvm_context *ctx,
+static LLVMValueRef lookup_interp_param(struct ac_shader_abi *abi,
 					enum glsl_interp_mode interp, unsigned location)
 {
+	struct nir_to_llvm_context *ctx = nir_to_llvm_context_from_abi(abi);
+
 	switch (interp) {
 	case INTERP_MODE_FLAT:
 	default:
@@ -4003,9 +4005,11 @@ static LLVMValueRef lookup_interp_param(struct nir_to_llvm_context *ctx,
 	return NULL;
 }
 
-static LLVMValueRef load_sample_position(struct nir_to_llvm_context *ctx,
+static LLVMValueRef load_sample_position(struct ac_shader_abi *abi,
 					 LLVMValueRef sample_id)
 {
+	struct nir_to_llvm_context *ctx = nir_to_llvm_context_from_abi(abi);
+
 	LLVMValueRef result;
 	LLVMValueRef ptr = ac_build_gep0(&ctx->ac, ctx->ring_offsets, LLVMConstInt(ctx->ac.i32, RING_PS_SAMPLE_POSITIONS, false));
 
@@ -4051,7 +4055,7 @@ static LLVMValueRef load_sample_mask_in(struct ac_nir_context *ctx)
 	return result;
 }
 
-static LLVMValueRef visit_interp(struct nir_to_llvm_context *ctx,
+static LLVMValueRef visit_interp(struct ac_nir_context *ctx,
 				 const nir_intrinsic_instr *instr)
 {
 	LLVMValueRef result[4];
@@ -4069,33 +4073,33 @@ static LLVMValueRef visit_interp(struct nir_to_llvm_context *ctx,
 	case nir_intrinsic_interp_var_at_sample:
 	case nir_intrinsic_interp_var_at_offset:
 		location = INTERP_CENTER;
-		src0 = get_src(ctx->nir, instr->src[0]);
+		src0 = get_src(ctx, instr->src[0]);
 		break;
 	default:
 		break;
 	}
 
 	if (instr->intrinsic == nir_intrinsic_interp_var_at_offset) {
-		src_c0 = ac_to_float(&ctx->ac, LLVMBuildExtractElement(ctx->builder, src0, ctx->ac.i32_0, ""));
-		src_c1 = ac_to_float(&ctx->ac, LLVMBuildExtractElement(ctx->builder, src0, ctx->ac.i32_1, ""));
+		src_c0 = ac_to_float(&ctx->ac, LLVMBuildExtractElement(ctx->ac.builder, src0, ctx->ac.i32_0, ""));
+		src_c1 = ac_to_float(&ctx->ac, LLVMBuildExtractElement(ctx->ac.builder, src0, ctx->ac.i32_1, ""));
 	} else if (instr->intrinsic == nir_intrinsic_interp_var_at_sample) {
 		LLVMValueRef sample_position;
 		LLVMValueRef halfval = LLVMConstReal(ctx->ac.f32, 0.5f);
 
 		/* fetch sample ID */
-		sample_position = load_sample_position(ctx, src0);
+		sample_position = ctx->abi->load_sample_position(ctx->abi, src0);
 
-		src_c0 = LLVMBuildExtractElement(ctx->builder, sample_position, ctx->ac.i32_0, "");
-		src_c0 = LLVMBuildFSub(ctx->builder, src_c0, halfval, "");
-		src_c1 = LLVMBuildExtractElement(ctx->builder, sample_position, ctx->ac.i32_1, "");
-		src_c1 = LLVMBuildFSub(ctx->builder, src_c1, halfval, "");
+		src_c0 = LLVMBuildExtractElement(ctx->ac.builder, sample_position, ctx->ac.i32_0, "");
+		src_c0 = LLVMBuildFSub(ctx->ac.builder, src_c0, halfval, "");
+		src_c1 = LLVMBuildExtractElement(ctx->ac.builder, sample_position, ctx->ac.i32_1, "");
+		src_c1 = LLVMBuildFSub(ctx->ac.builder, src_c1, halfval, "");
 	}
-	interp_param = lookup_interp_param(ctx, instr->variables[0]->var->data.interpolation, location);
+	interp_param = ctx->abi->lookup_interp_param(ctx->abi, instr->variables[0]->var->data.interpolation, location);
 	attr_number = LLVMConstInt(ctx->ac.i32, input_index, false);
 
 	if (location == INTERP_CENTER) {
 		LLVMValueRef ij_out[2];
-		LLVMValueRef ddxy_out = emit_ddxy_interp(ctx->nir, interp_param);
+		LLVMValueRef ddxy_out = emit_ddxy_interp(ctx, interp_param);
 
 		/*
 		 * take the I then J parameters, and the DDX/Y for it, and
@@ -4108,24 +4112,24 @@ static LLVMValueRef visit_interp(struct nir_to_llvm_context *ctx,
 		for (unsigned i = 0; i < 2; i++) {
 			LLVMValueRef ix_ll = LLVMConstInt(ctx->ac.i32, i, false);
 			LLVMValueRef iy_ll = LLVMConstInt(ctx->ac.i32, i + 2, false);
-			LLVMValueRef ddx_el = LLVMBuildExtractElement(ctx->builder,
+			LLVMValueRef ddx_el = LLVMBuildExtractElement(ctx->ac.builder,
 								      ddxy_out, ix_ll, "");
-			LLVMValueRef ddy_el = LLVMBuildExtractElement(ctx->builder,
+			LLVMValueRef ddy_el = LLVMBuildExtractElement(ctx->ac.builder,
 								      ddxy_out, iy_ll, "");
-			LLVMValueRef interp_el = LLVMBuildExtractElement(ctx->builder,
+			LLVMValueRef interp_el = LLVMBuildExtractElement(ctx->ac.builder,
 									 interp_param, ix_ll, "");
 			LLVMValueRef temp1, temp2;
 
-			interp_el = LLVMBuildBitCast(ctx->builder, interp_el,
+			interp_el = LLVMBuildBitCast(ctx->ac.builder, interp_el,
 						     ctx->ac.f32, "");
 
-			temp1 = LLVMBuildFMul(ctx->builder, ddx_el, src_c0, "");
-			temp1 = LLVMBuildFAdd(ctx->builder, temp1, interp_el, "");
+			temp1 = LLVMBuildFMul(ctx->ac.builder, ddx_el, src_c0, "");
+			temp1 = LLVMBuildFAdd(ctx->ac.builder, temp1, interp_el, "");
 
-			temp2 = LLVMBuildFMul(ctx->builder, ddy_el, src_c1, "");
-			temp2 = LLVMBuildFAdd(ctx->builder, temp2, temp1, "");
+			temp2 = LLVMBuildFMul(ctx->ac.builder, ddy_el, src_c1, "");
+			temp2 = LLVMBuildFAdd(ctx->ac.builder, temp2, temp1, "");
 
-			ij_out[i] = LLVMBuildBitCast(ctx->builder,
+			ij_out[i] = LLVMBuildBitCast(ctx->ac.builder,
 						     temp2, ctx->ac.i32, "");
 		}
 		interp_param = ac_build_gather_values(&ctx->ac, ij_out, 2);
@@ -4136,21 +4140,21 @@ static LLVMValueRef visit_interp(struct nir_to_llvm_context *ctx,
 		LLVMValueRef llvm_chan = LLVMConstInt(ctx->ac.i32, chan, false);
 
 		if (interp_param) {
-			interp_param = LLVMBuildBitCast(ctx->builder,
+			interp_param = LLVMBuildBitCast(ctx->ac.builder,
 							interp_param, ctx->ac.v2f32, "");
 			LLVMValueRef i = LLVMBuildExtractElement(
-				ctx->builder, interp_param, ctx->ac.i32_0, "");
+				ctx->ac.builder, interp_param, ctx->ac.i32_0, "");
 			LLVMValueRef j = LLVMBuildExtractElement(
-				ctx->builder, interp_param, ctx->ac.i32_1, "");
+				ctx->ac.builder, interp_param, ctx->ac.i32_1, "");
 
 			result[chan] = ac_build_fs_interp(&ctx->ac,
 							  llvm_chan, attr_number,
-							  ctx->abi.prim_mask, i, j);
+							  ctx->abi->prim_mask, i, j);
 		} else {
 			result[chan] = ac_build_fs_interp_mov(&ctx->ac,
 							      LLVMConstInt(ctx->ac.i32, 2, false),
 							      llvm_chan, attr_number,
-							      ctx->abi.prim_mask);
+							      ctx->abi->prim_mask);
 		}
 	}
 	return ac_build_varying_gather_values(&ctx->ac, result, instr->num_components,
@@ -4473,7 +4477,7 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
 	case nir_intrinsic_interp_var_at_centroid:
 	case nir_intrinsic_interp_var_at_sample:
 	case nir_intrinsic_interp_var_at_offset:
-		result = visit_interp(ctx->nctx, instr);
+		result = visit_interp(ctx, instr);
 		break;
 	case nir_intrinsic_emit_vertex:
 		ctx->abi->emit_vertex(ctx->abi, nir_intrinsic_stream_id(instr), ctx->outputs);
@@ -5426,7 +5430,7 @@ handle_fs_input_decl(struct nir_to_llvm_context *ctx,
 		else
 			interp_type = INTERP_CENTER;
 
-		interp = lookup_interp_param(ctx, variable->data.interpolation, interp_type);
+		interp = lookup_interp_param(&ctx->abi, variable->data.interpolation, interp_type);
 	} else
 		interp = NULL;
 
@@ -6870,6 +6874,8 @@ LLVMModuleRef ac_translate_nir_to_llvm(LLVMTargetMachineRef tm,
 			}
 		} else if (shaders[i]->info.stage == MESA_SHADER_FRAGMENT) {
 			shader_info->fs.can_discard = shaders[i]->info.fs.uses_discard;
+			ctx.abi.lookup_interp_param = lookup_interp_param;
+			ctx.abi.load_sample_position = load_sample_position;
 		}
 
 		if (i)
diff --git a/src/amd/common/ac_shader_abi.h b/src/amd/common/ac_shader_abi.h
index 9cdfd9d1df..d9bb5a1e32 100644
--- a/src/amd/common/ac_shader_abi.h
+++ b/src/amd/common/ac_shader_abi.h
@@ -147,6 +147,13 @@ struct ac_shader_abi {
 					  enum ac_descriptor_type desc_type,
 					  bool image, bool write);
 
+	LLVMValueRef (*lookup_interp_param)(struct ac_shader_abi *abi,
+					    enum glsl_interp_mode interp,
+					    unsigned location);
+
+	LLVMValueRef (*load_sample_position)(struct ac_shader_abi *abi,
+					     LLVMValueRef sample_id);
+
 	/* Whether to clamp the shadow reference value to [0,1]on VI. Radeonsi currently
 	 * uses it due to promoting D16 to D32, but radv needs it off. */
 	bool clamp_shadow_reference;
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index dfec070d33..76215b318a 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -6028,6 +6028,8 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx,
 		ctx->load_input = declare_input_fs;
 		ctx->abi.emit_outputs = si_llvm_return_fs_outputs;
 		bld_base->emit_epilogue = si_tgsi_emit_epilogue;
+		ctx->abi.lookup_interp_param = si_nir_lookup_interp_param;
+		ctx->abi.load_sample_position = load_sample_position;
 		break;
 	case PIPE_SHADER_COMPUTE:
 		break;
-- 
2.14.3



More information about the mesa-dev mailing list