r300/compiler: Add remove dead sources pass

The instruction scheduler will sometimes leave orphaned sources when
converting instructions from RGB to Alpha.  If one of these orphaned
sources has an index greater than the maximum temporary register index,
then the compiler will incorrectly report "Too many hardware temporaries
used".  The dead sources pass cleans up these orphaned sources.
This commit is contained in:
Tom Stellard
2011-03-25 17:05:53 -07:00
parent bd661a933b
commit 6a6068e5e1
5 changed files with 66 additions and 0 deletions

View File

@@ -20,6 +20,7 @@ C_SOURCES = \
radeon_pair_translate.c \
radeon_pair_schedule.c \
radeon_pair_regalloc.c \
radeon_pair_dead_sources.c \
radeon_dataflow.c \
radeon_dataflow_deadcode.c \
radeon_dataflow_swizzles.c \

View File

@@ -22,6 +22,7 @@ r300compiler = env.ConvenienceLibrary(
'radeon_pair_translate.c',
'radeon_pair_schedule.c',
'radeon_pair_regalloc.c',
'radeon_pair_dead_sources.c',
'radeon_optimize.c',
'radeon_remove_constants.c',
'radeon_rename_regs.c',

View File

@@ -148,6 +148,7 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
{"register rename", 1, !is_r500, rc_rename_regs, NULL},
{"pair translate", 1, 1, rc_pair_translate, NULL},
{"pair scheduling", 1, 1, rc_pair_schedule, NULL},
{"dead sources", 1, 1, rc_pair_remove_dead_sources, NULL},
{"register allocation", 1, opt, rc_pair_regalloc, NULL},
{"dumb register allocation", 1, !opt, rc_pair_regalloc_inputs_only, NULL},
{"final code validation", 0, 1, rc_validate_final_shader, NULL},

View File

@@ -0,0 +1,62 @@
#include "radeon_compiler.h"
#include "radeon_compiler_util.h"
#include "radeon_opcodes.h"
#include "radeon_program_pair.h"
static void mark_used_presub(struct rc_pair_sub_instruction * sub)
{
if (sub->Src[RC_PAIR_PRESUB_SRC].Used) {
unsigned int presub_reg_count = rc_presubtract_src_reg_count(
sub->Src[RC_PAIR_PRESUB_SRC].Index);
unsigned int i;
for (i = 0; i < presub_reg_count; i++) {
sub->Src[i].Used = 1;
}
}
}
static void mark_used(
struct rc_instruction * inst,
struct rc_pair_sub_instruction * sub)
{
unsigned int i;
const struct rc_opcode_info * info = rc_get_opcode_info(sub->Opcode);
for (i = 0; i < info->NumSrcRegs; i++) {
unsigned int src_type = rc_source_type_swz(sub->Arg[i].Swizzle);
if (src_type & RC_SOURCE_RGB) {
inst->U.P.RGB.Src[sub->Arg[i].Source].Used = 1;
}
if (src_type & RC_SOURCE_ALPHA) {
inst->U.P.Alpha.Src[sub->Arg[i].Source].Used = 1;
}
}
}
/**
* This pass finds sources that are not used by their instruction and marks
* them as unused.
*/
void rc_pair_remove_dead_sources(struct radeon_compiler * c, void *user)
{
struct rc_instruction * inst;
for (inst = c->Program.Instructions.Next;
inst != &c->Program.Instructions;
inst = inst->Next) {
unsigned int i;
if (inst->Type == RC_INSTRUCTION_NORMAL)
continue;
/* Mark all sources as unused */
for (i = 0; i < 4; i++) {
inst->U.P.RGB.Src[i].Used = 0;
inst->U.P.Alpha.Src[i].Used = 0;
}
mark_used(inst, &inst->U.P.RGB);
mark_used(inst, &inst->U.P.Alpha);
mark_used_presub(&inst->U.P.RGB);
mark_used_presub(&inst->U.P.Alpha);
}
}

View File

@@ -127,6 +127,7 @@ void rc_pair_translate(struct radeon_compiler *cc, void *user);
void rc_pair_schedule(struct radeon_compiler *cc, void *user);
void rc_pair_regalloc(struct radeon_compiler *cc, void *user);
void rc_pair_regalloc_inputs_only(struct radeon_compiler *cc, void *user);
void rc_pair_remove_dead_sources(struct radeon_compiler *c, void *user);
/*@}*/
#endif /* __RADEON_PROGRAM_PAIR_H_ */