[Mesa-dev] [PATCH 89/92] ac/nir, radeonsi: add and use ac_shader_abi::param_frag_pos

Nicolai Hähnle nhaehnle at gmail.com
Mon Jun 26 14:19:18 UTC 2017


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

---
 src/amd/common/ac_nir_to_llvm.c          | 30 +++++++++++++++++++-----------
 src/amd/common/ac_shader_abi.h           |  1 +
 src/gallium/drivers/radeonsi/si_shader.c |  1 +
 3 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index 1cb920c..0457d43 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -60,20 +60,21 @@ struct ac_nir_context {
 
 	LLVMValueRef main_function;
 	LLVMBasicBlockRef continue_block;
 	LLVMBasicBlockRef break_block;
 
 	LLVMValueRef outputs[RADEON_LLVM_MAX_OUTPUTS * 4];
 
 	int num_locals;
 	LLVMValueRef *locals;
 
+	LLVMValueRef frag_pos[4];
 	LLVMValueRef ddxy_lds;
 
 	struct nir_to_llvm_context *nctx; /* TODO get rid of this */
 };
 
 struct nir_to_llvm_context {
 	struct ac_llvm_context ac;
 	const struct ac_nir_compiler_options *options;
 	struct ac_shader_variant_info *shader_info;
 	struct ac_shader_abi abi;
@@ -121,21 +122,20 @@ struct nir_to_llvm_context {
 
 	LLVMValueRef esgs_ring;
 	LLVMValueRef gsvs_ring;
 	LLVMValueRef hs_ring_tess_offchip;
 	LLVMValueRef hs_ring_tess_factor;
 
 	LLVMValueRef prim_mask;
 	LLVMValueRef sample_pos_offset;
 	LLVMValueRef persp_sample, persp_center, persp_centroid;
 	LLVMValueRef linear_sample, linear_center, linear_centroid;
-	LLVMValueRef frag_pos[4];
 
 	LLVMTypeRef i1;
 	LLVMTypeRef i8;
 	LLVMTypeRef i16;
 	LLVMTypeRef i32;
 	LLVMTypeRef i64;
 	LLVMTypeRef v2i32;
 	LLVMTypeRef v3i32;
 	LLVMTypeRef v4i32;
 	LLVMTypeRef v8i32;
@@ -822,24 +822,25 @@ static void create_function(struct nir_to_llvm_context *ctx)
 			add_user_sgpr_argument(&args, ctx->i32, &ctx->sample_pos_offset); /* sample position offset */
 		add_sgpr_argument(&args, ctx->i32, &ctx->prim_mask); /* prim mask */
 		add_vgpr_argument(&args, ctx->v2i32, &ctx->persp_sample); /* persp sample */
 		add_vgpr_argument(&args, ctx->v2i32, &ctx->persp_center); /* persp center */
 		add_vgpr_argument(&args, ctx->v2i32, &ctx->persp_centroid); /* persp centroid */
 		add_vgpr_argument(&args, ctx->v3i32, NULL); /* persp pull model */
 		add_vgpr_argument(&args, ctx->v2i32, &ctx->linear_sample); /* linear sample */
 		add_vgpr_argument(&args, ctx->v2i32, &ctx->linear_center); /* linear center */
 		add_vgpr_argument(&args, ctx->v2i32, &ctx->linear_centroid); /* linear centroid */
 		add_vgpr_argument(&args, ctx->f32, NULL);  /* line stipple tex */
-		add_vgpr_argument(&args, ctx->f32, &ctx->frag_pos[0]);  /* pos x float */
-		add_vgpr_argument(&args, ctx->f32, &ctx->frag_pos[1]);  /* pos y float */
-		add_vgpr_argument(&args, ctx->f32, &ctx->frag_pos[2]);  /* pos z float */
-		add_vgpr_argument(&args, ctx->f32, &ctx->frag_pos[3]);  /* pos w float */
+		ctx->abi.param_frag_pos =
+			add_vgpr_argument(&args, ctx->f32, NULL);  /* pos x float */
+		add_vgpr_argument(&args, ctx->f32, NULL);  /* pos y float */
+		add_vgpr_argument(&args, ctx->f32, NULL);  /* pos z float */
+		add_vgpr_argument(&args, ctx->f32, NULL);  /* pos w float */
 		ctx->abi.param_front_face =
 			add_vgpr_argument(&args, ctx->i32, NULL);  /* front face */
 		ctx->abi.param_ancillary =
 			add_vgpr_argument(&args, ctx->i32, NULL);  /* ancillary */
 		ctx->abi.param_sample_coverage =
 			add_vgpr_argument(&args, ctx->i32, NULL);  /* sample coverage */
 		add_vgpr_argument(&args, ctx->i32, NULL);  /* fixed pt */
 		break;
 	default:
 		unreachable("Shader stage not implemented");
@@ -3244,21 +3245,21 @@ static LLVMValueRef get_image_coords(struct ac_nir_context *ctx,
 		int chan;
 
 		fmask_load_address[0] = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[0], "");
 		fmask_load_address[1] = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[1], "");
 		if (glsl_sampler_type_is_array(type))
 			fmask_load_address[2] = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[2], "");
 		else
 			fmask_load_address[2] = NULL;
 		if (add_frag_pos) {
 			for (chan = 0; chan < 2; ++chan)
-				fmask_load_address[chan] = LLVMBuildAdd(ctx->ac.builder, fmask_load_address[chan], LLVMBuildFPToUI(ctx->ac.builder, ctx->nctx->frag_pos[chan], ctx->ac.i32, ""), "");
+				fmask_load_address[chan] = LLVMBuildAdd(ctx->ac.builder, fmask_load_address[chan], LLVMBuildFPToUI(ctx->ac.builder, ctx->frag_pos[chan], ctx->ac.i32, ""), "");
 		}
 		sample_index = adjust_sample_index_using_fmask(&ctx->ac,
 							       fmask_load_address[0],
 							       fmask_load_address[1],
 							       fmask_load_address[2],
 							       sample_index,
 							       get_sampler_desc(ctx, instr->variables[0], AC_DESC_FMASK, true, false));
 	}
 	if (count == 1) {
 		if (instr->src[0].ssa->num_components)
@@ -3268,21 +3269,21 @@ static LLVMValueRef get_image_coords(struct ac_nir_context *ctx,
 	} else {
 		int chan;
 		if (is_ms)
 			count--;
 		for (chan = 0; chan < count; ++chan) {
 			coords[chan] = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[chan], "");
 		}
 
 		if (add_frag_pos) {
 			for (chan = 0; chan < count; ++chan)
-				coords[chan] = LLVMBuildAdd(ctx->ac.builder, coords[chan], LLVMBuildFPToUI(ctx->ac.builder, ctx->nctx->frag_pos[chan], ctx->ac.i32, ""), "");
+				coords[chan] = LLVMBuildAdd(ctx->ac.builder, coords[chan], LLVMBuildFPToUI(ctx->ac.builder, ctx->frag_pos[chan], ctx->ac.i32, ""), "");
 		}
 		if (is_ms) {
 			coords[count] = sample_index;
 			count++;
 		}
 
 		if (count == 3) {
 			coords[3] = LLVMGetUndef(ctx->ac.i32);
 			count = 4;
 		}
@@ -3672,21 +3673,21 @@ static LLVMValueRef load_sample_position(struct nir_to_llvm_context *ctx,
 
 	ptr = LLVMBuildBitCast(ctx->builder, ptr,
 			       const_array(ctx->v2f32, 64), "");
 
 	sample_id = LLVMBuildAdd(ctx->builder, sample_id, ctx->sample_pos_offset, "");
 	result = ac_build_indexed_load(&ctx->ac, ptr, sample_id, false);
 
 	return result;
 }
 
-static LLVMValueRef load_sample_pos(struct nir_to_llvm_context *ctx)
+static LLVMValueRef load_sample_pos(struct ac_nir_context *ctx)
 {
 	LLVMValueRef values[2];
 
 	values[0] = emit_ffract(&ctx->ac, ctx->frag_pos[0]);
 	values[1] = emit_ffract(&ctx->ac, ctx->frag_pos[1]);
 	return ac_build_gather_values(&ctx->ac, values, 2);
 }
 
 static LLVMValueRef visit_interp(struct nir_to_llvm_context *ctx,
 				 const nir_intrinsic_instr *instr)
@@ -3930,21 +3931,21 @@ static void visit_intrinsic(struct ac_nir_context *ctx,
 			result = ctx->nctx->tes_patch_id;
 		else
 			fprintf(stderr, "Unknown primitive id intrinsic: %d", ctx->stage);
 		break;
 	case nir_intrinsic_load_sample_id:
 		result = unpack_param(ctx->nctx,
 				      LLVMGetParam(ctx->main_function, ctx->abi->param_ancillary),
 				      8, 4);
 		break;
 	case nir_intrinsic_load_sample_pos:
-		result = load_sample_pos(ctx->nctx);
+		result = load_sample_pos(ctx);
 		break;
 	case nir_intrinsic_load_sample_mask_in:
 		result = LLVMGetParam(ctx->main_function, ctx->abi->param_sample_coverage);
 		break;
 	case nir_intrinsic_load_front_face:
 		result = LLVMGetParam(ctx->main_function, ctx->abi->param_front_face);
 		break;
 	case nir_intrinsic_load_instance_id:
 		result = LLVMGetParam(ctx->main_function, ctx->abi->param_instance_id);
 		break;
@@ -4940,23 +4941,25 @@ handle_fs_inputs_pre(struct nir_to_llvm_context *ctx,
 		    i == VARYING_SLOT_PRIMITIVE_ID || i == VARYING_SLOT_LAYER) {
 			interp_param = *inputs;
 			interp_fs_input(ctx, index, interp_param, ctx->prim_mask,
 					inputs);
 
 			if (!interp_param)
 				ctx->shader_info->fs.flat_shaded_mask |= 1u << index;
 			++index;
 		} else if (i == VARYING_SLOT_POS) {
 			for(int i = 0; i < 3; ++i)
-				inputs[i] = ctx->frag_pos[i];
+				inputs[i] = LLVMGetParam(ctx->main_function, ctx->abi.param_frag_pos + i);
 
-			inputs[3] = ac_build_fdiv(&ctx->ac, ctx->f32one, ctx->frag_pos[3]);
+			inputs[3] = ac_build_fdiv(&ctx->ac, ctx->f32one,
+						  LLVMGetParam(ctx->main_function,
+							       ctx->abi.param_frag_pos + 3));
 		}
 	}
 	ctx->shader_info->fs.num_interp = index;
 	if (ctx->input_mask & (1 << VARYING_SLOT_PNTC))
 		ctx->shader_info->fs.has_pcoord = true;
 	if (ctx->input_mask & (1 << VARYING_SLOT_PRIMITIVE_ID))
 		ctx->shader_info->fs.prim_id_input = true;
 	if (ctx->input_mask & (1 << VARYING_SLOT_LAYER))
 		ctx->shader_info->fs.layer_input = true;
 	ctx->shader_info->fs.input_mask = ctx->input_mask >> VARYING_SLOT_VAR0;
@@ -6016,20 +6019,25 @@ void ac_nir_translate(struct ac_llvm_context *ac, struct ac_shader_abi *abi,
 
 	ctx.defs = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
 	                                   _mesa_key_pointer_equal);
 	ctx.phis = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
 	                                   _mesa_key_pointer_equal);
 
 	func = (struct nir_function *)exec_list_get_head(&nir->functions);
 
 	setup_locals(&ctx, func);
 
