Module: Mesa
Branch: main
Commit: a02ed8a95fba82169dd0a8b5382c91b6bfc5454a
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=a02ed8a95fba82169dd0a8b5382c91b6bfc5454a

Author: Marek Olšák <[email protected]>
Date:   Mon Nov 27 21:51:47 2023 -0500

glthread: add option to put autogenerated marshal structures in the header file

This is used when we want to be able to read the calls of autogenerated
functions, or when we want to use the default structure for our custom
marshal functions.

Reviewed-by: Timothy Arceri <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26548>

---

 src/mapi/glapi/gen/gl_API.dtd      |  5 ++
 src/mapi/glapi/gen/gl_marshal.py   | 85 ++--------------------------------
 src/mapi/glapi/gen/gl_marshal_h.py |  4 +-
 src/mapi/glapi/gen/marshal_XML.py  | 95 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 106 insertions(+), 83 deletions(-)

diff --git a/src/mapi/glapi/gen/gl_API.dtd b/src/mapi/glapi/gen/gl_API.dtd
index 714120b1db3..a5aae816c48 100644
--- a/src/mapi/glapi/gen/gl_API.dtd
+++ b/src/mapi/glapi/gen/gl_API.dtd
@@ -44,6 +44,7 @@
                    marshal_count       CDATA #IMPLIED>
                    marshal_call_before CDATA #IMPLIED>
                    marshal_call_after  CDATA #IMPLIED>
+                   marshal_struct      CDATA #IMPLIED>
 <!ATTLIST size     name                NMTOKEN #REQUIRED
                    count               NMTOKEN #IMPLIED
                    mode                (get | set) "set">
@@ -138,6 +139,10 @@ param:
      marshal_call_before - insert the string at the beginning of the marshal
         function
      marshal_call_after - insert the string at the end of the marshal function
+     marshal_struct - if "public", insert the structure into the generated
+        header file instead of the C file. It's done even with
+        marshal="custom", in which case you don't have to define the structure
+        manually.
 
 glx:
      rop - Opcode value for "render" commands
diff --git a/src/mapi/glapi/gen/gl_marshal.py b/src/mapi/glapi/gen/gl_marshal.py
index 5f59f634a9c..a4bb2d0bb01 100644
--- a/src/mapi/glapi/gen/gl_marshal.py
+++ b/src/mapi/glapi/gen/gl_marshal.py
@@ -103,91 +103,12 @@ class PrintCode(gl_XML.gl_print_base):
         out('')
         out('')
 
-    def get_type_size(self, str):
-        if str.find('*') != -1:
-            return 8;
-
-        mapping = {
-            'GLboolean': 1,
-            'GLbyte': 1,
-            'GLubyte': 1,
-            'GLenum': 2, # uses GLenum16, clamped to 0xffff (invalid enum)
-            'GLshort': 2,
-            'GLushort': 2,
-            'GLhalfNV': 2,
-            'GLint': 4,
-            'GLuint': 4,
-            'GLbitfield': 4,
-            'GLsizei': 4,
-            'GLfloat': 4,
-            'GLclampf': 4,
-            'GLfixed': 4,
-            'GLclampx': 4,
-            'GLhandleARB': 4,
-            'int': 4,
-            'float': 4,
-            'GLdouble': 8,
-            'GLclampd': 8,
-            'GLintptr': 8,
-            'GLsizeiptr': 8,
-            'GLint64': 8,
-            'GLuint64': 8,
-            'GLuint64EXT': 8,
-            'GLsync': 8,
-        }
-        val = mapping.get(str, 9999)
-        if val == 9999:
-            print('Unhandled type in gl_marshal.py.get_type_size: ' + str, 
file=sys.stderr)
-            assert False
-        return val
-
     def print_async_body(self, func):
-        # We want glthread to ignore variable-sized parameters if the only 
thing
-        # we want is to pass the pointer parameter as-is, e.g. when a PBO is 
bound.
-        # Making it conditional on marshal_sync is kinda hacky, but it's the 
easiest
-        # path towards handling PBOs in glthread, which use marshal_sync to 
check whether
-        # a PBO is bound.
-        if func.marshal_sync:
-            fixed_params = func.fixed_params + func.variable_params
-            variable_params = []
-        else:
-            fixed_params = func.fixed_params
-            variable_params = func.variable_params
+        fixed_params = func.get_fixed_params()
+        variable_params = func.get_variable_params()
 
         out('/* {0}: marshalled asynchronously */'.format(func.name))
