From 82f8e43bfa27b0318b01674e2a273c06becae263 Mon Sep 17 00:00:00 2001
From: Marek Olšák <maraeo@gmail.com>
Date: Tue, 28 Sep 2010 02:20:26 +0200
Subject: r300g: code cleanups

Some random stuff I had here.

1) Fixed some misleading comments.
2) Removed fake_npot, since it's redundant.
3) lower_texture_rect -> scale_texcoords
4) Reordered and reindented some TEX transform code.
---
 src/mesa/drivers/dri/r300/compiler/radeon_code.h   |  16 +-
 .../drivers/dri/r300/compiler/radeon_program_tex.c | 265 ++++++++++-----------
 2 files changed, 131 insertions(+), 150 deletions(-)

(limited to 'src/mesa')

diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_code.h b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
index f76676fae8e..53cc1bd77e9 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_code.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
@@ -126,11 +126,7 @@ struct r300_fragment_program_external_state {
 	struct {
 		/**
 		 * If the sampler is used as a shadow sampler,
-		 * this field is:
-		 *  0 - GL_LUMINANCE
-		 *  1 - GL_INTENSITY
-		 *  2 - GL_ALPHA
-		 * depending on the depth texture mode.
+		 * this field contains swizzle depending on the depth texture mode.
 		 */
 		unsigned depth_texture_swizzle:12;
 
@@ -150,13 +146,9 @@ struct r300_fragment_program_external_state {
 		unsigned compare_mode_enabled : 1;
 
 		/**
-		 * If the sampler needs to fake NPOT, this field is set.
-		 */
-		unsigned fake_npot : 1;
-
-		/**
-		 * If the sampler will recieve non-normalized coords,
-		 * this field is set.
+		 * If the sampler will receive non-normalized coords,
+		 * this field is set. The scaling factor is given by
+		 * RC_STATE_R300_TEXRECT_FACTOR.
 		 */
 		unsigned non_normalized_coords : 1;
 
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
index ddce590ee66..7ce5fb8639f 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2010 Corbin Simpson
+ * Copyright (C) 2010 Marek Olšák <maraeo@gmail.com>
  *
  * All Rights Reserved.
  *
@@ -46,31 +47,28 @@ static struct rc_src_register shadow_ambient(struct r300_fragment_program_compil
 	return reg;
 }
 
-static void lower_texture_rect(struct r300_fragment_program_compiler *compiler,
-							   struct rc_instruction *inst)
+static void scale_texcoords(struct r300_fragment_program_compiler *compiler,
+			    struct rc_instruction *inst,
+			    unsigned state_constant)
 {
-	struct rc_instruction *inst_rect;
-	unsigned temp = rc_find_free_temporary(&compiler->Base);
+	struct rc_instruction *inst_mov;
 
-	if (inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
-		compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords) {
-		inst_rect = rc_insert_new_instruction(&compiler->Base, inst->Prev);
+	unsigned temp = rc_find_free_temporary(&compiler->Base);
 
-		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].File = RC_FILE_CONSTANT;
-		inst_rect->U.I.SrcReg[1].Index =
-				rc_constants_add_state(&compiler->Base.Program.Constants,
-									   RC_STATE_R300_TEXRECT_FACTOR, inst->U.I.TexSrcUnit);
+	inst_mov = rc_insert_new_instruction(&compiler->Base, inst->Prev);
 
-		reset_srcreg(&inst->U.I.SrcReg[0]);
-		inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
-		inst->U.I.SrcReg[0].Index = temp;
+	inst_mov->U.I.Opcode = RC_OPCODE_MUL;
+	inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
+	inst_mov->U.I.DstReg.Index = temp;
+	inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
+	inst_mov->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
+	inst_mov->U.I.SrcReg[1].Index =
+			rc_constants_add_state(&compiler->Base.Program.Constants,
+					       state_constant, inst->U.I.TexSrcUnit);
 
-		inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
-	}
+	reset_srcreg(&inst->U.I.SrcReg[0]);
+	inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+	inst->U.I.SrcReg[0].Index = temp;
 }
 
 /**
@@ -88,6 +86,9 @@ int radeonTransformTEX(
 {
 	struct r300_fragment_program_compiler *compiler =
 		(struct r300_fragment_program_compiler*)data;
+	rc_wrap_mode wrapmode = compiler->state.unit[inst->U.I.TexSrcUnit].wrap_mode;
+	int is_rect = inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
+		      compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords;
 
 	if (inst->U.I.Opcode != RC_OPCODE_TEX &&
 		inst->U.I.Opcode != RC_OPCODE_TXB &&
@@ -141,6 +142,7 @@ int radeonTransformTEX(
 				inst_rcp->U.I.DstReg.Index = tmp_recip_w;
 				inst_rcp->U.I.DstReg.WriteMask = RC_MASK_W;
 				inst_rcp->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
+				/* XXX do not take W, instead, see which channel is mapped to W. */
 				inst_rcp->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_WWWW;
 			}
 
@@ -206,11 +208,15 @@ int radeonTransformTEX(
 		}
 	}
 
