Module: Mesa Branch: main Commit: a02ed8a95fba82169dd0a8b5382c91b6bfc5454a URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=a02ed8a95fba82169dd0a8b5382c91b6bfc5454a
Author: Marek Olšák <[email protected]> Date: Mon Nov 27 21:51:47 2023 -0500 glthread: add option to put autogenerated marshal structures in the header file This is used when we want to be able to read the calls of autogenerated functions, or when we want to use the default structure for our custom marshal functions. Reviewed-by: Timothy Arceri <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26548> --- src/mapi/glapi/gen/gl_API.dtd | 5 ++ src/mapi/glapi/gen/gl_marshal.py | 85 ++-------------------------------- src/mapi/glapi/gen/gl_marshal_h.py | 4 +- src/mapi/glapi/gen/marshal_XML.py | 95 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 83 deletions(-) diff --git a/src/mapi/glapi/gen/gl_API.dtd b/src/mapi/glapi/gen/gl_API.dtd index 714120b1db3..a5aae816c48 100644 --- a/src/mapi/glapi/gen/gl_API.dtd +++ b/src/mapi/glapi/gen/gl_API.dtd @@ -44,6 +44,7 @@ marshal_count CDATA #IMPLIED> marshal_call_before CDATA #IMPLIED> marshal_call_after CDATA #IMPLIED> + marshal_struct CDATA #IMPLIED> <!ATTLIST size name NMTOKEN #REQUIRED count NMTOKEN #IMPLIED mode (get | set) "set"> @@ -138,6 +139,10 @@ param: marshal_call_before - insert the string at the beginning of the marshal function marshal_call_after - insert the string at the end of the marshal function + marshal_struct - if "public", insert the structure into the generated + header file instead of the C file. It's done even with + marshal="custom", in which case you don't have to define the structure + manually. glx: rop - Opcode value for "render" commands diff --git a/src/mapi/glapi/gen/gl_marshal.py b/src/mapi/glapi/gen/gl_marshal.py index 5f59f634a9c..a4bb2d0bb01 100644 --- a/src/mapi/glapi/gen/gl_marshal.py +++ b/src/mapi/glapi/gen/gl_marshal.py @@ -103,91 +103,12 @@ class PrintCode(gl_XML.gl_print_base): out('') out('') - def get_type_size(self, str): - if str.find('*') != -1: - return 8; - - mapping = { - 'GLboolean': 1, - 'GLbyte': 1, - 'GLubyte': 1, - 'GLenum': 2, # uses GLenum16, clamped to 0xffff (invalid enum) - 'GLshort': 2, - 'GLushort': 2, - 'GLhalfNV': 2, - '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) - assert False - return val - def print_async_body(self, func): - # We want glthread to ignore variable-sized parameters if the only thing - # we want is to pass the pointer parameter as-is, e.g. when a PBO is bound. - # Making it conditional on marshal_sync is kinda hacky, but it's the easiest - # path towards handling PBOs in glthread, which use marshal_sync to check whether - # a PBO is bound. - if func.marshal_sync: - fixed_params = func.fixed_params + func.variable_params - variable_params = [] - else: - fixed_params = func.fixed_params - variable_params = func.variable_params + fixed_params = func.get_fixed_params() + variable_params = func.get_variable_params() out('/* {0}: marshalled asynchronously */'.format(func.name)) - out('struct marshal_cmd_{0}'.format(func.name)) - out('{') - with indent(): - out('struct marshal_cmd_base cmd_base;') - - # Sort the parameters according to their size to pack the structure optimally - for p in sorted(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)) - else: - type = p.type_string() - if type == 'GLenum': - type = 'GLenum16' - out('{0} {1};'.format(type, p.name)) - - for p in variable_params: - if p.img_null_flag: - out('bool {0}_null; /* If set, no data follows ' - 'for "{0}" */'.format(p.name)) - - for p in variable_params: - if p.count_scale != 1: - out(('/* Next {0} bytes are ' - '{1} {2}[{3}][{4}] */').format( - p.size_string(marshal=1), 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(marshal=1), p.get_base_type_string(), - p.name, p.counter)) - out('};') + func.print_struct() out('uint32_t') out(('_mesa_unmarshal_{0}(struct gl_context *ctx, ' diff --git a/src/mapi/glapi/gen/gl_marshal_h.py b/src/mapi/glapi/gen/gl_marshal_h.py index fd12b3916fd..d155d233340 100644 --- a/src/mapi/glapi/gen/gl_marshal_h.py +++ b/src/mapi/glapi/gen/gl_marshal_h.py @@ -66,9 +66,11 @@ class PrintCode(gl_XML.gl_print_base): print('') for func in api.functionIterateAll(): + func.print_struct(is_header=True) + flavor = func.marshal_flavor() + if flavor in ('custom', 'async'): - print('struct marshal_cmd_{0};'.format(func.name)) print(('uint32_t _mesa_unmarshal_{0}(struct gl_context *ctx, ' 'const struct marshal_cmd_{0} *restrict cmd);').format(func.name)) diff --git a/src/mapi/glapi/gen/marshal_XML.py b/src/mapi/glapi/gen/marshal_XML.py index bd8fa36c087..01ec84502ab 100644 --- a/src/mapi/glapi/gen/marshal_XML.py +++ b/src/mapi/glapi/gen/marshal_XML.py @@ -25,6 +25,43 @@ import gl_XML +def get_type_size(str): + if str.find('*') != -1: + return 8; + + mapping = { + 'GLboolean': 1, + 'GLbyte': 1, + 'GLubyte': 1, + 'GLenum': 2, # uses GLenum16, clamped to 0xffff (invalid enum) + 'GLshort': 2, + 'GLushort': 2, + 'GLhalfNV': 2, + '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 marshal_XML.get_type_size: ' + str, file=sys.stderr) + assert False + return val class marshal_item_factory(gl_XML.gl_item_factory): """Factory to create objects derived from gl_item containing @@ -60,6 +97,7 @@ class marshal_function(gl_XML.gl_function): self.marshal_sync = element.get('marshal_sync') self.marshal_call_before = element.get('marshal_call_before') self.marshal_call_after = element.get('marshal_call_after') + self.marshal_struct = element.get('marshal_struct') def marshal_flavor(self): """Find out how this function should be marshalled between @@ -91,3 +129,60 @@ class marshal_function(gl_XML.gl_function): return (self.marshal_flavor() != 'custom' and self.name[0:8] != 'Internal' and self.exec_flavor != 'beginend') + + def get_fixed_params(self): + # We want glthread to ignore variable-sized parameters if the only thing + # we want is to pass the pointer parameter as-is, e.g. when a PBO is bound. + # Making it conditional on marshal_sync is kinda hacky, but it's the easiest + # path towards handling PBOs in glthread, which use marshal_sync to check whether + # a PBO is bound. + if self.marshal_sync: + return self.fixed_params + self.variable_params + else: + return self.fixed_params + + def get_variable_params(self): + if self.marshal_sync: + return [] + else: + return self.variable_params + + def print_struct(self, is_header=False): + fixed_params = self.get_fixed_params() + variable_params = self.get_variable_params() + + if (self.marshal_struct == 'public') == is_header: + print('struct marshal_cmd_{0}'.format(self.name)) + print('{') + print(' struct marshal_cmd_base cmd_base;') + + # Sort the parameters according to their size to pack the structure optimally + for p in sorted(fixed_params, key=lambda p: get_type_size(p.type_string())): + if p.count: + print(' {0} {1}[{2}];'.format( + p.get_base_type_string(), p.name, p.count)) + else: + type = p.type_string() + if type == 'GLenum': + type = 'GLenum16' + print(' {0} {1};'.format(type, p.name)) + + for p in variable_params: + if p.img_null_flag: + print(' bool {0}_null; /* If set, no data follows ' + 'for "{0}" */'.format(p.name)) + + for p in variable_params: + if p.count_scale != 1: + print((' /* Next {0} bytes are ' + '{1} {2}[{3}][{4}] */').format( + p.size_string(marshal=1), p.get_base_type_string(), + p.name, p.counter, p.count_scale)) + else: + print((' /* Next {0} bytes are ' + '{1} {2}[{3}] */').format( + p.size_string(marshal=1), p.get_base_type_string(), + p.name, p.counter)) + print('};') + elif self.marshal_flavor() in ('custom', 'async'): + print('struct marshal_cmd_{0};'.format(self.name))
