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.
This commit is contained in:
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user