Mesa (7.10): r300/compiler: Fix incorrect presubtract conversion

Tom Stellard tstellar at kemper.freedesktop.org
Sat Apr 16 14:49:53 PDT 2011


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

Author: Tom Stellard <tstellar at gmail.com>
Date:   Sat Apr 16 12:39:09 2011 -0700

r300/compiler: Fix incorrect presubtract conversion

ADD instructions with constant swizzles can't be converted to
presubtract operations.

(cherry picked from commit 0fa81d6d05b12db825be31533d9a485625ae35e2)

---

 .../drivers/dri/r300/compiler/radeon_optimize.c    |   24 ++++++++++++++++++++
 1 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c b/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c
index 44f4c0f..4c02246 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c
@@ -499,10 +499,34 @@ static int is_presub_candidate(
 {
 	const struct rc_opcode_info * info = rc_get_opcode_info(inst->U.I.Opcode);
 	unsigned int i;
+	unsigned int is_constant[2] = {0, 0};
+
+	assert(inst->U.I.Opcode == RC_OPCODE_ADD);
 
 	if (inst->U.I.PreSub.Opcode != RC_PRESUB_NONE || inst->U.I.SaturateMode)
 		return 0;
 
+	/* If both sources use a constant swizzle, then we can't convert it to
+	 * a presubtract operation.  In fact for the ADD and SUB presubtract
+	 * operations neither source can contain a constant swizzle.  This
+	 * specific case is checked in peephole_add_presub_add() when
+	 * we make sure the swizzles for both sources are equal, so we
+	 * don't need to worry about it here. */
+	for (i = 0; i < 2; i++) {
+		int chan;
+		for (chan = 0; chan < 4; chan++) {
+			rc_swizzle swz =
+				get_swz(inst->U.I.SrcReg[i].Swizzle, chan);
+			if (swz == RC_SWIZZLE_ONE
+					|| swz == RC_SWIZZLE_ZERO
+					|| swz == RC_SWIZZLE_HALF) {
+				is_constant[i] = 1;
+			}
+		}
+	}
+	if (is_constant[0] && is_constant[1])
+		return 0;
+
 	for(i = 0; i < info->NumSrcRegs; i++) {
 		struct rc_src_register src = inst->U.I.SrcReg[i];
 		if (src_reads_dst_mask(src, inst->U.I.DstReg))



More information about the mesa-commit mailing list