diff options
-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)) |