summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965/brw_ir_fs.h
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2015-11-19 16:00:18 -0800
committerKenneth Graunke <kenneth@whitecape.org>2015-11-30 00:34:07 -0800
commit83dedb6354d0e9b04e8ccad77e86bdb7bad44bdd (patch)
treea7334a4f185711e186ca84dfc14308b900d7cd2f /src/mesa/drivers/dri/i965/brw_ir_fs.h
parent1ac1581f3889d5f7e6e231c05651f44fbd80f0b6 (diff)
downloadexternal_mesa3d-83dedb6354d0e9b04e8ccad77e86bdb7bad44bdd.zip
external_mesa3d-83dedb6354d0e9b04e8ccad77e86bdb7bad44bdd.tar.gz
external_mesa3d-83dedb6354d0e9b04e8ccad77e86bdb7bad44bdd.tar.bz2
i965: Add src/dst interference for certain instructions with hazards.
When working on tessellation shaders, I created some vec4 virtual opcodes for creating message headers through a sequence like: mov(8) g7<1>UD 0x00000000UD { align1 WE_all 1Q compacted }; mov(1) g7.5<1>UD 0x00000100UD { align1 WE_all }; mov(1) g7<1>UD g0<0,1,0>UD { align1 WE_all compacted }; mov(1) g7.3<1>UD g8<0,1,0>UD { align1 WE_all }; This is done in the generator since the vec4 backend can't handle align1 regioning. From the visitor's point of view, this is a single opcode: hs_set_output_urb_offsets vgrf7.0:UD, 1U, vgrf8.xxxx:UD Normally, there's no hazard between sources and destinations - an instruction (naturally) reads its sources, then writes the result to the destination. However, when the virtual instruction generates multiple hardware instructions, we can get into trouble. In the above example, if the register allocator assigned vgrf7 and vgrf8 to the same hardware register, then we'd clobber the source with 0 in the first instruction, and read back the wrong value in the last one. It occured to me that this is exactly the same problem we have with SIMD16 instructions that use W/UW or B/UB types with 0 stride. The hardware implicitly decodes them as two SIMD8 instructions, and with the overlapping regions, the first would clobber the second. Previously, we handled that by incrementing the live range end IP by 1, which works, but is excessive: the next instruction doesn't actually care about that. It might also be the end of control flow. This might keep values alive too long. What we really want is to say "my source and destinations interfere". This patch creates new infrastructure for doing just that, and teaches the register allocator to add interference when there's a hazard. For my vec4 case, we can determine this by switching on opcodes. For the SIMD16 case, we just move the existing code there. I audited our existing virtual opcodes that generate multiple instructions; I believe FS_OPCODE_PACK_HALF_2x16_SPLIT needs this treatment as well, but no others. v2: Rebased by mattst88. Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Matt Turner <mattst88@gmail.com>
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_ir_fs.h')
-rw-r--r--src/mesa/drivers/dri/i965/brw_ir_fs.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_ir_fs.h b/src/mesa/drivers/dri/i965/brw_ir_fs.h
index 84ee529..c3eec2e 100644
--- a/src/mesa/drivers/dri/i965/brw_ir_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_ir_fs.h
@@ -205,6 +205,7 @@ public:
bool can_do_source_mods(const struct brw_device_info *devinfo);
bool can_change_types() const;
bool has_side_effects() const;
+ bool has_source_and_destination_hazard() const;
bool reads_flag() const;
bool writes_flag() const;