gallium/hud: add GALLIUM_HUD_PERIOD env var
[mesa.git] / src / gallium / auxiliary / hud / hud_context.c
index 65b82473b8341d7fe7074a04f30859da339aef83..983f0575687cb7ff4bd3dd2085768c97965ea859 100644 (file)
@@ -59,7 +59,7 @@ struct hud_context {
    /* states */
    struct pipe_blend_state alpha_blend;
    struct pipe_depth_stencil_alpha_state dsa;
-   void *fs_color, *fs_texture;
+   void *fs_color, *fs_text;
    struct pipe_rasterizer_state rasterizer;
    void *vs;
    struct pipe_vertex_element velems[2];
@@ -90,6 +90,10 @@ struct hud_context {
       unsigned max_num_vertices;
       unsigned num_vertices;
    } text, bg, whitelines;
+
+   struct {
+      boolean query_pipeline_statistics;
+   } cap;
 };
 
 
@@ -522,7 +526,7 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
    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_texture);
+      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, NULL);
@@ -617,7 +621,7 @@ hud_pane_add_graph(struct hud_pane *pane, struct hud_graph *gr)
    }
 
    assert(pane->num_graphs < Elements(colors));
-   gr->vertices = malloc(pane->max_num_vertices * sizeof(float) * 2);
+   gr->vertices = MALLOC(pane->max_num_vertices * sizeof(float) * 2);
    gr->color[0] = colors[pane->num_graphs][0];
    gr->color[1] = colors[pane->num_graphs][1];
    gr->color[2] = colors[pane->num_graphs][2];
@@ -699,12 +703,27 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
    struct hud_pane *pane = NULL;
    unsigned x = 10, y = 10;
    unsigned width = 251, height = 100;
+   unsigned period = 500 * 1000;  /* default period (1/2 second) */
+   const char *period_env;
+
+   /*
+    * The GALLIUM_HUD_PERIOD env var sets the graph update rate.
+    * The env var is in seconds (a float).
+    * Zero means update after every frame.
+    */
+   period_env = getenv("GALLIUM_HUD_PERIOD");
+   if (period_env) {
+      float p = atof(period_env);
+      if (p >= 0.0) {
+         period = (unsigned) (p * 1000 * 1000);
+      }
+   }
 
    while ((num = parse_string(env, name)) != 0) {
       env += num;
 
       if (!pane) {
-         pane = hud_pane_create(x, y, x + width, y + height, 40000, 10);
+         pane = hud_pane_create(x, y, x + width, y + height, period, 10);
          if (!pane)
             return;
       }
@@ -719,15 +738,45 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
       else if (sscanf(name, "cpu%u%s", &i, s) == 1) {
          hud_cpu_graph_install(pane, i);
       }
-      else if (strcmp(name, "pixels-rendered") == 0 &&
+      else if (strcmp(name, "samples-passed") == 0 &&
                has_occlusion_query(hud->pipe->screen)) {
-         hud_pipe_query_install(pane, hud->pipe, "pixels-rendered",
-                            PIPE_QUERY_OCCLUSION_COUNTER, 0, FALSE);
+         hud_pipe_query_install(pane, hud->pipe, "samples-passed",
+                                PIPE_QUERY_OCCLUSION_COUNTER, 0, 0, FALSE);
       }
       else if (strcmp(name, "primitives-generated") == 0 &&
                has_streamout(hud->pipe->screen)) {
          hud_pipe_query_install(pane, hud->pipe, "primitives-generated",
-                            PIPE_QUERY_PRIMITIVES_GENERATED, 0, FALSE);
+                                PIPE_QUERY_PRIMITIVES_GENERATED, 0, 0, FALSE);
+      }
+      else if (strncmp(name, "pipeline-statistics-", 20) == 0) {
+         if (hud->cap.query_pipeline_statistics) {
+            static const char *pipeline_statistics_names[] =
+            {
+               "ia-vertices",
+               "ia-primitives",
+               "vs-invocations",
+               "gs-invocations",
+               "gs-primitives",
+               "clipper-invocations",
+               "clipper-primitives-generated",
+               "ps-invocations",
+               "hs-invocations",
+               "ds-invocations",
+               "cs-invocations"
+            };
+            for (i = 0; i < Elements(pipeline_statistics_names); ++i)
+               if (strcmp(&name[20], pipeline_statistics_names[i]) == 0)
+                  break;
+            if (i < Elements(pipeline_statistics_names))
+               hud_pipe_query_install(pane, hud->pipe, &name[20],
+                                      PIPE_QUERY_PIPELINE_STATISTICS, i,
+                                      0, FALSE);
+            else
+               fprintf(stderr, "gallium_hud: invalid pipeline-statistics-*\n");
+         } else {
+            fprintf(stderr, "gallium_hud: PIPE_QUERY_PIPELINE_STATISTICS "
+                    "not supported by the driver\n");
+         }
       }
       else {
          if (!hud_driver_query_install(pane, hud->pipe, name)){
@@ -893,9 +942,33 @@ hud_create(struct pipe_context *pipe, struct cso_context *cso)
                                                TGSI_SEMANTIC_COLOR,
                                                TGSI_INTERPOLATE_CONSTANT);
 
-   hud->fs_texture =
-         util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_RECT,
-                                       TGSI_INTERPOLATE_PERSPECTIVE);
+   {
+      /* Read a texture and do .xxxx swizzling. */
+      static const char *fragment_shader_text = {
+         "FRAG\n"
+         "DCL IN[0], GENERIC[0], LINEAR\n"
+         "DCL SAMP[0]\n"
+         "DCL OUT[0], COLOR[0]\n"
+         "DCL TEMP[0]\n"
+
+         "TEX TEMP[0], IN[0], SAMP[0], RECT\n"
+         "MOV OUT[0], TEMP[0].xxxx\n"
+         "END\n"
+      };
+
+      struct tgsi_token tokens[1000];
+      struct pipe_shader_state state = {tokens};
+
+      if (!tgsi_text_translate(fragment_shader_text, tokens, Elements(tokens))) {
+         assert(0);
+         pipe_resource_reference(&hud->font.texture, NULL);
+         u_upload_destroy(hud->uploader);
+         FREE(hud);
+         return NULL;
+      }
+
+      hud->fs_text = pipe->create_fs_state(pipe, &state);
+   }
 
    /* rasterizer */
    hud->rasterizer.gl_rasterization_rules = 1;
@@ -960,12 +1033,21 @@ hud_create(struct pipe_context *pipe, struct cso_context *cso)
    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;
+   hud->font_sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+   hud->font_sampler_state.normalized_coords = 0;
+
    /* constants */
    hud->constbuf.buffer_size = sizeof(hud->constants);
    hud->constbuf.user_buffer = &hud->constants;
 
    LIST_INITHEAD(&hud->pane_list);
 
+   hud->cap.query_pipeline_statistics =
+      pipe->screen->get_param(pipe->screen, PIPE_CAP_QUERY_PIPELINE_STATISTICS);
+
    hud_parse_env_var(hud, env);
    return hud;
 }
@@ -987,7 +1069,7 @@ hud_destroy(struct hud_context *hud)
    }
 
    pipe->delete_fs_state(pipe, hud->fs_color);
-   pipe->delete_fs_state(pipe, hud->fs_texture);
+   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);