gl_marshal.py: rework how the marshal dispatch table is initialized
authorMarek Olšák <marek.olsak@amd.com>
Thu, 11 Aug 2022 13:10:15 +0000 (09:10 -0400)
committerMarge Bot <emma+marge@anholt.net>
Wed, 19 Oct 2022 04:23:05 +0000 (04:23 +0000)
Instead of setting all function pointers in marshal_generated0.c,
set the function pointers in the file that contains the functions,
and remove all the forward declarations of marshal functions
in marshal_generated.h.

Acked-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18199>

src/mapi/glapi/gen/gl_marshal.py
src/mapi/glapi/gen/gl_marshal_h.py
src/mapi/glapi/gen/marshal_XML.py
src/mesa/main/glthread.c
src/mesa/main/glthread.h
src/mesa/main/glthread_marshal.h

index ebaec99..f1f355b 100644 (file)
@@ -93,7 +93,7 @@ class PrintCode(gl_XML.gl_print_base):
 
     def print_sync_body(self, func):
         out('/* {0}: marshalled synchronously */'.format(func.name))
-        out('{0} GLAPIENTRY'.format(func.return_type))
+        out('{0}{1} GLAPIENTRY'.format('static ' if func.marshal_is_static() else '', func.return_type))
         out('_mesa_marshal_{0}({1})'.format(func.name, func.get_parameter_string()))
         out('{')
         with indent():
@@ -319,7 +319,7 @@ class PrintCode(gl_XML.gl_print_base):
         out('}')
 
     def print_async_marshal(self, func):
-        out('{0} GLAPIENTRY'.format(func.return_type))
+        out('{0}{1} GLAPIENTRY'.format('static ' if func.marshal_is_static() else '', func.return_type))
         out('_mesa_marshal_{0}({1})'.format(
                 func.name, func.get_parameter_string()))
         out('{')
@@ -366,29 +366,21 @@ class PrintCode(gl_XML.gl_print_base):
         out('')
         out('')
 
-    def print_create_marshal_table(self, api):
+    def print_init_marshal_table(self, functions):
         out('/* _mesa_create_marshal_table takes a long time to compile with -O2 */')
         out('#if defined(__GNUC__) && !defined(__clang__)')
         out('__attribute__((optimize("O1")))')
         out('#endif')
-        out('bool')
-        out('_mesa_create_marshal_tables(struct gl_context *ctx)')
+        out('void')
+        out('_mesa_glthread_init_dispatch%u(struct gl_context *ctx, '
+                                           'struct _glapi_table *table)' % file_index)
         out('{')
         with indent():
-            out('ctx->MarshalExec = _mesa_alloc_dispatch_table(true);')
-            out('if (!ctx->MarshalExec)')
-            with indent():
-                out('return false;')
-            out('')
-
             # Collect SET_* calls by the condition under which they should
             # be called.
             settings_by_condition = collections.defaultdict(lambda: [])
 
-            for func in api.functionIterateAll():
-                if func.marshal_flavor() == 'skip':
-                    continue
-
+            for func in functions:
                 condition = apiexec.get_api_condition(func)
                 if not condition:
                     continue
@@ -397,7 +389,7 @@ class PrintCode(gl_XML.gl_print_base):
                 # by 20 seconds (on Ryzen 1700X).
                 settings_by_condition[condition].append(
                     ('if (_gloffset_{0} >= 0)\n' +
-                     '   ((_glapi_proc *)(ctx->MarshalExec))[_gloffset_{0}] =' +
+                     '   ((_glapi_proc *)table)[_gloffset_{0}] =' +
                      ' (_glapi_proc)_mesa_marshal_{0};').format(func.name))
 
             # Print out an if statement for each unique condition, with
@@ -409,32 +401,31 @@ class PrintCode(gl_XML.gl_print_base):
                         for line in setting.split('\n'):
                             out(line)
                 out('}')
-
-        out('')
-        out('   return true;')
         out('}')
 
     def printBody(self, api):
