Meta-instructions that implicitly write then read/consume a MRF value don't pose write-after-write conflicts with each other, since they're actually:
- Write value 1, then consume it. - Write value 2, then consume it. These can safely be done in either order. By tracking the last implicit write as an additional piece of information, all explicit/explicit or implicit/explicit dependencies are still handled exactly as they were, which I believe is necessary. Fixes es3conform's uniform_buffer_object_max_uniform_block_size test on Sandybridge (together with the previous patch). NOTE: This is a candidate for the 9.1 branch. Cc: Eric Anholt <e...@anholt.net> Cc: Ian Romanick <i...@freedesktop.org> Cc: Matt Turner <matts...@gmail.com> Signed-off-by: Kenneth Graunke <kenneth.w.grau...@intel.com> --- .../drivers/dri/i965/brw_fs_schedule_instructions.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_fs_schedule_instructions.cpp b/src/mesa/drivers/dri/i965/brw_fs_schedule_instructions.cpp index 166b79f..35a1b55 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_schedule_instructions.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_schedule_instructions.cpp @@ -443,6 +443,7 @@ instruction_scheduler::calculate_deps() */ schedule_node *last_grf_write[grf_count]; schedule_node *last_mrf_write[BRW_MAX_MRF]; + schedule_node *last_implied_mrf_write[BRW_MAX_MRF]; schedule_node *last_conditional_mod[2] = { NULL, NULL }; /* Fixed HW registers are assumed to be separate from the virtual * GRFs, so they can be tracked separately. We don't really write @@ -463,6 +464,7 @@ instruction_scheduler::calculate_deps() memset(last_grf_write, 0, sizeof(last_grf_write)); memset(last_mrf_write, 0, sizeof(last_mrf_write)); + memset(last_implied_mrf_write, 0, sizeof(last_implied_mrf_write)); /* top-to-bottom dependencies: RAW and WAW. */ foreach_list(node, &instructions) { @@ -550,8 +552,19 @@ instruction_scheduler::calculate_deps() if (inst->mlen > 0) { for (int i = 0; i < v->implied_mrf_writes(inst); i++) { - add_dep(last_mrf_write[inst->base_mrf + i], n); - last_mrf_write[inst->base_mrf + i] = n; + int reg = inst->base_mrf + i; + + /* Implied MRF writes both write and consume the values, in one + * atomic "instruction" (from the scheduler's point of view). + * + * If both are implied writes, the two operations can be scheduled + * in either order, and there's no actual dependency. + */ + if (last_mrf_write[reg] != last_implied_mrf_write[reg]) + add_dep(last_mrf_write[inst->base_mrf + i], n); + + last_mrf_write[reg] = n; + last_implied_mrf_write[reg] = n; } } @@ -568,6 +581,7 @@ instruction_scheduler::calculate_deps() /* bottom-to-top dependencies: WAR */ memset(last_grf_write, 0, sizeof(last_grf_write)); memset(last_mrf_write, 0, sizeof(last_mrf_write)); + memset(last_implied_mrf_write, 0, sizeof(last_implied_mrf_write)); memset(last_conditional_mod, 0, sizeof(last_conditional_mod)); last_fixed_grf_write = NULL; -- 1.8.1.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev