Module: Mesa Branch: main Commit: 90916c955b99a4480e14367b518f04882fae8b1f URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=90916c955b99a4480e14367b518f04882fae8b1f
Author: Sarah Walker <sarah.wal...@imgtec.com> Date: Wed Apr 12 17:21:12 2023 +0100 pvr: csbgen: Add dummy implementation of stream type This is enough of an implementation to allow stream layout to be added to rogue_kmd_stream.xml. Signed-off-by: Sarah Walker <sarah.wal...@imgtec.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15507> --- src/imagination/csbgen/gen_pack_header.py | 112 ++++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 6 deletions(-) diff --git a/src/imagination/csbgen/gen_pack_header.py b/src/imagination/csbgen/gen_pack_header.py index d7bdf90a992..f047ec07e3e 100644 --- a/src/imagination/csbgen/gen_pack_header.py +++ b/src/imagination/csbgen/gen_pack_header.py @@ -123,13 +123,14 @@ class Node(ABC): class Csbgen(Node): - __slots__ = ["prefix_field", "filename", "_defines", "_enums", "_structs"] + __slots__ = ["prefix_field", "filename", "_defines", "_enums", "_structs", "_streams"] prefix_field: str filename: str _defines: t.List[Define] _enums: t.Dict[str, Enum] _structs: t.Dict[str, Struct] + _streams: t.Dict[str, Stream] def __init__(self, name: str, prefix: str, filename: str) -> None: super().__init__(None, name.upper()) @@ -139,6 +140,7 @@ class Csbgen(Node): self._defines = [] self._enums = {} self._structs = {} + self._streams = {} @property def full_name(self) -> str: @@ -159,6 +161,11 @@ class Csbgen(Node): raise RuntimeError("Struct redefined. Struct: %s" % element.name) self._structs[element.name] = element + elif isinstance(element, Stream): + if element.name in self._streams: + raise RuntimeError("Stream redefined. Stream: %s" % element.name) + + self._streams[element.name] = element elif isinstance(element, Define): define_names = [d.full_name for d in self._defines] if element.full_name in define_names: @@ -189,6 +196,9 @@ class Csbgen(Node): for struct in self._structs.values(): struct.emit(self) + for stream in self._streams.values(): + stream.emit(self) + print("#endif /* %s */" % self._gen_guard()) def is_known_struct(self, struct_name: str) -> bool: @@ -424,6 +434,63 @@ class Struct(Node): self._emit_unpack_function(root) +class Stream(Node): + __slots__ = ["length", "size", "_children"] + + length: int + size: int + _children: t.Dict[str, t.Union[Condition, Field]] + + def __init__(self, parent: Node, name: str, length: int) -> None: + self._children = {} + + super().__init__(parent, name) + + @property + def fields(self) -> t.List[Field]: + fields = [] + + @property + def prefix(self) -> str: + return self.full_name + + def add(self, element: Node) -> None: + # We don't support conditions and field having the same name. + if isinstance(element, Field): + if element.name in self._children.keys(): + raise ValueError("Field is being redefined. Field: '%s', Struct: '%s'" + % (element.name, self.full_name)) + + self._children[element.name] = element + + elif isinstance(element, Condition): + # We only save ifs, and ignore the rest. The rest will be linked to + # the if condition so we just need to call emit() on the if and the + # rest will also be emitted. + if element.type == "if": + self._children[element.name] = element + else: + if element.name not in self._children.keys(): + raise RuntimeError("Unknown condition: '%s'" % element.name) + + else: + super().add(element) + + def _emit_header(self, root: Csbgen) -> None: + pass + + def _emit_helper_macros(self) -> None: + pass + + def _emit_pack_function(self, root: Csbgen) -> None: + pass + + def _emit_unpack_function(self, root: Csbgen) -> None: + pass + + def emit(self, root: Csbgen) -> None: + pass + class Field(Node): __slots__ = ["start", "end", "type", "default", "shift", "_defines"] @@ -501,13 +568,15 @@ class Field(Node): elif self.type == "int": return "int32_t" elif self.type == "uint": - if self.end - self.start < 32: + if self.end - self.start <= 32: return "uint32_t" - elif self.end - self.start < 64: + elif self.end - self.start <= 64: return "uint64_t" raise RuntimeError("No known C type found to hold %d bit sized value. Field: '%s'" % (self.end - self.start, self.name)) + elif self.type == "uint_array": + return "uint8_t" elif root.is_known_struct(self.type): return "struct " + self.type elif root.is_known_enum(self.type): @@ -531,7 +600,10 @@ class Field(Node): if self.type == "mbo": return - print(" %-36s %s;" % (self._get_c_type(root), self.name)) + if self.type == "uint_array": + print(" %-36s %s[%u];" % (self._get_c_type(root), self.name, (self.end - self.start) / 8)) + else: + print(" %-36s %s;" % (self._get_c_type(root), self.name)) class Define(Node): @@ -838,6 +910,8 @@ class Group: elif field.type == "offset": non_address_fields.append("__pvr_offset(values->%s, %d, %d)" % (field.name, field.start - dword_start, field.end - dword_start)) + elif field.type == "uint_array": + pass elif field.is_struct_type(): non_address_fields.append("__pvr_uint(v%d_%d, %d, %d)" % (index, field_index, field.start - dword_start, @@ -947,6 +1021,7 @@ class Group: print("/* unhandled field %s, type %s */" % (field.name, field.type)) + class Parser: __slots__ = ["parser", "context", "filename"] @@ -980,6 +1055,10 @@ class Parser: struct = Struct(parent, attrs["name"], int(attrs["length"])) self.context.append(struct) + elif name == "stream": + stream = Stream(parent, attrs["name"], int(attrs["length"])) + self.context.append(stream) + elif name == "field": default = None if "default" in attrs.keys(): @@ -989,8 +1068,26 @@ class Parser: if "shift" in attrs.keys(): shift = attrs["shift"] - field = Field(parent, name=attrs["name"], start=int(attrs["start"]), end=int(attrs["end"]), - ty=attrs["type"], default=default, shift=shift) + if "start" in attrs.keys(): + if ":" in str(attrs["start"]): + (word, bit) = attrs["start"].split(":") + start = (int(word) * 32) + int(bit) + else: + start = int(attrs["start"]) + else: + element = self.context[-1] + if isinstance(element, Stream): + start = 0 + else: + raise RuntimeError("Field requires start attribute outside of stream.") + + if "size" in attrs.keys(): + end = start + int(attrs["size"]) + else: + end = int(attrs["end"]) + + field = Field(parent, name=attrs["name"], start=start, end=end, ty=attrs["type"], + default=default, shift=shift) self.context.append(field) elif name == "enum": @@ -1043,6 +1140,9 @@ class Parser: if name == "struct": if not isinstance(element, Struct): raise RuntimeError("Expected struct tag to be closed.") + elif name == "stream": + if not isinstance(element, Stream): + raise RuntimeError("Expected stream tag to be closed.") elif name == "field": if not isinstance(element, Field): raise RuntimeError("Expected field tag to be closed.")