diff options
author | Marek Olšák <marek.olsak@amd.com> | 2023-11-27 21:51:47 -0500 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2023-12-08 04:25:52 +0000 |
commit | a02ed8a95fba82169dd0a8b5382c91b6bfc5454a (patch) | |
tree | e01005faed9eec6dd1f0d6abbc08314d3ab60b6f /src | |
parent | bdb771b27c1a36ad728b02111060001defd55767 (diff) |
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 <tarceri@itsqueeze.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26548>
Diffstat (limited to 'src')
-rw-r--r-- | src/mapi/glapi/gen/gl_API.dtd | 5 | ||||
-rw-r--r-- | src/mapi/glapi/gen/gl_marshal.py | 85 | ||||
-rw-r--r-- | src/mapi/glapi/gen/gl_marshal_h.py | 4 | ||||
-rw-r--r-- | 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)) |