Mesa (master): r300/compiler: Create a helper function for merging presubtract sources

Tom Stellard tstellar at kemper.freedesktop.org
Tue Oct 19 04:06:23 UTC 2010


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

Author: Tom Stellard <tstellar at gmail.com>
Date:   Thu Sep 30 23:36:57 2010 -0700

r300/compiler: Create a helper function for merging presubtract sources

---

 .../dri/r300/compiler/radeon_pair_schedule.c       |  219 +++++++++-----------
 1 files changed, 102 insertions(+), 117 deletions(-)

diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
index bfe3553..15e7c0b 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
@@ -275,13 +275,112 @@ static void emit_all_tex(struct schedule_state * s, struct rc_instruction * befo
 	}
 }
 
+/* This is a helper function for destructive_merge_instructions().  It helps
+ * merge presubtract sources from two instructions and makes sure the
+ * presubtract sources end up in the correct spot.  This function assumes that
+ * dst_full is an rgb instruction, meaning that it has a vector instruction(rgb)
+ * but no scalar instruction (alpha).
+ * @return 0 if merging the presubtract sources fails.
+ * @retrun 1 if merging the presubtract sources succeeds.
+ */
+static int merge_presub_sources(
+	struct rc_pair_instruction * dst_full,
+	struct rc_pair_sub_instruction src,
+	rc_pair_source_type type)
+{
+	unsigned int srcp_src, srcp_regs, is_rgb, is_alpha;
+	struct rc_pair_sub_instruction * dst_sub;
+
+	assert(dst_full->Alpha.Opcode == RC_OPCODE_NOP);
+
+	switch(type) {
+	case RC_PAIR_SOURCE_RGB:
+		is_rgb = 1;
+		is_alpha = 0;
+		dst_sub = &dst_full->RGB;
+		break;
+	case RC_PAIR_SOURCE_ALPHA:
+		is_rgb = 0;
+		is_alpha = 1;
+		dst_sub = &dst_full->Alpha;
+		break;
+	default:
+		assert(0);
+		return 0;
+	}
+
+	const struct rc_opcode_info * info =
+					rc_get_opcode_info(dst_full->RGB.Opcode);
+	if (dst_sub->Src[RC_PAIR_PRESUB_SRC].Used)
+		return 0;
+
+	srcp_regs = rc_presubtract_src_reg_count(
+					src.Src[RC_PAIR_PRESUB_SRC].Index);
+	for(srcp_src = 0; srcp_src < srcp_regs; srcp_src++) {
+		unsigned int arg;
+		int free_source;
+		unsigned int one_way = 0;
+		struct rc_pair_instruction_source srcp = src.Src[srcp_src];
+		struct rc_pair_instruction_source temp;
+
+		free_source = rc_pair_alloc_source(dst_full, is_rgb, is_alpha,
+							srcp.File, srcp.Index);
+
+		/* If free_source < 0 then there are no free source
+		 * slots. */
+		if (free_source < 0)
+			return 0;
+
+		temp = dst_sub->Src[srcp_src];
+		dst_sub->Src[srcp_src] = dst_sub->Src[free_source];
+
+		/* srcp needs src0 and src1 to be the same */
+		if (free_source < srcp_src) {
+			if (!temp.Used)
+				continue;
+			free_source = rc_pair_alloc_source(dst_full, is_rgb,
+					is_alpha, temp.File, temp.Index);
+			one_way = 1;
+		} else {
+			dst_sub->Src[free_source] = temp;
+		}
+
+		/* If free_source == srcp_src, then the presubtract
+		 * source is already in the correct place. */
+		if (free_source == srcp_src)
+			continue;
+
+		/* Shuffle the sources, so we can put the
+		 * presubtract source in the correct place. */
+		for(arg = 0; arg < info->NumSrcRegs; arg++) {
+			/*If this arg does not read from an rgb source,
+			 * do nothing. */
+			if (rc_source_type_that_arg_reads(
+				dst_full->RGB.Arg[arg].Source,
+				dst_full->RGB.Arg[arg].Swizzle, 3) != type) {
+				continue;
+			}
+			if (dst_full->RGB.Arg[arg].Source == srcp_src)
+				dst_full->RGB.Arg[arg].Source = free_source;
+			/* We need to do this just in case register
+			 * is one of the sources already, but in the
+			 * wrong spot. */
+			else if(dst_full->RGB.Arg[arg].Source == free_source
+							&& !one_way) {
+				dst_full->RGB.Arg[arg].Source = srcp_src;
+			}
+		}
+	}
+	return 1;
+}
+
 
