summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <tstellar@gmail.com>2011-03-25 17:05:53 -0700
committerTom Stellard <tstellar@gmail.com>2011-04-30 11:00:15 -0700
commit6a6068e5e110f9902fbf368bbff2a728657e81c6 (patch)
tree147e2f2f515abf7a7e49a597f8c283041b99d781
parentbd661a933b18fccd7102d05932774ee61a90ec9e (diff)
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.
-rw-r--r--src/mesa/drivers/dri/r300/compiler/Makefile1
-rwxr-xr-xsrc/mesa/drivers/dri/r300/compiler/SConscript1
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c1
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_pair_dead_sources.c62
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h1
5 files changed, 66 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/r300/compiler/Makefile b/src/mesa/drivers/dri/r300/compiler/Makefile
index 51b896ae91f..90bd8e86768 100644
--- a/src/mesa/drivers/dri/r300/compiler/Makefile
+++ b/src/mesa/drivers/dri/r300/compiler/Makefile
@@ -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 \
diff --git a/src/mesa/drivers/dri/r300/compiler/SConscript b/src/mesa/drivers/dri/r300/compiler/SConscript
index 2b4bce1c08c..d44b745562c 100755
--- a/src/mesa/drivers/dri/r300/compiler/SConscript
+++ b/src/mesa/drivers/dri/r300/compiler/SConscript
@@ -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',
diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
index 9286733635f..cdfda0b3196 100644
--- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
+++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
@@ -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},
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_dead_sources.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_dead_sources.c
new file mode 100644
index 00000000000..1e9a2c09d44
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_dead_sources.c
@@ -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);
+ }
+}
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h
index d1a435fc530..82d7815aa78 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h
@@ -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_ */