diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2019-01-29 11:52:33 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2019-01-29 11:52:33 +0000 |
commit | 37bbf6a1792773f11c15a4da1588a7520ee2fb4e (patch) | |
tree | 64944d4aa665a1e479cfc004e446593062254550 /lib/mesa/src/gallium/auxiliary/hud | |
parent | 6b139c2063623e9310025247cd966490b9aa57ea (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.c | 590 | ||||
-rw-r--r-- | lib/mesa/src/gallium/auxiliary/hud/hud_context.h | 10 | ||||
-rw-r--r-- | lib/mesa/src/gallium/auxiliary/hud/hud_cpu.c | 19 | ||||
-rw-r--r-- | lib/mesa/src/gallium/auxiliary/hud/hud_cpufreq.c | 14 | ||||
-rw-r--r-- | lib/mesa/src/gallium/auxiliary/hud/hud_diskstat.c | 6 | ||||
-rw-r--r-- | lib/mesa/src/gallium/auxiliary/hud/hud_driver_query.c | 85 | ||||
-rw-r--r-- | lib/mesa/src/gallium/auxiliary/hud/hud_fps.c | 40 | ||||
-rw-r--r-- | lib/mesa/src/gallium/auxiliary/hud/hud_nic.c | 6 | ||||
-rw-r--r-- | lib/mesa/src/gallium/auxiliary/hud/hud_private.h | 39 | ||||
-rw-r--r-- | lib/mesa/src/gallium/auxiliary/hud/hud_sensors_temp.c | 19 |
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; } |