[Mesa-dev] [PATCH 3/6] radeonsi: Flesh out support for depth/stencil exports from the pixel shader.

Michel Dänzer michel at daenzer.net
Thu Nov 22 09:57:34 PST 2012


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

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 src/gallium/drivers/radeonsi/radeonsi_shader.c |   62 ++++++++++++++++++++++--
 src/gallium/drivers/radeonsi/si_state_draw.c   |   13 +++--
 2 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.c b/src/gallium/drivers/radeonsi/radeonsi_shader.c
index 21e9018..00149ba 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_shader.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_shader.c
@@ -587,14 +587,15 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
 	struct lp_build_context * uint =
 				&si_shader_ctx->radeon_bld.soa.bld_base.uint_bld;
 	struct tgsi_parse_context *parse = &si_shader_ctx->parse;
+	LLVMValueRef args[9];
 	LLVMValueRef last_args[9] = { 0 };
 	unsigned color_count = 0;
 	unsigned param_count = 0;
+	int depth_index = -1, stencil_index = -1;
 
 	while (!tgsi_parse_end_of_tokens(parse)) {
 		struct tgsi_full_declaration *d =
 					&parse->FullToken.FullDeclaration;
-		LLVMValueRef args[9];
 		unsigned target;
 		unsigned index;
 		int i;
@@ -626,9 +627,18 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
 		for (index = d->Range.First; index <= d->Range.Last; index++) {
 			/* Select the correct target */
 			switch(d->Semantic.Name) {
-			case TGSI_SEMANTIC_PSIZE:
 			case TGSI_SEMANTIC_POSITION:
-				target = V_008DFC_SQ_EXP_POS;
+				if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX) {
+			case TGSI_SEMANTIC_PSIZE:
+					target = V_008DFC_SQ_EXP_POS;
+				} else {
+			case TGSI_SEMANTIC_STENCIL:
+					if (d->Semantic.Name == TGSI_SEMANTIC_STENCIL)
+						stencil_index = index;
+					else
+						depth_index = index;
+					continue;
+				}
 				break;
 			case TGSI_SEMANTIC_COLOR:
 				if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX) {
@@ -681,6 +691,52 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
 		}
 	}
 
+	if (depth_index >= 0 || stencil_index >= 0) {
+		LLVMValueRef out_ptr;
+		unsigned mask = 0;
+
+		/* Specify the target we are exporting */
+		args[3] = lp_build_const_int32(base->gallivm, V_008DFC_SQ_EXP_MRTZ);
+
+		if (depth_index >= 0) {
+			out_ptr = si_shader_ctx->radeon_bld.soa.outputs[depth_index][2];
+			args[5] = LLVMBuildLoad(base->gallivm->builder, out_ptr, "");
+			mask |= 0x1;
+
+			if (stencil_index < 0) {
+				args[6] =
+				args[7] =
+				args[8] = args[5];
+			}
+		}
+
+		if (stencil_index >= 0) {
+			out_ptr = si_shader_ctx->radeon_bld.soa.outputs[stencil_index][1];
+			args[7] =
+			args[8] =
+			args[6] = LLVMBuildLoad(base->gallivm->builder, out_ptr, "");
+			mask |= 0x2;
+
+			if (depth_index < 0)
+				args[5] = args[6];
+		}
+
+		/* Specify which components to enable */
+		args[0] = lp_build_const_int32(base->gallivm, mask);
+
+		args[1] =
+		args[2] =
+		args[4] = uint->zero;
+
+		if (last_args[0])
+			lp_build_intrinsic(base->gallivm->builder,
+					   "llvm.SI.export",
+					   LLVMVoidTypeInContext(base->gallivm->context),
+					   args, 9);
+		else
+			memcpy(last_args, args, sizeof(args));
+	}
+
 	if (!last_args[0]) {
 		assert(si_shader_ctx->type == TGSI_PROCESSOR_FRAGMENT);
 
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
index b608f20..257bf1e 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -100,7 +100,7 @@ static void si_pipe_shader_ps(struct pipe_context *ctx, struct si_pipe_shader *s
 	unsigned num_sgprs, num_user_sgprs;
 	boolean have_linear = FALSE, have_centroid = FALSE, have_perspective = FALSE;
 	unsigned fragcoord_interp_mode = 0;
-	unsigned spi_baryc_cntl, spi_ps_input_ena;
+	unsigned spi_baryc_cntl, spi_ps_input_ena, spi_shader_z_format;
 	uint64_t va;
 
 	si_pm4_delete_state(rctx, ps, shader->pm4);
@@ -145,7 +145,7 @@ static void si_pipe_shader_ps(struct pipe_context *ctx, struct si_pipe_shader *s
 		if (shader->shader.output[i].name == TGSI_SEMANTIC_POSITION)
 			db_shader_control |= S_02880C_Z_EXPORT_ENABLE(1);
 		if (shader->shader.output[i].name == TGSI_SEMANTIC_STENCIL)
-			db_shader_control |= 0; // XXX OP_VAL or TEST_VAL?
+			db_shader_control |= S_02880C_STENCIL_TEST_VAL_EXPORT_ENABLE(1);
 	}
 	if (shader->shader.uses_kill || shader->key.alpha_func != PIPE_FUNC_ALWAYS)
 		db_shader_control |= S_02880C_KILL_ENABLE(1);
@@ -195,8 +195,13 @@ static void si_pipe_shader_ps(struct pipe_context *ctx, struct si_pipe_shader *s
 	si_pm4_set_reg(pm4, R_0286D0_SPI_PS_INPUT_ADDR, spi_ps_input_ena);
 	si_pm4_set_reg(pm4, R_0286D8_SPI_PS_IN_CONTROL, spi_ps_in_control);
 
-	/* XXX: Depends on Z buffer format? */
-	si_pm4_set_reg(pm4, R_028710_SPI_SHADER_Z_FORMAT, 0);
+	if (G_02880C_STENCIL_TEST_VAL_EXPORT_ENABLE(db_shader_control))
+		spi_shader_z_format = V_028710_SPI_SHADER_32_GR;
+	else if (G_02880C_Z_EXPORT_ENABLE(db_shader_control))
+		spi_shader_z_format = V_028710_SPI_SHADER_32_R;
+	else
+		spi_shader_z_format = 0;
+	si_pm4_set_reg(pm4, R_028710_SPI_SHADER_Z_FORMAT, spi_shader_z_format);
 
 	va = r600_resource_va(ctx->screen, (void *)shader->bo);
 	si_pm4_add_bo(pm4, shader->bo, RADEON_USAGE_READ);
-- 
1.7.10.4



More information about the mesa-dev mailing list