diff options
| author | Corbin Simpson <MostAwesomeDude@gmail.com> | 2010-04-12 02:40:40 -0700 | 
|---|---|---|
| committer | Corbin Simpson <MostAwesomeDude@gmail.com> | 2010-04-12 03:03:37 -0700 | 
| commit | f0b8677d57f32ea66c997dfc8c3bf06987c6ebcd (patch) | |
| tree | 36b2f9fcd368081f755608bf6847cbaaf48be672 /src/mesa | |
| parent | a57dcef636d2a9d0fa77a7ff485bd1ed9018b64c (diff) | |
r300/compiler: Comment code, add much better mirror maths.
Diffstat (limited to 'src/mesa')
| -rw-r--r-- | src/mesa/drivers/dri/r300/compiler/r300_fragprog.c | 81 | ||||
| -rw-r--r-- | 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 4a60d05cd7..50360de3a3 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 +				 */ -			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_MUL;  				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] = 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); + +				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; +			}  		}  	} diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c index c20ee90fcd..647bc87d0b 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; +			}  		}  	} | 
