[Mesa-dev] [PATCH 03/12] gallium/hud: split hud_draw into 3 separate functions

Marek Olšák maraeo at gmail.com
Tue Nov 21 17:46:03 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

---
 src/gallium/auxiliary/hud/hud_context.c          | 168 +++++++++++++----------
 src/gallium/auxiliary/hud/hud_context.h          |   2 +-
 src/gallium/state_trackers/dri/dri_drawable.c    |   2 +-
 src/gallium/state_trackers/glx/xlib/xm_api.c     |   2 +-
 src/gallium/state_trackers/nine/swapchain9.c     |   2 +-
 src/gallium/state_trackers/wgl/stw_framebuffer.c |   2 +-
 6 files changed, 99 insertions(+), 79 deletions(-)

diff --git a/src/gallium/auxiliary/hud/hud_context.c b/src/gallium/auxiliary/hud/hud_context.c
index ed2e849..83b3204 100644
--- a/src/gallium/auxiliary/hud/hud_context.c
+++ b/src/gallium/auxiliary/hud/hud_context.c
@@ -421,32 +421,31 @@ hud_prepare_vertices(struct hud_context *hud, struct vertex_queue *v,
    v->num_vertices = 0;
    v->max_num_vertices = num_vertices;
    v->vbuf.stride = stride;
    v->buffer_size = stride * num_vertices;
 }
 
 /**
  * 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;
    struct pipe_framebuffer_state fb;
    struct pipe_surface surf_templ, *surf;
    struct pipe_viewport_state viewport;
    const struct pipe_sampler_state *sampler_states[] =
          { &hud->font_sampler_state };
    struct hud_pane *pane;
-   struct hud_graph *gr, *next;
 
    if (!huds_visible)
       return;
 
    hud->fb_width = tex->width0;
    hud->fb_height = tex->height0;
    hud->constants.two_div_fb_width = 2.0f / hud->fb_width;
    hud->constants.two_div_fb_height = 2.0f / hud->fb_height;
 
    cso_save_state(cso, (CSO_BIT_FRAMEBUFFER |
@@ -512,90 +511,20 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
    cso_set_tesseval_shader_handle(cso, NULL);
    cso_set_geometry_shader_handle(cso, NULL);
    cso_set_vertex_shader_handle(cso, hud->vs);
    cso_set_vertex_elements(cso, 2, hud->velems);
    cso_set_render_condition(cso, NULL, FALSE, 0);
    cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, 1,
                          &hud->font_sampler_view);
    cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, 1, sampler_states);
    cso_set_constant_buffer(cso, PIPE_SHADER_VERTEX, 0, &hud->constbuf);
 
-   /* 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));
-   hud_prepare_vertices(hud, &hud->text, 16 * 1024, 4 * sizeof(float));
-   hud_prepare_vertices(hud, &hud->color_prims, 32 * 1024, 2 * sizeof(float));
-
-   /* 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,
-                  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;
-   }
-
-   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);
-   pipe_resource_reference(&hud->color_prims.vbuf.buffer.resource, hud->bg.vbuf.buffer.resource);
-
-   hud->whitelines.vbuf.buffer_offset = hud->bg.vbuf.buffer_offset +
-                                        hud->bg.buffer_size;
-   hud->whitelines.vertices = hud->bg.vertices +
-                              hud->bg.buffer_size / sizeof(float);
-
-   hud->text.vbuf.buffer_offset = hud->whitelines.vbuf.buffer_offset +
-                                  hud->whitelines.buffer_size;
-   hud->text.vertices = hud->whitelines.vertices +
-                        hud->whitelines.buffer_size / sizeof(float);
-
-   hud->color_prims.vbuf.buffer_offset = hud->text.vbuf.buffer_offset +
-                                         hud->text.buffer_size;
-   hud->color_prims.vertices = hud->text.vertices +
-                               hud->text.buffer_size / sizeof(float);
-
-   /* prepare all graphs */
-   hud_batch_query_update(hud->batch_query);
-
-   LIST_FOR_EACH_ENTRY(pane, &hud->pane_list, head) {
-      LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) {
-         gr->query_new_value(gr);
-      }
-
-      if (pane->sort_items) {
-         LIST_FOR_EACH_ENTRY_SAFE(gr, next, &pane->graph_list, head) {
-            /* ignore the last one */
-            if (&gr->head == pane->graph_list.prev)
-               continue;
-
-            /* This is an incremental bubble sort, because we only do one pass
-             * per frame. It will eventually reach an equilibrium.
-             */
-            if (gr->current_value <
-                LIST_ENTRY(struct hud_graph, next, head)->current_value) {
-               LIST_DEL(&gr->head);
-               LIST_ADD(&gr->head, &next->head);
-            }
-         }
-      }
-
-      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;
@@ -641,37 +570,128 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
    }
    pipe_resource_reference(&hud->text.vbuf.buffer.resource, NULL);
 
    /* 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);
    }
 
-out:
    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 hud_pane *pane;
+   struct hud_graph *gr;
 
    /* Start queries. */
    hud_batch_query_begin(hud->batch_query);
 
    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);
       }
    }
 }
 