-        # The first file only contains the dispatch tables
-        if file_index == 0:
-            self.print_create_marshal_table(api)
-            return
-
-        # The remaining files contain the marshal and unmarshal functions
-        func_per_file = (len(api.functionIterateAll()) // (file_count - 1)) + 1
-        i = -1
-        for func in api.functionIterateAll():
-            i += 1
-            if i // func_per_file != (file_index - 1):
-                continue
-
+        # Don't generate marshal/unmarshal functions for skipped and custom functions
+        functions = [func for func in api.functionIterateAll()
+                     if func.marshal_flavor() not in ('skip', 'custom')]
+        # Divide the functions between files
+        func_per_file = len(functions) // file_count + 1
+        functions = functions[file_index*func_per_file:(file_index+1)*func_per_file]
+
+        for func in functions:
             flavor = func.marshal_flavor()
-            if flavor in ('skip', 'custom'):
-                continue
-            elif flavor == 'async':
+            if flavor == 'async':
                 self.print_async_body(func)
             elif flavor == 'sync':
                 self.print_sync_body(func)
+            else:
+                assert False
+
+        # The first file will also set custom functions
+        if file_index == 0:
+            functions += [func for func in api.functionIterateAll()
+                          if func.marshal_flavor() == 'custom']
+
+        self.print_init_marshal_table(functions)
 
 
 def show_usage():
index c45b848..aaf7403 100644 (file)
@@ -71,8 +71,8 @@ class PrintCode(gl_XML.gl_print_base):
                 print('struct marshal_cmd_{0};'.format(func.name))
                 print(('uint32_t _mesa_unmarshal_{0}(struct gl_context *ctx, '
                        'const struct marshal_cmd_{0} *cmd, const uint64_t *last);').format(func.name))
-                print('{0} GLAPIENTRY _mesa_marshal_{1}({2});'.format(func.return_type, func.name, func.get_parameter_string()))
-            elif flavor == 'sync':
+
+            if flavor in ('custom', 'async', 'sync') and not func.marshal_is_static():
                 print('{0} GLAPIENTRY _mesa_marshal_{1}({2});'.format(func.return_type, func.name, func.get_parameter_string()))
 
 
index 7323b9d..e049f25 100644 (file)
@@ -86,3 +86,6 @@ class marshal_function(gl_XML.gl_function):
                 # written logic to handle this yet.  TODO: fix.
                 return 'sync'
         return 'async'
+
+    def marshal_is_static(self):
+        return self.marshal_flavor() != 'custom' and self.name[0:8] != 'Internal'
index b66e374..b737d97 100644 (file)
@@ -91,6 +91,20 @@ glthread_thread_initialization(void *job, void *gdata, int thread_index)
    _glapi_set_context(ctx);
 }
 
+static void
+_mesa_glthread_init_dispatch(struct gl_context *ctx,
+                             struct _glapi_table *table)
+{
+   _mesa_glthread_init_dispatch0(ctx, table);
+   _mesa_glthread_init_dispatch1(ctx, table);
+   _mesa_glthread_init_dispatch2(ctx, table);
+   _mesa_glthread_init_dispatch3(ctx, table);
+   _mesa_glthread_init_dispatch4(ctx, table);
+   _mesa_glthread_init_dispatch5(ctx, table);
+   _mesa_glthread_init_dispatch6(ctx, table);
+   _mesa_glthread_init_dispatch7(ctx, table);
+}
+
 void
 _mesa_glthread_init(struct gl_context *ctx)
 {
@@ -112,12 +126,15 @@ _mesa_glthread_init(struct gl_context *ctx)
    _mesa_glthread_reset_vao(&glthread->DefaultVAO);
    glthread->CurrentVAO = &glthread->DefaultVAO;
 
-   if (!_mesa_create_marshal_tables(ctx)) {
+   ctx->MarshalExec = _mesa_alloc_dispatch_table(true);
+   if (!ctx->MarshalExec) {
       _mesa_DeleteHashTable(glthread->VAOs);
       util_queue_destroy(&glthread->queue);
       return;
    }
 
+   _mesa_glthread_init_dispatch(ctx, ctx->MarshalExec);
+
    for (unsigned i = 0; i < MARSHAL_MAX_BATCHES; i++) {
       glthread->batches[i].ctx = ctx;
       util_queue_fence_init(&glthread->batches[i].fence);
index fbce31f..e0f9251 100644 (file)
@@ -61,6 +61,7 @@ extern "C" {
 struct gl_context;
 struct gl_buffer_object;
 struct _mesa_HashTable;
+struct _glapi_table;
 
 struct glthread_attrib_binding {
    struct gl_buffer_object *buffer; /**< where non-VBO data was uploaded */
@@ -244,6 +245,23 @@ struct glthread_state
 void _mesa_glthread_init(struct gl_context *ctx);
 void _mesa_glthread_destroy(struct gl_context *ctx, const char *reason);
 
+void _mesa_glthread_init_dispatch0(struct gl_context *ctx,
+                                   struct _glapi_table *table);
+void _mesa_glthread_init_dispatch1(struct gl_context *ctx,
+                                   struct _glapi_table *table);
+void _mesa_glthread_init_dispatch2(struct gl_context *ctx,
+                                   struct _glapi_table *table);
+void _mesa_glthread_init_dispatch3(struct gl_context *ctx,
+                                   struct _glapi_table *table);
+void _mesa_glthread_init_dispatch4(struct gl_context *ctx,
+                                   struct _glapi_table *table);
+void _mesa_glthread_init_dispatch5(struct gl_context *ctx,
+                                   struct _glapi_table *table);
+void _mesa_glthread_init_dispatch6(struct gl_context *ctx,
+                                   struct _glapi_table *table);
+void _mesa_glthread_init_dispatch7(struct gl_context *ctx,
+                                   struct _glapi_table *table);
+
 void _mesa_glthread_flush_batch(struct gl_context *ctx);
 void _mesa_glthread_finish(struct gl_context *ctx);
 void _mesa_glthread_finish_before(struct gl_context *ctx, const char *func);
index 4b16b85..8d4d3a5 100644 (file)
@@ -133,10 +133,6 @@ _mesa_glthread_has_non_vbo_vertices_or_indices_or_indirect(const struct gl_conte
            (vao->UserPointerMask & vao->BufferEnabled));
 }
 
-
-bool
-_mesa_create_marshal_tables(struct gl_context *ctx);
-
 static inline unsigned
 _mesa_buffer_enum_to_count(GLenum buffer)
 {