[Mesa-dev] [RFC 09/13] begin generalizing gl_marshal_h.py for doing both.

Dylan Baker dylan at pnwbakers.com
Fri Nov 23 22:27:58 UTC 2018


This is undiffed, but does generate successfully.
---
 src/mapi/glapi/gen/gl_marshal_h.py | 166 +++++++++++++++++++++++++----
 src/mesa/main/meson.build          |   3 +-
 2 files changed, 145 insertions(+), 24 deletions(-)

diff --git a/src/mapi/glapi/gen/gl_marshal_h.py b/src/mapi/glapi/gen/gl_marshal_h.py
index abc6afc4cdf..ac39d121b61 100644
--- a/src/mapi/glapi/gen/gl_marshal_h.py
+++ b/src/mapi/glapi/gen/gl_marshal_h.py
@@ -33,7 +33,7 @@ from mesa_data import ExecType, MarshalType
 import khr_xml
 
 
-TEMPLATE = """\
+HEADER_TEMPLATE = """\
 <%namespace name="helpers" file="helpers.mako"/>
 <%include file="copyright.mako"/>
 
@@ -42,18 +42,104 @@ ${helpers.start_guard(guard)}
 enum marshal_dispatch_cmd_id
 {
 % for func in functions:
-   DISPATCH_CMD_${func},
+   DISPATCH_CMD_${func.name},
 % endfor
 };
 
 ${helpers.end_guard(guard)}
 """
 
+CODE_TEMPLATE = """\
+<%namespace name="helpers" file="helpers.mako"/>
+<%include file="copyright.mako"/>
+
+#include "api_exec.h"
+#include "context.h"
+#include "dispatch.h"
+#include "glthread.h"
+#include "marshal.h"
+#include "marshal_generated.h"
+
+static inline int safe_mul(int a, int b)
+{
+    if (a < 0 || b < 0) return -1;
+    if (a == 0 || b == 0) return 0;
+    if (a > INT_MAX / b) return -1;
+    return a * b;
+}
+
+% for func, marshal in functions:
+
+  % if marshal is MarshalType.SYNC:
+    /* ${func.name}: marshalled synchronously */
+    static ${func.return_type} GLAPIENTRY
+    _mesa_marshal_${func.name}(${', '.join(str(p) for p in func.params)})
+    {
+      GET_CURRENT_CONTEXT(ctx);
+      _mesa_glthread_finish(ctx);
+      debug_print_sync("${func.name}");
+      ${'return ' if func.return_type != 'void' else ''}CALL_${func.name}(ctx->CurrentServerdispatch, (${', '.join([p.name for p in func.params])}));
+    }
+  % else:
+    /* ${func.name}: marshalled asynchronously */
+    struct marshal_cmd_${func.name}
+    {
+        struct marshal_cmd_base cmd_base;
+    % for p in (a for a in func.params if not a.len.is_dynamic()):
+      % if not p.len:
+        ${p.type} ${p.name};
+      % else:
+        ${p.type} ${p.name}[${p.len.value}];
+      % endif
+    % endfor
+    % for p, m in zip(func.params, func.mesa.params):
+      % if p.len.is_dynamic() and m.img_null_flag:
+        bool ${func.name}_null; /* If set, no data follows for ${func.name} */
+      % endif
+    % endfor
+    # TODO: about next N bytes
+    };
+    static inline void
+    _mesa_unmarshal_${func.name}(struct gl_context *ctx, const struct marshl_cmd_${func.name} *cmd)
+    {
+    % for p in (a for a in func.params if not a.len.is_dynamic()):
+      % if p.len.is_static():
+        const ${p.type} * ${p.name} = cmd->${p.name};
+      % else:
+        const ${p.type} ${p.name} = cmd->${p.name};
+      % endif
+    % endfor
+    % if any(p.len.is_dynamic() for p in func.params):
+      % for p in (a for a in func.params if a.len.is_dynamic()):
+        const ${p.type} * ${p.name};
+      % endfor
+        const char *variable_data = (const char *) (cmd + 1);
+      % for p, m in zip(func.params, func.mesa.params):
+        <% if not p.len.is_dynamic(): continue %>
+        ${p.name} = (const ${p.type} *) variable_data;
+        % if m.img_null_flag:
+            if (cmd->${p.name}_null) {
+                ${p.name} = NULL;
+            } else {
+                /* TODO: variable_data += */
+            }
+        % else:
+            /* TODO: variable_data += */
+        % endif
+      % endfor
+    % endif
+        CALL_${func.name}(ctx->CurrentServerdispatch, (${', '.join([p.name for p in func.params])}));
+    };
+  % endif
+% endfor
+"""
+
 
 def gen_functions(xml):
-    """Generator that gets the name of each command in OpenGL and yeilds it.
+    """Generator that returns each function and it's actual marshal type
 
-    Ignores commands with special marshaling requirements.
+    Ignores commands with special marshaling requirements and that are not
+    implemented.
     """
     for func in khr_xml.make_functions(xml):
         # If the function is not in our records we don't implement it, at all,
