[Mesa-dev] [PATCH v2 36/73] radeonsi/nir: load FS inputs

Nicolai Hähnle nhaehnle at gmail.com
Wed Jul 5 10:48:20 UTC 2017


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

---
 src/gallium/drivers/radeonsi/si_shader.c          | 31 +++++++++++++++--------
 src/gallium/drivers/radeonsi/si_shader_internal.h |  4 +++
 src/gallium/drivers/radeonsi/si_shader_nir.c      | 28 +++++++++++++++++++-
 3 files changed, 52 insertions(+), 11 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 7bf0303..e90d25c 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -1383,63 +1383,74 @@ static void interp_fs_input(struct si_shader_context *ctx,
 					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);
 			}
 		}
 	}
 }
 
-static void declare_input_fs(
+void si_llvm_load_input_fs(
 	struct si_shader_context *ctx,
 	unsigned input_index,
-	const struct tgsi_full_declaration *decl,
 	LLVMValueRef out[4])
 {
 	struct lp_build_context *base = &ctx->bld_base.base;
 	struct si_shader *shader = ctx->shader;
+	struct tgsi_shader_info *info = &shader->selector->info;
 	LLVMValueRef main_fn = ctx->main_fn;
 	LLVMValueRef interp_param = NULL;
 	int interp_param_idx;
+	enum tgsi_semantic semantic_name = info->input_semantic_name[input_index];
+	unsigned semantic_index = info->input_semantic_index[input_index];
+	enum tgsi_interpolate_mode interp_mode = info->input_interpolate[input_index];
+	enum tgsi_interpolate_loc interp_loc = info->input_interpolate_loc[input_index];
 
 	/* Get colors from input VGPRs (set by the prolog). */
-	if (decl->Semantic.Name == TGSI_SEMANTIC_COLOR) {
-		unsigned i = decl->Semantic.Index;
+	if (semantic_name == TGSI_SEMANTIC_COLOR) {
 		unsigned colors_read = shader->selector->info.colors_read;
-		unsigned mask = colors_read >> (i * 4);
+		unsigned mask = colors_read >> (semantic_index * 4);
 		unsigned offset = SI_PARAM_POS_FIXED_PT + 1 +
-				  (i ? util_bitcount(colors_read & 0xf) : 0);
+				  (semantic_index ? util_bitcount(colors_read & 0xf) : 0);
 
 		out[0] = mask & 0x1 ? LLVMGetParam(main_fn, offset++) : base->undef;
 		out[1] = mask & 0x2 ? LLVMGetParam(main_fn, offset++) : base->undef;
 		out[2] = mask & 0x4 ? LLVMGetParam(main_fn, offset++) : base->undef;
 		out[3] = mask & 0x8 ? LLVMGetParam(main_fn, offset++) : base->undef;
 		return;
 	}
 
-	interp_param_idx = lookup_interp_param_index(decl->Interp.Interpolate,
-						     decl->Interp.Location);
+	interp_param_idx = lookup_interp_param_index(interp_mode, interp_loc);
 	if (interp_param_idx == -1)
 		return;
 	else if (interp_param_idx) {
 		interp_param = LLVMGetParam(ctx->main_fn, interp_param_idx);
 	}
 
-	interp_fs_input(ctx, input_index, decl->Semantic.Name,
-			decl->Semantic.Index, shader->selector->info.num_inputs,
+	interp_fs_input(ctx, input_index, semantic_name,
+			semantic_index, shader->selector->info.num_inputs,
 			shader->selector->info.colors_read, interp_param,
 			LLVMGetParam(main_fn, SI_PARAM_PRIM_MASK),
 			LLVMGetParam(main_fn, SI_PARAM_FRONT_FACE),
 			&out[0]);
 }
 
+static void declare_input_fs(
+	struct si_shader_context *ctx,
+	unsigned input_index,
+	const struct tgsi_full_declaration *decl,
+	LLVMValueRef out[4])
+{
+	si_llvm_load_input_fs(ctx, input_index, out);
+}
+
 static LLVMValueRef get_sample_id(struct si_shader_context *ctx)
 {
 	return unpack_param(ctx, SI_PARAM_ANCILLARY, 8, 4);
 }
 
 
 /**
  * Load a dword from a constant buffer.
  */
 static LLVMValueRef buffer_load_const(struct si_shader_context *ctx,
diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h
index 99d17c2..d4358bd 100644
--- a/src/gallium/drivers/radeonsi/si_shader_internal.h
+++ b/src/gallium/drivers/radeonsi/si_shader_internal.h
@@ -310,14 +310,18 @@ LLVMValueRef si_get_bounded_indirect_index(struct si_shader_context *ctx,
 
 LLVMTypeRef si_const_array(LLVMTypeRef elem_type, int num_elements);
 
 void si_shader_context_init_alu(struct lp_build_tgsi_context *bld_base);
 void si_shader_context_init_mem(struct si_shader_context *ctx);
 
 void si_llvm_load_input_vs(
 	struct si_shader_context *ctx,
 	unsigned input_index,
 	LLVMValueRef out[4]);
+void si_llvm_load_input_fs(
+	struct si_shader_context *ctx,
+	unsigned input_index,
+	LLVMValueRef out[4]);
 
 bool si_nir_build_llvm(struct si_shader_context *ctx, struct nir_shader *nir);
 
 #endif
diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c b/src/gallium/drivers/radeonsi/si_shader_nir.c
index 8b8baac..01eac1c 100644
--- a/src/gallium/drivers/radeonsi/si_shader_nir.c
+++ b/src/gallium/drivers/radeonsi/si_shader_nir.c
@@ -313,31 +313,57 @@ void si_nir_scan_shader(const struct nir_shader *nir,
 	}
 }
 
 static void declare_nir_input_vs(struct si_shader_context *ctx,
 				 struct nir_variable *variable, unsigned rel,
 				 LLVMValueRef out[4])
 {
 	si_llvm_load_input_vs(ctx, variable->data.driver_location / 4 + rel, out);
 }
 
+static void declare_nir_input_fs(struct si_shader_context *ctx,
+				 struct nir_variable *variable, unsigned rel,
+				 unsigned *fs_attr_idx,
+				 LLVMValueRef out[4])
+{
+	unsigned slot = variable->data.location + rel;
+
+	assert(variable->data.location >= VARYING_SLOT_VAR0 || rel == 0);
+
+	if (slot == VARYING_SLOT_POS) {
+		out[0] = LLVMGetParam(ctx->main_fn, SI_PARAM_POS_X_FLOAT);
+		out[1] = LLVMGetParam(ctx->main_fn, SI_PARAM_POS_Y_FLOAT);
+		out[2] = LLVMGetParam(ctx->main_fn, SI_PARAM_POS_Z_FLOAT);
+		out[3] = ac_build_fdiv(&ctx->ac, ctx->ac.f32_1,
+				LLVMGetParam(ctx->main_fn, SI_PARAM_POS_W_FLOAT));
+		return;
+	}
+
+	si_llvm_load_input_fs(ctx, *fs_attr_idx, out);
+	(*fs_attr_idx)++;
+}
+
 bool si_nir_build_llvm(struct si_shader_context *ctx, struct nir_shader *nir)
 {
+	unsigned fs_attr_idx = 0;
 	nir_foreach_variable(variable, &nir->inputs) {
 		unsigned attrib_count = glsl_count_attribute_slots(variable->type,
 								   nir->stage == MESA_SHADER_VERTEX);
 		unsigned input_idx = variable->data.driver_location;
 
 		for (unsigned i = 0; i < attrib_count; ++i) {
 			LLVMValueRef data[4];
 
-			declare_nir_input_vs(ctx, variable, i, data);
+			if (nir->stage == MESA_SHADER_VERTEX)
+				declare_nir_input_vs(ctx, variable, i, data);
+			else if (nir->stage == MESA_SHADER_FRAGMENT)
+				declare_nir_input_fs(ctx, variable, i, &fs_attr_idx, data);
 
 			for (unsigned chan = 0; chan < 4; chan++) {
 				ctx->inputs[input_idx + chan] =
 					LLVMBuildBitCast(ctx->ac.builder, data[chan], ctx->ac.i32, "");
 			}
 		}
 	}
 
 	ctx->abi.inputs = &ctx->inputs[0];
 
-- 
2.9.3



More information about the mesa-dev mailing list