[Mesa-dev] [RFH PATCH] r600g: broken attempt to fix glsl-fs-shader-stencil-export

Dave Airlie airlied at gmail.com
Thu Jul 21 09:15:46 PDT 2011


From: Dave Airlie <airlied at redhat.com>

I've been hacking around trying to make this test work and discovered
writing some bits up at bit 16 of the exported word seems to act like
some sort of mask. However I've no idea what this is or why this fixes
this test. However it breaks the stencilreaddraw test in mesa-demos, which
means its not entirely correct. My current trend is to blame some float vs
int mixup somewhere, otherwise I'm pretty lost.

Maybe AMD guys could take a look when they resurface.

Dave.
---
 src/gallium/drivers/r600/r600_shader.c |   67 +++++++++++++++++++++++++++++---
 1 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 3e21ad1..1e1d964 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -734,6 +734,55 @@ static int r600_shader_from_tgsi(struct r600_pipe_context * rctx, struct r600_pi
 
 	noutput = shader->noutput;
 
+	/* fixup stencil export - stencil export seems to have
+	   some sort of mask expected in the 16-24 bits,
+	   this seems undocumented but the value doesn't get used
+	   unless these bits are there.
+	   - it also looks like we have to combine Z and stencil
+	     exports into a single GPR */
+	if (ctx.info.writes_stencil) {
+		int depth_idx = -1;
+		if (ctx.info.writes_z) {
+			for (i = 0; i < noutput; i++) {
+				if (shader->output[i].name == TGSI_SEMANTIC_POSITION) {
+					depth_idx = i;
+					break;
+				}
+			}
+		}
+		for (i = 0; i < noutput; i++) {
+			if (shader->output[i].name == TGSI_SEMANTIC_STENCIL) {
+				int j;
+				
+				struct r600_bc_alu alu;
+				float stencil_value = (255 << 16);
+				memset(&alu, 0, sizeof(struct r600_bc_alu));
+				alu.inst = BC_INST(ctx.bc, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD);
+				if (ctx.info.writes_z)
+					alu.dst.sel = shader->output[depth_idx].gpr;
+				else
+					alu.dst.sel = shader->output[i].gpr;
+				alu.dst.chan = 1;
+				alu.dst.write = 1;
+
+				alu.src[0].sel = shader->output[i].gpr;
+				alu.src[0].chan = 1;
+
+				alu.last = 1;
+
+				alu.src[1].sel = V_SQ_ALU_SRC_LITERAL;
+				alu.src[1].value = *(uint32_t *)&stencil_value;
+				
+				r = r600_bc_add_alu(ctx.bc, &alu);
+				if (r)
+					return r;
+
+				if (ctx.info.writes_z)
+					shader->output[i].gpr = shader->output[depth_idx].gpr;
+			}
+		}
+	}
+
 	/* clamp color outputs */
 	if (shader->clamp_color) {
 		for (i = 0; i < noutput; i++) {
@@ -817,17 +866,23 @@ static int r600_shader_from_tgsi(struct r600_pipe_context * rctx, struct r600_pi
 					j--;
 				}
 			} else if (shader->output[i].name == TGSI_SEMANTIC_POSITION) {
+
 				output[i + j].array_base = 61;
 				output[i + j].swizzle_x = 2;
-				output[i + j].swizzle_y = 7;
+				if (ctx.info.writes_stencil)
+					output[i + j].swizzle_y = 1;
+				else
+					output[i + j].swizzle_y = 7;
 				output[i + j].swizzle_z = output[i + j].swizzle_w = 7;
 				output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
 			} else if (shader->output[i].name == TGSI_SEMANTIC_STENCIL) {
-				output[i + j].array_base = 61;
-				output[i + j].swizzle_x = 7;
-				output[i + j].swizzle_y = 1;
-				output[i + j].swizzle_z = output[i + j].swizzle_w = 7;
-				output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
+				if (!ctx.info.writes_z) {
+					output[i + j].array_base = 61;
+					output[i + j].swizzle_x = 7;
+					output[i + j].swizzle_y = 1;
+					output[i + j].swizzle_z = output[i + j].swizzle_w = 7;
+					output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
+				}
 			} else {
 				R600_ERR("unsupported fragment output name %d\n", shader->output[i].name);
 				r = -EINVAL;
-- 
1.7.6



More information about the mesa-dev mailing list