Mesa (master): r300/compiler: Comment code, add much better mirror maths.

Corbin Simpson csimpson at kemper.freedesktop.org
Mon Apr 12 10:03:45 UTC 2010


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

Author: Corbin Simpson <MostAwesomeDude at gmail.com>
Date:   Mon Apr 12 02:40:40 2010 -0700

r300/compiler: Comment code, add much better mirror maths.

---

 src/mesa/drivers/dri/r300/compiler/r300_fragprog.c |   81 ++++++++++++---
 src/mesa/drivers/dri/r300/compiler/r500_fragprog.c |  109 +++++++++++++++++---
 2 files changed, 161 insertions(+), 29 deletions(-)

diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
index 4a60d05..50360de 100644
--- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
+++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
@@ -142,6 +142,8 @@ int r300_transform_TEX(
 	/* Hardware uses [0..1]x[0..1] range for rectangle textures
 	 * instead of [0..Width]x[0..Height].
 	 * Add a scaling instruction.
+	 *
+	 * See also comments in this same section in r500_fragprog.c
 	 */
 	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
 		(inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
@@ -166,35 +168,86 @@ int r300_transform_TEX(
 
 			reset_srcreg(&inst->U.I.SrcReg[0]);
 			inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
-			inst->U.I.SrcReg[0].Index = inst_rect->U.I.DstReg.Index;
+			inst->U.I.SrcReg[0].Index = temp;
 
 			inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
 		}
 
 		if (compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot &&
 			wrapmode != RC_WRAP_NONE && wrapmode != RC_WRAP_CLAMP) {
-			/* Repeat, with optional mirror */
-			inst_rect = rc_insert_new_instruction(c, inst->Prev);
+			if (wrapmode == RC_WRAP_REPEAT) {
+				inst_rect = rc_insert_new_instruction(c, inst->Prev);
 
-			inst_rect->U.I.Opcode = RC_OPCODE_FRC;
-			inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
-			inst_rect->U.I.DstReg.Index = temp;
-			inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
+				inst_rect->U.I.Opcode = RC_OPCODE_FRC;
+				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.DstReg.Index = temp;
+				inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
+
+				reset_srcreg(&inst->U.I.SrcReg[0]);
+				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+				inst->U.I.SrcReg[0].Index = temp;
+			} else if (wrapmode == RC_WRAP_MIRROR) {
+				unsigned temp1;
+				/*
+				 * MUL temp0, abs(temp0), 0.5
+				 * FRC temp0, temp0
+				 * SGE temp1, temp0, 0.5
+				 * MAD temp0, neg(0.5), temp1, temp0
+				 * ADD temp0, temp0, temp0
+				 */
+
+				inst_rect = rc_insert_new_instruction(c, inst->Prev);
+
+				inst_rect->U.I.Opcode = RC_OPCODE_MUL;
+				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.DstReg.Index = temp;
+				inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
+				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
+
+				inst_rect = rc_insert_new_instruction(c, inst->Prev);
+
+				inst_rect->U.I.Opcode = RC_OPCODE_FRC;
+				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.DstReg.Index = temp;
+				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.SrcReg[0].Index = temp;
+
+				temp1 = rc_find_free_temporary(c);
+				inst_rect = rc_insert_new_instruction(c, inst->Prev);
+
+				inst_rect->U.I.Opcode = RC_OPCODE_SGE;
+				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.DstReg.Index = temp1;
+				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.SrcReg[0].Index = temp;
+				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
 
-			if (wrapmode == RC_WRAP_MIRROR) {
 				inst_rect = rc_insert_new_instruction(c, inst->Prev);
 
-				inst_rect->U.I.Opcode = RC_OPCODE_SUB;
+				inst_rect->U.I.Opcode = RC_OPCODE_MAD;
 				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
 				inst_rect->U.I.DstReg.Index = temp;
-				inst_rect->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_1111;
+				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.SrcReg[0].Index = temp1;
+				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
+				inst_rect->U.I.SrcReg[1].Negate = 1;
+				inst_rect->U.I.SrcReg[2].File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.SrcReg[2].Index = temp;
+
+				inst_rect = rc_insert_new_instruction(c, inst->Prev);
+
+				inst_rect->U.I.Opcode = RC_OPCODE_ADD;
+				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.DstReg.Index = temp;
+				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.SrcReg[0].Index = temp;
 				inst_rect->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
 				inst_rect->U.I.SrcReg[1].Index = temp;
-			}
 
-			reset_srcreg(&inst->U.I.SrcReg[0]);
-			inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
-			inst->U.I.SrcReg[0].Index = inst_rect->U.I.DstReg.Index;
+				reset_srcreg(&inst->U.I.SrcReg[0]);
+				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+				inst->U.I.SrcReg[0].Index = temp;
+			}
 		}
 	}
 
diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
index c20ee90..647bc87 100644
--- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
+++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
@@ -138,7 +138,36 @@ int r500_transform_TEX(
 		}
 	}
 
