radeonsi: remove si_shader_selector::type
[mesa.git] / src / gallium / drivers / freedreno / freedreno_log.c
index 3edbcdede74914f5e0accf111c8133ba95d412c8..ad4c49eb2ec40919720cdb5859fa6057e6e76da5 100644 (file)
  * for profiling at that level.
  */
 
-const unsigned bo_size = 0x1000;
-const unsigned msgs_per_chunk = bo_size / sizeof(uint64_t);
+enum {
+       bo_size = 0x1000,
+       msgs_per_chunk = bo_size / sizeof(uint64_t),
+};
 
 struct fd_log_chunk {
        struct list_head node;
@@ -66,7 +68,9 @@ struct fd_log_chunk {
        /* 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;
 };
 
 static struct fd_log_chunk *
@@ -80,6 +84,10 @@ get_chunk(struct fd_batch *batch)
                                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: */
@@ -87,6 +95,7 @@ get_chunk(struct fd_batch *batch)
        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);
 
@@ -103,41 +112,65 @@ free_chunk(struct fd_log_chunk *chunk)
        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)
 {
-       printf("+----- 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;
 
        while (u_fifo_pop(chunk->msg_fifo, (void **)&msg)) {
                uint64_t ts = timestamps[n++];
                uint64_t ns = ctx->ts_to_ns(ts);
-               int32_t delta = last_time_ns ? ns - last_time_ns : 0;
-
-               if (!first_time_ns)
-                       first_time_ns = ns;
-
-               last_time_ns = ns;
-
-               printf("%016"PRIu64" %016"PRIu64" %+9d: %s\n", ts, ns, delta, msg);
+               int32_t delta;
+
+               if (!t->first_time_ns)
+                       t->first_time_ns = ns;
+
+               if (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 = t->last_time_ns;
+                       delta = 0;
+               }
+
+               fprintf(ctx->log_out, "%016"PRIu64" %016"PRIu64" %+9d: %s\n",
+                       ts, ns, delta, msg);
                free(msg);
 
        }
 
-       printf("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)
-               printf("END OF FRAME %u\n", ctx->frame_nr++);
+               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);
@@ -150,9 +183,18 @@ fd_log_process(struct fd_context *ctx, bool wait)
                if (ret)
                        break;
 
-               process_chunk(ctx, chunk);
+               process_chunk(ctx, chunk, &times);
                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);
 }
 
 void
@@ -173,17 +215,32 @@ _fd_log(struct fd_batch *batch, const char *fmt, ...)
 
        va_list ap;
        va_start(ap, fmt);
-       if (vasprintf(&msg, fmt, ap) < 0)
+       if (vasprintf(&msg, fmt, ap) < 0) {
+               va_end(ap);
                return;
+       }
        va_end(ap);
 
        u_fifo_add(chunk->msg_fifo, msg);
 
        assert(ctx->record_timestamp);
-       ctx->record_timestamp(ring, chunk->timestamps_bo,
-                       chunk->num_msgs * sizeof(uint64_t));
+
+       /* If nothing else has been emitted to the ring since the last log msg,
+        * skip emitting another timestamp.
+        */
+       if (ring->cur == chunk->ring_cur) {
+               uint64_t *ts = fd_bo_map(chunk->timestamps_bo);
+               /* zero signifies an invalid timestamp to process_chunk(), so it
+                * will use the last valid timestamp for this msg instead.
+                */
+               ts[chunk->num_msgs] = 0;
+       } else {
+               ctx->record_timestamp(ring, chunk->timestamps_bo,
+                               chunk->num_msgs * sizeof(uint64_t));
+       }
 
        chunk->num_msgs++;
+       chunk->ring_cur = ring->cur;
 }
 
 void fd_log_eof(struct fd_context *ctx)
@@ -192,7 +249,7 @@ void fd_log_eof(struct fd_context *ctx)
                return;
 
        if (list_is_empty(&ctx->log_chunks)) {
-               printf("WARNING: no log chunks!\n");
+               fprintf(ctx->log_out, "WARNING: no log chunks!\n");
                return;
        }