gl_marshal.py: rework how the marshal dispatch table is initialized

Instead of setting all function pointers in marshal_generated0.c,
set the function pointers in the file that contains the functions,
and remove all the forward declarations of marshal functions
in marshal_generated.h.

Acked-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18199>
This commit is contained in:
Marek Olšák 2022-08-11 09:10:15 -04:00 committed by Marge Bot
parent 5e66e26998
commit 67c7260571
6 changed files with 66 additions and 41 deletions

View file

@ -93,7 +93,7 @@ class PrintCode(gl_XML.gl_print_base):
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():
@ -319,7 +319,7 @@ class PrintCode(gl_XML.gl_print_base):
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('{')
@ -366,29 +366,21 @@ class PrintCode(gl_XML.gl_print_base):
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
@ -397,7 +389,7 @@ class PrintCode(gl_XML.gl_print_base):
# 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
@ -409,32 +401,31 @@ class PrintCode(gl_XML.gl_print_base):
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():

View file

@ -71,8 +71,8 @@ class PrintCode(gl_XML.gl_print_base):
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()))

View file

@ -86,3 +86,6 @@ class marshal_function(gl_XML.gl_function):
# 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'

View file

@ -91,6 +91,20 @@ glthread_thread_initialization(void *job, void *gdata, int thread_index)
_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)
{
@ -112,12 +126,15 @@ _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);

View file

@ -61,6 +61,7 @@ extern "C" {
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 */
@ -244,6 +245,23 @@ struct glthread_state
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);

View file

@ -133,10 +133,6 @@ _mesa_glthread_has_non_vbo_vertices_or_indices_or_indirect(const struct gl_conte
(vao->UserPointerMask & vao->BufferEnabled));
}
bool
_mesa_create_marshal_tables(struct gl_context *ctx);
static inline unsigned
_mesa_buffer_enum_to_count(GLenum buffer)
{