-        out('struct marshal_cmd_{0}'.format(func.name))
-        out('{')
-        with indent():
-            out('struct marshal_cmd_base cmd_base;')
-
-            # Sort the parameters according to their size to pack the 
structure optimally
-            for p in sorted(fixed_params, key=lambda p: 
self.get_type_size(p.type_string())):
-                if p.count:
-                    out('{0} {1}[{2}];'.format(
-                            p.get_base_type_string(), p.name, p.count))
-                else:
-                    type = p.type_string()
-                    if type == 'GLenum':
-                        type = 'GLenum16'
-                    out('{0} {1};'.format(type, p.name))
-
-            for p in variable_params:
-                if p.img_null_flag:
-                    out('bool {0}_null; /* If set, no data follows '
-                        'for "{0}" */'.format(p.name))
-
-            for p in variable_params:
-                if p.count_scale != 1:
-                    out(('/* Next {0} bytes are '
-                         '{1} {2}[{3}][{4}] */').format(
-                            p.size_string(marshal=1), p.get_base_type_string(),
-                            p.name, p.counter, p.count_scale))
-                else:
-                    out(('/* Next {0} bytes are '
-                         '{1} {2}[{3}] */').format(
-                            p.size_string(marshal=1), p.get_base_type_string(),
-                            p.name, p.counter))
-        out('};')
+        func.print_struct()
 
         out('uint32_t')
         out(('_mesa_unmarshal_{0}(struct gl_context *ctx, '
diff --git a/src/mapi/glapi/gen/gl_marshal_h.py 
b/src/mapi/glapi/gen/gl_marshal_h.py
index fd12b3916fd..d155d233340 100644
--- a/src/mapi/glapi/gen/gl_marshal_h.py
+++ b/src/mapi/glapi/gen/gl_marshal_h.py
@@ -66,9 +66,11 @@ class PrintCode(gl_XML.gl_print_base):
         print('')
 
         for func in api.functionIterateAll():
+            func.print_struct(is_header=True)
+
             flavor = func.marshal_flavor()
+
             if flavor in ('custom', 'async'):
-                print('struct marshal_cmd_{0};'.format(func.name))
                 print(('uint32_t _mesa_unmarshal_{0}(struct gl_context *ctx, '
                        'const struct marshal_cmd_{0} *restrict 
cmd);').format(func.name))
 
diff --git a/src/mapi/glapi/gen/marshal_XML.py 
b/src/mapi/glapi/gen/marshal_XML.py
index bd8fa36c087..01ec84502ab 100644
--- a/src/mapi/glapi/gen/marshal_XML.py
+++ b/src/mapi/glapi/gen/marshal_XML.py
@@ -25,6 +25,43 @@
 
 import gl_XML
 
+def get_type_size(str):
+    if str.find('*') != -1:
+        return 8;
+
+    mapping = {
+        'GLboolean': 1,
+        'GLbyte': 1,
+        'GLubyte': 1,
+        'GLenum': 2, # uses GLenum16, clamped to 0xffff (invalid enum)
+        'GLshort': 2,
+        'GLushort': 2,
+        'GLhalfNV': 2,
+        'GLint': 4,
+        'GLuint': 4,
+        'GLbitfield': 4,
+        'GLsizei': 4,
+        'GLfloat': 4,
+        'GLclampf': 4,
+        'GLfixed': 4,
+        'GLclampx': 4,
+        'GLhandleARB': 4,
+        'int': 4,
+        'float': 4,
+        'GLdouble': 8,
+        'GLclampd': 8,
+        'GLintptr': 8,
+        'GLsizeiptr': 8,
+        'GLint64': 8,
+        'GLuint64': 8,
+        'GLuint64EXT': 8,
+        'GLsync': 8,
+    }
+    val = mapping.get(str, 9999)
+    if val == 9999:
+        print('Unhandled type in marshal_XML.get_type_size: ' + str, 
file=sys.stderr)
+        assert False
+    return val
 
 class marshal_item_factory(gl_XML.gl_item_factory):
     """Factory to create objects derived from gl_item containing
@@ -60,6 +97,7 @@ class marshal_function(gl_XML.gl_function):
         self.marshal_sync = element.get('marshal_sync')
         self.marshal_call_before = element.get('marshal_call_before')
         self.marshal_call_after = element.get('marshal_call_after')
+        self.marshal_struct = element.get('marshal_struct')
 
     def marshal_flavor(self):
         """Find out how this function should be marshalled between
@@ -91,3 +129,60 @@ class marshal_function(gl_XML.gl_function):
         return (self.marshal_flavor() != 'custom' and
                 self.name[0:8] != 'Internal' and
                 self.exec_flavor != 'beginend')
+
+    def get_fixed_params(self):
+        # We want glthread to ignore variable-sized parameters if the only 
thing
+        # we want is to pass the pointer parameter as-is, e.g. when a PBO is 
bound.
+        # Making it conditional on marshal_sync is kinda hacky, but it's the 
easiest
+        # path towards handling PBOs in glthread, which use marshal_sync to 
check whether
+        # a PBO is bound.
+        if self.marshal_sync:
+            return self.fixed_params + self.variable_params
+        else:
+            return self.fixed_params
+
+    def get_variable_params(self):
+        if self.marshal_sync:
+            return []
+        else:
+            return self.variable_params
+
+    def print_struct(self, is_header=False):
+        fixed_params = self.get_fixed_params()
+        variable_params = self.get_variable_params()
+
+        if (self.marshal_struct == 'public') == is_header:
+            print('struct marshal_cmd_{0}'.format(self.name))
+            print('{')
+            print('   struct marshal_cmd_base cmd_base;')
+
+            # Sort the parameters according to their size to pack the 
structure optimally
+            for p in sorted(fixed_params, key=lambda p: 
get_type_size(p.type_string())):
+                if p.count:
+                    print('   {0} {1}[{2}];'.format(
+                            p.get_base_type_string(), p.name, p.count))
+                else:
+                    type = p.type_string()
+                    if type == 'GLenum':
+                        type = 'GLenum16'
+                    print('   {0} {1};'.format(type, p.name))
+
+            for p in variable_params:
+                if p.img_null_flag:
+                    print('   bool {0}_null; /* If set, no data follows '
+                        'for "{0}" */'.format(p.name))
+
+            for p in variable_params:
+                if p.count_scale != 1:
+                    print(('   /* Next {0} bytes are '
+                         '{1} {2}[{3}][{4}] */').format(
+                            p.size_string(marshal=1), p.get_base_type_string(),
+                            p.name, p.counter, p.count_scale))
+                else:
+                    print(('   /* Next {0} bytes are '
+                         '{1} {2}[{3}] */').format(
+                            p.size_string(marshal=1), p.get_base_type_string(),
+                            p.name, p.counter))
+            print('};')
+        elif self.marshal_flavor() in ('custom', 'async'):
+            print('struct marshal_cmd_{0};'.format(self.name))

Reply via email to