@@ -65,52 +151,88 @@ def gen_functions(xml):
         if func.mesa.alias:
             continue
 
-        if func.mesa.marshal is MarshalType.SYNC:
-            continue
-
         if func.mesa.marshal not in [MarshalType.DEFAULT, MarshalType.DRAW]:
-            yield func.name
+            yield func, func.mesa.marshal
             continue
 
         if func.mesa.exectype is ExecType.SKIP:
             continue
 
         if func.return_type != 'void':
+            yield func, MarshalType.SYNC
             continue
 
-        if func.mesa.output:
+        flagged = False
+        for param in func.mesa.params:
+            if param.mutates:
+                yield func, MarshalType.SYNC
+                flagged = True
+                break
+        if flagged:
             continue
 
+        flagged = False
         for param in func.params:
-            if (param.is_pointer() and param.len is None and not
-                    (func.mesa.marshal is MarshalType.DRAW and
-                     param.name == 'indices')):
+            if (param.is_pointer() and not param.len and not
+                    (func.mesa.marshal is MarshalType.DRAW and param.name == 'indices')):
+                yield func, MarshalType.SYNC
+                flagged = True
                 break
-        else:
-            yield func.name
+        if flagged:
+            continue
+
+        yield func, MarshalType.ASYNC
+
+
+def gen_header_functions(xml):
+    """Only yield functions that we need to generate a header entry for."""
+    for func, marshal in gen_functions(xml):
+        if marshal is not MarshalType.SYNC:
+            yield func
+
+
+def gen_code_functions(xml):
+    """Only yield functions that we need to generate a header entry for."""
+    for func, marshal in gen_functions(xml):
+        if marshal in [MarshalType.SYNC, MarshalType.ASYNC]:
+            yield func, marshal
 
 
 def main():
     parser = argparse.ArgumentParser()
     parser.add_argument('registry')
     parser.add_argument('templatedir')
-    parser.add_argument('outfile')
+    parser.add_argument('--header', action='store')
+    parser.add_argument('--code', action='store')
     args = parser.parse_args()
 
+    if not (args.code or args.header):
+        parser.error('At least one of --header or --code is required')
+
     lookup = TemplateLookup(directories=[args.templatedir],
                             input_encoding='utf-8',
                             output_encoding='utf-8')
-    lookup.put_string('main', TEMPLATE)
+    lookup.put_string('header', HEADER_TEMPLATE)
+    lookup.put_string('code', CODE_TEMPLATE)
 
     tree = et.parse(args.registry)
     root = tree.getroot()
 
-    with io.open(args.outfile, 'wb') as f:
-        f.write(lookup.get_template('main').render(
-            functions=gen_functions(root),
-            guard='MARSHAL_GENERATABLE',
-            copyrights=['Copyright (C) 2012 Intel Corporation'],
-            script=os.path.basename(__file__)))
+    if args.header:
+        with io.open(args.header, 'wb') as f:
+            f.write(lookup.get_template('header').render(
+                functions=gen_header_functions(root),
+                guard='MARSHAL_GENERATABLE',
+                copyrights=['Copyright (C) 2012 Intel Corporation'],
+                script=os.path.basename(__file__)))
+
+    if args.code:
+        with open(args.code, 'w') as f:
+            f.write(lookup.get_template('code').render(
+                functions=gen_code_functions(root),
+                MarshalType=MarshalType,
+                copyrights=['Copyright (C) 2012 Intel Corporation'],
+                script=os.path.basename(__file__)))
 
 
 if __name__ == '__main__':
diff --git a/src/mesa/main/meson.build b/src/mesa/main/meson.build
index 56d070f224b..fdbc7c5754b 100644
--- a/src/mesa/main/meson.build
+++ b/src/mesa/main/meson.build
@@ -32,9 +32,8 @@ main_marshal_generated_h = custom_target(
   input : ['../../mapi/glapi/gen/gl_marshal_h.py', files_gl_xml],
   output : 'marshal_generated.h',
   command : [
-    prog_python, '@INPUT0@', '@INPUT1@', 
+    prog_python, '@INPUT0@', '--header', '@OUTPUT@', '@INPUT1@', 
     join_paths(meson.current_source_dir(), '../../mapi/glapi/gen/templates'),
-    '@OUTPUT@',
   ],
   depend_files : glapi_new_gen_depends,
 )
-- 
2.19.2



More information about the mesa-dev mailing list