[Mesa-dev] [PATCH 2/2] gallium/hud: Add a frame time query

Bas Nieuwenhuizen bas at basnieuwenhuizen.nl
Thu Feb 18 23:59:19 UTC 2016


Implements a query that tracks the time between frames. It can track
three things:
  - wall clock time
  - elapsed time of the process
  - elapsed time of the current thread

The last option is bogus when the context is passed around between
threads, but is still very useful for the many applications that
do not do that.

Signed-off-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
---
 src/gallium/auxiliary/Makefile.sources     |   1 +
 src/gallium/auxiliary/hud/hud_context.c    |  18 +++++
 src/gallium/auxiliary/hud/hud_frame_time.c | 114 +++++++++++++++++++++++++++++
 src/gallium/auxiliary/hud/hud_private.h    |   1 +
 4 files changed, 134 insertions(+)
 create mode 100644 src/gallium/auxiliary/hud/hud_frame_time.c

diff --git a/src/gallium/auxiliary/Makefile.sources b/src/gallium/auxiliary/Makefile.sources
index 84da85c..3bc0e09 100644
--- a/src/gallium/auxiliary/Makefile.sources
+++ b/src/gallium/auxiliary/Makefile.sources
@@ -64,6 +64,7 @@ C_SOURCES := \
 	hud/hud_cpu.c \
 	hud/hud_driver_query.c \
 	hud/hud_fps.c \
+	hud/hud_frame_time.c \
 	hud/hud_private.h \
 	indices/u_indices.h \
 	indices/u_indices_priv.h \
diff --git a/src/gallium/auxiliary/hud/hud_context.c b/src/gallium/auxiliary/hud/hud_context.c
index fb99834..1fe3b75 100644
--- a/src/gallium/auxiliary/hud/hud_context.c
+++ b/src/gallium/auxiliary/hud/hud_context.c
@@ -40,6 +40,8 @@
 #include "hud/hud_private.h"
 #include "hud/font.h"
 
+#include "os/os_time.h"
+
 #include "cso_cache/cso_context.h"
 #include "util/u_draw_quad.h"
 #include "util/u_inlines.h"
@@ -917,6 +919,16 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
                                 PIPE_DRIVER_QUERY_RESULT_TYPE_AVERAGE,
                                 0);
       }
+      else if(strcmp(name, "frame-time") == 0 && os_cpu_time_supported()) {
+         hud_frame_time_graph_install(pane, 0);
+      }
+      else if(strcmp(name, "frame-cpu-time") == 0 && os_cpu_time_supported()) {
+         hud_frame_time_graph_install(pane, 1);
+      }
+      else if(strcmp(name, "frame-cpu-thread-time") == 0 &&
+              os_cpu_time_supported()) {
+         hud_frame_time_graph_install(pane, 2);
+      }
       else {
          boolean processed = FALSE;
 
@@ -1089,6 +1101,12 @@ print_help(struct pipe_screen *screen)
    for (i = 0; i < num_cpus; i++)
       printf("    cpu%i\n", i);
 
+   puts("    frame-time");
+   if (os_cpu_time_supported()) {
+      puts("    frame-cpu-time");
+      puts("    frame-cpu-thread-time");
+   }
+
    if (has_occlusion_query(screen))
       puts("    samples-passed");
    if (has_streamout(screen))
diff --git a/src/gallium/auxiliary/hud/hud_frame_time.c b/src/gallium/auxiliary/hud/hud_frame_time.c
new file mode 100644
index 0000000..c37c629
--- /dev/null
+++ b/src/gallium/auxiliary/hud/hud_frame_time.c
@@ -0,0 +1,114 @@
+/**************************************************************************
+ *
+ * Copyright 2016 Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* This file contains code for tracking the time between frames.
+ */
+
+#include "hud/hud_private.h"
+#include "os/os_time.h"
+#include "util/u_memory.h"
+
+
+#include "time.h"
+
+struct frame_time_info {
+   int specificity;
+   int64_t previous_cpu_time;
+   int64_t previous_time;
+   int frames;
+};
+
+static void
+query_frame_cpu_time(struct hud_graph *gr)
+{
+   struct frame_time_info *info = gr->query_data;
+   int64_t now = os_time_get();
+   int64_t now_cpu;
+   if (info->specificity == 2)
+      now_cpu = os_thread_time_get_nano();
+   else if(info->specificity == 1)
+      now_cpu = os_process_time_get_nano();
+   else
+      now_cpu = os_time_get_nano();
+
+   ++info->frames;
+
+   if (info->previous_time) {
+      if (info->previous_time + gr->pane->period <= now) {
+         double avg = (double)(now_cpu - info->previous_cpu_time) / info->frames;
+         info->frames = 0;
+         info->previous_time = now;
+         info->previous_cpu_time = now_cpu;
+
+         hud_graph_add_value(gr, (uint64_t) avg);
+      }
+   } else {
+      info->previous_time = now;
+      info->previous_cpu_time = now_cpu;
+   }
+}
+
+static void
+free_query_data(void *p)
+{
+   FREE(p);
+}
+
+/*
+ * Installs the query to track frame times. Valid values for specificity:
+ * 0 - wall clock frame time
+ * 1 - elapsed process CPU time during the frame
+ * 2 - elapsed thread CPU time during the frame
+ */
+void
+hud_frame_time_graph_install(struct hud_pane *pane, int specificity)
+{
+   struct frame_time_info *info;
+   struct hud_graph *gr = CALLOC_STRUCT(hud_graph);
+
+   if (!gr)
+      return;
+
+   if (specificity == 2)
+      strcpy(gr->name, "frame cpu thread time (ns)");
+   else if (specificity == 1)
+      strcpy(gr->name, "frame cpu time (ns)");
+   else
+      strcpy(gr->name, "frame time (ns)");
+
+   info = CALLOC_STRUCT(frame_time_info);
+   if (!info) {
+      FREE(gr);
+      return;
+   }
+   info->specificity = specificity;
+   gr->query_data = info;
+   gr->query_new_value = query_frame_cpu_time;
+   gr->free_query_data = free_query_data;
+
+   hud_pane_add_graph(pane, gr);
+}
diff --git a/src/gallium/auxiliary/hud/hud_private.h b/src/gallium/auxiliary/hud/hud_private.h
index 4a788bb..ccc577a 100644
--- a/src/gallium/auxiliary/hud/hud_private.h
+++ b/src/gallium/auxiliary/hud/hud_private.h
@@ -99,6 +99,7 @@ void hud_pipe_query_install(struct hud_batch_query_context **pbq,
 boolean hud_driver_query_install(struct hud_batch_query_context **pbq,
                                  struct hud_pane *pane,
                                  struct pipe_context *pipe, const char *name);
+void hud_frame_time_graph_install(struct hud_pane *pane, int specificity);
 void hud_batch_query_update(struct hud_batch_query_context *bq);
 void hud_batch_query_cleanup(struct hud_batch_query_context **pbq);
 
-- 
2.7.1



More information about the mesa-dev mailing list