+/* This function assumes that rgb.Alpha and alpha.RGB are unused */
 static int destructive_merge_instructions(
 		struct rc_pair_instruction * rgb,
 		struct rc_pair_instruction * alpha)
 {
 	const struct rc_opcode_info * opcode;
-	const struct rc_opcode_info * rgb_info;
 
 	assert(rgb->Alpha.Opcode == RC_OPCODE_NOP);
 	assert(alpha->RGB.Opcode == RC_OPCODE_NOP);
@@ -291,129 +390,15 @@ static int destructive_merge_instructions(
 	 * src1. */
 
 	/* Merge the rgb presubtract registers. */
-	rgb_info = rc_get_opcode_info(rgb->RGB.Opcode);
 	if (alpha->RGB.Src[RC_PAIR_PRESUB_SRC].Used) {
-		unsigned int srcp_src;
-		unsigned int srcp_regs;
-		if (rgb->RGB.Src[RC_PAIR_PRESUB_SRC].Used)
+		if (!merge_presub_sources(rgb, alpha->RGB, RC_PAIR_SOURCE_RGB)) {
 			return 0;
-		srcp_regs = rc_presubtract_src_reg_count(
-				alpha->RGB.Src[RC_PAIR_PRESUB_SRC].Index);
-		for(srcp_src = 0; srcp_src < srcp_regs; srcp_src++) {
-			unsigned int arg;
-			int free_source;
-			unsigned int one_way = 0;
-			struct rc_pair_instruction_source srcp =
-						alpha->RGB.Src[srcp_src];
-			struct rc_pair_instruction_source temp;
-			/* 2nd arg of 1 means this is an rgb source.
-			 * 3rd arg of 0 means this is not an alpha source. */
-			free_source = rc_pair_alloc_source(rgb, 1, 0,
-							srcp.File, srcp.Index);
-			/* If free_source < 0 then there are no free source
-			 * slots. */
-			if (free_source < 0)
-				return 0;
-
-			temp = rgb->RGB.Src[srcp_src];
-			rgb->RGB.Src[srcp_src] = rgb->RGB.Src[free_source];
-			/* srcp needs src0 and src1 to be the same */
-			if (free_source < srcp_src) {
-				if (!temp.Used)
-					continue;
-				free_source = rc_pair_alloc_source(rgb, 1, 0,
-							srcp.File, srcp.Index);
-				one_way = 1;
-			} else {
-				rgb->RGB.Src[free_source] = temp;
-			}
-			/* If free_source == srcp_src, then the presubtract
-			 * source is already in the correct place. */
-			if (free_source == srcp_src)
-				continue;
-			/* Shuffle the sources, so we can put the
-			 * presubtract source in the correct place. */
-			for (arg = 0; arg < rgb_info->NumSrcRegs; arg++) {
-				/*If this arg does not read from an rgb source,
-				 * do nothing. */
-				if (rc_source_type_that_arg_reads(
-					rgb->RGB.Arg[arg].Source,
-					rgb->RGB.Arg[arg].Swizzle, 3)
-							!= RC_PAIR_SOURCE_RGB) {
-					continue;
-				}
-				if (rgb->RGB.Arg[arg].Source == srcp_src)
-					rgb->RGB.Arg[arg].Source = free_source;
-				/* We need to do this just in case register
-				 * is one of the sources already, but in the
-				 * wrong spot. */
-				else if(rgb->RGB.Arg[arg].Source == free_source
-								&& !one_way) {
-					rgb->RGB.Arg[arg].Source = srcp_src;
-				}
-			}
 		}
 	}
-
 	/* Merge the alpha presubtract registers */
 	if (alpha->Alpha.Src[RC_PAIR_PRESUB_SRC].Used) {
-		unsigned int srcp_src;
-		unsigned int srcp_regs;
-		if(rgb->Alpha.Src[RC_PAIR_PRESUB_SRC].Used)
+		if(!merge_presub_sources(rgb,  alpha->Alpha, RC_PAIR_SOURCE_ALPHA)){
 			return 0;
-
-		srcp_regs = rc_presubtract_src_reg_count(
-			alpha->Alpha.Src[RC_PAIR_PRESUB_SRC].Index);
-		for(srcp_src = 0; srcp_src < srcp_regs; srcp_src++) {
-			unsigned int arg;
-			int free_source;
-			unsigned int one_way = 0;
-			struct rc_pair_instruction_source srcp =
-						alpha->Alpha.Src[srcp_src];
-			struct rc_pair_instruction_source temp;
-			/* 2nd arg of 0 means this is not an rgb source.
-			 * 3rd arg of 1 means this is an alpha source. */
-			free_source = rc_pair_alloc_source(rgb, 0, 1,
-							srcp.File, srcp.Index);
-			/* If free_source < 0 then there are no free source
-			 * slots. */
-			if (free_source < 0)
-				return 0;
-
-			temp = rgb->Alpha.Src[srcp_src];
-			rgb->Alpha.Src[srcp_src] = rgb->Alpha.Src[free_source];
-			/* srcp needs src0 and src1 to be the same. */
-			if (free_source < srcp_src) {
-				if (!temp.Used)
-					continue;
-				free_source = rc_pair_alloc_source(rgb, 0, 1,
-							temp.File, temp.Index);
-				one_way = 1;
-			} else {
-				rgb->Alpha.Src[free_source] = temp;
-			}
-			/* If free_source == srcp_src, then the presubtract
-			 * source is already in the correct place. */
-			if (free_source == srcp_src)
-				continue;
-			/* Shuffle the sources, so we can put the
-			 * presubtract source in the correct place. */
-			for(arg = 0; arg < rgb_info->NumSrcRegs; arg++) {
-				/*If this arg does not read from an alpha
-				 * source, do nothing. */
-				if (rc_source_type_that_arg_reads(
-					rgb->RGB.Arg[arg].Source,
-					rgb->RGB.Arg[arg].Swizzle, 3)
-						!= RC_PAIR_SOURCE_ALPHA) {
-					continue;
-				}
-				if (rgb->RGB.Arg[arg].Source == srcp_src)
-					rgb->RGB.Arg[arg].Source = free_source;
-				else if (rgb->RGB.Arg[arg].Source == free_source
-								&& !one_way) {
-					rgb->RGB.Arg[arg].Source = srcp_src;
-				}
-			}
 		}
 	}
 




More information about the mesa-commit mailing list