Mesa (master): radeonsi: Handle TGSI_SEMANTIC_BCOLOR.

Michel Dänzer daenzer at kemper.freedesktop.org
Fri Oct 26 13:56:25 UTC 2012


Module: Mesa
Branch: master
Commit: 691f08dbeaeb71bfa26784e7ec18aa07e34893fb
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=691f08dbeaeb71bfa26784e7ec18aa07e34893fb

Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Sep  6 18:03:38 2012 +0200

radeonsi: Handle TGSI_SEMANTIC_BCOLOR.

Put the back face colour right after the front face colour in the LDS parameter
space.

Fixes 18 piglit tests related to two sided lighting.

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
Reviewed-by: Tom Stellard <thomas.stellard at amd.com>

---

 src/gallium/drivers/radeonsi/radeonsi_shader.c |   60 ++++++++++++++++++++---
 src/gallium/drivers/radeonsi/radeonsi_shader.h |    1 +
 src/gallium/drivers/radeonsi/si_state.c        |    9 ++-
 src/gallium/drivers/radeonsi/si_state.h        |    1 +
 src/gallium/drivers/radeonsi/si_state_draw.c   |   19 ++++++--
 5 files changed, 75 insertions(+), 15 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.c b/src/gallium/drivers/radeonsi/radeonsi_shader.c
index 3275512..aec5c2e 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_shader.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_shader.c
@@ -320,16 +320,59 @@ static void declare_input_fs(
 	}
 
 	/* XXX: Could there be more than TGSI_NUM_CHANNELS (4) ? */
-	for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+	if (decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
+	    si_shader_ctx->key.color_two_side) {
 		LLVMValueRef args[3];
-		LLVMValueRef llvm_chan = lp_build_const_int32(gallivm, chan);
-		unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan);
-		args[0] = llvm_chan;
-		args[1] = attr_number;
+		LLVMValueRef face, is_face_positive;
+		LLVMValueRef back_attr_number =
+			lp_build_const_int32(gallivm,
+					     shader->input[input_index].param_offset + 1);
+
+		face = build_intrinsic(gallivm->builder,
+				       "llvm.SI.fs.read.face",
+				       input_type,
+				       NULL, 0, LLVMReadNoneAttribute);
+		is_face_positive = LLVMBuildFCmp(gallivm->builder,
+						 LLVMRealUGT, face,
+						 lp_build_const_float(gallivm, 0.0f),
+						 "");
+
 		args[2] = params;
-		si_shader_ctx->radeon_bld.inputs[soa_index] =
-			build_intrinsic(base->gallivm->builder, intr_name,
-				input_type, args, 3, LLVMReadOnlyAttribute);
+		for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+			LLVMValueRef llvm_chan = lp_build_const_int32(gallivm, chan);
+			unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan);
+			LLVMValueRef front, back;
+
+			args[0] = llvm_chan;
+			args[1] = attr_number;
+			front = build_intrinsic(base->gallivm->builder, intr_name,
+						input_type, args, 3, LLVMReadOnlyAttribute);
+
+			args[1] = back_attr_number;
+			back = build_intrinsic(base->gallivm->builder, intr_name,
+					       input_type, args, 3, LLVMReadOnlyAttribute);
+
+			si_shader_ctx->radeon_bld.inputs[soa_index] =
+				LLVMBuildSelect(gallivm->builder,
+						is_face_positive,
+						front,
+						back,
+						"");
+		}
+
+		shader->ninterp++;
+	} else {
+		for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+			LLVMValueRef args[3];
+			LLVMValueRef llvm_chan = lp_build_const_int32(gallivm, chan);
+			unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan);
+			args[0] = llvm_chan;
+			args[1] = attr_number;
+			args[2] = params;
+			si_shader_ctx->radeon_bld.inputs[soa_index] =
+				build_intrinsic(base->gallivm->builder, intr_name,
+						input_type, args, 3, LLVMReadOnlyAttribute);
+		}
 	}
 }
 
