mapi: Fix a couple of warning in generated code
[mesa.git] / src / mapi / glapi / gen / gl_marshal.py
index 05c4e28eec178e18c6d2d1ba4e7a34b77984bade..c7019a80328799ada4f46a323a22e39c3d183f8b 100644 (file)
@@ -31,13 +31,24 @@ import sys
 
 header = """
 #include "api_exec.h"
-#include "context.h"
+#include "glthread_marshal.h"
+#include "bufferobj.h"
 #include "dispatch.h"
-#include "glthread.h"
-#include "marshal.h"
+
+#define COMPAT (ctx->API != API_OPENGL_CORE)
+
+UNUSED 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;
+}
 """
 
 
+file_index = 0
+file_count = 1
 current_indent = 0
 
 
@@ -66,14 +77,6 @@ class PrintCode(gl_XML.gl_print_base):
 
     def printRealHeader(self):
         print(header)
-        print('static inline int safe_mul(int a, int b)')
-        print('{')
-        print('    if (a < 0 || b < 0) return -1;')
-        print('    if (a == 0 || b == 0) return 0;')
-        print('    if (a > INT_MAX / b) return -1;')
-        print('    return a * b;')
-        print('}')
-        print()
 
     def printRealFooter(self):
         pass
@@ -94,7 +97,7 @@ class PrintCode(gl_XML.gl_print_base):
 
     def print_sync_body(self, func):
         out('/* {0}: marshalled synchronously */'.format(func.name))
-        out('static {0} GLAPIENTRY'.format(func.return_type))
+        out('{0} GLAPIENTRY'.format(func.return_type))
         out('_mesa_marshal_{0}({1})'.format(func.name, func.get_parameter_string()))
         out('{')
         with indent():
@@ -141,12 +144,50 @@ class PrintCode(gl_XML.gl_print_base):
         # Uncomment this if you want to call _mesa_glthread_finish for debugging
         #out('_mesa_glthread_finish(ctx);')
 
+    def get_type_size(self, str):
+        if str.find('*') != -1:
+            return 8;
+
+        mapping = {
+            'GLboolean': 1,
+            'GLbyte': 1,
+            'GLubyte': 1,
+            'GLshort': 2,
+            'GLushort': 2,
+            'GLenum': 4,
+            '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)
+        return val
+
     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:
+
+            # Sort the parameters according to their size to pack the structure optimally
+            for p in sorted(func.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))
@@ -172,7 +213,7 @@ class PrintCode(gl_XML.gl_print_base):
         out('};')
 
     def print_async_unmarshal(self, func):
-        out('static inline void')
+        out('void')
         out(('_mesa_unmarshal_{0}(struct gl_context *ctx, '
              'const struct marshal_cmd_{0} *cmd)').format(func.name))
         out('{')
@@ -240,7 +281,7 @@ class PrintCode(gl_XML.gl_print_base):
         out('}')
 
     def print_async_marshal(self, func):
-        out('static void GLAPIENTRY')
+        out('void GLAPIENTRY')
         out('_mesa_marshal_{0}({1})'.format(
                 func.name, func.get_parameter_string()))
         out('{')
@@ -259,18 +300,8 @@ class PrintCode(gl_XML.gl_print_base):
             out('int cmd_size = {0};'.format(' + '.join(size_terms)))
             out('{0} *cmd;'.format(struct))
 
-            out('debug_print_marshal("{0}");'.format(func.name))
-
             self.validate_count_or_fallback(func)
 
-            if func.marshal_fail:
-                out('if ({0}) {{'.format(func.marshal_fail))
-                with indent():
-                    out('_mesa_glthread_disable(ctx, "{0}");'.format(func.name))
-                    self.print_sync_dispatch(func)
-                    out('return;')
-                out('}')
-
             if func.marshal_sync:
                 out('if ({0}) {{'.format(func.marshal_sync))
                 with indent():
@@ -304,6 +335,10 @@ class PrintCode(gl_XML.gl_print_base):
         out('')
 
     def print_create_marshal_table(self, api):
+        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('struct _glapi_table *')
         out('_mesa_create_marshal_table(const struct gl_context *ctx)')
         out('{')
@@ -318,7 +353,11 @@ class PrintCode(gl_XML.gl_print_base):
             for func in api.functionIterateAll():
                 if func.marshal_flavor() == 'skip':
                     continue
-                out('SET_{0}(table, _mesa_marshal_{0});'.format(func.name))
+                # Don't use the SET_* functions, because they increase compile time
+                # by 20 seconds (on Ryzen 1700X).
+                out('if (_gloffset_{0} >= 0)'.format(func.name))
+                out('   ((_glapi_proc *)(table))[_gloffset_{0}] = (_glapi_proc)_mesa_marshal_{0};'
+                    .format(func.name))
             out('')
             out('return table;')
         out('}')
@@ -326,18 +365,27 @@ class PrintCode(gl_XML.gl_print_base):
         out('')
 
     def printBody(self, api):
-        async_funcs = []
+        # The first file only contains the dispatch tables
+        if file_index == 0:
+            self.print_unmarshal_dispatch_cmd(api)
+            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
+
             flavor = func.marshal_flavor()
             if flavor in ('skip', 'custom'):
                 continue
             elif flavor == 'async':
                 self.print_async_body(func)
-                async_funcs.append(func)
             elif flavor == 'sync':
                 self.print_sync_body(func)
-        self.print_unmarshal_dispatch_cmd(api)
-        self.print_create_marshal_table(api)
 
 
 def show_usage():
@@ -349,14 +397,19 @@ if __name__ == '__main__':
     file_name = 'gl_API.xml'
 
     try:
-        (args, trail) = getopt.getopt(sys.argv[1:], 'm:f:')
+        (args, trail) = getopt.getopt(sys.argv[1:], 'm:f:i:n:')
     except Exception:
         show_usage()
 
     for (arg,val) in args:
         if arg == '-f':
             file_name = val
+        elif arg == '-i':
+            file_index = int(val)
+        elif arg == '-n':
+            file_count = int(val)
 
+    assert file_index < file_count
     printer = PrintCode()
 
     api = gl_XML.parse_GL_API(file_name, marshal_XML.marshal_item_factory())