def print_sync_body(self, func):
out('/* {0}: marshalled synchronously */'.format(func.name))
- out('{0} GLAPIENTRY'.format(func.return_type))
+ out('{0}{1} GLAPIENTRY'.format('static ' if func.marshal_is_static() else '', func.return_type))
out('_mesa_marshal_{0}({1})'.format(func.name, func.get_parameter_string()))
out('{')
with indent():
out('}')
def print_async_marshal(self, func):
- out('{0} GLAPIENTRY'.format(func.return_type))
+ out('{0}{1} GLAPIENTRY'.format('static ' if func.marshal_is_static() else '', func.return_type))
out('_mesa_marshal_{0}({1})'.format(
func.name, func.get_parameter_string()))
out('{')
out('')
out('')
- def print_create_marshal_table(self, api):
+ def print_init_marshal_table(self, functions):
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('bool')
- out('_mesa_create_marshal_tables(struct gl_context *ctx)')
+ out('void')
+ out('_mesa_glthread_init_dispatch%u(struct gl_context *ctx, '
+ 'struct _glapi_table *table)' % file_index)
out('{')
with indent():
- out('ctx->MarshalExec = _mesa_alloc_dispatch_table(true);')
- out('if (!ctx->MarshalExec)')
- with indent():
- out('return false;')
- out('')
-
# Collect SET_* calls by the condition under which they should
# be called.
settings_by_condition = collections.defaultdict(lambda: [])
- for func in api.functionIterateAll():
- if func.marshal_flavor() == 'skip':
- continue
-
+ for func in functions:
condition = apiexec.get_api_condition(func)
if not condition:
continue
# by 20 seconds (on Ryzen 1700X).
settings_by_condition[condition].append(
('if (_gloffset_{0} >= 0)\n' +
- ' ((_glapi_proc *)(ctx->MarshalExec))[_gloffset_{0}] =' +
+ ' ((_glapi_proc *)table)[_gloffset_{0}] =' +
' (_glapi_proc)_mesa_marshal_{0};').format(func.name))
# Print out an if statement for each unique condition, with
for line in setting.split('\n'):
out(line)
out('}')
-
- out('')
- out(' return true;')
out('}')
def printBody(self, api):
- # The first file only contains the dispatch tables
- if file_index == 0:
- 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
-
+ # Don't generate marshal/unmarshal functions for skipped and custom functions
+ functions = [func for func in api.functionIterateAll()
+ if func.marshal_flavor() not in ('skip', 'custom')]
+ # Divide the functions between files
+ func_per_file = len(functions) // file_count + 1
+ functions = functions[file_index*func_per_file:(file_index+1)*func_per_file]
+
+ for func in functions:
flavor = func.marshal_flavor()
- if flavor in ('skip', 'custom'):
- continue
- elif flavor == 'async':
+ if flavor == 'async':
self.print_async_body(func)
elif flavor == 'sync':
self.print_sync_body(func)
+ else:
+ assert False
+
+ # The first file will also set custom functions
+ if file_index == 0:
+ functions += [func for func in api.functionIterateAll()
+ if func.marshal_flavor() == 'custom']
+
+ self.print_init_marshal_table(functions)
def show_usage():
print('struct marshal_cmd_{0};'.format(func.name))
print(('uint32_t _mesa_unmarshal_{0}(struct gl_context *ctx, '
'const struct marshal_cmd_{0} *cmd, const uint64_t *last);').format(func.name))
- print('{0} GLAPIENTRY _mesa_marshal_{1}({2});'.format(func.return_type, func.name, func.get_parameter_string()))
- elif flavor == 'sync':
+
+ if flavor in ('custom', 'async', 'sync') and not func.marshal_is_static():
print('{0} GLAPIENTRY _mesa_marshal_{1}({2});'.format(func.return_type, func.name, func.get_parameter_string()))
# written logic to handle this yet. TODO: fix.
return 'sync'
return 'async'
+
+ def marshal_is_static(self):
+ return self.marshal_flavor() != 'custom' and self.name[0:8] != 'Internal'
_glapi_set_context(ctx);
}
+static void
+_mesa_glthread_init_dispatch(struct gl_context *ctx,
+ struct _glapi_table *table)
+{
+ _mesa_glthread_init_dispatch0(ctx, table);
+ _mesa_glthread_init_dispatch1(ctx, table);
+ _mesa_glthread_init_dispatch2(ctx, table);
+ _mesa_glthread_init_dispatch3(ctx, table);
+ _mesa_glthread_init_dispatch4(ctx, table);
+ _mesa_glthread_init_dispatch5(ctx, table);
+ _mesa_glthread_init_dispatch6(ctx, table);
+ _mesa_glthread_init_dispatch7(ctx, table);
+}
+
void
_mesa_glthread_init(struct gl_context *ctx)
{
_mesa_glthread_reset_vao(&glthread->DefaultVAO);
glthread->CurrentVAO = &glthread->DefaultVAO;
- if (!_mesa_create_marshal_tables(ctx)) {
+ ctx->MarshalExec = _mesa_alloc_dispatch_table(true);
+ if (!ctx->MarshalExec) {
_mesa_DeleteHashTable(glthread->VAOs);
util_queue_destroy(&glthread->queue);
return;
}
+ _mesa_glthread_init_dispatch(ctx, ctx->MarshalExec);
+
for (unsigned i = 0; i < MARSHAL_MAX_BATCHES; i++) {
glthread->batches[i].ctx = ctx;
util_queue_fence_init(&glthread->batches[i].fence);
struct gl_context;
struct gl_buffer_object;
struct _mesa_HashTable;
+struct _glapi_table;
struct glthread_attrib_binding {
struct gl_buffer_object *buffer; /**< where non-VBO data was uploaded */
void _mesa_glthread_init(struct gl_context *ctx);
void _mesa_glthread_destroy(struct gl_context *ctx, const char *reason);
+void _mesa_glthread_init_dispatch0(struct gl_context *ctx,
+ struct _glapi_table *table);
+void _mesa_glthread_init_dispatch1(struct gl_context *ctx,
+ struct _glapi_table *table);
+void _mesa_glthread_init_dispatch2(struct gl_context *ctx,
+ struct _glapi_table *table);
+void _mesa_glthread_init_dispatch3(struct gl_context *ctx,
+ struct _glapi_table *table);
+void _mesa_glthread_init_dispatch4(struct gl_context *ctx,
+ struct _glapi_table *table);
+void _mesa_glthread_init_dispatch5(struct gl_context *ctx,
+ struct _glapi_table *table);
+void _mesa_glthread_init_dispatch6(struct gl_context *ctx,
+ struct _glapi_table *table);
+void _mesa_glthread_init_dispatch7(struct gl_context *ctx,
+ struct _glapi_table *table);
+
void _mesa_glthread_flush_batch(struct gl_context *ctx);
void _mesa_glthread_finish(struct gl_context *ctx);
void _mesa_glthread_finish_before(struct gl_context *ctx, const char *func);
(vao->UserPointerMask & vao->BufferEnabled));
}
-
-bool
-_mesa_create_marshal_tables(struct gl_context *ctx);
-
static inline unsigned
_mesa_buffer_enum_to_count(GLenum buffer)
{