mesa: put dispatch table initialization into one place
authorMarek Olšák <marek.olsak@amd.com>
Thu, 11 Aug 2022 07:00:40 +0000 (03:00 -0400)
committerMarek Olšák <marek.olsak@amd.com>
Sun, 12 Mar 2023 21:56:16 +0000 (17:56 -0400)
We have 3 new/changed functions with this commit:
1. _mesa_alloc_dispatch_tables creates all dispatch tables that are not
   created on demand and sets them to nop. This operates on gl_dispatch,
   so it's reusable (e.g. glthread will want to use it)
2. _mesa_free_dispatch_tables frees everything
3. _mesa_initialize_dispatch_tables initializes gl_dispatch for GL
   (not glthread)

Acked-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21777>

src/mesa/main/context.c
src/mesa/main/context.h
src/mesa/state_tracker/st_context.c

index 3573f5b..f16d8ca 100644 (file)
@@ -903,18 +903,60 @@ _mesa_alloc_dispatch_table(bool glthread)
    return table;
 }
 
-void
+/**
+ * Allocate dispatch tables and set all functions to nop.
+ * It also makes the OutsideBeginEnd dispatch table current within gl_dispatch.
+ *
+ * \param glthread Whether to set nop dispatch for glthread or regular dispatch
+ */
+bool
+_mesa_alloc_dispatch_tables(gl_api api, struct gl_dispatch *d, bool glthread)
+{
+   d->OutsideBeginEnd = _mesa_alloc_dispatch_table(glthread);
+   if (!d->OutsideBeginEnd)
+      return false;
+
+   if (api == API_OPENGL_COMPAT) {
+      d->BeginEnd = _mesa_alloc_dispatch_table(glthread);
+      d->Save = _mesa_alloc_dispatch_table(glthread);
+      if (!d->BeginEnd || !d->Save)
+         return false;
+   }
+
+   d->Current = d->Exec = d->OutsideBeginEnd;
+   return true;
+}
+
+static void
+_mesa_free_dispatch_tables(struct gl_dispatch *d)
+{
+   free(d->OutsideBeginEnd);
+   free(d->BeginEnd);
+   free(d->HWSelectModeBeginEnd);
+   free(d->Save);
+   free(d->ContextLost);
+}
+
+bool
 _mesa_initialize_dispatch_tables(struct gl_context *ctx)
 {
-   /* Do the code-generated setup of the exec table in api_exec_init.c. */
+   if (!_mesa_alloc_dispatch_tables(ctx->API, &ctx->Dispatch, false))
+      return false;
+
+   /* Do the code-generated initialization of dispatch tables. */
    _mesa_init_dispatch(ctx);
+   vbo_init_dispatch_begin_end(ctx);
 
-   if (ctx->Dispatch.Save)
+   if (_mesa_is_desktop_gl_compat(ctx)) {
       _mesa_init_dispatch_save(ctx);
-
-   vbo_init_dispatch_begin_end(ctx);
-   if (_mesa_is_desktop_gl_compat(ctx))
       _mesa_init_dispatch_save_begin_end(ctx);
+   }
+
+   /* This binds the dispatch table to the context, but MakeCurrent will
+    * bind it for the user. If glthread is enabled, it will override it.
+    */
+   ctx->GLApi = ctx->Dispatch.Current;
+   return true;
 }
 
 /**
@@ -1004,13 +1046,6 @@ _mesa_initialize_context(struct gl_context *ctx,
    if (no_error)
       ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR;
 
-   /* setup the API dispatch tables with all nop functions */
-   ctx->Dispatch.OutsideBeginEnd = _mesa_alloc_dispatch_table(false);
-   if (!ctx->Dispatch.OutsideBeginEnd)
-      goto fail;
-   ctx->Dispatch.Exec = ctx->Dispatch.OutsideBeginEnd;
-   ctx->GLApi = ctx->Dispatch.Current = ctx->Dispatch.OutsideBeginEnd;
-
    _mesa_reset_vertex_processing_mode(ctx);
 
    /* Mesa core handles all the formats that mesa core knows about.
@@ -1022,12 +1057,6 @@ _mesa_initialize_context(struct gl_context *ctx,
 
    switch (ctx->API) {
    case API_OPENGL_COMPAT:
-      ctx->Dispatch.BeginEnd = _mesa_alloc_dispatch_table(false);
-      ctx->Dispatch.Save = _mesa_alloc_dispatch_table(false);
-      if (!ctx->Dispatch.BeginEnd || !ctx->Dispatch.Save)
-         goto fail;
-
-      FALLTHROUGH;
    case API_OPENGL_CORE:
    case API_OPENGLES2:
       break;
@@ -1058,9 +1087,6 @@ _mesa_initialize_context(struct gl_context *ctx,
 
 fail:
    _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
-   free(ctx->Dispatch.BeginEnd);
-   free(ctx->Dispatch.OutsideBeginEnd);
-   free(ctx->Dispatch.Save);
    return GL_FALSE;
 }
 
@@ -1135,12 +1161,8 @@ _mesa_free_context_data(struct gl_context *ctx, bool destroy_debug_output)
    _mesa_free_buffer_objects(ctx);
 
    /* free dispatch tables */
-   free(ctx->Dispatch.BeginEnd);
-   free(ctx->Dispatch.OutsideBeginEnd);
-   free(ctx->Dispatch.Save);
-   free(ctx->Dispatch.ContextLost);
+   _mesa_free_dispatch_tables(&ctx->Dispatch);
    free(ctx->MarshalExec);
-   free(ctx->Dispatch.HWSelectModeBeginEnd);
 
    /* Shared context state (display lists, textures, etc) */
    _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
index 34bc762..1b25627 100644 (file)
@@ -84,7 +84,10 @@ _mesa_alloc_dispatch_table(bool glthread);
 extern void
 _mesa_init_dispatch(struct gl_context *ctx);
 
-extern void
+extern bool
+_mesa_alloc_dispatch_tables(gl_api api, struct gl_dispatch *d, bool glthread);
+
+extern bool
 _mesa_initialize_dispatch_tables(struct gl_context *ctx);
 
 extern struct _glapi_table *
index 37b809a..a60d184 100644 (file)
@@ -769,7 +769,8 @@ st_create_context_priv(struct gl_context *ctx, struct pipe_context *pipe,
    _mesa_override_extensions(ctx);
    _mesa_compute_version(ctx);
 
-   if (ctx->Version == 0) {
+   if (ctx->Version == 0 ||
+       !_mesa_initialize_dispatch_tables(ctx)) {
       /* This can happen when a core profile was requested, but the driver
        * does not support some features of GL 3.1 or later.
        */
@@ -793,7 +794,6 @@ st_create_context_priv(struct gl_context *ctx, struct pipe_context *pipe,
     */
    _vbo_CreateContext(ctx);
 
-   _mesa_initialize_dispatch_tables(ctx);
    st_init_driver_flags(st);
 
    /* Initialize context's winsys buffers list */