Mesa (master): intel/aubinator: Properly handle batch buffer chaining

Jason Ekstrand jekstrand at kemper.freedesktop.org
Tue Nov 29 00:45:51 UTC 2016


Module: Mesa
Branch: master
Commit: d6cef320477354f1c139c0bb7fb9b68731aa15cd
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=d6cef320477354f1c139c0bb7fb9b68731aa15cd

Author: Jason Ekstrand <jason at jlekstrand.net>
Date:   Thu Sep  8 21:12:11 2016 -0700

intel/aubinator: Properly handle batch buffer chaining

The original aubinator that Kristian wrote had a bug in the handling of
MI_BATCH_BUFFER_START that propagated into the version in upstream mesa.
In particular, it ignored the "2nd level" bit which tells you whether this
MI_BATCH_BUFFER_START is a subroutine call (2nd level) or a goto.  Since
the Vulkan driver uses batch chaining, this can lead to a very confusing
interpretation of the batches.  In some cases, depending on how things are
laid out in the virtual GTT, you can even end up with infinite loops in
batch processing.

Reviewed-by: Kristian H. Kristensen <hoegsberg at google.com>

---

 src/intel/tools/aubinator.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/src/intel/tools/aubinator.c b/src/intel/tools/aubinator.c
index 0d4b3f9..78682c5 100644
--- a/src/intel/tools/aubinator.c
+++ b/src/intel/tools/aubinator.c
@@ -790,7 +790,25 @@ parse_commands(struct gen_spec *spec, uint32_t *cmds, int size, int engine)
          else
             start = p[1];
 
-         parse_commands(spec, gtt + start, 1 << 20, engine);
+         if (p[0] & (1 << 22)) {
+            /* MI_BATCH_BUFFER_START with "2nd Level Batch Buffer" set acts
+             * like a subroutine call.  Commands that come afterwards get
+             * processed once the 2nd level batch buffer returns with
+             * MI_BATCH_BUFFER_END.
+             */
+            parse_commands(spec, gtt + start, gtt_end - start, engine);
+         } else {
+            /* MI_BATCH_BUFFER_START with "2nd Level Batch Buffer" unset acts
+             * like a goto.  Nothing after it will ever get processed.  In
+             * order to prevent the recursion from growing, we just reset the
+             * loop and continue;
+             */
+            p = gtt + start;
+            /* We don't know where secondaries end so use the GTT end */
+            end = gtt + gtt_end;
+            length = 0;
+            continue;
+         }
       } else if ((p[0] & 0xffff0000) == AUB_MI_BATCH_BUFFER_END) {
          break;
       }




More information about the mesa-commit mailing list