+/* Stop queries, query results, and record vertices for charts. */
+static void
+hud_stop_queries(struct hud_context *hud)
+{
+   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));
+   hud_prepare_vertices(hud, &hud->text, 16 * 1024, 4 * sizeof(float));
+   hud_prepare_vertices(hud, &hud->color_prims, 32 * 1024, 2 * sizeof(float));
+
+   /* 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,
+                  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)
+      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);
+   pipe_resource_reference(&hud->color_prims.vbuf.buffer.resource, hud->bg.vbuf.buffer.resource);
+
+   hud->whitelines.vbuf.buffer_offset = hud->bg.vbuf.buffer_offset +
+                                        hud->bg.buffer_size;
+   hud->whitelines.vertices = hud->bg.vertices +
+                              hud->bg.buffer_size / sizeof(float);
+
+   hud->text.vbuf.buffer_offset = hud->whitelines.vbuf.buffer_offset +
+                                  hud->whitelines.buffer_size;
+   hud->text.vertices = hud->whitelines.vertices +
+                        hud->whitelines.buffer_size / sizeof(float);
+
+   hud->color_prims.vbuf.buffer_offset = hud->text.vbuf.buffer_offset +
+                                         hud->text.buffer_size;
+   hud->color_prims.vertices = hud->text.vertices +
+                               hud->text.buffer_size / sizeof(float);
+
+   /* prepare all graphs */
+   hud_batch_query_update(hud->batch_query);
+
+   LIST_FOR_EACH_ENTRY(pane, &hud->pane_list, head) {
+      LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) {
+         gr->query_new_value(gr);
+      }
+
+      if (pane->sort_items) {
+         LIST_FOR_EACH_ENTRY_SAFE(gr, next, &pane->graph_list, head) {
+            /* ignore the last one */
+            if (&gr->head == pane->graph_list.prev)
+               continue;
+
+            /* This is an incremental bubble sort, because we only do one pass
+             * per frame. It will eventually reach an equilibrium.
+             */
+            if (gr->current_value <
+                LIST_ENTRY(struct hud_graph, next, head)->current_value) {
+               LIST_DEL(&gr->head);
+               LIST_ADD(&gr->head, &next->head);
+            }
+         }
+      }
+
+      hud_pane_accumulate_vertices(hud, pane);
+   }
+
+   /* unmap the uploader's vertex buffer before drawing */
+   u_upload_unmap(hud->pipe->stream_uploader);
+}
+
+void
+hud_run(struct hud_context *hud, struct pipe_resource *tex)
+{
+   hud_stop_queries(hud);
+   hud_draw_results(hud, tex);
+   hud_start_queries(hud);
+}
+
 static void
 fixup_bytes(enum pipe_driver_query_type type, int position, uint64_t *exp10)
 {
    if (type == PIPE_DRIVER_QUERY_TYPE_BYTES && position % 3 == 0)
       *exp10 = (*exp10 / 1000) * 1024;
 }
 
 /**
  * Set the maximum value for the Y axis of the graph.
  * This scales the graph accordingly.
diff --git a/src/gallium/auxiliary/hud/hud_context.h b/src/gallium/auxiliary/hud/hud_context.h
index 5a7e13b..deb60ef 100644
--- a/src/gallium/auxiliary/hud/hud_context.h
+++ b/src/gallium/auxiliary/hud/hud_context.h
@@ -34,17 +34,17 @@ struct pipe_context;
 struct pipe_resource;
 struct util_queue_monitoring;
 
 struct hud_context *
 hud_create(struct pipe_context *pipe, struct cso_context *cso);
 
 void
 hud_destroy(struct hud_context *hud);
 
 void
-hud_draw(struct hud_context *hud, struct pipe_resource *tex);
+hud_run(struct hud_context *hud, struct pipe_resource *tex);
 
 void
 hud_add_queue_for_monitoring(struct hud_context *hud,
                              struct util_queue_monitoring *queue_info);
 
 #endif
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
index d586b75..53dbfd7 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -512,21 +512,21 @@ dri_flush(__DRIcontext *cPriv,
              drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT]) {
             swap_msaa_buffers = TRUE;
          }
 
          /* FRONT_LEFT is resolved in drawable->flush_frontbuffer. */
       }
 
       dri_postprocessing(ctx, drawable, ST_ATTACHMENT_BACK_LEFT);
 
       if (ctx->hud) {
-         hud_draw(ctx->hud, drawable->textures[ST_ATTACHMENT_BACK_LEFT]);
+         hud_run(ctx->hud, drawable->textures[ST_ATTACHMENT_BACK_LEFT]);
       }
 
       pipe->flush_resource(pipe, drawable->textures[ST_ATTACHMENT_BACK_LEFT]);
 
       if (pipe->invalidate_resource &&
           (flags & __DRI2_FLUSH_INVALIDATE_ANCILLARY)) {
          if (drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL])
             pipe->invalidate_resource(pipe, drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL]);
          if (drawable->msaa_textures[ST_ATTACHMENT_DEPTH_STENCIL])
             pipe->invalidate_resource(pipe, drawable->msaa_textures[ST_ATTACHMENT_DEPTH_STENCIL]);
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index 828253b..74b5975 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
@@ -1350,21 +1350,21 @@ XMesaContext XMesaGetCurrentContext( void )
  */
 PUBLIC
 void XMesaSwapBuffers( XMesaBuffer b )
 {
    XMesaContext xmctx = XMesaGetCurrentContext();
 
    /* Need to draw HUD before flushing */
    if (xmctx && xmctx->hud) {
       struct pipe_resource *back =
          xmesa_get_framebuffer_resource(b->stfb, ST_ATTACHMENT_BACK_LEFT);
-      hud_draw(xmctx->hud, back);
+      hud_run(xmctx->hud, back);
    }
 
    if (xmctx && xmctx->xm_buffer == b) {
       xmctx->st->flush( xmctx->st, ST_FLUSH_FRONT, NULL);
    }
 
    xmesa_swap_st_framebuffer(b->stfb);
 }
 
 
