traxator.py 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. #!/usr/bin/python
  2. from pydrk import serial
  3. from collections import namedtuple
  4. from dataclasses import dataclass
  5. from typing import Union
  6. import sys
  7. @dataclass
  8. class SetScale:
  9. scale: float
  10. @dataclass
  11. class Move:
  12. x: float
  13. y: float
  14. @dataclass
  15. class SetPos:
  16. x: float
  17. y: float
  18. @dataclass
  19. class ApplyView:
  20. x: float
  21. y: float
  22. w: float
  23. h: float
  24. @dataclass
  25. class Draw:
  26. vert_id: int
  27. vert_epoch: int
  28. vert_tag: str
  29. vert_buftype: int
  30. index_id: int
  31. index_epoch: int
  32. index_tag: str
  33. index_buftype: int
  34. tex: (int, int, str)
  35. num_elements: int
  36. Instr = Union[SetScale, Move, SetPos, ApplyView, Draw]
  37. def hex(dat):
  38. return " ".join(f"{b:02x}" for b in dat)
  39. DrawCall = namedtuple("DrawCall", [
  40. "dc_id",
  41. "instrs",
  42. "dcs",
  43. "z_index",
  44. "debug_str"
  45. ])
  46. def read_dc(cur):
  47. dc_id = serial.read_u64(cur)
  48. instrs = serial.decode_arr(cur, read_instr)
  49. dcs = serial.decode_arr(cur, serial.read_u64)
  50. z_index = serial.read_u32(cur)
  51. debug_str = serial.decode_str(cur)
  52. return DrawCall(
  53. dc_id,
  54. instrs,
  55. dcs,
  56. z_index,
  57. debug_str
  58. )
  59. def read_instr(cur):
  60. enum = serial.read_u8(cur)
  61. match enum:
  62. case 0:
  63. scale = serial.read_f32(cur)
  64. return SetScale(scale)
  65. case 1:
  66. x = serial.read_f32(cur)
  67. y = serial.read_f32(cur)
  68. return Move(x, y)
  69. case 2:
  70. x = serial.read_f32(cur)
  71. y = serial.read_f32(cur)
  72. #print(f" set_pos x={x}, y={y}")
  73. return SetPos(x, y)
  74. case 3:
  75. x = serial.read_f32(cur)
  76. y = serial.read_f32(cur)
  77. w = serial.read_f32(cur)
  78. h = serial.read_f32(cur)
  79. #print(f" apply_view x={x}, y={y}, w={w}, h={h}")
  80. return ApplyView(x, y, w, h)
  81. case 4:
  82. vert_id = serial.read_u32(cur)
  83. vert_epoch = serial.read_u32(cur)
  84. vert_tag = serial.decode_opt(cur, serial.decode_str)
  85. vert_buftype = serial.read_u8(cur)
  86. index_id = serial.read_u32(cur)
  87. index_epoch = serial.read_u32(cur)
  88. index_tag = serial.decode_opt(cur, serial.decode_str)
  89. index_buftype = serial.read_u8(cur)
  90. def read_tex(cur):
  91. id = serial.read_u32(cur)
  92. epoch = serial.read_u32(cur)
  93. tag = serial.decode_opt(cur, serial.decode_str)
  94. return (id, epoch, tag)
  95. tex = serial.decode_opt(cur, read_tex)
  96. num_elements = serial.read_i32(cur)
  97. return Draw(
  98. vert_id,
  99. vert_epoch,
  100. vert_tag,
  101. vert_buftype,
  102. index_id,
  103. index_epoch,
  104. index_tag,
  105. index_buftype,
  106. tex,
  107. num_elements
  108. )
  109. case _:
  110. raise NotImplementedError
  111. @dataclass
  112. class Vertex:
  113. x: float
  114. y: float
  115. r: float
  116. g: float
  117. b: float
  118. a: float
  119. u: float
  120. v: float
  121. @dataclass
  122. class PutDrawCall:
  123. epoch: int
  124. batch_id: int
  125. timest: int
  126. dcs: [DrawCall]
  127. stats: [int]
  128. @dataclass
  129. class PutStartBatch:
  130. epoch: int
  131. batch_id: int
  132. debug_str: str
  133. stat: int
  134. @dataclass
  135. class PutEndBatch:
  136. epoch: int
  137. batch_id: int
  138. stat: int
  139. @dataclass
  140. class PutTex:
  141. epoch: int
  142. tex: int
  143. tag: str
  144. stat: int
  145. @dataclass
  146. class PutVerts:
  147. epoch: int
  148. verts: [Vertex]
  149. buf: int
  150. tag: str
  151. buftype: int
  152. stat: int
  153. @dataclass
  154. class PutIdxs:
  155. epoch: int
  156. idxs: [int]
  157. buf: int
  158. tag: str
  159. buftype: int
  160. stat: int
  161. @dataclass
  162. class DelTex:
  163. epoch: int
  164. buf: int
  165. tag: str
  166. stat: int
  167. @dataclass
  168. class DelBuf:
  169. epoch: int
  170. buf: int
  171. tag: str
  172. buftype: int
  173. stat: int
  174. @dataclass
  175. class SetCurr:
  176. dc: int
  177. @dataclass
  178. class SetInstr:
  179. idx: int
  180. Section = Union[PutDrawCall, PutTex, PutVerts, PutIdxs, DelTex, DelBuf, SetCurr, SetInstr]
  181. def read_vert(cur):
  182. return Vertex(
  183. serial.read_f32(cur),
  184. serial.read_f32(cur),
  185. serial.read_f32(cur),
  186. serial.read_f32(cur),
  187. serial.read_f32(cur),
  188. serial.read_f32(cur),
  189. serial.read_f32(cur),
  190. serial.read_f32(cur),
  191. )
  192. def read_section(f):
  193. fpos = f.tell()
  194. buf = serial.decode_buf(f)
  195. if not buf:
  196. return None
  197. cur = serial.Cursor(buf)
  198. c = serial.read_u8(cur)
  199. #print(f"SECTION: {c} {len(buf)}B [{fpos}]")
  200. #print(hex(cur.by))
  201. match c:
  202. case 0:
  203. epoch = serial.read_u32(cur)
  204. batch_id = serial.read_u32(cur)
  205. timest = serial.read_u64(cur)
  206. dcs = serial.decode_arr(cur, read_dc)
  207. stats = []
  208. for _ in dcs:
  209. stat = serial.read_u8(cur)
  210. stats.append(stat)
  211. #print(f" stat={stat}")
  212. #print(f"put_dcs epoch={epoch}, batch_id={batch_id}, timest={timest}, dcs={dcs}, stats={stats}")
  213. sect = PutDrawCall(epoch, batch_id, timest, dcs, stats)
  214. case 1:
  215. epoch = serial.read_u32(cur)
  216. batch_id = serial.read_u32(cur)
  217. debug_str = serial.decode_opt(cur, serial.decode_str)
  218. stat = serial.read_u8(cur)
  219. #print(f"put_start_batch epoch={epoch}, batch_id={batch_id}, stat={stat}")
  220. sect = PutStartBatch(epoch, batch_id, debug_str, stats)
  221. case 2:
  222. epoch = serial.read_u32(cur)
  223. batch_id = serial.read_u32(cur)
  224. stat = serial.read_u8(cur)
  225. #print(f"put_end_batch epoch={epoch}, batch_id={batch_id}, stat={stat}")
  226. sect = PutEndBatch(epoch, batch_id, stats)
  227. case 3:
  228. epoch = serial.read_u32(cur)
  229. tex = serial.read_u32(cur)
  230. tag = serial.decode_opt(cur, serial.decode_str)
  231. stat = serial.read_u8(cur)
  232. #print(f"put_tex epoch={epoch}, tex={tex}, tag='{tag}', stat={stat}")
  233. sect = PutTex(epoch, tex, tag, stat)
  234. case 4:
  235. epoch = serial.read_u32(cur)
  236. verts = serial.decode_arr(cur, read_vert)
  237. buf = serial.read_u32(cur)
  238. tag = serial.decode_opt(cur, serial.decode_str)
  239. buftype = serial.read_u8(cur)
  240. stat = serial.read_u8(cur)
  241. #print(f"put_verts epoch={epoch}, buf={buf}, tag='{tag}', buftype={buftype}, stat={stat}")
  242. sect = PutVerts(epoch, verts, buf, tag, buftype, stat)
  243. case 5:
  244. epoch = serial.read_u32(cur)
  245. idxs = serial.decode_arr(cur, serial.read_u16)
  246. buf = serial.read_u32(cur)
  247. tag = serial.decode_opt(cur, serial.decode_str)
  248. buftype = serial.read_u8(cur)
  249. stat = serial.read_u8(cur)
  250. #print(f"put_idxs epoch={epoch}, buf={buf}, tag='{tag}', buftype={buftype}, stat={stat}")
  251. sect = PutIdxs(epoch, idxs, buf, tag, buftype, stat)
  252. case 6:
  253. epoch = serial.read_u32(cur)
  254. buf = serial.read_u32(cur)
  255. tag = serial.decode_opt(cur, serial.decode_str)
  256. stat = serial.read_u8(cur)
  257. #print(f"del_tex epoch={epoch}, buf={buf}, tag='{tag}', stat={stat}")
  258. sect = DelTex(epoch, buf, tag, stat)
  259. case 7:
  260. epoch = serial.read_u32(cur)
  261. buf = serial.read_u32(cur)
  262. tag = serial.decode_opt(cur, serial.decode_str)
  263. buftype = serial.read_u8(cur)
  264. stat = serial.read_u8(cur)
  265. #print(f"del_buf epoch={epoch}, buf={buf}, tag='{tag}', buftype={buftype}, stat={stat}")
  266. sect = DelBuf(epoch, buf, tag, buftype, stat)
  267. case 8:
  268. dc = serial.read_u64(cur)
  269. #print(f"set_curr dc={dc}")
  270. sect = SetCurr(dc)
  271. case 9:
  272. idx = serial.read_u64(cur)
  273. #print(f"set_instr idx={idx}")
  274. sect = SetInstr(idx)
  275. case _:
  276. raise NotImplementedError
  277. # Crash out if we didn't fully consume the buffer
  278. if not cur.is_end():
  279. print(hex(cur.remain_data()))
  280. assert cur.is_end()
  281. return sect
  282. def read_trax(fname):
  283. f = open(fname, "rb")
  284. sections = []
  285. while True:
  286. if (sect := read_section(f)) is None:
  287. break
  288. sections.append(sect)
  289. return sections
  290. if __name__ == "__main__":
  291. if len(sys.argv) != 2:
  292. print("wrong args", file=sys.stderr)
  293. sys.exit(-1)
  294. fname = sys.argv[1]
  295. sections = read_trax(fname)
  296. for sect in sections:
  297. print(sect)