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
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
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():
# 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))
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('{')
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('{')
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():
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('{')
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('}')
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():
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())