diff --git a/src/panfrost/lib/gen_pack.py b/src/panfrost/lib/gen_pack.py index 8c1f2e755cd..e91769c193c 100644 --- a/src/panfrost/lib/gen_pack.py +++ b/src/panfrost/lib/gen_pack.py @@ -213,7 +213,7 @@ class Field(object): self.modifier = parse_modifier(attrs.get("modifier")) - def emit_template_struct(self, dim): + def emit_template_struct(self, dim, opaque_structs): if self.type == 'address': type = 'uint64_t' elif self.type == 'bool': @@ -228,6 +228,9 @@ class Field(object): type = 'uint32_t' elif self.type in self.parser.structs: type = 'struct ' + self.parser.gen_prefix(safe_name(self.type.upper())) + + if opaque_structs: + type = type.lower() + '_packed' elif self.type in self.parser.enums: type = 'enum ' + enum_name(self.type) else: @@ -254,7 +257,7 @@ class Group(object): self.length = 0 self.fields = [] - def emit_template_struct(self, dim): + def emit_template_struct(self, dim, opaque_structs): if self.count == 0: print(" /* variable length fields follow */") else: @@ -265,7 +268,7 @@ class Group(object): if field.exact is not None: continue - field.emit_template_struct(dim) + field.emit_template_struct(dim, opaque_structs) class Word: def __init__(self): @@ -283,7 +286,7 @@ class Group(object): words[b].fields.append(field) - def emit_pack_function(self): + def emit_pack_function(self, opaque_structs): # Determine number of bytes in this group. calculated = max(field.end // 8 for field in self.fields) + 1 @@ -330,9 +333,13 @@ class Group(object): start = first.start assert((first.start % 32) == 0) assert(first.end == first.start + (self.parser.structs[first.type].length * 8) - 1) - print(" {}_pack(cl + {}, &values->{});".format(pack_name, first.start // 32, first.name)) emitted_structs.add(first.start) + if opaque_structs: + print(" memcpy(cl + {}, &values->{}, {});".format(first.start // 32, first.name, (first.end - first.start + 1) // 8)) + else: + print(" {}_pack(cl + {}, &values->{});".format(pack_name, first.start // 32, first.name)) + for field in word.fields: name = field.name start = field.start @@ -497,6 +504,7 @@ class Parser(object): print(pack_header) elif name == "struct": name = attrs["name"] + self.with_opaque = attrs.get("with_opaque", False) object_name = self.gen_prefix(safe_name(name.upper())) self.struct = object_name @@ -548,18 +556,30 @@ class Parser(object): print(", \\\n".join(default_fields)) print('') - def emit_template_struct(self, name, group): - print("struct %s {" % name) - group.emit_template_struct("") + def emit_template_struct(self, name, group, opaque_structs): + print("struct %s {" % (name + ('_OPAQUE' if opaque_structs else ''))) + group.emit_template_struct("", opaque_structs) print("};\n") - def emit_pack_function(self, name, group): + if opaque_structs: + # Just so it isn't left undefined + print('#define %-40s 0' % (name + '_OPAQUE_header')) + + def emit_pack_function(self, name, group, with_opaque): print("static inline void\n%s_pack(uint32_t * restrict cl,\n%sconst struct %s * restrict values)\n{" % (name, ' ' * (len(name) + 6), name)) - group.emit_pack_function() + group.emit_pack_function(False) - print("}\n") + print("}\n\n") + + if with_opaque: + print("static inline void\n%s_OPAQUE_pack(uint32_t * restrict cl,\n%sconst struct %s_OPAQUE * restrict values)\n{" % + (name, ' ' * (len(name) + 6), name)) + + group.emit_pack_function(True) + + print("}\n") # Should be a whole number of words assert((self.group.length % 4) == 0) @@ -587,9 +607,11 @@ class Parser(object): def emit_struct(self): name = self.struct - self.emit_template_struct(self.struct, self.group) + self.emit_template_struct(self.struct, self.group, False) + if self.with_opaque: + self.emit_template_struct(self.struct, self.group, True) self.emit_header(name) - self.emit_pack_function(self.struct, self.group) + self.emit_pack_function(self.struct, self.group, self.with_opaque) self.emit_unpack_function(self.struct, self.group) self.emit_print_function(self.struct, self.group)