[Mesa-dev] [PATCH 19/26] mesa: Add support for NULL arguments like in glBufferData() in marshalling.

Marek Olšák maraeo at gmail.com
Wed Feb 8 18:03:33 UTC 2017


From: Eric Anholt <eric at anholt.net>

This will let us support things like glBufferData() that should be
asynchronous.
---
 src/mapi/glapi/gen/gl_marshal.py  | 38 ++++++++++++++++++++++++++++++++++----
 src/mapi/glapi/gen/marshal_XML.py |  5 -----
 2 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/src/mapi/glapi/gen/gl_marshal.py b/src/mapi/glapi/gen/gl_marshal.py
index e4137f4..3b9868f 100644
--- a/src/mapi/glapi/gen/gl_marshal.py
+++ b/src/mapi/glapi/gen/gl_marshal.py
@@ -111,39 +111,56 @@ class PrintCode(gl_XML.gl_print_base):
             'DISPATCH_CMD_{0}, cmd_size);'.format(func.name))
         for p in func.fixed_params:
             if p.count:
                 out('memcpy(cmd->{0}, {0}, {1});'.format(
                         p.name, p.size_string()))
             else:
                 out('cmd->{0} = {0};'.format(p.name))
         if func.variable_params:
             out('char *variable_data = (char *) (cmd + 1);')
             for p in func.variable_params:
-                out(('memcpy(variable_data, {0}, {1});').format(
+                if p.img_null_flag:
+                    out('cmd->{0}_null = !{0};'.format(p.name))
+                    out('if (!cmd->{0}_null) {{'.format(p.name))
+                    with indent():
+                        out(('memcpy(variable_data, {0}, {1});').format(
+                            p.name, p.size_string(False)))
+                        out('variable_data += {0};'.format(
+                            p.size_string(False)))
+                    out('}')
+                else:
+                    out(('memcpy(variable_data, {0}, {1});').format(
                         p.name, p.size_string(False)))
-                out('variable_data += {0};'.format(
+                    out('variable_data += {0};'.format(
                         p.size_string(False)))
+
         if not func.fixed_params and not func.variable_params:
             out('(void) cmd;\n')
         out('_mesa_post_marshal_hook(ctx);')
 
     def print_async_struct(self, func):
         out('struct marshal_cmd_{0}'.format(func.name))
         out('{')
         with indent():
             out('struct marshal_cmd_base cmd_base;')
             for p in func.fixed_params:
                 if p.count:
                     out('{0} {1}[{2}];'.format(
                             p.get_base_type_string(), p.name, p.count))
                 else:
                     out('{0} {1};'.format(p.type_string(), p.name))
+
+            for p in func.variable_params:
+                if p.img_null_flag:
+                    out('bool {0}_null; /* If set, no data follows '
+                        'for "{0}" */'.format(p.name))
+
             for p in func.variable_params:
                 if p.count_scale != 1:
                     out(('/* Next {0} bytes are '
                          '{1} {2}[{3}][{4}] */').format(
                             p.size_string(), 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(), p.get_base_type_string(),
@@ -164,21 +181,31 @@ class PrintCode(gl_XML.gl_print_base):
                     out('const {0} {1} = cmd->{1};'.format(
                             p.type_string(), p.name))
             if func.variable_params:
                 for p in func.variable_params:
                     out('const {0} * {1};'.format(
                             p.get_base_type_string(), p.name))
                 out('const char *variable_data = (const char *) (cmd + 1);')
                 for p in func.variable_params:
                     out('{0} = (const {1} *) variable_data;'.format(
                             p.name, p.get_base_type_string()))
-                    out('variable_data += {0};'.format(p.size_string(False)))
+
+                    if p.img_null_flag:
+                        out('if (cmd->{0}_null)'.format(p.name))
+                        with indent():
+                            out('{0} = NULL;'.format(p.name))
+                        out('else')
+                        with indent():
+                            out('variable_data += {0};'.format(p.size_string(False)))
+                    else:
+                        out('variable_data += {0};'.format(p.size_string(False)))
+
             self.print_sync_call(func)
         out('}')
 
     def validate_count_or_return(self, func):
         # Check that any counts for variable-length arguments might be < 0, in
         # which case the command alloc or the memcpy would blow up before we
         # get to the validation in Mesa core.
         for p in func.parameters:
             if p.is_variable_length():
                 out('if (unlikely({0} < 0)) {{'.format(p.size_string()))
@@ -191,21 +218,24 @@ class PrintCode(gl_XML.gl_print_base):
     def print_async_marshal(self, func):
         out('static void GLAPIENTRY')
         out('_mesa_marshal_{0}({1})'.format(
                 func.name, func.get_parameter_string()))
         out('{')
         with indent():
             out('GET_CURRENT_CONTEXT(ctx);')
             struct = 'struct marshal_cmd_{0}'.format(func.name)
             size_terms = ['sizeof({0})'.format(struct)]
             for p in func.variable_params:
-                size_terms.append(p.size_string())
+                size = p.size_string()
+                if p.img_null_flag:
+                    size = '({0} ? {1} : 0)'.format(p.name, size)
+                size_terms.append(size)
             out('size_t cmd_size = {0};'.format(' + '.join(size_terms)))
             out('{0} *cmd;'.format(struct))
 
             out('debug_print_marshal("{0}");'.format(func.name))
 
             self.validate_count_or_return(func)
 
             out('if (cmd_size <= MARSHAL_MAX_CMD_SIZE) {')
             with indent():
                 self.print_async_dispatch(func)
diff --git a/src/mapi/glapi/gen/marshal_XML.py b/src/mapi/glapi/gen/marshal_XML.py
index e8ddb7f..9d5688d 100644
--- a/src/mapi/glapi/gen/marshal_XML.py
+++ b/src/mapi/glapi/gen/marshal_XML.py
@@ -81,16 +81,11 @@ class marshal_function(gl_XML.gl_function):
             return 'sync'
         for p in self.parameters:
             if p.is_output:
                 return 'sync'
             if p.is_pointer() and not (p.count or p.counter):
                 return 'sync'
             if p.count_parameter_list:
                 # Parameter size is determined by enums; haven't
                 # written logic to handle this yet.  TODO: fix.
                 return 'sync'
-            if p.img_null_flag:
-                # Caller is allowed to pass NULL for this parameter;
-                # haven't written logic to handle this yet.  TODO:
-                # fix.
-                return 'sync'
         return 'async'
-- 
2.7.4



More information about the mesa-dev mailing list