+	if (nir->stage == MESA_SHADER_FRAGMENT) {
+		for (unsigned i = 0; i < 4; ++i)
+			ctx.frag_pos[i] = LLVMGetParam(ctx.main_function, ctx.abi->param_frag_pos + i);
+	}
+
 	visit_cf_list(&ctx, &func->impl->body);
 	phi_post_pass(&ctx);
 
 	ctx.abi->emit_outputs(ctx.abi, RADEON_LLVM_MAX_OUTPUTS,
 			      ctx.outputs);
 
 	free(ctx.locals);
 	ralloc_free(ctx.defs);
 	ralloc_free(ctx.phis);
 
diff --git a/src/amd/common/ac_shader_abi.h b/src/amd/common/ac_shader_abi.h
index 5caee91..9fc4390 100644
--- a/src/amd/common/ac_shader_abi.h
+++ b/src/amd/common/ac_shader_abi.h
@@ -35,20 +35,21 @@ enum ac_descriptor_type {
  * radv to share a compiler backend.
  */
 struct ac_shader_abi {
 	enum chip_class chip_class;
 
 	int param_base_vertex;
 	int param_start_instance;
 	int param_draw_id;
 	int param_vertex_id;
 	int param_instance_id;
+	int param_frag_pos;
 	int param_front_face;
 	int param_ancillary;
 	int param_sample_coverage;
 
 	/* For VS and PS: pre-loaded shader inputs.
 	 *
 	 * Currently only used for NIR shaders; indexed by variables'
 	 * driver_location.
 	 */
 	LLVMValueRef *inputs;
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 5e53797..91bc067 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -4453,20 +4453,21 @@ static void create_function(struct si_shader_context *ctx)
 		last_sgpr = SI_PARAM_PRIM_MASK;
 		params[SI_PARAM_PERSP_SAMPLE] = ctx->v2i32;
 		params[SI_PARAM_PERSP_CENTER] = ctx->v2i32;
 		params[SI_PARAM_PERSP_CENTROID] = ctx->v2i32;
 		params[SI_PARAM_PERSP_PULL_MODEL] = v3i32;
 		params[SI_PARAM_LINEAR_SAMPLE] = ctx->v2i32;
 		params[SI_PARAM_LINEAR_CENTER] = ctx->v2i32;
 		params[SI_PARAM_LINEAR_CENTROID] = ctx->v2i32;
 		params[SI_PARAM_LINE_STIPPLE_TEX] = ctx->f32;
 		params[SI_PARAM_POS_X_FLOAT] = ctx->f32;
+		ctx->abi.param_frag_pos = SI_PARAM_POS_X_FLOAT;
 		params[SI_PARAM_POS_Y_FLOAT] = ctx->f32;
 		params[SI_PARAM_POS_Z_FLOAT] = ctx->f32;
 		params[SI_PARAM_POS_W_FLOAT] = ctx->f32;
 		params[SI_PARAM_FRONT_FACE] = ctx->i32;
 		ctx->abi.param_front_face = SI_PARAM_FRONT_FACE;
 		shader->info.face_vgpr_index = 20;
 		params[SI_PARAM_ANCILLARY] = ctx->i32;
 		ctx->abi.param_ancillary = SI_PARAM_ANCILLARY;
 		params[SI_PARAM_SAMPLE_COVERAGE] = ctx->f32;
 		ctx->abi.param_sample_coverage = SI_PARAM_SAMPLE_COVERAGE;
-- 
2.9.3



More information about the mesa-dev mailing list