/* list of recorded 64b timestamps */
        struct fd_bo *timestamps_bo;
 
-       bool eof;
+       bool last;          /* this chunk is last in submit */
+       bool eof;           /* this chunk is last in frame */
        uint32_t *ring_cur;
 };
 
                                struct fd_log_chunk, node);
                if (chunk->num_msgs < msgs_per_chunk)
                        return chunk;
+               /* we need to expand to add another chunk to the batch, so
+                * the current one is no longer the last one of the batch:
+                */
+               chunk->last = false;
        }
 
        /* .. if not, then create a new one: */
        chunk->msg_fifo = u_fifo_create(msgs_per_chunk);
        chunk->timestamps_bo = fd_bo_new(batch->ctx->screen->dev, bo_size,
                        DRM_FREEDRENO_GEM_TYPE_KMEM, "timestamps");
+       chunk->last = true;
 
        list_addtail(&chunk->node, &batch->log_chunks);
 
        free(chunk);
 }
 
+/* state to accumulate time across N chunks associated with a single batch: */
+struct times {
+       uint64_t last_time_ns;
+       uint64_t first_time_ns;
+};
+
 static void
-process_chunk(struct fd_context *ctx, struct fd_log_chunk *chunk)
+process_chunk(struct fd_context *ctx, struct fd_log_chunk *chunk, struct times *t)
 {
-       fprintf(ctx->log_out, "+----- TS -----+ +----- NS -----+ +-- Δ --+  +----- MSG -----\n");
+       /* For first chunk of batch, accumulated times will be zerod: */
+       if (!t->last_time_ns) {
+               fprintf(ctx->log_out,
+                       "+----- TS -----+ +----- NS -----+ +-- Δ --+  +----- MSG -----\n");
+       }
 
        uint64_t *timestamps = fd_bo_map(chunk->timestamps_bo);
-       uint64_t last_time_ns = 0;
-       uint64_t first_time_ns = 0;
        unsigned n = 0;
        char *msg;
 
                uint64_t ns = ctx->ts_to_ns(ts);
                int32_t delta;
 
-               if (!first_time_ns)
-                       first_time_ns = ns;
+               if (!t->first_time_ns)
+                       t->first_time_ns = ns;
 
                if (ns) {
-                       delta = last_time_ns ? ns - last_time_ns : 0;
-                       last_time_ns = ns;
+                       delta = t->last_time_ns ? ns - t->last_time_ns : 0;
+                       t->last_time_ns = ns;
                } else {
                        /* we skipped recording the timestamp, so it should be
                         * the same as last msg:
                         */
-                       ns = last_time_ns;
+                       ns = t->last_time_ns;
                        delta = 0;
                }
 
-               fprintf(ctx->log_out, "%016"PRIu64" %016"PRIu64" %+9d: %s\n", ts, ns, delta, msg);
+               fprintf(ctx->log_out, "%016"PRIu64" %016"PRIu64" %+9d: %s\n",
+                       ts, ns, delta, msg);
                free(msg);
 
        }
 
-       fprintf(ctx->log_out, "ELAPSED: %"PRIu64" ns\n", last_time_ns - first_time_ns);
+       if (chunk->last) {
+               fprintf(ctx->log_out, "ELAPSED: %"PRIu64" ns\n",
+                       t->last_time_ns - t->first_time_ns);
+               memset(t, 0, sizeof(*t));
+       }
 
        if (chunk->eof)
                fprintf(ctx->log_out, "END OF FRAME %u\n", ctx->frame_nr++);
 void
 fd_log_process(struct fd_context *ctx, bool wait)
 {
+       struct times times = {0};
+
        while (!list_is_empty(&ctx->log_chunks)) {
                struct fd_log_chunk *chunk = list_first_entry(&ctx->log_chunks,
                                struct fd_log_chunk, node);
                if (ret)
                        break;
 
-               process_chunk(ctx, chunk);
+               process_chunk(ctx, chunk, ×);
                free_chunk(chunk);
        }
 
+       /* We expect that the last processed chunk was the last in it's
+        * batch, which should reset the times:
+        */
+       if (times.last_time_ns) {
+               fprintf(ctx->log_out, "WARNING: last processed chunk not last in batch?");
+       }
+
        fflush(ctx->log_out);
 }