-	/* Texture wrap modes don't work on NPOT textures or texrects. */
+	/* Texture wrap modes don't work on NPOT textures or texrects.
+	 *
+	 * The game plan is simple. We have two flags, fake_npot and
+	 * non_normalized_coords, as well as a tex target. The RECT tex target
+	 * will make the emitted code use non-scaled texcoords.
+	 *
+	 * Non-wrapped/clamped texcoords with NPOT are free in HW. Repeat and
+	 * mirroring are not. If we need to repeat, we do:
+	 *
+	 * MUL temp, texcoord, <scaling factor constant>
+	 * FRC temp, temp ; Discard integer portion of coords
+	 *
+	 * This gives us coords in [0, 1].
+	 *
+	 * Mirroring is trickier. We're going to start out like repeat:
+	 *
+	 * MUL temp0, texcoord, <scaling factor constant> ; De-mirror across axes
+	 * MUL temp0, abs(temp0), 0.5 ; Pattern repeats in [0, 2]
+	 *                            ; so scale to [0, 1]
+	 * FRC temp0, temp0 ; Make the pattern repeat
+	 * SGE temp1, temp0, 0.5 ; Select components that need to be "reflected"
+	 *                       ; across the mirror
+	 * MAD temp0, neg(0.5), temp1, temp0 ; Add -0.5 to the
+	 *                                   ; selected components
+	 * ADD temp0, temp0, temp0 ; Poor man's 2x to undo earlier MUL
+	 *
+	 * This gives us coords in [0, 1].
+	 *
+	 * ~ C.
+	 */
 	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
 		(inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
 			compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot ||
@@ -165,33 +194,83 @@ int r500_transform_TEX(
 
 				reset_srcreg(&inst->U.I.SrcReg[0]);
 				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
-				inst->U.I.SrcReg[0].Index = inst_rect->U.I.DstReg.Index;
+				inst->U.I.SrcReg[0].Index = temp;
 
 				inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
 			}
 
-			/* Repeat, with optional mirror */
-			inst_rect = rc_insert_new_instruction(c, inst->Prev);
+			if (wrapmode == RC_WRAP_REPEAT) {
+				inst_rect = rc_insert_new_instruction(c, inst->Prev);
+
+				inst_rect->U.I.Opcode = RC_OPCODE_FRC;
+				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.DstReg.Index = temp;
+				inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
+
+				reset_srcreg(&inst->U.I.SrcReg[0]);
+				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+				inst->U.I.SrcReg[0].Index = temp;
+			} else if (wrapmode == RC_WRAP_MIRROR) {
+				unsigned temp1;
+				/*
+				 * MUL temp0, abs(temp0), 0.5
+				 * FRC temp0, temp0
+				 * SGE temp1, temp0, 0.5
+				 * MAD temp0, neg(0.5), temp1, temp0
+				 * ADD temp0, temp0, temp0
+				 */
+				inst_rect = rc_insert_new_instruction(c, inst->Prev);
 
-			inst_rect->U.I.Opcode = RC_OPCODE_FRC;
-			inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
-			inst_rect->U.I.DstReg.Index = temp;
-			inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
+				inst_rect->U.I.Opcode = RC_OPCODE_MUL;
+				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.DstReg.Index = temp;
+				inst_rect->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
+				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
 
-			if (wrapmode == RC_WRAP_MIRROR) {
 				inst_rect = rc_insert_new_instruction(c, inst->Prev);
 
-				inst_rect->U.I.Opcode = RC_OPCODE_SUB;
+				inst_rect->U.I.Opcode = RC_OPCODE_FRC;
 				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
 				inst_rect->U.I.DstReg.Index = temp;
-				inst_rect->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_1111;
+				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.SrcReg[0].Index = temp;
+
+				temp1 = rc_find_free_temporary(c);
+				inst_rect = rc_insert_new_instruction(c, inst->Prev);
+
+				inst_rect->U.I.Opcode = RC_OPCODE_SGE;
+				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.DstReg.Index = temp1;
+				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.SrcReg[0].Index = temp;
+				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
+
+				inst_rect = rc_insert_new_instruction(c, inst->Prev);
+
+				inst_rect->U.I.Opcode = RC_OPCODE_MAD;
+				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.DstReg.Index = temp;
+				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.SrcReg[0].Index = temp1;
+				inst_rect->U.I.SrcReg[1].Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_HALF);
+				inst_rect->U.I.SrcReg[1].Negate = 1;
+				inst_rect->U.I.SrcReg[2].File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.SrcReg[2].Index = temp;
+
+				inst_rect = rc_insert_new_instruction(c, inst->Prev);
+
+				inst_rect->U.I.Opcode = RC_OPCODE_ADD;
+				inst_rect->U.I.DstReg.File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.DstReg.Index = temp;
+				inst_rect->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+				inst_rect->U.I.SrcReg[0].Index = temp;
 				inst_rect->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
 				inst_rect->U.I.SrcReg[1].Index = temp;
-			}
 
-			reset_srcreg(&inst->U.I.SrcReg[0]);
-			inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
-			inst->U.I.SrcReg[0].Index = inst_rect->U.I.DstReg.Index;
+				reset_srcreg(&inst->U.I.SrcReg[0]);
+				inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+				inst->U.I.SrcReg[0].Index = temp;
+			}
 		}
 	}
 




More information about the mesa-commit mailing list