r300/compiler: Use the smart scheduler for r300 cards

This commit is contained in:
Tom Stellard
2012-02-13 21:26:15 -05:00
parent 342cac7166
commit 134a0a5ff8
@@ -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;