[Mesa-dev] [PATCH 06/10] radeonsi: add si_build_fs_interp helper

Marek Olšák maraeo at gmail.com
Sat Jul 8 00:42:15 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

This is much simpler.
---
 src/gallium/drivers/radeonsi/si_shader.c | 100 ++++++++++++-------------------
 1 file changed, 39 insertions(+), 61 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 349e57b..ad1fb7b 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -1195,20 +1195,38 @@ static int lookup_interp_param_index(unsigned interpolate, unsigned location)
 			return SI_PARAM_PERSP_CENTROID;
 		else
 			return SI_PARAM_PERSP_CENTER;
 		break;
 	default:
 		fprintf(stderr, "Warning: Unhandled interpolation mode.\n");
 		return -1;
 	}
 }
 
+static LLVMValueRef si_build_fs_interp(struct si_shader_context *ctx,
+				       unsigned attr_index, unsigned chan,
+				       LLVMValueRef prim_mask,
+				       LLVMValueRef i, LLVMValueRef j)
+{
+	if (i || j) {
+		return ac_build_fs_interp(&ctx->ac,
+					  LLVMConstInt(ctx->i32, chan, 0),
+					  LLVMConstInt(ctx->i32, attr_index, 0),
+					  prim_mask, i, j);
+	}
+	return ac_build_fs_interp_mov(&ctx->ac,
+				      LLVMConstInt(ctx->i32, 2, 0), /* P0 */
+				      LLVMConstInt(ctx->i32, chan, 0),
+				      LLVMConstInt(ctx->i32, attr_index, 0),
+				      prim_mask);
+}
+
 /**
  * Interpolate a fragment shader input.
  *
  * @param ctx		context
  * @param input_index		index of the input in hardware
  * @param semantic_name		TGSI_SEMANTIC_*
  * @param semantic_index	semantic index
  * @param num_interp_inputs	number of all interpolated inputs (= BCOLOR offset)
  * @param colors_read_mask	color components read (4 bits for each color, 8 bits in total)
  * @param interp_param		interpolation weights (i,j)
@@ -1221,119 +1239,89 @@ static void interp_fs_input(struct si_shader_context *ctx,
 			    unsigned semantic_name,
 			    unsigned semantic_index,
 			    unsigned num_interp_inputs,
 			    unsigned colors_read_mask,
 			    LLVMValueRef interp_param,
 			    LLVMValueRef prim_mask,
 			    LLVMValueRef face,
 			    LLVMValueRef result[4])
 {
 	struct gallivm_state *gallivm = &ctx->gallivm;
-	LLVMValueRef attr_number;
-	LLVMValueRef i, j;
-
+	LLVMValueRef i = NULL, j = NULL;
 	unsigned chan;
 
 	/* fs.constant returns the param from the middle vertex, so it's not
 	 * really useful for flat shading. It's meant to be used for custom
 	 * interpolation (but the intrinsic can't fetch from the other two
 	 * vertices).
 	 *
 	 * Luckily, it doesn't matter, because we rely on the FLAT_SHADE state
 	 * to do the right thing. The only reason we use fs.constant is that
 	 * fs.interp cannot be used on integers, because they can be equal
 	 * to NaN.
 	 *
 	 * When interp is false we will use fs.constant or for newer llvm,
          * amdgcn.interp.mov.
 	 */
 	bool interp = interp_param != NULL;
 
