[Mesa-dev] [PATCH 4/5] radeonsi: Handle TGSI_SEMANTIC_CLIPVERTEX

Michel Dänzer michel at daenzer.net
Fri May 17 02:27:47 PDT 2013


From: Michel Dänzer <michel.daenzer at amd.com>

17 more little piglits.

NOTE: This is a candidate for the 9.1 branch.
Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 src/gallium/drivers/radeonsi/radeonsi_pipe.h   |  1 -
 src/gallium/drivers/radeonsi/radeonsi_shader.c | 62 ++++++++++++++++++++++++++
 src/gallium/drivers/radeonsi/radeonsi_shader.h |  1 +
 src/gallium/drivers/radeonsi/si_state.c        | 10 ++++-
 src/gallium/drivers/radeonsi/si_state.h        |  1 +
 src/gallium/drivers/radeonsi/si_state_draw.c   | 19 +++++---
 6 files changed, 86 insertions(+), 8 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.h b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
index e50088f..3274049 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.h
+++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
@@ -146,7 +146,6 @@ struct r600_context {
 	struct pipe_framebuffer_state	framebuffer;
 	unsigned			pa_sc_line_stipple;
 	unsigned			pa_su_sc_mode_cntl;
-	unsigned			pa_cl_clip_cntl;
 	/* for saving when using blitter */
 	struct pipe_stencil_ref		stencil_ref;
 	struct si_pipe_shader_selector	*ps_shader;
diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.c b/src/gallium/drivers/radeonsi/radeonsi_shader.c
index e6ed545..484f7ec 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_shader.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_shader.c
@@ -554,6 +554,64 @@ static void si_alpha_test(struct lp_build_tgsi_context *bld_base,
 	}
 }
 
+static void si_llvm_emit_clipvertex(struct lp_build_tgsi_context * bld_base,
+				    unsigned index)
+{
+	struct si_shader_context *si_shader_ctx = si_shader_context(bld_base);
+	struct lp_build_context *base = &bld_base->base;
+	struct lp_build_context *uint = &si_shader_ctx->radeon_bld.soa.bld_base.uint_bld;
+	LLVMValueRef args[9];
+	unsigned reg_index;
+	unsigned chan;
+	unsigned const_chan;
+	LLVMValueRef out_elts[4];
+	LLVMValueRef base_elt;
+	LLVMValueRef ptr = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_CONST);
+	LLVMValueRef const_resource = build_indexed_load(si_shader_ctx, ptr, uint->one);
+
+	for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+		LLVMValueRef out_ptr = si_shader_ctx->radeon_bld.soa.outputs[index][chan];
+		out_elts[chan] = LLVMBuildLoad(base->gallivm->builder, out_ptr, "");
+	}
+
+	for (reg_index = 0; reg_index < 2; reg_index ++) {
+		args[5] =
+		args[6] =
+		args[7] =
+		args[8] = lp_build_const_float(base->gallivm, 0.0f);
+
+		/* Compute dot products of position and user clip plane vectors */
+		for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+			for (const_chan = 0; const_chan < TGSI_NUM_CHANNELS; const_chan++) {
+				args[0] = const_resource;
+				args[1] = lp_build_const_int32(base->gallivm,
+							       ((reg_index * 4 + chan) * 4 +
+								const_chan) * 4);
+				base_elt = build_intrinsic(base->gallivm->builder,
+							   "llvm.SI.load.const",
+							   base->elem_type,
+							   args, 2,
+							   LLVMReadNoneAttribute | LLVMNoUnwindAttribute);
+				args[5 + chan] =
+					lp_build_add(base, args[5 + chan],
+						     lp_build_mul(base, base_elt,
+								  out_elts[const_chan]));
+			}
+		}
+
+		args[0] = lp_build_const_int32(base->gallivm, 0xf);
+		args[1] = uint->zero;
+		args[2] = uint->zero;
+		args[3] = lp_build_const_int32(base->gallivm,
+					       V_008DFC_SQ_EXP_POS + 2 + reg_index);
+		args[4] = uint->zero;
+		lp_build_intrinsic(base->gallivm->builder,
+				   "llvm.SI.export",
+				   LLVMVoidTypeInContext(base->gallivm->context),
+				   args, 9);
+	}
+}
+
 /* XXX: This is partially implemented for VS only at this point.  It is not complete */
 static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
 {
@@ -642,6 +700,10 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
 					color_count++;
 				}
 				break;
+			case TGSI_SEMANTIC_CLIPVERTEX:
+				si_llvm_emit_clipvertex(bld_base, index);
+				shader->clip_dist_write = 0xFF;
+				continue;
 			case TGSI_SEMANTIC_FOG:
 			case TGSI_SEMANTIC_GENERIC:
 				target = V_008DFC_SQ_EXP_PARAM + param_count;
diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.h b/src/gallium/drivers/radeonsi/radeonsi_shader.h
index 667f2c3..01b8b5d 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_shader.h
+++ b/src/gallium/drivers/radeonsi/radeonsi_shader.h
@@ -113,6 +113,7 @@ struct si_shader {
 	bool			vs_out_misc_write;
 	bool			vs_out_point_size;
 	unsigned		nr_cbufs;
+	unsigned		clip_dist_write;
 };
 
 union si_shader_key {
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index de86b1e..dec535c 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -237,6 +237,7 @@ static void si_set_clip_state(struct pipe_context *ctx,
 {
 	struct r600_context *rctx = (struct r600_context *)ctx;
 	struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
+	struct pipe_constant_buffer cb;
 
 	if (pm4 == NULL)
 		return;
@@ -252,6 +253,13 @@ static void si_set_clip_state(struct pipe_context *ctx,
 			       fui(state->ucp[i][3]));
         }
 
+	cb.buffer = NULL;
+	cb.user_buffer = state->ucp;
+	cb.buffer_offset = 0;
+	cb.buffer_size = 4*4*8;
+	ctx->set_constant_buffer(ctx, PIPE_SHADER_VERTEX, 1, &cb);
+	pipe_resource_reference(&cb.buffer, NULL);
+
 	si_pm4_set_state(rctx, clip, pm4);
 }
 
@@ -387,6 +395,7 @@ static void *si_create_rs_state(struct pipe_context *ctx,
 	}
 
 	rs->two_side = state->light_twoside;
+	rs->clip_plane_enable = state->clip_plane_enable;
 
 	polygon_dual_mode = (state->fill_front != PIPE_POLYGON_MODE_FILL ||
 				state->fill_back != PIPE_POLYGON_MODE_FILL);
@@ -484,7 +493,6 @@ static void si_bind_rs_state(struct pipe_context *ctx, void *state)
 	rctx->sprite_coord_enable = rs->sprite_coord_enable;
 	rctx->pa_sc_line_stipple = rs->pa_sc_line_stipple;
 	rctx->pa_su_sc_mode_cntl = rs->pa_su_sc_mode_cntl;
-	rctx->pa_cl_clip_cntl = rs->pa_cl_clip_cntl;
 
 	si_pm4_bind_state(rctx, rasterizer, rs);
 	si_update_fb_rs_state(rctx);
diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index c49b029..7ce084e 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -49,6 +49,7 @@ struct si_state_rasterizer {
 	unsigned		pa_su_sc_mode_cntl;
 	unsigned		pa_cl_clip_cntl;
 	unsigned		pa_cl_vs_out_cntl;
+	unsigned		clip_plane_enable;
 	float			offset_units;
 	float			offset_scale;
 };
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
index 1c63b14..4380d2c 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -74,8 +74,12 @@ static void si_pipe_shader_vs(struct pipe_context *ctx, struct si_pipe_shader *s
 		       S_02870C_POS1_EXPORT_FORMAT(shader->shader.vs_out_misc_write ?
 						   V_02870C_SPI_SHADER_4COMP :
 						   V_02870C_SPI_SHADER_NONE) |
-		       S_02870C_POS2_EXPORT_FORMAT(V_02870C_SPI_SHADER_NONE) |
-		       S_02870C_POS3_EXPORT_FORMAT(V_02870C_SPI_SHADER_NONE));
+		       S_02870C_POS2_EXPORT_FORMAT((shader->shader.clip_dist_write & 0x0F) ?
+						   V_02870C_SPI_SHADER_4COMP :
+						   V_02870C_SPI_SHADER_NONE) |
+		       S_02870C_POS3_EXPORT_FORMAT((shader->shader.clip_dist_write & 0xF0) ?
+						   V_02870C_SPI_SHADER_4COMP :
+						   V_02870C_SPI_SHADER_NONE));
 
 	va = r600_resource_va(ctx->screen, (void *)shader->bo);
 	si_pm4_add_bo(pm4, shader->bo, RADEON_USAGE_READ);
@@ -306,10 +310,13 @@ static bool si_update_draw_info_state(struct r600_context *rctx,
         }
 	si_pm4_set_reg(pm4, R_02881C_PA_CL_VS_OUT_CNTL,
 		       S_02881C_USE_VTX_POINT_SIZE(vs->vs_out_point_size) |
-		       S_02881C_VS_OUT_MISC_VEC_ENA(vs->vs_out_misc_write)
-		       /*| (rctx->rasterizer->clip_plane_enable &
-		       rctx->vs_shader->shader.clip_dist_write)*/);
-	si_pm4_set_reg(pm4, R_028810_PA_CL_CLIP_CNTL, rctx->pa_cl_clip_cntl
+		       S_02881C_VS_OUT_CCDIST0_VEC_ENA((vs->clip_dist_write & 0x0F) != 0) |
+		       S_02881C_VS_OUT_CCDIST1_VEC_ENA((vs->clip_dist_write & 0xF0) != 0) |
+		       S_02881C_VS_OUT_MISC_VEC_ENA(vs->vs_out_misc_write) |
+		       (rctx->queued.named.rasterizer->clip_plane_enable &
+			vs->clip_dist_write));
+	si_pm4_set_reg(pm4, R_028810_PA_CL_CLIP_CNTL,
+		       rctx->queued.named.rasterizer->pa_cl_clip_cntl
 			/*| (rctx->vs_shader->shader.clip_dist_write ||
 			rctx->vs_shader->shader.vs_prohibit_ucps ?
 			0 : rctx->rasterizer->clip_plane_enable & 0x3F)*/);
-- 
1.8.3.rc1



More information about the mesa-dev mailing list