Mesa (master): r300/compiler: Use the smart scheduler for r300 cards

Tom Stellard tstellar at kemper.freedesktop.org
Sun Feb 26 21:20:52 UTC 2012


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

Author: Tom Stellard <tstellar at gmail.com>
Date:   Mon Feb 13 21:26:15 2012 -0500

r300/compiler: Use the smart scheduler for r300 cards

---

 .../drivers/r300/compiler/radeon_pair_schedule.c   |  127 ++++++++-----------
 1 files changed, 54 insertions(+), 73 deletions(-)

diff --git a/src/gallium/drivers/r300/compiler/radeon_pair_schedule.c b/src/gallium/drivers/r300/compiler/radeon_pair_schedule.c
index fa2e80f..d230206 100644
--- a/src/gallium/drivers/r300/compiler/radeon_pair_schedule.c
+++ b/src/gallium/drivers/r300/compiler/radeon_pair_schedule.c
@@ -298,9 +298,53 @@ static void calc_score_deps(struct schedule_instruction * sinst)
 
 #endif
 
-#define NO_READ_TEX_SCORE (1 << 16)
 #define NO_OUTPUT_SCORE (1 << 24)
 
+static void score_no_output(struct schedule_instruction * sinst)
+{
+	assert(sinst->Instruction->Type != RC_INSTRUCTION_NORMAL);
+	if (!sinst->Instruction->U.P.RGB.OutputWriteMask &&
+			!sinst->Instruction->U.P.Alpha.OutputWriteMask) {
+		if (sinst->PairedInst) {
+			if (!sinst->PairedInst->Instruction->U.P.
+							RGB.OutputWriteMask
+					&& !sinst->PairedInst->Instruction->U.P.
+							Alpha.OutputWriteMask) {
+				sinst->Score |= NO_OUTPUT_SCORE;
+			}
+
+		} else {
+			sinst->Score |= NO_OUTPUT_SCORE;
+		}
+	}
+}
+
+#define PAIRED_SCORE (1 << 16)
+
+static void calc_score_r300(struct schedule_instruction * sinst)
+{
+	unsigned src_idx;
+
+	if (sinst->Instruction->Type == RC_INSTRUCTION_NORMAL) {
+		sinst->Score = 0;
+		return;
+	}
+
+	score_no_output(sinst);
+
+	if (sinst->PairedInst) {
+		sinst->Score |= PAIRED_SCORE;
+		return;
+	}
+
+	for (src_idx = 0; src_idx < 4; src_idx++) {
+		sinst->Score += sinst->Instruction->U.P.RGB.Src[src_idx].Used +
+				sinst->Instruction->U.P.Alpha.Src[src_idx].Used;
+	}
+}
+
+#define NO_READ_TEX_SCORE (1 << 16)
+
 static void calc_score_readers(struct schedule_instruction * sinst)
 {
 	if (sinst->Instruction->Type == RC_INSTRUCTION_NORMAL) {
@@ -313,20 +357,7 @@ static void calc_score_readers(struct schedule_instruction * sinst)
 		if (get_tex_read_count(sinst) == 0) {
 			sinst->Score |= NO_READ_TEX_SCORE;
 		}
-		if (!sinst->Instruction->U.P.RGB.OutputWriteMask &&
-			!sinst->Instruction->U.P.Alpha.OutputWriteMask) {
-			if (sinst->PairedInst) {
-				if (!sinst->PairedInst->Instruction->U.P.
-						RGB.OutputWriteMask
-				&& !sinst->PairedInst->Instruction->U.P.
-						Alpha.OutputWriteMask) {
-					sinst->Score |= NO_OUTPUT_SCORE;
-				}
-
-			} else {
-				sinst->Score |= NO_OUTPUT_SCORE;
-			}
-		}
+		score_no_output(sinst);
 	}
 }
 
@@ -1080,7 +1111,8 @@ static void emit_instruction(
 	update_max_score(s, &s->ReadyAlpha, &max_score, &max_inst, &max_list);
 
 	if (tex_count >= s->max_tex_group || max_score == -1
-		|| (s->TEXCount > 0 && tex_count == s->TEXCount)) {
+		|| (s->TEXCount > 0 && tex_count == s->TEXCount)
+		|| (!s->C->is_r500 && tex_count > 0 && max_score == -1)) {
 		emit_all_tex(s, before);
 	} else {
 
@@ -1093,53 +1125,6 @@ static void emit_instruction(
 	}
 }
 
-/**
- * Find a good ALU instruction or pair of ALU instruction and emit it.
- *
- * Prefer emitting full ALU instructions, so that when we reach a point
- * where no full ALU instruction can be emitted, we have more candidates
- * for RGB/Alpha pairing.
- */
-static void emit_one_alu(struct schedule_state *s, struct rc_instruction * before)
-{
-	struct schedule_instruction * sinst;
-	int rgb_score = -1, alpha_score = -1;
-
-	/* Try to merge RGB and Alpha instructions together. */
-	pair_instructions(s);
-
-	if (s->ReadyFullALU) {
-		sinst = s->ReadyFullALU;
-		s->ReadyFullALU = s->ReadyFullALU->NextReady;
-		rc_insert_instruction(before->Prev, sinst->Instruction);
-		commit_alu_instruction(s, sinst);
-	} else {
-		if (s->ReadyRGB) {
-			rgb_score = s->ReadyRGB->Score;
-		}
-		if (s->ReadyAlpha) {
-			alpha_score = s->ReadyAlpha->Score;
-		}
-		if (rgb_score > alpha_score) {
-			sinst = s->ReadyRGB;
-			s->ReadyRGB = s->ReadyRGB->NextReady;
-		} else if (s->ReadyAlpha) {
-			sinst = s->ReadyAlpha;
-			s->ReadyAlpha = s->ReadyAlpha->NextReady;
-		} else {
-			/*XXX Something real bad has happened. */
-			assert(0);
-		}
-
-		rc_insert_instruction(before->Prev, sinst->Instruction);
-		commit_alu_instruction(s, sinst);
-	}
-	/* If the instruction we just emitted uses a presubtract value, and
-	 * the presubtract sources were written by the previous intstruction,
-	 * the previous instruction needs a nop. */
-	presub_nop(before->Prev);
-}
-
 static void add_tex_reader(
 	struct schedule_state * s,
 	struct schedule_instruction * writer,
@@ -1317,15 +1302,7 @@ static void schedule_block(struct schedule_state * s,
 	/* Schedule instructions back */
 	while(!s->C->Error &&
 	      (s->ReadyTEX || s->ReadyRGB || s->ReadyAlpha || s->ReadyFullALU)) {
-		if (s->C->is_r500) {
-			emit_instruction(s, end);
-		} else {
-			if (s->ReadyTEX)
-				emit_all_tex(s, end);
-
-			while(!s->C->Error && (s->ReadyFullALU || s->ReadyRGB || s->ReadyAlpha))
-				emit_one_alu(s, end);
-		}
+		emit_instruction(s, end);
 	}
 }
 
@@ -1348,7 +1325,11 @@ void rc_pair_schedule(struct radeon_compiler *cc, void *user)
 	memset(&s, 0, sizeof(s));
 	s.Opt = *opt;
 	s.C = &c->Base;
-	s.CalcScore = calc_score_readers;
+	if (s.C->is_r500) {
+		s.CalcScore = calc_score_readers;
+	} else {
+		s.CalcScore = calc_score_r300;
+	}
 	s.max_tex_group = debug_get_num_option("RADEON_TEX_GROUP", 8);
 	while(inst != &c->Base.Program.Instructions) {
 		struct rc_instruction * first;




More information about the mesa-commit mailing list