[Mesa-dev] [PATCH 1/3] svga: keep a list of contexts for the screen

Brian Paul brianp at vmware.com
Tue Mar 5 23:57:50 UTC 2019


This will allow us to query whether a context is valid.

In addition to keeping a list of contexts, we need to give each
context we create a unique ID which is never re-used.  The screen
also contains a bitmask to track which IDs are valid.  We need the
ID since a context pointer could be recycled by the memory allocator.
---
 src/gallium/drivers/svga/svga_context.c |  7 +++
 src/gallium/drivers/svga/svga_context.h |  6 +++
 src/gallium/drivers/svga/svga_screen.c  | 86 +++++++++++++++++++++++++++++++++
 src/gallium/drivers/svga/svga_screen.h  | 23 +++++++++
 4 files changed, 122 insertions(+)

diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c
index 7b3e9e8..1284d2f 100644
--- a/src/gallium/drivers/svga/svga_context.c
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -57,6 +57,7 @@ DEBUG_GET_ONCE_BOOL_OPTION(force_hw_line_stipple, "SVGA_FORCE_HW_LINE_STIPPLE",
 static void
 svga_destroy(struct pipe_context *pipe)
 {
+   struct svga_screen *svgascreen = svga_screen(pipe->screen);
    struct svga_context *svga = svga_context(pipe);
    unsigned shader, i;
 
@@ -97,6 +98,9 @@ svga_destroy(struct pipe_context *pipe)
 
    svga->swc->destroy(svga->swc);
 
+   /* remove this context from the screen's list */
+   svga_screen_remove_context(svgascreen, svga);
+
    util_bitmask_destroy(svga->blend_object_id_bm);
    util_bitmask_destroy(svga->ds_object_id_bm);
    util_bitmask_destroy(svga->input_element_object_id_bm);
@@ -300,6 +304,9 @@ svga_context_create(struct pipe_screen *screen, void *priv, unsigned flags)
    svga->pred.query_id = SVGA3D_INVALID_ID;
    svga->disable_rasterizer = FALSE;
 
+   /* add this context to the screen's list */
+   svga_screen_save_context(svgascreen, svga);
+
    goto done;
 
 cleanup:
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index fc63ec3..2ec6b3f 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -441,6 +441,12 @@ struct svga_context
    struct u_upload_mgr *const0_upload;
    struct u_upload_mgr *tex_upload;
 
+   /** used for svga_screen's list of contexts */
+   struct list_head context_node;
+
+   /** A per-context ID which is never reused */
+   unsigned context_id;
+
    struct {
       boolean no_swtnl;
       boolean force_swtnl;
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index 6cb5a14..6f4e8fc 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -24,6 +24,7 @@
  **********************************************************/
 
 #include "git_sha1.h" /* For MESA_GIT_SHA1 */
+#include "util/u_bitmask.h"
 #include "util/u_format.h"
 #include "util/u_memory.h"
 #include "util/u_inlines.h"
@@ -1129,6 +1130,11 @@ svga_screen_create(struct svga_winsys_screen *sws)
       debug_printf("svga: msaa samples mask: 0x%x\n", svgascreen->ms_samples);
    }
 
+   LIST_INITHEAD(&svgascreen->contexts);
+   mtx_init(&svgascreen->contexts_mutex, mtx_plain);
+
+   svgascreen->context_id_bm = util_bitmask_create();
+
    (void) mtx_init(&svgascreen->tex_mutex, mtx_plain);
    (void) mtx_init(&svgascreen->swc_mutex, mtx_recursive);
 
@@ -1144,6 +1150,86 @@ error1:
 }
 
 
+/*
+ * Add the given context to the screen's list.
+ * This should be done once when a context is created.
+ */
+void
+svga_screen_save_context(struct svga_screen *svgascreen,
+                         struct svga_context *svga)
+{
+   /* This context should not already be in the list */
+   assert(!svga_screen_context_exists(svgascreen, svga));
+
+   /* the context ID should not be set yet */
+   assert(svga->context_id == 0);
+
+   mtx_lock(&svgascreen->contexts_mutex);
+
+   /* Assign a unique ID to the svga context.  The ID is never reused */
+   svga->context_id = svgascreen->context_counter++;
+
+   util_bitmask_set(svgascreen->context_id_bm, svga->context_id);
+
+   LIST_ADDTAIL(&svga->context_node, &svgascreen->contexts);
+
+   mtx_unlock(&svgascreen->contexts_mutex);
+}
+
+
+/*
+ * Remove the given context from the screen's list.
+ * This should be done once when a context is destroyed;
+ */
+void
+svga_screen_remove_context(struct svga_screen *svgascreen,
+                           struct svga_context *svga)
+{
+   /* This context should be in the list */
+   assert(svga_screen_context_exists(svgascreen, svga));
+
+   mtx_lock(&svgascreen->contexts_mutex);
+
+   /* remove the ID from the bitmask */
+   util_bitmask_clear(svgascreen->context_id_bm, svga->context_id);
+
+   LIST_DEL(&svga->context_node);
+
+   mtx_unlock(&svgascreen->contexts_mutex);
+}
+
+
+/*
+ * Return true if the context exists in the screen's list and its ID
+ * is valid, false otherwise.
+ */
+boolean
+svga_screen_context_exists(struct svga_screen *svgascreen,
+                           const struct svga_context *svga)
+{
+   struct svga_context *ctx;
+   boolean found = FALSE;
+
+   mtx_lock(&svgascreen->contexts_mutex);
+
+   LIST_FOR_EACH_ENTRY(ctx, &svgascreen->contexts, context_node) {
+      if (ctx == svga) {
+         /* Also check that the context ID is valid since a context
+          * pointer could be recycled by the memory allocator.
+          */
+         if (util_bitmask_get(svgascreen->context_id_bm, svga->context_id)) {
+            found = TRUE;
+            break;
+         }
+      }
+   }
+
+   mtx_unlock(&svgascreen->contexts_mutex);
+
+   return found;
+}
+
+
 struct svga_winsys_screen *
 svga_winsys_screen(struct pipe_screen *screen)
 {
diff --git a/src/gallium/drivers/svga/svga_screen.h b/src/gallium/drivers/svga/svga_screen.h
index 12b9346..5ada452 100644
--- a/src/gallium/drivers/svga/svga_screen.h
+++ b/src/gallium/drivers/svga/svga_screen.h
@@ -45,6 +45,15 @@ struct svga_screen
    struct pipe_screen screen;
    struct svga_winsys_screen *sws;
 
+   /** list of svga_contexts */
+   struct list_head contexts;
+   mtx_t contexts_mutex;
+
+   /** Bitmask used to allocate context IDs */
+   struct util_bitmask *context_id_bm;
+
+   unsigned context_counter;
+
    SVGA3dHardwareVersion hw_version;
 
    /** Device caps */
@@ -102,4 +111,18 @@ struct svga_screen *
 svga_screen(struct pipe_screen *screen);
 #endif
 
+
+void
+svga_screen_save_context(struct svga_screen *screen,
+                         struct svga_context *svga);
+
+void
+svga_screen_remove_context(struct svga_screen *screen,
+                           struct svga_context *svga);
+
+boolean
+svga_screen_context_exists(struct svga_screen *screen,
+                           const struct svga_context *svga);
+
+
 #endif /* SVGA_SCREEN_H */
-- 
1.8.5.6



More information about the mesa-dev mailing list