diff --git a/src/gallium/state_trackers/nine/swapchain9.c b/src/gallium/state_trackers/nine/swapchain9.c
index 9815acf..096d582 100644
--- a/src/gallium/state_trackers/nine/swapchain9.c
+++ b/src/gallium/state_trackers/nine/swapchain9.c
@@ -599,21 +599,21 @@ handle_draw_cursor_and_hud( struct NineSwapChain9 *This, struct pipe_resource *r
             blit.dst.box.x, blit.dst.box.y);
 
         blit.alpha_blend = TRUE;
         pipe = NineDevice9_GetPipe(This->base.device);
         pipe->blit(pipe, &blit);
     }
 
     if (device->hud && resource) {
         /* Implicit use of context pipe */
         (void)NineDevice9_GetPipe(This->base.device);
-        hud_draw(device->hud, resource); /* XXX: no offset */
+        hud_run(device->hud, resource); /* XXX: no offset */
         /* HUD doesn't clobber stipple */
         nine_state_restore_non_cso(device);
     }
 }
 
 struct end_present_struct {
     struct pipe_screen *screen;
     struct pipe_fence_handle *fence_to_wait;
     ID3DPresent *present;
     D3DWindowBuffer *present_handle;
diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c
index 7348ea3..47e76c6 100644
--- a/src/gallium/state_trackers/wgl/stw_framebuffer.c
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c
@@ -634,21 +634,21 @@ DrvSwapBuffers(HDC hdc)
       return TRUE;
    }
 
    ctx = stw_current_context();
    if (ctx) {
       if (ctx->hud) {
          /* Display the HUD */
          struct pipe_resource *back =
             stw_get_framebuffer_resource(fb->stfb, ST_ATTACHMENT_BACK_LEFT);
          if (back) {
-            hud_draw(ctx->hud, back);
+            hud_run(ctx->hud, back);
          }
       }
 
       if (ctx->current_framebuffer == fb) {
          /* flush current context */
          ctx->st->flush(ctx->st, ST_FLUSH_END_OF_FRAME, NULL);
       }
    }
 
    if (stw_dev->swap_interval != 0) {
-- 
2.7.4



More information about the mesa-dev mailing list