[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