@@ -530,6 +573,7 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
 				break;
 			case TGSI_SEMANTIC_COLOR:
 				if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX) {
+			case TGSI_SEMANTIC_BCOLOR:
 					target = V_008DFC_SQ_EXP_PARAM + param_count;
 					shader->output[i].param_offset = param_count;
 					param_count++;
diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.h b/src/gallium/drivers/radeonsi/radeonsi_shader.h
index 9d382d5..23030bc 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_shader.h
+++ b/src/gallium/drivers/radeonsi/radeonsi_shader.h
@@ -80,6 +80,7 @@ struct si_shader {
 struct si_shader_key {
 	unsigned		export_16bpc:8;
 	unsigned		nr_cbufs:4;
+	unsigned		color_two_side:1;
 };
 
 struct si_pipe_shader {
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 20f4be3..66f0bd8 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -379,6 +379,8 @@ static void *si_create_rs_state(struct pipe_context *ctx,
 		return NULL;
 	}
 
+	rs->two_side = state->light_twoside;
+
 	polygon_dual_mode = (state->fill_front != PIPE_POLYGON_MODE_FILL ||
 				state->fill_back != PIPE_POLYGON_MODE_FILL);
 
@@ -1841,9 +1843,10 @@ static INLINE struct si_shader_key si_shader_selector_key(struct pipe_context *c
 		if (sel->fs_write_all)
 			key.nr_cbufs = rctx->framebuffer.nr_cbufs;
 		key.export_16bpc = rctx->export_16bpc;
-		/*if (rctx->queued.named.rasterizer)
-			  key.flatshade = rctx->queued.named.rasterizer->flatshade;*/
-		/*key.color_two_side |== rctx->two_side;*/
+		if (rctx->queued.named.rasterizer) {
+			key.color_two_side = rctx->queued.named.rasterizer->two_side;
+			/*key.flatshade = rctx->queued.named.rasterizer->flatshade;*/
+		}
 	}
 
 	return key;
diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index 136ac86..8f1ab43 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -43,6 +43,7 @@ struct si_state_viewport {
 struct si_state_rasterizer {
 	struct si_pm4_state	pm4;
 	bool			flatshade;
+	bool			two_side;
 	unsigned		sprite_coord_enable;
 	unsigned		pa_sc_line_stipple;
 	unsigned		pa_su_sc_mode_cntl;
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
index 629ec03..3ac80b0 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -328,11 +328,15 @@ static void si_update_spi_map(struct r600_context *rctx)
 	unsigned i, j, tmp;
 
 	for (i = 0; i < ps->ninput; i++) {
+		unsigned name = ps->input[i].name;
+		unsigned param_offset = ps->input[i].param_offset;
+
+bcolor:
 		tmp = 0;
 
 #if 0
 		/* XXX: Flat shading hangs the GPU */
-		if (ps->input[i].name == TGSI_SEMANTIC_POSITION ||
+		if (name == TGSI_SEMANTIC_POSITION ||
 		    ps->input[i].interpolate == TGSI_INTERPOLATE_CONSTANT ||
 		    (ps->input[i].interpolate == TGSI_INTERPOLATE_COLOR &&
 		     rctx->rasterizer && rctx->rasterizer->flatshade)) {
@@ -340,13 +344,13 @@ static void si_update_spi_map(struct r600_context *rctx)
 		}
 #endif
 
-		if (ps->input[i].name == TGSI_SEMANTIC_GENERIC &&
+		if (name == TGSI_SEMANTIC_GENERIC &&
 		    rctx->sprite_coord_enable & (1 << ps->input[i].sid)) {
 			tmp |= S_028644_PT_SPRITE_TEX(1);
 		}
 
 		for (j = 0; j < vs->noutput; j++) {
-			if (ps->input[i].name == vs->output[j].name &&
+			if (name == vs->output[j].name &&
 			    ps->input[i].sid == vs->output[j].sid) {
 				tmp |= S_028644_OFFSET(vs->output[j].param_offset);
 				break;
@@ -359,8 +363,15 @@ static void si_update_spi_map(struct r600_context *rctx)
 		}
 
 		si_pm4_set_reg(pm4,
-			       R_028644_SPI_PS_INPUT_CNTL_0 + ps->input[i].param_offset * 4,
+			       R_028644_SPI_PS_INPUT_CNTL_0 + param_offset * 4,
 			       tmp);
+
+		if (name == TGSI_SEMANTIC_COLOR &&
+		    rctx->ps_shader->current->key.color_two_side) {
+			name = TGSI_SEMANTIC_BCOLOR;
+			param_offset++;
+			goto bcolor;
+		}
 	}
 
 	si_pm4_set_state(rctx, spi, pm4);




More information about the mesa-commit mailing list