Mesa (master): r300/compiler: Try to eliminate REPL_ALPHA instructions

Tom Stellard tstellar at kemper.freedesktop.org
Sun Oct 16 19:58:33 PDT 2011


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

Author: Tom Stellard <tstellar at gmail.com>
Date:   Sat Oct 15 17:56:15 2011 -0400

r300/compiler: Try to eliminate REPL_ALPHA instructions

Scalar instruction that need to write to the xyz components of a
register must reserve the RGB instruction slot for a REPL_ALPHA
instruction.  With this commit, the scheduler will attempt to free
the RGB slot by moving the write to the w component of a register.

---

 .../drivers/r300/compiler/radeon_pair_schedule.c   |   90 ++++++++++++-------
 1 files changed, 57 insertions(+), 33 deletions(-)

diff --git a/src/gallium/drivers/r300/compiler/radeon_pair_schedule.c b/src/gallium/drivers/r300/compiler/radeon_pair_schedule.c
index 94cf9a7..b3b0f6f 100644
--- a/src/gallium/drivers/r300/compiler/radeon_pair_schedule.c
+++ b/src/gallium/drivers/r300/compiler/radeon_pair_schedule.c
@@ -896,7 +896,16 @@ static int convert_rgb_to_alpha(
 		return 0;
 	}
 
-	pair_inst->Alpha.Opcode = pair_inst->RGB.Opcode;
+	/* If we are converting a full instruction with RC_OPCODE_REPL_ALPHA
+	 * as the RGB opcode, then the Alpha instruction will already contain
+	 * the correct opcode and instruction args, so we do not want to
+	 * overwrite them.
+	 */
+	if (pair_inst->RGB.Opcode != RC_OPCODE_REPL_ALPHA) {
+		pair_inst->Alpha.Opcode = pair_inst->RGB.Opcode;
+		memcpy(pair_inst->Alpha.Arg, pair_inst->RGB.Arg,
+						sizeof(pair_inst->Alpha.Arg));
+	}
 	pair_inst->Alpha.DestIndex = new_index;
 	pair_inst->Alpha.WriteMask = RC_MASK_W;
 	pair_inst->Alpha.Target = pair_inst->RGB.Target;
@@ -904,8 +913,6 @@ static int convert_rgb_to_alpha(
 	pair_inst->Alpha.DepthWriteMask = pair_inst->RGB.DepthWriteMask;
 	pair_inst->Alpha.Saturate = pair_inst->RGB.Saturate;
 	pair_inst->Alpha.Omod = pair_inst->RGB.Omod;
-	memcpy(pair_inst->Alpha.Arg, pair_inst->RGB.Arg,
-						sizeof(pair_inst->Alpha.Arg));
 	/* Move the swizzles into the first chan */
 	for (i = 0; i < info->NumSrcRegs; i++) {
 		unsigned int j;
@@ -935,6 +942,48 @@ static int convert_rgb_to_alpha(
 	return 1;
 }
 
+static void try_convert_and_pair(
+	struct schedule_state *s,
+	struct schedule_instruction ** inst_list)
+{
+	struct schedule_instruction * list_ptr = *inst_list;
+	while (list_ptr && *inst_list && (*inst_list)->NextReady) {
+		int paired = 0;
+		if (list_ptr->Instruction->U.P.Alpha.Opcode != RC_OPCODE_NOP
+			&& list_ptr->Instruction->U.P.RGB.Opcode
+						!= RC_OPCODE_REPL_ALPHA) {
+				goto next;
+		}
+		if (list_ptr->NumWriteValues == 1
+					&& convert_rgb_to_alpha(s, list_ptr)) {
+
+			struct schedule_instruction * pair_ptr;
+			remove_inst_from_list(inst_list, list_ptr);
+			add_inst_to_list_score(&s->ReadyAlpha, list_ptr);
+
+			for (pair_ptr = s->ReadyRGB; pair_ptr;
+					pair_ptr = pair_ptr->NextReady) {
+				if (merge_instructions(&pair_ptr->Instruction->U.P,
+						&list_ptr->Instruction->U.P)) {
+					remove_inst_from_list(&s->ReadyAlpha, list_ptr);
+					remove_inst_from_list(&s->ReadyRGB, pair_ptr);
+					pair_ptr->PairedInst = list_ptr;
+
+					add_inst_to_list(&s->ReadyFullALU, pair_ptr);
+					list_ptr = *inst_list;
+					paired = 1;
+					break;
+				}
+
+			}
+		}
+		if (!paired) {
+next:
+			list_ptr = list_ptr->NextReady;
+		}
+	}
+}
+
 /**
  * This function attempts to merge RGB and Alpha instructions together.
  */
@@ -969,38 +1018,13 @@ static void pair_instructions(struct schedule_state * s)
 		return;
 	}
 
+	/* Full instructions that have RC_OPCODE_REPL_ALPHA in the RGB
+	 * slot can be converted into Alpha instructions. */
+	try_convert_and_pair(s, &s->ReadyFullALU);
+
 	/* Try to convert some of the RGB instructions to Alpha and
 	 * try to pair it with another RGB. */
-	rgb_ptr = s->ReadyRGB;
-	while (rgb_ptr && s->ReadyRGB && s->ReadyRGB->NextReady) {
-		int paired = 0;
-		if (rgb_ptr->NumWriteValues == 1
-					&& convert_rgb_to_alpha(s, rgb_ptr)) {
-
-			struct schedule_instruction * pair_ptr;
-			remove_inst_from_list(&s->ReadyRGB, rgb_ptr);
-			add_inst_to_list_score(&s->ReadyAlpha, rgb_ptr);
-
-			for (pair_ptr = s->ReadyRGB; pair_ptr;
-					pair_ptr = pair_ptr->NextReady) {
-				if (merge_instructions(&pair_ptr->Instruction->U.P,
-						&rgb_ptr->Instruction->U.P)) {
-					remove_inst_from_list(&s->ReadyAlpha, rgb_ptr);
-					remove_inst_from_list(&s->ReadyRGB, pair_ptr);
-					pair_ptr->PairedInst = rgb_ptr;
-
-					add_inst_to_list(&s->ReadyFullALU, pair_ptr);
-					rgb_ptr = s->ReadyRGB;
-					paired = 1;
-					break;
-				}
-
-			}
-		}
-		if (!paired) {
-			rgb_ptr = rgb_ptr->NextReady;
-		}
-	}
+	try_convert_and_pair(s, &s->ReadyRGB);
 }
 
 static void update_max_score(



More information about the mesa-commit mailing list