summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2012-11-14 20:50:05 -0800
committerKenneth Graunke <kenneth@whitecape.org>2012-11-17 14:37:16 -0800
commit5cea0273414bd5897c318b4d632b08ce8080a2fe (patch)
tree35cfbb723d3310c8f1dba45c0284dc89c630c67f
parent3c368bb307544a51f8b8d13f0d496a742086c9e2 (diff)
i965/fs: Properly patch special values during VGRF compaction.
In addition to registers used by instructions, fs_visitor maintains direct references to certain "special" values used for inputs/outputs. When I added VGRF compaction, I overlooked these, believing that these direct references weren't used once instructions were generated. That was wrong. For example, pixel_x/y are used in virtual_grf_interferes(), which is called by optimization passes and register allocation. This patch treats all of them as used and patches them after compacting. While it's not strictly necessary to patch all of them (as some aren't used after emitting code), it seems safer to simply fix them all. Fixes oglconform's textureswizzle/advanced.shader.targets, piglit's glsl-fs-lots-of-tex, and glean's texCombine on pre-Gen6 hardware. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=56790 Reviewed-by: Eric Anholt <eric@anholt.net>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index f25fd16ffe..2cd3ffe726 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -1130,6 +1130,27 @@ fs_visitor::compact_virtual_grfs()
}
}
+ /* In addition to registers used in instructions, fs_visitor keeps
+ * direct references to certain special values which must be patched:
+ */
+ fs_reg *special[] = {
+ &frag_depth, &pixel_x, &pixel_y, &pixel_w, &wpos_w, &dual_src_output,
+ &outputs[0], &outputs[1], &outputs[2], &outputs[3],
+ &outputs[4], &outputs[5], &outputs[6], &outputs[7],
+ &delta_x[0], &delta_x[1], &delta_x[2],
+ &delta_x[3], &delta_x[4], &delta_x[5],
+ &delta_y[0], &delta_y[1], &delta_y[2],
+ &delta_y[3], &delta_y[4], &delta_y[5],
+ };
+ STATIC_ASSERT(BRW_WM_BARYCENTRIC_INTERP_MODE_COUNT == 6);
+ STATIC_ASSERT(BRW_MAX_DRAW_BUFFERS == 8);
+
+ /* Treat all special values as used, to be conservative */
+ for (unsigned i = 0; i < ARRAY_SIZE(special); i++) {
+ if (special[i]->file == GRF)
+ remap_table[special[i]->reg] = 0;
+ }
+
/* Compact the GRF arrays. */
int new_index = 0;
for (int i = 0; i < this->virtual_grf_count; i++) {
@@ -1158,6 +1179,12 @@ fs_visitor::compact_virtual_grfs()
inst->src[i].reg = remap_table[inst->src[i].reg];
}
}
+
+ /* Patch all the references to special values */
+ for (unsigned i = 0; i < ARRAY_SIZE(special); i++) {
+ if (special[i]->file == GRF && remap_table[special[i]->reg] != -1)
+ special[i]->reg = remap_table[special[i]->reg];
+ }
}
bool