summaryrefslogtreecommitdiff
path: root/lib/mesa/src/gallium/auxiliary/hud
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2019-01-29 11:52:33 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2019-01-29 11:52:33 +0000
commit37bbf6a1792773f11c15a4da1588a7520ee2fb4e (patch)
tree64944d4aa665a1e479cfc004e446593062254550 /lib/mesa/src/gallium/auxiliary/hud
parent6b139c2063623e9310025247cd966490b9aa57ea (diff)
Merge Mesa 18.3.2
Diffstat (limited to 'lib/mesa/src/gallium/auxiliary/hud')
-rw-r--r--lib/mesa/src/gallium/auxiliary/hud/hud_context.c590
-rw-r--r--lib/mesa/src/gallium/auxiliary/hud/hud_context.h10
-rw-r--r--lib/mesa/src/gallium/auxiliary/hud/hud_cpu.c19
-rw-r--r--lib/mesa/src/gallium/auxiliary/hud/hud_cpufreq.c14
-rw-r--r--lib/mesa/src/gallium/auxiliary/hud/hud_diskstat.c6
-rw-r--r--lib/mesa/src/gallium/auxiliary/hud/hud_driver_query.c85
-rw-r--r--lib/mesa/src/gallium/auxiliary/hud/hud_fps.c40
-rw-r--r--lib/mesa/src/gallium/auxiliary/hud/hud_nic.c6
-rw-r--r--lib/mesa/src/gallium/auxiliary/hud/hud_private.h39
-rw-r--r--lib/mesa/src/gallium/auxiliary/hud/hud_sensors_temp.c19
10 files changed, 556 insertions, 272 deletions
diff --git a/lib/mesa/src/gallium/auxiliary/hud/hud_context.c b/lib/mesa/src/gallium/auxiliary/hud/hud_context.c
index ed2e84911..9f9db850a 100644
--- a/lib/mesa/src/gallium/auxiliary/hud/hud_context.c
+++ b/lib/mesa/src/gallium/auxiliary/hud/hud_context.c
@@ -74,7 +74,10 @@ hud_draw_colored_prims(struct hud_context *hud, unsigned prim,
struct cso_context *cso = hud->cso;
unsigned size = num_vertices * hud->color_prims.vbuf.stride;
- assert(size <= hud->color_prims.buffer_size);
+ /* If a recording context is inactive, don't draw anything. */
+ if (size > hud->color_prims.buffer_size)
+ return;
+
memcpy(hud->color_prims.vertices, buffer, size);
hud->constants.color[0] = r;
@@ -87,8 +90,7 @@ hud_draw_colored_prims(struct hud_context *hud, unsigned prim,
hud->constants.scale[1] = yscale;
cso_set_constant_buffer(cso, PIPE_SHADER_VERTEX, 0, &hud->constbuf);
- cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso),
- 1, &hud->color_prims.vbuf);
+ cso_set_vertex_buffers(cso, 0, 1, &hud->color_prims.vbuf);
cso_set_fragment_shader_handle(hud->cso, hud->fs_color);
cso_draw_arrays(cso, prim, 0, num_vertices);
@@ -221,6 +223,7 @@ number_to_human_readable(double num, enum pipe_driver_query_type type,
static const char *volt_units[] = {" mV", " V"};
static const char *amp_units[] = {" mA", " A"};
static const char *watt_units[] = {" mW", " W"};
+ static const char *float_units[] = {""};
const char **units;
unsigned max_unit;
@@ -249,6 +252,10 @@ number_to_human_readable(double num, enum pipe_driver_query_type type,
max_unit = ARRAY_SIZE(temperature_units)-1;
units = temperature_units;
break;
+ case PIPE_DRIVER_QUERY_TYPE_FLOAT:
+ max_unit = ARRAY_SIZE(float_units)-1;
+ units = float_units;
+ break;
case PIPE_DRIVER_QUERY_TYPE_PERCENTAGE:
max_unit = ARRAY_SIZE(percent_units)-1;
units = percent_units;
@@ -391,6 +398,26 @@ hud_pane_accumulate_vertices(struct hud_context *hud,
}
static void
+hud_pane_accumulate_vertices_simple(struct hud_context *hud,
+ const struct hud_pane *pane)
+{
+ struct hud_graph *gr;
+ unsigned i;
+ char str[32];
+
+ /* draw info below the pane */
+ i = 0;
+ LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) {
+ unsigned x = pane->x1;
+ unsigned y = pane->y_simple + i*hud->font.glyph_height;
+
+ number_to_human_readable(gr->current_value, pane->type, str);
+ hud_draw_string(hud, x, y, "%s: %s", gr->name, str);
+ i++;
+ }
+}
+
+static void
hud_pane_draw_colored_objects(struct hud_context *hud,
const struct hud_pane *pane)
{
@@ -428,8 +455,8 @@ hud_prepare_vertices(struct hud_context *hud, struct vertex_queue *v,
* Draw the HUD to the texture \p tex.
* The texture is usually the back buffer being displayed.
*/
-void
-hud_draw(struct hud_context *hud, struct pipe_resource *tex)
+static void
+hud_draw_results(struct hud_context *hud, struct pipe_resource *tex)
{
struct cso_context *cso = hud->cso;
struct pipe_context *pipe = hud->pipe;
@@ -439,7 +466,6 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
const struct pipe_sampler_state *sampler_states[] =
{ &hud->font_sampler_state };
struct hud_pane *pane;
- struct hud_graph *gr, *next;
if (!huds_visible)
return;
@@ -519,6 +545,100 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, 1, sampler_states);
cso_set_constant_buffer(cso, PIPE_SHADER_VERTEX, 0, &hud->constbuf);
+ /* draw accumulated vertices for background quads */
+ cso_set_blend(cso, &hud->alpha_blend);
+ cso_set_fragment_shader_handle(hud->cso, hud->fs_color);
+
+ if (hud->bg.num_vertices) {
+ hud->constants.color[0] = 0;
+ hud->constants.color[1] = 0;
+ hud->constants.color[2] = 0;
+ hud->constants.color[3] = 0.666f;
+ hud->constants.translate[0] = 0;
+ hud->constants.translate[1] = 0;
+ hud->constants.scale[0] = 1;
+ hud->constants.scale[1] = 1;
+
+ cso_set_constant_buffer(cso, PIPE_SHADER_VERTEX, 0, &hud->constbuf);
+ cso_set_vertex_buffers(cso, 0, 1, &hud->bg.vbuf);
+ cso_draw_arrays(cso, PIPE_PRIM_QUADS, 0, hud->bg.num_vertices);
+ }
+ pipe_resource_reference(&hud->bg.vbuf.buffer.resource, NULL);
+
+ /* draw accumulated vertices for text */
+ if (hud->text.num_vertices) {
+ cso_set_vertex_buffers(cso, 0, 1, &hud->text.vbuf);
+ cso_set_fragment_shader_handle(hud->cso, hud->fs_text);
+ cso_draw_arrays(cso, PIPE_PRIM_QUADS, 0, hud->text.num_vertices);
+ }
+ pipe_resource_reference(&hud->text.vbuf.buffer.resource, NULL);
+
+ if (hud->simple) {
+ cso_restore_state(cso);
+ cso_restore_constant_buffer_slot0(cso, PIPE_SHADER_VERTEX);
+
+ pipe_surface_reference(&surf, NULL);
+ return;
+ }
+
+ /* draw accumulated vertices for white lines */
+ cso_set_blend(cso, &hud->no_blend);
+
+ hud->constants.color[0] = 1;
+ hud->constants.color[1] = 1;
+ hud->constants.color[2] = 1;
+ hud->constants.color[3] = 1;
+ hud->constants.translate[0] = 0;
+ hud->constants.translate[1] = 0;
+ hud->constants.scale[0] = 1;
+ hud->constants.scale[1] = 1;
+ cso_set_constant_buffer(cso, PIPE_SHADER_VERTEX, 0, &hud->constbuf);
+
+ if (hud->whitelines.num_vertices) {
+ cso_set_vertex_buffers(cso, 0, 1, &hud->whitelines.vbuf);
+ cso_set_fragment_shader_handle(hud->cso, hud->fs_color);
+ cso_draw_arrays(cso, PIPE_PRIM_LINES, 0, hud->whitelines.num_vertices);
+ }
+ pipe_resource_reference(&hud->whitelines.vbuf.buffer.resource, NULL);
+
+ /* draw the rest */
+ cso_set_blend(cso, &hud->alpha_blend);
+ cso_set_rasterizer(cso, &hud->rasterizer_aa_lines);
+ LIST_FOR_EACH_ENTRY(pane, &hud->pane_list, head) {
+ if (pane)
+ hud_pane_draw_colored_objects(hud, pane);
+ }
+
+ cso_restore_state(cso);
+ cso_restore_constant_buffer_slot0(cso, PIPE_SHADER_VERTEX);
+
+ pipe_surface_reference(&surf, NULL);
+}
+
+static void
+hud_start_queries(struct hud_context *hud, struct pipe_context *pipe)
+{
+ struct hud_pane *pane;
+ struct hud_graph *gr;
+
+ /* Start queries. */
+ hud_batch_query_begin(hud->batch_query, pipe);
+
+ LIST_FOR_EACH_ENTRY(pane, &hud->pane_list, head) {
+ LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) {
+ if (gr->begin_query)
+ gr->begin_query(gr, pipe);
+ }
+ }
+}
+
+/* Stop queries, query results, and record vertices for charts. */
+static void
+hud_stop_queries(struct hud_context *hud, struct pipe_context *pipe)
+{
+ struct hud_pane *pane;
+ struct hud_graph *gr, *next;
+
/* prepare vertex buffers */
hud_prepare_vertices(hud, &hud->bg, 16 * 256, 2 * sizeof(float));
hud_prepare_vertices(hud, &hud->whitelines, 4 * 256, 2 * sizeof(float));
@@ -528,16 +648,15 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
/* Allocate everything once and divide the storage into 3 portions
* manually, because u_upload_alloc can unmap memory from previous calls.
*/
- u_upload_alloc(hud->pipe->stream_uploader, 0,
+ u_upload_alloc(pipe->stream_uploader, 0,
hud->bg.buffer_size +
hud->whitelines.buffer_size +
hud->text.buffer_size +
hud->color_prims.buffer_size,
16, &hud->bg.vbuf.buffer_offset, &hud->bg.vbuf.buffer.resource,
(void**)&hud->bg.vertices);
- if (!hud->bg.vertices) {
- goto out;
- }
+ if (!hud->bg.vertices)
+ return;
pipe_resource_reference(&hud->whitelines.vbuf.buffer.resource, hud->bg.vbuf.buffer.resource);
pipe_resource_reference(&hud->text.vbuf.buffer.resource, hud->bg.vbuf.buffer.resource);
@@ -559,11 +678,11 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
hud->text.buffer_size / sizeof(float);
/* prepare all graphs */
- hud_batch_query_update(hud->batch_query);
+ hud_batch_query_update(hud->batch_query, pipe);
LIST_FOR_EACH_ENTRY(pane, &hud->pane_list, head) {
LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) {
- gr->query_new_value(gr);
+ gr->query_new_value(gr, pipe);
}
if (pane->sort_items) {
@@ -583,86 +702,56 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
}
}
- hud_pane_accumulate_vertices(hud, pane);
+ if (hud->simple)
+ hud_pane_accumulate_vertices_simple(hud, pane);
+ else
+ hud_pane_accumulate_vertices(hud, pane);
}
/* unmap the uploader's vertex buffer before drawing */
u_upload_unmap(pipe->stream_uploader);
+}
- /* draw accumulated vertices for background quads */
- cso_set_blend(cso, &hud->alpha_blend);
- cso_set_fragment_shader_handle(hud->cso, hud->fs_color);
-
- if (hud->bg.num_vertices) {
- hud->constants.color[0] = 0;
- hud->constants.color[1] = 0;
- hud->constants.color[2] = 0;
- hud->constants.color[3] = 0.666f;
- hud->constants.translate[0] = 0;
- hud->constants.translate[1] = 0;
- hud->constants.scale[0] = 1;
- hud->constants.scale[1] = 1;
-
- cso_set_constant_buffer(cso, PIPE_SHADER_VERTEX, 0, &hud->constbuf);
- cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso), 1,
- &hud->bg.vbuf);
- cso_draw_arrays(cso, PIPE_PRIM_QUADS, 0, hud->bg.num_vertices);
- }
- pipe_resource_reference(&hud->bg.vbuf.buffer.resource, NULL);
-
- /* draw accumulated vertices for white lines */
- cso_set_blend(cso, &hud->no_blend);
-
- hud->constants.color[0] = 1;
- hud->constants.color[1] = 1;
- hud->constants.color[2] = 1;
- hud->constants.color[3] = 1;
- hud->constants.translate[0] = 0;
- hud->constants.translate[1] = 0;
- hud->constants.scale[0] = 1;
- hud->constants.scale[1] = 1;
- cso_set_constant_buffer(cso, PIPE_SHADER_VERTEX, 0, &hud->constbuf);
-
- if (hud->whitelines.num_vertices) {
- cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso), 1,
- &hud->whitelines.vbuf);
- cso_set_fragment_shader_handle(hud->cso, hud->fs_color);
- cso_draw_arrays(cso, PIPE_PRIM_LINES, 0, hud->whitelines.num_vertices);
- }
- pipe_resource_reference(&hud->whitelines.vbuf.buffer.resource, NULL);
+/**
+ * Record queries and draw the HUD. The "cso" parameter acts as a filter.
+ * If "cso" is not the recording context, recording is skipped.
+ * If "cso" is not the drawing context, drawing is skipped.
+ * cso == NULL ignores the filter.
+ */
+void
+hud_run(struct hud_context *hud, struct cso_context *cso,
+ struct pipe_resource *tex)
+{
+ struct pipe_context *pipe = cso ? cso_get_pipe_context(cso) : NULL;
- /* draw accumulated vertices for text */
- cso_set_blend(cso, &hud->alpha_blend);
- if (hud->text.num_vertices) {
- cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso), 1,
- &hud->text.vbuf);
- cso_set_fragment_shader_handle(hud->cso, hud->fs_text);
- cso_draw_arrays(cso, PIPE_PRIM_QUADS, 0, hud->text.num_vertices);
- }
- pipe_resource_reference(&hud->text.vbuf.buffer.resource, NULL);
+ /* If "cso" is the recording or drawing context or NULL, execute
+ * the operation. Otherwise, don't do anything.
+ */
+ if (hud->record_pipe && (!pipe || pipe == hud->record_pipe))
+ hud_stop_queries(hud, hud->record_pipe);
- /* draw the rest */
- cso_set_rasterizer(cso, &hud->rasterizer_aa_lines);
- LIST_FOR_EACH_ENTRY(pane, &hud->pane_list, head) {
- if (pane)
- hud_pane_draw_colored_objects(hud, pane);
- }
+ if (hud->cso && (!cso || cso == hud->cso))
+ hud_draw_results(hud, tex);
-out:
- cso_restore_state(cso);
- cso_restore_constant_buffer_slot0(cso, PIPE_SHADER_VERTEX);
+ if (hud->record_pipe && (!pipe || pipe == hud->record_pipe))
+ hud_start_queries(hud, hud->record_pipe);
+}
- pipe_surface_reference(&surf, NULL);
+/**
+ * Record query results and assemble vertices if "pipe" is a recording but
+ * not drawing context.
+ */
+void
+hud_record_only(struct hud_context *hud, struct pipe_context *pipe)
+{
+ assert(pipe);
- /* Start queries. */
- hud_batch_query_begin(hud->batch_query);
+ /* If it's a drawing context, only hud_run() records query results. */
+ if (pipe == hud->pipe || pipe != hud->record_pipe)
+ return;
- LIST_FOR_EACH_ENTRY(pane, &hud->pane_list, head) {
- LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) {
- if (gr->begin_query)
- gr->begin_query(gr);
- }
- }
+ hud_stop_queries(hud, hud->record_pipe);
+ hud_start_queries(hud, hud->record_pipe);
}
static void
@@ -780,6 +869,7 @@ hud_pane_update_dyn_ceiling(struct hud_graph *gr, struct hud_pane *pane)
static struct hud_pane *
hud_pane_create(struct hud_context *hud,
unsigned x1, unsigned y1, unsigned x2, unsigned y2,
+ unsigned y_simple,
unsigned period, uint64_t max_value, uint64_t ceiling,
boolean dyn_ceiling, boolean sort_items)
{
@@ -793,6 +883,7 @@ hud_pane_create(struct hud_context *hud,
pane->y1 = y1;
pane->x2 = x2;
pane->y2 = y2;
+ pane->y_simple = y_simple;
pane->inner_x1 = x1 + 1;
pane->inner_x2 = x2 - 1;
pane->inner_y1 = y1 + 1;
@@ -897,11 +988,11 @@ hud_graph_add_value(struct hud_graph *gr, double value)
}
static void
-hud_graph_destroy(struct hud_graph *graph)
+hud_graph_destroy(struct hud_graph *graph, struct pipe_context *pipe)
{
FREE(graph->vertices);
if (graph->free_query_data)
- graph->free_query_data(graph->query_data);
+ graph->free_query_data(graph->query_data, pipe);
if (graph->fd)
fclose(graph->fd);
FREE(graph);
@@ -1087,13 +1178,14 @@ has_pipeline_stats_query(struct pipe_screen *screen)
}
static void
-hud_parse_env_var(struct hud_context *hud, const char *env)
+hud_parse_env_var(struct hud_context *hud, struct pipe_screen *screen,
+ const char *env)
{
unsigned num, i;
char name_a[256], s[256];
char *name;
struct hud_pane *pane = NULL;
- unsigned x = 10, y = 10;
+ unsigned x = 10, y = 10, y_simple = 10;
unsigned width = 251, height = 100;
unsigned period = 500 * 1000; /* default period (1/2 second) */
uint64_t ceiling = UINT64_MAX;
@@ -1103,6 +1195,11 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
boolean sort_items = false;
const char *period_env;
+ if (util_strncmp(env, "simple,", 7) == 0) {
+ hud->simple = true;
+ env += 7;
+ }
+
/*
* The GALLIUM_HUD_PERIOD env var sets the graph update rate.
* The env var is in seconds (a float).
@@ -1117,6 +1214,8 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
}
while ((num = parse_string(env, name_a)) != 0) {
+ bool added = true;
+
env += num;
/* check for explicit location, size and etc. settings */
@@ -1131,8 +1230,8 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
column_width = width > column_width ? width : column_width;
if (!pane) {
- pane = hud_pane_create(hud, x, y, x + width, y + height, period, 10,
- ceiling, dyn_ceiling, sort_items);
+ pane = hud_pane_create(hud, x, y, x + width, y + height, y_simple,
+ period, 10, ceiling, dyn_ceiling, sort_items);
if (!pane)
return;
}
@@ -1143,13 +1242,16 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
}
/* Add a graph. */
-#if HAVE_GALLIUM_EXTRA_HUD || HAVE_LIBSENSORS
+#if defined(HAVE_GALLIUM_EXTRA_HUD) || defined(HAVE_LIBSENSORS)
char arg_name[64];
#endif
/* IF YOU CHANGE THIS, UPDATE print_help! */
if (strcmp(name, "fps") == 0) {
hud_fps_graph_install(pane);
}
+ else if (strcmp(name, "frametime") == 0) {
+ hud_frametime_graph_install(pane);
+ }
else if (strcmp(name, "cpu") == 0) {
hud_cpu_graph_install(pane, ALL_CPUS);
}
@@ -1171,7 +1273,7 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
else if (strcmp(name, "main-thread-busy") == 0) {
hud_thread_busy_install(pane, name, true);
}
-#if HAVE_GALLIUM_EXTRA_HUD
+#ifdef HAVE_GALLIUM_EXTRA_HUD
else if (sscanf(name, "nic-rx-%s", arg_name) == 1) {
hud_nic_graph_install(pane, arg_name, NIC_DIRECTION_RX);
}
@@ -1203,7 +1305,7 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
pane->type = PIPE_DRIVER_QUERY_TYPE_HZ;
}
#endif
-#if HAVE_LIBSENSORS
+#ifdef HAVE_LIBSENSORS
else if (sscanf(name, "sensors_temp_cu-%s", arg_name) == 1) {
hud_sensors_temp_graph_install(pane, arg_name,
SENSORS_TEMP_CURRENT);
@@ -1231,8 +1333,8 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
}
#endif
else if (strcmp(name, "samples-passed") == 0 &&
- has_occlusion_query(hud->pipe->screen)) {
- hud_pipe_query_install(&hud->batch_query, pane, hud->pipe,
+ has_occlusion_query(screen)) {
+ hud_pipe_query_install(&hud->batch_query, pane,
"samples-passed",
PIPE_QUERY_OCCLUSION_COUNTER, 0, 0,
PIPE_DRIVER_QUERY_TYPE_UINT64,
@@ -1240,8 +1342,8 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
0);
}
else if (strcmp(name, "primitives-generated") == 0 &&
- has_streamout(hud->pipe->screen)) {
- hud_pipe_query_install(&hud->batch_query, pane, hud->pipe,
+ has_streamout(screen)) {
+ hud_pipe_query_install(&hud->batch_query, pane,
"primitives-generated",
PIPE_QUERY_PRIMITIVES_GENERATED, 0, 0,
PIPE_DRIVER_QUERY_TYPE_UINT64,
@@ -1252,7 +1354,7 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
boolean processed = FALSE;
/* pipeline statistics queries */
- if (has_pipeline_stats_query(hud->pipe->screen)) {
+ if (has_pipeline_stats_query(screen)) {
static const char *pipeline_statistics_names[] =
{
"ia-vertices",
@@ -1271,7 +1373,7 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
if (strcmp(name, pipeline_statistics_names[i]) == 0)
break;
if (i < ARRAY_SIZE(pipeline_statistics_names)) {
- hud_pipe_query_install(&hud->batch_query, pane, hud->pipe, name,
+ hud_pipe_query_install(&hud->batch_query, pane, name,
PIPE_QUERY_PIPELINE_STATISTICS, i,
0, PIPE_DRIVER_QUERY_TYPE_UINT64,
PIPE_DRIVER_QUERY_RESULT_TYPE_AVERAGE,
@@ -1282,10 +1384,11 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
/* driver queries */
if (!processed) {
- if (!hud_driver_query_install(&hud->batch_query, pane, hud->pipe,
- name)) {
+ if (!hud_driver_query_install(&hud->batch_query, pane,
+ screen, name)) {
fprintf(stderr, "gallium_hud: unknown driver query '%s'\n", name);
fflush(stderr);
+ added = false;
}
}
}
@@ -1328,7 +1431,7 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
env += num;
strip_hyphens(s);
- if (!LIST_IS_EMPTY(&pane->graph_list)) {
+ if (added && !LIST_IS_EMPTY(&pane->graph_list)) {
struct hud_graph *graph;
graph = LIST_ENTRY(struct hud_graph, pane->graph_list.prev, head);
strncpy(graph->name, s, sizeof(graph->name)-1);
@@ -1351,6 +1454,7 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
break;
y += height + hud->font.glyph_height * (pane->num_graphs + 2);
+ y_simple += hud->font.glyph_height * (pane->num_graphs + 1);
height = 100;
if (pane && pane->num_graphs) {
@@ -1362,6 +1466,7 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
case ';':
env++;
y = 10;
+ y_simple = 10;
x += column_width + hud->font.glyph_width * 9;
height = 100;
@@ -1450,10 +1555,15 @@ print_help(struct pipe_screen *screen)
puts(" the Y axis does not go above the restriction imposed by 'c' while");
puts(" still adjusting the value of the Y axis down when appropriate.");
puts("");
+ puts(" You can change behavior of the whole HUD by adding these options at");
+ puts(" the beginning of the environment variable:");
+ puts(" 'simple,' disables all the fancy stuff and only draws text.");
+ puts("");
puts(" Example: GALLIUM_HUD=\".w256.h64.x1600.y520.d.c1000fps+cpu,.datom-count\"");
puts("");
puts(" Available names:");
puts(" fps");
+ puts(" frametime");
puts(" cpu");
for (i = 0; i < num_cpus; i++)
@@ -1478,12 +1588,12 @@ print_help(struct pipe_screen *screen)
puts(" cs-invocations");
}
-#if HAVE_GALLIUM_EXTRA_HUD
+#ifdef HAVE_GALLIUM_EXTRA_HUD
hud_get_num_disks(1);
hud_get_num_nics(1);
hud_get_num_cpufreq(1);
#endif
-#if HAVE_LIBSENSORS
+#ifdef HAVE_LIBSENSORS
hud_get_num_sensors(1);
#endif
@@ -1509,58 +1619,49 @@ print_help(struct pipe_screen *screen)
fflush(stdout);
}
-struct hud_context *
-hud_create(struct pipe_context *pipe, struct cso_context *cso)
+static void
+hud_unset_draw_context(struct hud_context *hud)
{
- struct pipe_screen *screen = pipe->screen;
- struct hud_context *hud;
- struct pipe_sampler_view view_templ;
- unsigned i;
- const char *env = debug_get_option("GALLIUM_HUD", NULL);
-#ifdef PIPE_OS_UNIX
- unsigned signo = debug_get_num_option("GALLIUM_HUD_TOGGLE_SIGNAL", 0);
- static boolean sig_handled = FALSE;
- struct sigaction action = {};
-#endif
- huds_visible = debug_get_bool_option("GALLIUM_HUD_VISIBLE", TRUE);
+ struct pipe_context *pipe = hud->pipe;
- if (!env || !*env)
- return NULL;
+ if (!pipe)
+ return;
- if (strcmp(env, "help") == 0) {
- print_help(pipe->screen);
- return NULL;
+ pipe_sampler_view_reference(&hud->font_sampler_view, NULL);
+
+ if (hud->fs_color) {
+ pipe->delete_fs_state(pipe, hud->fs_color);
+ hud->fs_color = NULL;
+ }
+ if (hud->fs_text) {
+ pipe->delete_fs_state(pipe, hud->fs_text);
+ hud->fs_text = NULL;
+ }
+ if (hud->vs) {
+ pipe->delete_vs_state(pipe, hud->vs);
+ hud->vs = NULL;
}
- hud = CALLOC_STRUCT(hud_context);
- if (!hud)
- return NULL;
+ hud->cso = NULL;
+ hud->pipe = NULL;
+}
+
+static bool
+hud_set_draw_context(struct hud_context *hud, struct cso_context *cso)
+{
+ struct pipe_context *pipe = cso_get_pipe_context(cso);
+ assert(!hud->pipe);
hud->pipe = pipe;
hud->cso = cso;
- /* font */
- if (!util_font_create(pipe, UTIL_FONT_FIXED_8X13, &hud->font)) {
- FREE(hud);
- return NULL;
- }
-
- hud->has_srgb = screen->is_format_supported(screen,
- PIPE_FORMAT_B8G8R8A8_SRGB,
- PIPE_TEXTURE_2D, 0,
- PIPE_BIND_RENDER_TARGET) != 0;
-
- /* blend state */
- hud->no_blend.rt[0].colormask = PIPE_MASK_RGBA;
-
- hud->alpha_blend.rt[0].colormask = PIPE_MASK_RGBA;
- hud->alpha_blend.rt[0].blend_enable = 1;
- hud->alpha_blend.rt[0].rgb_func = PIPE_BLEND_ADD;
- hud->alpha_blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
- hud->alpha_blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
- hud->alpha_blend.rt[0].alpha_func = PIPE_BLEND_ADD;
- hud->alpha_blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
- hud->alpha_blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
+ struct pipe_sampler_view view_templ;
+ u_sampler_view_default_template(
+ &view_templ, hud->font.texture, hud->font.texture->format);
+ hud->font_sampler_view = pipe->create_sampler_view(pipe, hud->font.texture,
+ &view_templ);
+ if (!hud->font_sampler_view)
+ goto fail;
/* fragment shader */
hud->fs_color =
@@ -1589,24 +1690,12 @@ hud_create(struct pipe_context *pipe, struct cso_context *cso)
if (!tgsi_text_translate(fragment_shader_text, tokens, ARRAY_SIZE(tokens))) {
assert(0);
- pipe_resource_reference(&hud->font.texture, NULL);
- FREE(hud);
- return NULL;
+ goto fail;
}
pipe_shader_state_from_tgsi(&state, tokens);
hud->fs_text = pipe->create_fs_state(pipe, &state);
}
- /* rasterizer */
- hud->rasterizer.half_pixel_center = 1;
- hud->rasterizer.bottom_edge_rule = 1;
- hud->rasterizer.depth_clip = 1;
- hud->rasterizer.line_width = 1;
- hud->rasterizer.line_last_pixel = 1;
-
- hud->rasterizer_aa_lines = hud->rasterizer;
- hud->rasterizer_aa_lines.line_smooth = 1;
-
/* vertex shader */
{
static const char *vertex_shader_text = {
@@ -1637,27 +1726,155 @@ hud_create(struct pipe_context *pipe, struct cso_context *cso)
struct pipe_shader_state state;
if (!tgsi_text_translate(vertex_shader_text, tokens, ARRAY_SIZE(tokens))) {
assert(0);
- pipe_resource_reference(&hud->font.texture, NULL);
- FREE(hud);
- return NULL;
+ goto fail;
}
pipe_shader_state_from_tgsi(&state, tokens);
hud->vs = pipe->create_vs_state(pipe, &state);
}
+ return true;
+
+fail:
+ hud_unset_draw_context(hud);
+ fprintf(stderr, "hud: failed to set a draw context");
+ return false;
+}
+
+static void
+hud_unset_record_context(struct hud_context *hud)
+{
+ struct pipe_context *pipe = hud->record_pipe;
+ struct hud_pane *pane, *pane_tmp;
+ struct hud_graph *graph, *graph_tmp;
+
+ if (!pipe)
+ return;
+
+ LIST_FOR_EACH_ENTRY_SAFE(pane, pane_tmp, &hud->pane_list, head) {
+ LIST_FOR_EACH_ENTRY_SAFE(graph, graph_tmp, &pane->graph_list, head) {
+ LIST_DEL(&graph->head);
+ hud_graph_destroy(graph, pipe);
+ }
+ LIST_DEL(&pane->head);
+ FREE(pane);
+ }
+
+ hud_batch_query_cleanup(&hud->batch_query, pipe);
+ hud->record_pipe = NULL;
+}
+
+static void
+hud_set_record_context(struct hud_context *hud, struct pipe_context *pipe)
+{
+ hud->record_pipe = pipe;
+}
+
+/**
+ * Create the HUD.
+ *
+ * If "share" is non-NULL and GALLIUM_HUD_SHARE=x,y is set, increment the
+ * reference counter of "share", set "cso" as the recording or drawing context
+ * according to the environment variable, and return "share".
+ * This allows sharing the HUD instance within a multi-context share group,
+ * record queries in one context and draw them in another.
+ */
+struct hud_context *
+hud_create(struct cso_context *cso, struct hud_context *share)
+{
+ const char *share_env = debug_get_option("GALLIUM_HUD_SHARE", NULL);
+ unsigned record_ctx = 0, draw_ctx = 0;
+
+ if (share_env && sscanf(share_env, "%u,%u", &record_ctx, &draw_ctx) != 2)
+ share_env = NULL;
+
+ if (share && share_env) {
+ /* All contexts in a share group share the HUD instance.
+ * Only one context can record queries and only one context
+ * can draw the HUD.
+ *
+ * GALLIUM_HUD_SHARE=x,y determines the context indices.
+ */
+ int context_id = p_atomic_inc_return(&share->refcount) - 1;
+
+ if (context_id == record_ctx) {
+ assert(!share->record_pipe);
+ hud_set_record_context(share, cso_get_pipe_context(cso));
+ }
+
+ if (context_id == draw_ctx) {
+ assert(!share->pipe);
+ hud_set_draw_context(share, cso);
+ }
+
+ return share;
+ }
+
+ struct pipe_screen *screen = cso_get_pipe_context(cso)->screen;
+ struct hud_context *hud;
+ unsigned i;
+ const char *env = debug_get_option("GALLIUM_HUD", NULL);
+#ifdef PIPE_OS_UNIX
+ unsigned signo = debug_get_num_option("GALLIUM_HUD_TOGGLE_SIGNAL", 0);
+ static boolean sig_handled = FALSE;
+ struct sigaction action = {};
+#endif
+ huds_visible = debug_get_bool_option("GALLIUM_HUD_VISIBLE", TRUE);
+
+ if (!env || !*env)
+ return NULL;
+
+ if (strcmp(env, "help") == 0) {
+ print_help(screen);
+ return NULL;
+ }
+
+ hud = CALLOC_STRUCT(hud_context);
+ if (!hud)
+ return NULL;
+
+ /* font (the context is only used for the texture upload) */
+ if (!util_font_create(cso_get_pipe_context(cso),
+ UTIL_FONT_FIXED_8X13, &hud->font)) {
+ FREE(hud);
+ return NULL;
+ }
+
+ hud->refcount = 1;
+ hud->has_srgb = screen->is_format_supported(screen,
+ PIPE_FORMAT_B8G8R8A8_SRGB,
+ PIPE_TEXTURE_2D, 0, 0,
+ PIPE_BIND_RENDER_TARGET) != 0;
+
+ /* blend state */
+ hud->no_blend.rt[0].colormask = PIPE_MASK_RGBA;
+
+ hud->alpha_blend.rt[0].colormask = PIPE_MASK_RGBA;
+ hud->alpha_blend.rt[0].blend_enable = 1;
+ hud->alpha_blend.rt[0].rgb_func = PIPE_BLEND_ADD;
+ hud->alpha_blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
+ hud->alpha_blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ hud->alpha_blend.rt[0].alpha_func = PIPE_BLEND_ADD;
+ hud->alpha_blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
+ hud->alpha_blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
+
+ /* rasterizer */
+ hud->rasterizer.half_pixel_center = 1;
+ hud->rasterizer.bottom_edge_rule = 1;
+ hud->rasterizer.depth_clip_near = 1;
+ hud->rasterizer.depth_clip_far = 1;
+ hud->rasterizer.line_width = 1;
+ hud->rasterizer.line_last_pixel = 1;
+
+ hud->rasterizer_aa_lines = hud->rasterizer;
+ hud->rasterizer_aa_lines.line_smooth = 1;
+
/* vertex elements */
for (i = 0; i < 2; i++) {
hud->velems[i].src_offset = i * 2 * sizeof(float);
hud->velems[i].src_format = PIPE_FORMAT_R32G32_FLOAT;
- hud->velems[i].vertex_buffer_index = cso_get_aux_vertex_buffer_slot(cso);
+ hud->velems[i].vertex_buffer_index = 0;
}
- /* sampler view */
- u_sampler_view_default_template(
- &view_templ, hud->font.texture, hud->font.texture->format);
- hud->font_sampler_view = pipe->create_sampler_view(pipe, hud->font.texture,
- &view_templ);
-
/* sampler state (for font drawing) */
hud->font_sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
hud->font_sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
@@ -1686,33 +1903,32 @@ hud_create(struct pipe_context *pipe, struct cso_context *cso)
}
#endif
- hud_parse_env_var(hud, env);
+ if (record_ctx == 0)
+ hud_set_record_context(hud, cso_get_pipe_context(cso));
+ if (draw_ctx == 0)
+ hud_set_draw_context(hud, cso);
+
+ hud_parse_env_var(hud, screen, env);
return hud;
}
+/**
+ * Destroy a HUD. If the HUD has several users, decrease the reference counter
+ * and detach the context from the HUD.
+ */
void
-hud_destroy(struct hud_context *hud)
+hud_destroy(struct hud_context *hud, struct cso_context *cso)
{
- struct pipe_context *pipe = hud->pipe;
- struct hud_pane *pane, *pane_tmp;
- struct hud_graph *graph, *graph_tmp;
+ if (!cso || hud->record_pipe == cso_get_pipe_context(cso))
+ hud_unset_record_context(hud);
- LIST_FOR_EACH_ENTRY_SAFE(pane, pane_tmp, &hud->pane_list, head) {
- LIST_FOR_EACH_ENTRY_SAFE(graph, graph_tmp, &pane->graph_list, head) {
- LIST_DEL(&graph->head);
- hud_graph_destroy(graph);
- }
- LIST_DEL(&pane->head);
- FREE(pane);
- }
+ if (!cso || hud->cso == cso)
+ hud_unset_draw_context(hud);
- hud_batch_query_cleanup(&hud->batch_query);
- pipe->delete_fs_state(pipe, hud->fs_color);
- pipe->delete_fs_state(pipe, hud->fs_text);
- pipe->delete_vs_state(pipe, hud->vs);
- pipe_sampler_view_reference(&hud->font_sampler_view, NULL);
- pipe_resource_reference(&hud->font.texture, NULL);
- FREE(hud);
+ if (p_atomic_dec_zero(&hud->refcount)) {
+ pipe_resource_reference(&hud->font.texture, NULL);
+ FREE(hud);
+ }
}
void
diff --git a/lib/mesa/src/gallium/auxiliary/hud/hud_context.h b/lib/mesa/src/gallium/auxiliary/hud/hud_context.h
index 5a7e13b27..99e6f8d7e 100644
--- a/lib/mesa/src/gallium/auxiliary/hud/hud_context.h
+++ b/lib/mesa/src/gallium/auxiliary/hud/hud_context.h
@@ -35,13 +35,17 @@ struct pipe_resource;
struct util_queue_monitoring;
struct hud_context *
-hud_create(struct pipe_context *pipe, struct cso_context *cso);
+hud_create(struct cso_context *cso, struct hud_context *share);
void
-hud_destroy(struct hud_context *hud);
+hud_destroy(struct hud_context *hud, struct cso_context *cso);
void
-hud_draw(struct hud_context *hud, struct pipe_resource *tex);
+hud_run(struct hud_context *hud, struct cso_context *cso,
+ struct pipe_resource *tex);
+
+void
+hud_record_only(struct hud_context *hud, struct pipe_context *pipe);
void
hud_add_queue_for_monitoring(struct hud_context *hud,
diff --git a/lib/mesa/src/gallium/auxiliary/hud/hud_cpu.c b/lib/mesa/src/gallium/auxiliary/hud/hud_cpu.c
index 4caaab697..b7a524330 100644
--- a/lib/mesa/src/gallium/auxiliary/hud/hud_cpu.c
+++ b/lib/mesa/src/gallium/auxiliary/hud/hud_cpu.c
@@ -29,7 +29,7 @@
*/
#include "hud/hud_private.h"
-#include "os/os_time.h"
+#include "util/os_time.h"
#include "os/os_thread.h"
#include "util/u_memory.h"
#include "util/u_queue.h"
@@ -144,14 +144,15 @@ struct cpu_info {
};
static void
-query_cpu_load(struct hud_graph *gr)
+query_cpu_load(struct hud_graph *gr, struct pipe_context *pipe)
{
struct cpu_info *info = gr->query_data;
uint64_t now = os_time_get();
if (info->last_time) {
if (info->last_time + gr->pane->period <= now) {
- uint64_t cpu_busy, cpu_total, cpu_load;
+ uint64_t cpu_busy, cpu_total;
+ double cpu_load;
get_cpu_stats(info->cpu_index, &cpu_busy, &cpu_total);
@@ -173,7 +174,7 @@ query_cpu_load(struct hud_graph *gr)
}
static void
-free_query_data(void *p)
+free_query_data(void *p, struct pipe_context *pipe)
{
FREE(p);
}
@@ -238,7 +239,7 @@ struct thread_info {
};
static void
-query_api_thread_busy_status(struct hud_graph *gr)
+query_api_thread_busy_status(struct hud_graph *gr, struct pipe_context *pipe)
{
struct thread_info *info = gr->query_data;
int64_t now = os_time_get_nano();
@@ -258,15 +259,15 @@ query_api_thread_busy_status(struct hud_graph *gr)
thread_now = 0;
}
- unsigned percent = (thread_now - info->last_thread_time) * 100 /
+ double percent = (thread_now - info->last_thread_time) * 100.0 /
(now - info->last_time);
/* Check if the context changed a thread, so that we don't show
* a random value. When a thread is changed, the new thread clock
* is different, which can result in "percent" being very high.
*/
- if (percent > 100)
- percent = 0;
+ if (percent > 100.0)
+ percent = 0.0;
hud_graph_add_value(gr, percent);
info->last_thread_time = thread_now;
@@ -335,7 +336,7 @@ static unsigned get_counter(struct hud_graph *gr, enum hud_counter counter)
}
static void
-query_thread_counter(struct hud_graph *gr)
+query_thread_counter(struct hud_graph *gr, struct pipe_context *pipe)
{
struct counter_info *info = gr->query_data;
int64_t now = os_time_get_nano();
diff --git a/lib/mesa/src/gallium/auxiliary/hud/hud_cpufreq.c b/lib/mesa/src/gallium/auxiliary/hud/hud_cpufreq.c
index abb930d7e..d3cf2019c 100644
--- a/lib/mesa/src/gallium/auxiliary/hud/hud_cpufreq.c
+++ b/lib/mesa/src/gallium/auxiliary/hud/hud_cpufreq.c
@@ -26,7 +26,7 @@
*
**************************************************************************/
-#if HAVE_GALLIUM_EXTRA_HUD
+#ifdef HAVE_GALLIUM_EXTRA_HUD
/* Purpose:
* Reading /sys/devices/system/cpu/cpu?/cpufreq/scaling_???_freq
@@ -35,7 +35,7 @@
#include "hud/hud_private.h"
#include "util/list.h"
-#include "os/os_time.h"
+#include "util/os_time.h"
#include "os/os_thread.h"
#include "util/u_memory.h"
#include <stdio.h>
@@ -91,7 +91,7 @@ get_file_value(const char *fn, uint64_t *KHz)
}
static void
-query_cfi_load(struct hud_graph *gr)
+query_cfi_load(struct hud_graph *gr, struct pipe_context *pipe)
{
struct cpufreq_info *cfi = gr->query_data;
@@ -207,8 +207,12 @@ hud_get_num_cpufreq(bool displayhelp)
while ((dp = readdir(dir)) != NULL) {
- /* Avoid 'lo' and '..' and '.' */
- if (strlen(dp->d_name) <= 2)
+ size_t d_name_len = strlen(dp->d_name);
+
+ /* Avoid 'lo' and '..' and '.', and avoid overlong names that
+ * would result in a buffer overflow in add_object.
+ */
+ if (d_name_len <= 2 || d_name_len > 15)
continue;
if (sscanf(dp->d_name, "cpu%d\n", &cpu_index) != 1)
diff --git a/lib/mesa/src/gallium/auxiliary/hud/hud_diskstat.c b/lib/mesa/src/gallium/auxiliary/hud/hud_diskstat.c
index df86abd12..7eaaf35a7 100644
--- a/lib/mesa/src/gallium/auxiliary/hud/hud_diskstat.c
+++ b/lib/mesa/src/gallium/auxiliary/hud/hud_diskstat.c
@@ -26,7 +26,7 @@
*
**************************************************************************/
-#if HAVE_GALLIUM_EXTRA_HUD
+#ifdef HAVE_GALLIUM_EXTRA_HUD
/* Purpose: Reading /sys/block/<*>/stat MB/s read/write throughput per second,
* displaying on the HUD.
@@ -34,7 +34,7 @@
#include "hud/hud_private.h"
#include "util/list.h"
-#include "os/os_time.h"
+#include "util/os_time.h"
#include "os/os_thread.h"
#include "util/u_memory.h"
#include <stdio.h>
@@ -117,7 +117,7 @@ get_file_values(const char *fn, struct stat_s *s)
}
static void
-query_dsi_load(struct hud_graph *gr)
+query_dsi_load(struct hud_graph *gr, struct pipe_context *pipe)
{
/* The framework calls us periodically, compensate for the
* calling interval accordingly when reporting per second.
diff --git a/lib/mesa/src/gallium/auxiliary/hud/hud_driver_query.c b/lib/mesa/src/gallium/auxiliary/hud/hud_driver_query.c
index 76104b5b4..382de1af0 100644
--- a/lib/mesa/src/gallium/auxiliary/hud/hud_driver_query.c
+++ b/lib/mesa/src/gallium/auxiliary/hud/hud_driver_query.c
@@ -33,7 +33,7 @@
#include "hud/hud_private.h"
#include "pipe/p_screen.h"
-#include "os/os_time.h"
+#include "util/os_time.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include <stdio.h>
@@ -42,7 +42,6 @@
#define NUM_QUERIES 8
struct hud_batch_query_context {
- struct pipe_context *pipe;
unsigned num_query_types;
unsigned allocated_query_types;
unsigned *query_types;
@@ -54,15 +53,12 @@ struct hud_batch_query_context {
};
void
-hud_batch_query_update(struct hud_batch_query_context *bq)
+hud_batch_query_update(struct hud_batch_query_context *bq,
+ struct pipe_context *pipe)
{
- struct pipe_context *pipe;
-
if (!bq || bq->failed)
return;
- pipe = bq->pipe;
-
if (bq->query[bq->head])
pipe->end_query(pipe, bq->query[bq->head]);
@@ -97,7 +93,7 @@ hud_batch_query_update(struct hud_batch_query_context *bq)
assert(bq->query[bq->head]);
- pipe->destroy_query(bq->pipe, bq->query[bq->head]);
+ pipe->destroy_query(pipe, bq->query[bq->head]);
bq->query[bq->head] = NULL;
}
@@ -119,12 +115,13 @@ hud_batch_query_update(struct hud_batch_query_context *bq)
}
void
-hud_batch_query_begin(struct hud_batch_query_context *bq)
+hud_batch_query_begin(struct hud_batch_query_context *bq,
+ struct pipe_context *pipe)
{
if (!bq || bq->failed || !bq->query[bq->head])
return;
- if (!bq->pipe->begin_query(bq->pipe, bq->query[bq->head])) {
+ if (!pipe->begin_query(pipe, bq->query[bq->head])) {
fprintf(stderr,
"gallium_hud: could not begin batch query. You may have "
"selected too many or incompatible queries.\n");
@@ -134,8 +131,7 @@ hud_batch_query_begin(struct hud_batch_query_context *bq)
static boolean
batch_query_add(struct hud_batch_query_context **pbq,
- struct pipe_context *pipe, unsigned query_type,
- unsigned *result_index)
+ unsigned query_type, unsigned *result_index)
{
struct hud_batch_query_context *bq = *pbq;
unsigned i;
@@ -144,7 +140,6 @@ batch_query_add(struct hud_batch_query_context **pbq,
bq = CALLOC_STRUCT(hud_batch_query_context);
if (!bq)
return false;
- bq->pipe = pipe;
*pbq = bq;
}
@@ -173,7 +168,8 @@ batch_query_add(struct hud_batch_query_context **pbq,
}
void
-hud_batch_query_cleanup(struct hud_batch_query_context **pbq)
+hud_batch_query_cleanup(struct hud_batch_query_context **pbq,
+ struct pipe_context *pipe)
{
struct hud_batch_query_context *bq = *pbq;
unsigned idx;
@@ -184,11 +180,11 @@ hud_batch_query_cleanup(struct hud_batch_query_context **pbq)
*pbq = NULL;
if (bq->query[bq->head] && !bq->failed)
- bq->pipe->end_query(bq->pipe, bq->query[bq->head]);
+ pipe->end_query(pipe, bq->query[bq->head]);
for (idx = 0; idx < NUM_QUERIES; ++idx) {
if (bq->query[idx])
- bq->pipe->destroy_query(bq->pipe, bq->query[idx]);
+ pipe->destroy_query(pipe, bq->query[idx]);
FREE(bq->result[idx]);
}
@@ -197,11 +193,15 @@ hud_batch_query_cleanup(struct hud_batch_query_context **pbq)
}
struct query_info {
- struct pipe_context *pipe;
struct hud_batch_query_context *batch;
- unsigned query_type;
- unsigned result_index; /* unit depends on query_type */
+ enum pipe_query_type query_type;
+
+ /** index to choose fields in pipe_query_data_pipeline_statistics,
+ * for example.
+ */
+ unsigned result_index;
enum pipe_driver_query_result_type result_type;
+ enum pipe_driver_query_type type;
/* Ring of queries. If a query is busy, we use another slot. */
struct pipe_query *query[NUM_QUERIES];
@@ -230,10 +230,8 @@ query_new_value_batch(struct query_info *info)
}
static void
-query_new_value_normal(struct query_info *info)
+query_new_value_normal(struct query_info *info, struct pipe_context *pipe)
{
- struct pipe_context *pipe = info->pipe;
-
if (info->last_time) {
if (info->query[info->head])
pipe->end_query(pipe, info->query[info->head]);
@@ -245,7 +243,13 @@ query_new_value_normal(struct query_info *info)
uint64_t *res64 = (uint64_t *)&result;
if (query && pipe->get_query_result(pipe, query, FALSE, &result)) {
- info->results_cumulative += res64[info->result_index];
+ if (info->type == PIPE_DRIVER_QUERY_TYPE_FLOAT) {
+ assert(info->result_index == 0);
+ info->results_cumulative += (uint64_t) (result.f * 1000.0f);
+ }
+ else {
+ info->results_cumulative += res64[info->result_index];
+ }
info->num_results++;
if (info->tail == info->head)
@@ -287,10 +291,9 @@ query_new_value_normal(struct query_info *info)
}
static void
-begin_query(struct hud_graph *gr)
+begin_query(struct hud_graph *gr, struct pipe_context *pipe)
{
struct query_info *info = gr->query_data;
- struct pipe_context *pipe = info->pipe;
assert(!info->batch);
if (info->query[info->head])
@@ -298,7 +301,7 @@ begin_query(struct hud_graph *gr)
}
static void
-query_new_value(struct hud_graph *gr)
+query_new_value(struct hud_graph *gr, struct pipe_context *pipe)
{
struct query_info *info = gr->query_data;
uint64_t now = os_time_get();
@@ -306,7 +309,7 @@ query_new_value(struct hud_graph *gr)
if (info->batch) {
query_new_value_batch(info);
} else {
- query_new_value_normal(info);
+ query_new_value_normal(info, pipe);
}
if (!info->last_time) {
@@ -315,7 +318,7 @@ query_new_value(struct hud_graph *gr)
}
if (info->num_results && info->last_time + gr->pane->period <= now) {
- uint64_t value;
+ double value;
switch (info->result_type) {
default:
@@ -327,6 +330,10 @@ query_new_value(struct hud_graph *gr)
break;
}
+ if (info->type == PIPE_DRIVER_QUERY_TYPE_FLOAT) {
+ value /= 1000.0;
+ }
+
hud_graph_add_value(gr, value);
info->last_time = now;
@@ -336,12 +343,11 @@ query_new_value(struct hud_graph *gr)
}
static void
-free_query_info(void *ptr)
+free_query_info(void *ptr, struct pipe_context *pipe)
{
struct query_info *info = ptr;
if (!info->batch && info->last_time) {
- struct pipe_context *pipe = info->pipe;
int i;
pipe->end_query(pipe, info->query[info->head]);
@@ -355,10 +361,16 @@ free_query_info(void *ptr)
FREE(info);
}
+
+/**
+ * \param result_index to select fields of pipe_query_data_pipeline_statistics,
+ * for example.
+ */
void
hud_pipe_query_install(struct hud_batch_query_context **pbq,
- struct hud_pane *pane, struct pipe_context *pipe,
- const char *name, unsigned query_type,
+ struct hud_pane *pane,
+ const char *name,
+ enum pipe_query_type query_type,
unsigned result_index,
uint64_t max_value, enum pipe_driver_query_type type,
enum pipe_driver_query_result_type result_type,
@@ -381,11 +393,11 @@ hud_pipe_query_install(struct hud_batch_query_context **pbq,
gr->free_query_data = free_query_info;
info = gr->query_data;
- info->pipe = pipe;
info->result_type = result_type;
+ info->type = type;
if (flags & PIPE_DRIVER_QUERY_FLAG_BATCH) {
- if (!batch_query_add(pbq, pipe, query_type, &info->result_index))
+ if (!batch_query_add(pbq, query_type, &info->result_index))
goto fail_info;
info->batch = *pbq;
} else {
@@ -409,10 +421,9 @@ fail_gr:
boolean
hud_driver_query_install(struct hud_batch_query_context **pbq,
- struct hud_pane *pane, struct pipe_context *pipe,
+ struct hud_pane *pane, struct pipe_screen *screen,
const char *name)
{
- struct pipe_screen *screen = pipe->screen;
struct pipe_driver_query_info query;
unsigned num_queries, i;
boolean found = FALSE;
@@ -433,7 +444,7 @@ hud_driver_query_install(struct hud_batch_query_context **pbq,
if (!found)
return FALSE;
- hud_pipe_query_install(pbq, pane, pipe, query.name, query.query_type, 0,
+ hud_pipe_query_install(pbq, pane, query.name, query.query_type, 0,
query.max_value.u64, query.type, query.result_type,
query.flags);
diff --git a/lib/mesa/src/gallium/auxiliary/hud/hud_fps.c b/lib/mesa/src/gallium/auxiliary/hud/hud_fps.c
index 8aa7a665a..29110f557 100644
--- a/lib/mesa/src/gallium/auxiliary/hud/hud_fps.c
+++ b/lib/mesa/src/gallium/auxiliary/hud/hud_fps.c
@@ -29,16 +29,17 @@
*/
#include "hud/hud_private.h"
-#include "os/os_time.h"
+#include "util/os_time.h"
#include "util/u_memory.h"
struct fps_info {
+ boolean frametime;
int frames;
uint64_t last_time;
};
static void
-query_fps(struct hud_graph *gr)
+query_fps(struct hud_graph *gr, struct pipe_context *pipe)
{
struct fps_info *info = gr->query_data;
uint64_t now = os_time_get();
@@ -46,7 +47,12 @@ query_fps(struct hud_graph *gr)
info->frames++;
if (info->last_time) {
- if (info->last_time + gr->pane->period <= now) {
+ if (info->frametime) {
+ double frametime = ((double)now - (double)info->last_time) / 1000.0;
+ hud_graph_add_value(gr, frametime);
+ info->last_time = now;
+ }
+ else if (info->last_time + gr->pane->period <= now) {
double fps = ((uint64_t)info->frames) * 1000000 /
(double)(now - info->last_time);
info->frames = 0;
@@ -61,7 +67,7 @@ query_fps(struct hud_graph *gr)
}
static void
-free_query_data(void *p)
+free_query_data(void *p, struct pipe_context *pipe)
{
FREE(p);
}
@@ -80,6 +86,8 @@ hud_fps_graph_install(struct hud_pane *pane)
FREE(gr);
return;
}
+ struct fps_info *info = gr->query_data;
+ info->frametime = false;
gr->query_new_value = query_fps;
@@ -90,3 +98,27 @@ hud_fps_graph_install(struct hud_pane *pane)
hud_pane_add_graph(pane, gr);
}
+
+void
+hud_frametime_graph_install(struct hud_pane *pane)
+{
+ struct hud_graph *gr = CALLOC_STRUCT(hud_graph);
+
+ if (!gr)
+ return;
+
+ strcpy(gr->name, "frametime (ms)");
+ gr->query_data = CALLOC_STRUCT(fps_info);
+ if (!gr->query_data) {
+ FREE(gr);
+ return;
+ }
+ struct fps_info *info = gr->query_data;
+ info->frametime = true;
+
+ gr->query_new_value = query_fps;
+
+ gr->free_query_data = free_query_data;
+
+ hud_pane_add_graph(pane, gr);
+}
diff --git a/lib/mesa/src/gallium/auxiliary/hud/hud_nic.c b/lib/mesa/src/gallium/auxiliary/hud/hud_nic.c
index 835f92e2e..b6c0d9edd 100644
--- a/lib/mesa/src/gallium/auxiliary/hud/hud_nic.c
+++ b/lib/mesa/src/gallium/auxiliary/hud/hud_nic.c
@@ -26,7 +26,7 @@
*
**************************************************************************/
-#if HAVE_GALLIUM_EXTRA_HUD
+#ifdef HAVE_GALLIUM_EXTRA_HUD
/* Purpose: Reading network interface RX/TX throughput per second,
* displaying on the HUD.
@@ -34,7 +34,7 @@
#include "hud/hud_private.h"
#include "util/list.h"
-#include "os/os_time.h"
+#include "util/os_time.h"
#include "os/os_thread.h"
#include "util/u_memory.h"
#include <stdio.h>
@@ -171,7 +171,7 @@ query_nic_rssi(const struct nic_info *nic, uint64_t *leveldBm)
}
static void
-query_nic_load(struct hud_graph *gr)
+query_nic_load(struct hud_graph *gr, struct pipe_context *pipe)
{
/* The framework calls us at a regular but indefined period,
* not once per second, compensate the statistics accordingly.
diff --git a/lib/mesa/src/gallium/auxiliary/hud/hud_private.h b/lib/mesa/src/gallium/auxiliary/hud/hud_private.h
index 65baa8aa7..deed329a8 100644
--- a/lib/mesa/src/gallium/auxiliary/hud/hud_private.h
+++ b/lib/mesa/src/gallium/auxiliary/hud/hud_private.h
@@ -40,6 +40,13 @@ enum hud_counter {
};
struct hud_context {
+ int refcount;
+ bool simple;
+
+ /* Context where queries are executed. */
+ struct pipe_context *record_pipe;
+
+ /* Context where the HUD is drawn: */
struct pipe_context *pipe;
struct cso_context *cso;
@@ -97,9 +104,10 @@ struct hud_graph {
/* name and query */
char name[128];
void *query_data;
- void (*begin_query)(struct hud_graph *gr);
- void (*query_new_value)(struct hud_graph *gr);
- void (*free_query_data)(void *ptr); /**< do not use ordinary free() */
+ void (*begin_query)(struct hud_graph *gr, struct pipe_context *pipe);
+ void (*query_new_value)(struct hud_graph *gr, struct pipe_context *pipe);
+ /* use this instead of ordinary free() */
+ void (*free_query_data)(void *ptr, struct pipe_context *pipe);
/* mutable variables */
unsigned num_vertices;
@@ -111,7 +119,7 @@ struct hud_graph {
struct hud_pane {
struct list_head head;
struct hud_context *hud;
- unsigned x1, y1, x2, y2;
+ unsigned x1, y1, x2, y2, y_simple;
unsigned inner_x1;
unsigned inner_y1;
unsigned inner_x2;
@@ -149,13 +157,15 @@ struct hud_batch_query_context;
int hud_get_num_cpus(void);
void hud_fps_graph_install(struct hud_pane *pane);
+void hud_frametime_graph_install(struct hud_pane *pane);
void hud_cpu_graph_install(struct hud_pane *pane, unsigned cpu_index);
void hud_thread_busy_install(struct hud_pane *pane, const char *name, bool main);
void hud_thread_counter_install(struct hud_pane *pane, const char *name,
enum hud_counter counter);
void hud_pipe_query_install(struct hud_batch_query_context **pbq,
- struct hud_pane *pane, struct pipe_context *pipe,
- const char *name, unsigned query_type,
+ struct hud_pane *pane,
+ const char *name,
+ enum pipe_query_type query_type,
unsigned result_index,
uint64_t max_value,
enum pipe_driver_query_type type,
@@ -163,12 +173,15 @@ void hud_pipe_query_install(struct hud_batch_query_context **pbq,
unsigned flags);
boolean hud_driver_query_install(struct hud_batch_query_context **pbq,
struct hud_pane *pane,
- struct pipe_context *pipe, const char *name);
-void hud_batch_query_begin(struct hud_batch_query_context *bq);
-void hud_batch_query_update(struct hud_batch_query_context *bq);
-void hud_batch_query_cleanup(struct hud_batch_query_context **pbq);
-
-#if HAVE_GALLIUM_EXTRA_HUD
+ struct pipe_screen *screen, const char *name);
+void hud_batch_query_begin(struct hud_batch_query_context *bq,
+ struct pipe_context *pipe);
+void hud_batch_query_update(struct hud_batch_query_context *bq,
+ struct pipe_context *pipe);
+void hud_batch_query_cleanup(struct hud_batch_query_context **pbq,
+ struct pipe_context *pipe);
+
+#ifdef HAVE_GALLIUM_EXTRA_HUD
int hud_get_num_nics(bool displayhelp);
#define NIC_DIRECTION_RX 1
#define NIC_DIRECTION_TX 2
@@ -189,7 +202,7 @@ int hud_get_num_cpufreq(bool displayhelp);
void hud_cpufreq_graph_install(struct hud_pane *pane, int cpu_index, unsigned int mode);
#endif
-#if HAVE_LIBSENSORS
+#ifdef HAVE_LIBSENSORS
int hud_get_num_sensors(bool displayhelp);
#define SENSORS_TEMP_CURRENT 1
#define SENSORS_TEMP_CRITICAL 2
diff --git a/lib/mesa/src/gallium/auxiliary/hud/hud_sensors_temp.c b/lib/mesa/src/gallium/auxiliary/hud/hud_sensors_temp.c
index 29ee257ce..c226e89cc 100644
--- a/lib/mesa/src/gallium/auxiliary/hud/hud_sensors_temp.c
+++ b/lib/mesa/src/gallium/auxiliary/hud/hud_sensors_temp.c
@@ -26,12 +26,12 @@
*
**************************************************************************/
-#if HAVE_LIBSENSORS
+#ifdef HAVE_LIBSENSORS
/* Purpose: Extract lm-sensors data, expose temperature, power, voltage. */
#include "hud/hud_private.h"
#include "util/list.h"
-#include "os/os_time.h"
+#include "util/os_time.h"
#include "os/os_thread.h"
#include "util/u_memory.h"
#include <stdio.h>
@@ -122,6 +122,9 @@ get_sensor_values(struct sensors_temp_info *sti)
case SENSORS_POWER_CURRENT:
sf = sensors_get_subfeature(sti->chip, sti->feature,
SENSORS_SUBFEATURE_POWER_INPUT);
+ if (!sf)
+ sf = sensors_get_subfeature(sti->chip, sti->feature,
+ SENSORS_SUBFEATURE_POWER_AVERAGE);
if (sf) {
/* Sensors API returns in WATTs, even though driver is reporting mW,
* convert back to mW */
@@ -154,7 +157,7 @@ find_sti_by_name(const char *n, unsigned int mode)
}
static void
-query_sti_load(struct hud_graph *gr)
+query_sti_load(struct hud_graph *gr, struct pipe_context *pipe)
{
struct sensors_temp_info *sti = gr->query_data;
uint64_t now = os_time_get();
@@ -165,19 +168,19 @@ query_sti_load(struct hud_graph *gr)
switch (sti->mode) {
case SENSORS_TEMP_CURRENT:
- hud_graph_add_value(gr, (uint64_t) sti->current);
+ hud_graph_add_value(gr, sti->current);
break;
case SENSORS_TEMP_CRITICAL:
- hud_graph_add_value(gr, (uint64_t) sti->critical);
+ hud_graph_add_value(gr, sti->critical);
break;
case SENSORS_VOLTAGE_CURRENT:
- hud_graph_add_value(gr, (uint64_t)(sti->current * 1000));
+ hud_graph_add_value(gr, sti->current * 1000);
break;
case SENSORS_CURRENT_CURRENT:
- hud_graph_add_value(gr, (uint64_t) sti->current);
+ hud_graph_add_value(gr, sti->current);
break;
case SENSORS_POWER_CURRENT:
- hud_graph_add_value(gr, (uint64_t) sti->current);
+ hud_graph_add_value(gr, sti->current);
break;
}