-	/* 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.
+	/* R300 cannot sample from rectangles and the wrap mode fallback needs
+	 * normalized coordinates anyway. */
+	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
+	    is_rect && (!c->is_r500 || wrapmode != RC_WRAP_NONE)) {
+		scale_texcoords(compiler, inst, RC_STATE_R300_TEXRECT_FACTOR);
+		inst->U.I.TexSrcTarget = RC_TEXTURE_2D;
+	}
+
+	/* Texture wrap modes don't work on NPOT textures.
 	 *
 	 * Non-wrapped/clamped texcoords with NPOT are free in HW. Repeat and
 	 * mirroring are not. If we need to repeat, we do:
@@ -235,128 +241,111 @@ int radeonTransformTEX(
 	 * ~ C & M. ;)
 	 */
 	if (inst->U.I.Opcode != RC_OPCODE_KIL &&
-		(inst->U.I.TexSrcTarget == RC_TEXTURE_RECT ||
-			compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot ||
-			compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords)) {
-		rc_wrap_mode wrapmode = compiler->state.unit[inst->U.I.TexSrcUnit].wrap_mode;
-
-		/* R300 cannot sample from rectangles. */
-		if (!c->is_r500) {
-			lower_texture_rect(compiler, inst);
-		}
-
-		if (compiler->state.unit[inst->U.I.TexSrcUnit].fake_npot &&
-			wrapmode != RC_WRAP_NONE) {
+	    wrapmode != RC_WRAP_NONE) {
+		struct rc_instruction *inst_mov;
+		unsigned temp = rc_find_free_temporary(c);
+
+		if (wrapmode == RC_WRAP_REPEAT) {
+			/* Both instructions will be paired up. */
+			struct rc_instruction *inst_frc = rc_insert_new_instruction(c, inst->Prev);
+
+			inst_frc->U.I.Opcode = RC_OPCODE_FRC;
+			inst_frc->U.I.DstReg.File = RC_FILE_TEMPORARY;
+			inst_frc->U.I.DstReg.Index = temp;
+			inst_frc->U.I.DstReg.WriteMask = RC_MASK_XYZ;
+			inst_frc->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
+		} else if (wrapmode == RC_WRAP_MIRRORED_REPEAT) {
+			/*
+			 * Function:
+			 *   f(v) = 1 - abs(frac(v * 0.5) * 2 - 1)
+			 *
+			 * Code:
+			 *   MUL temp, src0, 0.5
+			 *   FRC temp, temp
+			 *   MAD temp, temp, 2, -1
+			 *   ADD temp, 1, -abs(temp)
+			 */
+
+			struct rc_instruction *inst_mul, *inst_frc, *inst_mad, *inst_add;
+			unsigned two, two_swizzle;
+
+			inst_mul = rc_insert_new_instruction(c, inst->Prev);
+
+			inst_mul->U.I.Opcode = RC_OPCODE_MUL;
+			inst_mul->U.I.DstReg.File = RC_FILE_TEMPORARY;
+			inst_mul->U.I.DstReg.Index = temp;
+			inst_mul->U.I.DstReg.WriteMask = RC_MASK_XYZ;
+			inst_mul->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
+			inst_mul->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_HHHH;
+
+			inst_frc = rc_insert_new_instruction(c, inst->Prev);
+
+			inst_frc->U.I.Opcode = RC_OPCODE_FRC;
+			inst_frc->U.I.DstReg.File = RC_FILE_TEMPORARY;
+			inst_frc->U.I.DstReg.Index = temp;
+			inst_frc->U.I.DstReg.WriteMask = RC_MASK_XYZ;
+			inst_frc->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+			inst_frc->U.I.SrcReg[0].Index = temp;
+			inst_frc->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZ0;
+
+			two = rc_constants_add_immediate_scalar(&c->Program.Constants, 2, &two_swizzle);
+			inst_mad = rc_insert_new_instruction(c, inst->Prev);
+
+			inst_mad->U.I.Opcode = RC_OPCODE_MAD;
+			inst_mad->U.I.DstReg.File = RC_FILE_TEMPORARY;
+			inst_mad->U.I.DstReg.Index = temp;
+			inst_mad->U.I.DstReg.WriteMask = RC_MASK_XYZ;
+			inst_mad->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
+			inst_mad->U.I.SrcReg[0].Index = temp;
+			inst_mad->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZ0;
+			inst_mad->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
+			inst_mad->U.I.SrcReg[1].Index = two;
+			inst_mad->U.I.SrcReg[1].Swizzle = two_swizzle;
+			inst_mad->U.I.SrcReg[2].Swizzle = RC_SWIZZLE_1111;
+			inst_mad->U.I.SrcReg[2].Negate = RC_MASK_XYZ;
+
+			inst_add = rc_insert_new_instruction(c, inst->Prev);
+
+			inst_add->U.I.Opcode = RC_OPCODE_ADD;
+			inst_add->U.I.DstReg.File = RC_FILE_TEMPORARY;
+			inst_add->U.I.DstReg.Index = temp;
+			inst_add->U.I.DstReg.WriteMask = RC_MASK_XYZ;
+			inst_add->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_1111;
+			inst_add->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
+			inst_add->U.I.SrcReg[1].Index = temp;
+			inst_add->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_XYZ0;
+			inst_add->U.I.SrcReg[1].Abs = 1;
+			inst_add->U.I.SrcReg[1].Negate = RC_MASK_XYZ;
+		} else if (wrapmode == RC_WRAP_MIRRORED_CLAMP) {
+			/*
+			 * Mirrored clamp modes are bloody simple, we just use abs
+			 * to mirror [0, 1] into [-1, 0]. This works for
+			 * all modes i.e. CLAMP, CLAMP_TO_EDGE, and CLAMP_TO_BORDER.
+			 */
 			struct rc_instruction *inst_mov;
-			unsigned temp = rc_find_free_temporary(c);
 
-			/* For NPOT fallback, we need normalized coordinates anyway. */
-			if (c->is_r500) {
-				lower_texture_rect(compiler, inst);
-			}
-
-			if (wrapmode == RC_WRAP_REPEAT) {
-				/* Both instructions will be paired up. */
-				struct rc_instruction *inst_frc = rc_insert_new_instruction(c, inst->Prev);
-
-				inst_frc->U.I.Opcode = RC_OPCODE_FRC;
-				inst_frc->U.I.DstReg.File = RC_FILE_TEMPORARY;
-				inst_frc->U.I.DstReg.Index = temp;
-				inst_frc->U.I.DstReg.WriteMask = RC_MASK_XYZ;
-				inst_frc->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
-			} else if (wrapmode == RC_WRAP_MIRRORED_REPEAT) {
-				/*
-				 * Function:
-				 *   f(v) = 1 - abs(frac(v * 0.5) * 2 - 1)
-				 *
-				 * Code:
-				 *   MUL temp, src0, 0.5
-				 *   FRC temp, temp
-				 *   MAD temp, temp, 2, -1
-				 *   ADD temp, 1, -abs(temp)
-				 */
-
-				struct rc_instruction *inst_mul, *inst_frc, *inst_mad, *inst_add;
-				unsigned two, two_swizzle;
-
-				inst_mul = rc_insert_new_instruction(c, inst->Prev);
-
-				inst_mul->U.I.Opcode = RC_OPCODE_MUL;
-				inst_mul->U.I.DstReg.File = RC_FILE_TEMPORARY;
-				inst_mul->U.I.DstReg.Index = temp;
-				inst_mul->U.I.DstReg.WriteMask = RC_MASK_XYZ;
-				inst_mul->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
-				inst_mul->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_HHHH;
-
-				inst_frc = rc_insert_new_instruction(c, inst->Prev);
-
-				inst_frc->U.I.Opcode = RC_OPCODE_FRC;
-				inst_frc->U.I.DstReg.File = RC_FILE_TEMPORARY;
-				inst_frc->U.I.DstReg.Index = temp;
-				inst_frc->U.I.DstReg.WriteMask = RC_MASK_XYZ;
-				inst_frc->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
-				inst_frc->U.I.SrcReg[0].Index = temp;
-				inst_frc->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZ0;
-
-				two = rc_constants_add_immediate_scalar(&c->Program.Constants, 2, &two_swizzle);
-				inst_mad = rc_insert_new_instruction(c, inst->Prev);
-
-				inst_mad->U.I.Opcode = RC_OPCODE_MAD;
-				inst_mad->U.I.DstReg.File = RC_FILE_TEMPORARY;
-				inst_mad->U.I.DstReg.Index = temp;
-				inst_mad->U.I.DstReg.WriteMask = RC_MASK_XYZ;
-				inst_mad->U.I.SrcReg[0].File = RC_FILE_TEMPORARY;
-				inst_mad->U.I.SrcReg[0].Index = temp;
-				inst_mad->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZ0;
-				inst_mad->U.I.SrcReg[1].File = RC_FILE_CONSTANT;
-				inst_mad->U.I.SrcReg[1].Index = two;
-				inst_mad->U.I.SrcReg[1].Swizzle = two_swizzle;
-				inst_mad->U.I.SrcReg[2].Swizzle = RC_SWIZZLE_1111;
-				inst_mad->U.I.SrcReg[2].Negate = RC_MASK_XYZ;
-
-				inst_add = rc_insert_new_instruction(c, inst->Prev);
-
-				inst_add->U.I.Opcode = RC_OPCODE_ADD;
-				inst_add->U.I.DstReg.File = RC_FILE_TEMPORARY;
-				inst_add->U.I.DstReg.Index = temp;
-				inst_add->U.I.DstReg.WriteMask = RC_MASK_XYZ;
-				inst_add->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_1111;
-				inst_add->U.I.SrcReg[1].File = RC_FILE_TEMPORARY;
-				inst_add->U.I.SrcReg[1].Index = temp;
-				inst_add->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_XYZ0;
-				inst_add->U.I.SrcReg[1].Abs = 1;
-				inst_add->U.I.SrcReg[1].Negate = RC_MASK_XYZ;
-			} else if (wrapmode == RC_WRAP_MIRRORED_CLAMP) {
-				/*
-				 * Mirrored clamp modes are bloody simple, we just use abs
-				 * to mirror [0, 1] into [-1, 0]. This works for
-				 * all modes i.e. CLAMP, CLAMP_TO_EDGE, and CLAMP_TO_BORDER.
-				 */
-				struct rc_instruction *inst_mov;
-
-				inst_mov = rc_insert_new_instruction(c, inst->Prev);
-
-				inst_mov->U.I.Opcode = RC_OPCODE_MOV;
-				inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
-				inst_mov->U.I.DstReg.Index = temp;
-				inst_mov->U.I.DstReg.WriteMask = RC_MASK_XYZ;
-				inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0];
-				inst_mov->U.I.SrcReg[0].Abs = 1;
-			}
-
-			/* Preserve W for TXP/TXB. */
 			inst_mov = rc_insert_new_instruction(c, inst->Prev);
 
 			inst_mov->U.I.Opcode = RC_OPCODE_MOV;
 			inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
 			inst_mov->U.I.DstReg.Index = temp;
-			inst_mov->U.I.DstReg.WriteMask = RC_MASK_W;
+			inst_mov->U.I.DstReg.WriteMask = RC_MASK_XYZ;
 			inst_mov->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;
+			inst_mov->U.I.SrcReg[0].Abs = 1;
 		}
+
+		/* Preserve W for TXP/TXB. */
+		inst_mov = rc_insert_new_instruction(c, inst->Prev);
+
+		inst_mov->U.I.Opcode = RC_OPCODE_MOV;
+		inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY;
+		inst_mov->U.I.DstReg.Index = temp;
+		inst_mov->U.I.DstReg.WriteMask = RC_MASK_W;
+		inst_mov->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;
 	}
 
 	/* Cannot write texture to output registers (all chips) or with masks (non-r500) */
-- 
cgit v1.2.3