-	attr_number = LLVMConstInt(ctx->i32, input_index, 0);
-
 	if (interp) {
 		interp_param = LLVMBuildBitCast(gallivm->builder, interp_param,
 						LLVMVectorType(ctx->f32, 2), "");
 
 		i = LLVMBuildExtractElement(gallivm->builder, interp_param,
 						ctx->i32_0, "");
 		j = LLVMBuildExtractElement(gallivm->builder, interp_param,
 						ctx->i32_1, "");
 	}
 
 	if (semantic_name == TGSI_SEMANTIC_COLOR &&
 	    ctx->shader->key.part.ps.prolog.color_two_side) {
 		LLVMValueRef is_face_positive;
-		LLVMValueRef back_attr_number;
 
 		/* If BCOLOR0 is used, BCOLOR1 is at offset "num_inputs + 1",
 		 * otherwise it's at offset "num_inputs".
 		 */
 		unsigned back_attr_offset = num_interp_inputs;
 		if (semantic_index == 1 && colors_read_mask & 0xf)
 			back_attr_offset += 1;
 
-		back_attr_number = LLVMConstInt(ctx->i32, back_attr_offset, 0);
-
 		is_face_positive = LLVMBuildICmp(gallivm->builder, LLVMIntNE,
 						 face, ctx->i32_0, "");
 
 		for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
-			LLVMValueRef llvm_chan = LLVMConstInt(ctx->i32, chan, 0);
 			LLVMValueRef front, back;
 
-			if (interp) {
-				front = ac_build_fs_interp(&ctx->ac, llvm_chan,
-							attr_number, prim_mask,
-							i, j);
-				back = ac_build_fs_interp(&ctx->ac, llvm_chan,
-							back_attr_number, prim_mask,
-							i, j);
-			} else {
-				front = ac_build_fs_interp_mov(&ctx->ac,
-					LLVMConstInt(ctx->i32, 2, 0), /* P0 */
-					llvm_chan, attr_number, prim_mask);
-				back = ac_build_fs_interp_mov(&ctx->ac,
-					LLVMConstInt(ctx->i32, 2, 0), /* P0 */
-					llvm_chan, back_attr_number, prim_mask);
-			}
+			front = si_build_fs_interp(ctx,
+						   input_index, chan,
+						   prim_mask, i, j);
+			back = si_build_fs_interp(ctx,
+						  back_attr_offset, chan,
+						  prim_mask, i, j);
 
 			result[chan] = LLVMBuildSelect(gallivm->builder,
 						is_face_positive,
 						front,
 						back,
 						"");
 		}
 	} else if (semantic_name == TGSI_SEMANTIC_FOG) {
-		if (interp) {
-			result[0] = ac_build_fs_interp(&ctx->ac, ctx->i32_0,
-						       attr_number, prim_mask, i, j);
-		} else {
-			result[0] = ac_build_fs_interp_mov(&ctx->ac, ctx->i32_0,
-							   LLVMConstInt(ctx->i32, 2, 0), /* P0 */
-							   attr_number, prim_mask);
-		}
+		result[0] = si_build_fs_interp(ctx, input_index,
+					       0, prim_mask, i, j);
 		result[1] =
 		result[2] = LLVMConstReal(ctx->f32, 0.0f);
 		result[3] = LLVMConstReal(ctx->f32, 1.0f);
 	} else {
 		for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
-			LLVMValueRef llvm_chan = LLVMConstInt(ctx->i32, chan, 0);
-
-			if (interp) {
-				result[chan] = ac_build_fs_interp(&ctx->ac,
-					llvm_chan, attr_number, prim_mask, i, j);
-			} else {
-				result[chan] = ac_build_fs_interp_mov(&ctx->ac,
-					LLVMConstInt(ctx->i32, 2, 0), /* P0 */
-					llvm_chan, attr_number, prim_mask);
-			}
+			result[chan] = si_build_fs_interp(ctx,
+							  input_index, chan,
+							  prim_mask, i, j);
 		}
 	}
 }
 
 static void declare_input_fs(
 	struct si_shader_context *ctx,
 	unsigned input_index,
 	const struct tgsi_full_declaration *decl,
 	LLVMValueRef out[4])
 {
@@ -3524,21 +3512,21 @@ static void build_interp_intrinsic(const struct lp_build_tgsi_action *action,
 	struct si_shader_context *ctx = si_shader_context(bld_base);
 	struct si_shader *shader = ctx->shader;
 	struct gallivm_state *gallivm = &ctx->gallivm;
 	const struct tgsi_shader_info *info = &shader->selector->info;
 	LLVMValueRef interp_param;
 	const struct tgsi_full_instruction *inst = emit_data->inst;
 	const struct tgsi_full_src_register *input = &inst->Src[0];
 	int input_base, input_array_size;
 	int chan;
 	int i;
-	LLVMValueRef params = LLVMGetParam(ctx->main_fn, SI_PARAM_PRIM_MASK);
+	LLVMValueRef prim_mask = LLVMGetParam(ctx->main_fn, SI_PARAM_PRIM_MASK);
 	LLVMValueRef array_idx;
 	int interp_param_idx;
 	unsigned interp;
 	unsigned location;
 
 	assert(input->Register.File == TGSI_FILE_INPUT);
 
 	if (input->Register.Indirect) {
 		unsigned array_id = input->Indirect.ArrayID;
 
@@ -3611,49 +3599,39 @@ static void build_interp_intrinsic(const struct lp_build_tgsi_action *action,
 		}
 		interp_param = lp_build_gather_values(gallivm, ij_out, 2);
 	}
 
 	if (interp_param) {
 		interp_param = LLVMBuildBitCast(gallivm->builder,
 			interp_param, LLVMVectorType(ctx->f32, 2), "");
 	}
 
 	for (chan = 0; chan < 4; chan++) {
-		LLVMValueRef llvm_chan;
 		LLVMValueRef gather = LLVMGetUndef(LLVMVectorType(ctx->f32, input_array_size));
-		unsigned schan;
-
-		schan = tgsi_util_get_full_src_register_swizzle(&inst->Src[0], chan);
-		llvm_chan = LLVMConstInt(ctx->i32, schan, 0);
+		unsigned schan = tgsi_util_get_full_src_register_swizzle(&inst->Src[0], chan);
 
-		for (unsigned i = 0; i < input_array_size; ++i) {
-			LLVMValueRef attr_number = LLVMConstInt(ctx->i32, input_base + i, false);
-			LLVMValueRef v;
+		for (unsigned idx = 0; idx < input_array_size; ++idx) {
+			LLVMValueRef v, i = NULL, j = NULL;
 
 			if (interp_param) {
 				interp_param = LLVMBuildBitCast(gallivm->builder,
 					interp_param, LLVMVectorType(ctx->f32, 2), "");
-				LLVMValueRef i = LLVMBuildExtractElement(
+				i = LLVMBuildExtractElement(
 					gallivm->builder, interp_param, ctx->i32_0, "");
-				LLVMValueRef j = LLVMBuildExtractElement(
+				j = LLVMBuildExtractElement(
 					gallivm->builder, interp_param, ctx->i32_1, "");
-				v = ac_build_fs_interp(&ctx->ac,
-					llvm_chan, attr_number, params,
-					i, j);
-			} else {
-				v = ac_build_fs_interp_mov(&ctx->ac,
-					LLVMConstInt(ctx->i32, 2, 0), /* P0 */
-					llvm_chan, attr_number, params);
 			}
+			v = si_build_fs_interp(ctx, input_base + idx, schan,
+					       prim_mask, i, j);
 
 			gather = LLVMBuildInsertElement(gallivm->builder,
-				gather, v, LLVMConstInt(ctx->i32, i, false), "");
+				gather, v, LLVMConstInt(ctx->i32, idx, false), "");
 		}
 
 		emit_data->output[chan] = LLVMBuildExtractElement(
 			gallivm->builder, gather, array_idx, "");
 	}
 }
 
 static LLVMValueRef si_emit_ballot(struct si_shader_context *ctx,
 				   LLVMValueRef value)
 {
-- 
2.7.4



More information about the mesa-dev mailing list