[Mesa-dev] [PATCH 08/12] gallium/hud: separate code for draw context init/release

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


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

---
 src/gallium/auxiliary/hud/hud_context.c | 181 ++++++++++++++++++++------------
 1 file changed, 111 insertions(+), 70 deletions(-)

diff --git a/src/gallium/auxiliary/hud/hud_context.c b/src/gallium/auxiliary/hud/hud_context.c
index 810c2ea..6689006 100644
--- a/src/gallium/auxiliary/hud/hud_context.c
+++ b/src/gallium/auxiliary/hud/hud_context.c
@@ -1523,73 +1523,63 @@ print_help(struct pipe_screen *screen)
             printf("    %s\n", info.name);
             skipping = false;
          }
       }
    }
 
    puts("");
    fflush(stdout);
 }
 
-struct hud_context *
-hud_create(struct cso_context *cso)
+static void
+hud_unset_draw_context(struct hud_context *hud)
 {
-   struct pipe_context *pipe = cso_get_pipe_context(cso);
-   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(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 =
          util_make_fragment_passthrough_shader(pipe,
                                                TGSI_SEMANTIC_COLOR,
                                                TGSI_INTERPOLATE_CONSTANT,
                                                TRUE);
 
    {
       /* Read a texture and do .xxxx swizzling. */
@@ -1604,38 +1594,26 @@ hud_create(struct cso_context *cso)
          "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;
 
       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 = {
          "VERT\n"
          "DCL IN[0..1]\n"
          "DCL OUT[0], POSITION\n"
          "DCL OUT[1], COLOR[0]\n" /* color */
          "DCL OUT[2], GENERIC[0]\n" /* texcoord */
          /* [0] = color,
           * [1] = (2/fb_width, 2/fb_height, xoffset, yoffset)
@@ -1652,53 +1630,119 @@ hud_create(struct cso_context *cso)
 
          "MOV OUT[1], CONST[0][0]\n"
          "MOV OUT[2], IN[1]\n"
          "END\n"
       };
 
       struct tgsi_token tokens[1000];
       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;
+}
+
+struct hud_context *
+hud_create(struct cso_context *cso)
+{
+   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->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;
+
+   /* 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 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);
    }
 
-   /* 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;
    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);
 
+   if (!hud_set_draw_context(hud, cso)) {
+      pipe_resource_reference(&hud->font.texture, NULL);
+      FREE(hud);
+      return NULL;
+   }
+
    /* setup sig handler once for all hud contexts */
 #ifdef PIPE_OS_UNIX
    if (!sig_handled && signo != 0) {
       action.sa_sigaction = &signal_visible_handler;
       action.sa_flags = SA_SIGINFO;
 
       if (signo >= NSIG)
          fprintf(stderr, "gallium_hud: invalid signal %u\n", signo);
       else if (sigaction(signo, &action, NULL) < 0)
          fprintf(stderr, "gallium_hud: unable to set handler for signal %u\n", signo);
@@ -1722,24 +1766,21 @@ hud_destroy(struct hud_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, pipe);
       }
       LIST_DEL(&pane->head);
       FREE(pane);
    }
 
    hud_batch_query_cleanup(&hud->batch_query, pipe);
-   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);
+   hud_unset_draw_context(hud);
    pipe_resource_reference(&hud->font.texture, NULL);
    FREE(hud);
 }
 
 void
 hud_add_queue_for_monitoring(struct hud_context *hud,
                              struct util_queue_monitoring *queue_info)
 {
    assert(!hud->monitored_queue);
    hud->monitored_queue = queue_info;
-- 
2.7.4



More information about the mesa-dev mailing list