[Mesa-dev] [PATCH 41/41] SQUASH: i965/fs: Force a high register for the final FB write
Jason Ekstrand
jason at jlekstrand.net
Sat Sep 20 10:23:30 PDT 2014
---
src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp | 24 ++++++++++++++++++++++-
src/mesa/drivers/dri/i965/intel_screen.h | 5 +++++
2 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
index b42f1e5..41e8855 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
@@ -116,8 +116,10 @@ brw_alloc_reg_set(struct intel_screen *screen, int reg_width)
/* Compute the total number of registers across all classes. */
int ra_reg_count = 0;
for (int i = 0; i < class_count; i++) {
+ screen->wm_reg_sets[index].class_first_reg[i] = ra_reg_count;
ra_reg_count += base_reg_count - (class_sizes[i] - 1);
}
+ screen->wm_reg_sets[index].class_first_reg[class_count] = ra_reg_count;
uint8_t *ra_reg_to_grf = ralloc_array(screen, uint8_t, ra_reg_count);
struct ra_regs *regs = ra_alloc_reg_set(screen, ra_reg_count);
@@ -469,9 +471,29 @@ fs_visitor::assign_regs(bool allow_spilling)
}
setup_payload_interference(g, payload_node_count, first_payload_node);
- if (brw->gen >= 7)
+ if (brw->gen >= 7) {
setup_mrf_hack_interference(g, first_mrf_hack_node);
+ foreach_in_list(fs_inst, inst, &instructions) {
+ /* When we do send-from-GRF for FB writes, we need to ensure that
+ * the last write instruction sends from a high register. This is
+ * because the vertex fetcher wants to start filling the low
+ * payload registers while the pixel data port is still working on
+ * writing out the memory. If we don't do this, we get rendering
+ * artifacts.
+ *
+ * We could just do "something high". Instead, we just pick the
+ * highest register that works.
+ */
+ if (inst->opcode == FS_OPCODE_FB_WRITE && inst->eot) {
+ int size = virtual_grf_sizes[inst->src[0].reg];
+ int reg = screen->wm_reg_sets[rsi].class_first_reg[size] - 1;
+ ra_set_node_reg(g, inst->src[0].reg, reg);
+ break;
+ }
+ }
+ }
+
if (dispatch_width > 8) {
/* In 16-wide dispatch we have an issue where a compressed
* instruction is actually two instructions executed simultaneiously.
diff --git a/src/mesa/drivers/dri/i965/intel_screen.h b/src/mesa/drivers/dri/i965/intel_screen.h
index 945f6f5..8bc6abd 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.h
+++ b/src/mesa/drivers/dri/i965/intel_screen.h
@@ -90,6 +90,11 @@ struct intel_screen
int classes[16];
/**
+ * Array of the first ra reg in eahch ra class.
+ */
+ int class_first_reg[17];
+
+ /**
* Mapping for register-allocated objects in *regs to the first
* GRF for that object.
*/
--
2.1.0
More information about the mesa-dev
mailing list