traxator.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  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. def read_tag(cur):
  40. return serial.decode_str(cur)
  41. DrawCall = namedtuple("DrawCall", [
  42. "dc_id",
  43. "instrs",
  44. "dcs",
  45. "z_index",
  46. "debug_str"
  47. ])
  48. def read_dc(cur):
  49. dc_id = serial.read_u64(cur)
  50. instrs = serial.decode_arr(cur, read_instr)
  51. dcs = serial.decode_arr(cur, serial.read_u64)
  52. z_index = serial.read_u32(cur)
  53. debug_str = serial.decode_str(cur)
  54. return DrawCall(
  55. dc_id,
  56. instrs,
  57. dcs,
  58. z_index,
  59. debug_str
  60. )
  61. def read_instr(cur):
  62. enum = serial.read_u8(cur)
  63. match enum:
  64. case 0:
  65. scale = serial.read_f32(cur)
  66. return SetScale(scale)
  67. case 1:
  68. x = serial.read_f32(cur)
  69. y = serial.read_f32(cur)
  70. return Move(x, y)
  71. case 2:
  72. x = serial.read_f32(cur)
  73. y = serial.read_f32(cur)
  74. #print(f" set_pos x={x}, y={y}")
  75. return SetPos(x, y)
  76. case 3:
  77. x = serial.read_f32(cur)
  78. y = serial.read_f32(cur)
  79. w = serial.read_f32(cur)
  80. h = serial.read_f32(cur)
  81. #print(f" apply_view x={x}, y={y}, w={w}, h={h}")
  82. return ApplyView(x, y, w, h)
  83. case 4:
  84. vert_id = serial.read_u32(cur)
  85. vert_epoch = serial.read_u32(cur)
  86. vert_tag = serial.decode_opt(cur, read_tag)
  87. vert_buftype = serial.read_u8(cur)
  88. index_id = serial.read_u32(cur)
  89. index_epoch = serial.read_u32(cur)
  90. index_tag = serial.decode_opt(cur, read_tag)
  91. index_buftype = serial.read_u8(cur)
  92. def read_tex(cur):
  93. id = serial.read_u32(cur)
  94. epoch = serial.read_u32(cur)
  95. tag = serial.decode_opt(cur, read_tag)
  96. return (id, epoch, tag)
  97. tex = serial.decode_opt(cur, read_tex)
  98. num_elements = serial.read_i32(cur)
  99. return Draw(
  100. vert_id,
  101. vert_epoch,
  102. vert_tag,
  103. vert_buftype,
  104. index_id,
  105. index_epoch,
  106. index_tag,
  107. index_buftype,
  108. tex,
  109. num_elements
  110. )
  111. case _:
  112. raise NotImplementedError
  113. @dataclass
  114. class Vertex:
  115. x: float
  116. y: float
  117. r: float
  118. g: float
  119. b: float
  120. a: float
  121. u: float
  122. v: float
  123. @dataclass
  124. class PutDrawCall:
  125. epoch: int
  126. batch_id: int
  127. timest: int
  128. dcs: [DrawCall]
  129. stats: [int]
  130. @dataclass
  131. class PutStartBatch:
  132. epoch: int
  133. batch_id: int
  134. stat: int
  135. @dataclass
  136. class PutEndBatch:
  137. epoch: int
  138. batch_id: int
  139. stat: int
  140. @dataclass
  141. class PutTex:
  142. epoch: int
  143. tex: int
  144. tag: str
  145. stat: int
  146. @dataclass
  147. class PutVerts:
  148. epoch: int
  149. verts: [Vertex]
  150. buf: int
  151. tag: str
  152. buftype: int
  153. stat: int
  154. @dataclass
  155. class PutIdxs:
  156. epoch: int
  157. idxs: [int]
  158. buf: int
  159. tag: str
  160. buftype: int
  161. stat: int
  162. @dataclass
  163. class DelTex:
  164. epoch: int
  165. buf: int
  166. tag: str
  167. stat: int
  168. @dataclass
  169. class DelBuf:
  170. epoch: int
  171. buf: int
  172. tag: str
  173. buftype: int
  174. stat: int
  175. @dataclass
  176. class SetCurr:
  177. dc: int
  178. @dataclass
  179. class SetInstr:
  180. idx: int
  181. Section = Union[PutDrawCall, PutTex, PutVerts, PutIdxs, DelTex, DelBuf, SetCurr, SetInstr]
  182. def read_vert(cur):
  183. return Vertex(
  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. serial.read_f32(cur),
  192. )
  193. def read_section(f):
  194. fpos = f.tell()
  195. buf = serial.decode_buf(f)
  196. if not buf:
  197. return None
  198. cur = serial.Cursor(buf)
  199. c = serial.read_u8(cur)
  200. #print(f"SECTION: {c} {len(buf)}B [{fpos}]")
  201. #print(hex(cur.by))
  202. match c:
  203. case 0:
  204. epoch = serial.read_u32(cur)
  205. batch_id = serial.read_u32(cur)
  206. timest = serial.read_u64(cur)
  207. dcs = serial.decode_arr(cur, read_dc)
  208. stats = []
  209. for _ in dcs:
  210. stat = serial.read_u8(cur)
  211. stats.append(stat)
  212. #print(f" stat={stat}")
  213. #print(f"put_dcs epoch={epoch}, batch_id={batch_id}, timest={timest}, dcs={dcs}, stats={stats}")
  214. sect = PutDrawCall(epoch, batch_id, timest, dcs, stats)
  215. case 1:
  216. epoch = serial.read_u32(cur)
  217. batch_id = serial.read_u32(cur)
  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, timest, dcs, 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, timest, dcs, stats)
  227. case 3:
  228. epoch = serial.read_u32(cur)
  229. tex = serial.read_u32(cur)
  230. tag = serial.decode_opt(cur, read_tag)
  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, read_tag)
  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, read_tag)
  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, read_tag)
  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, read_tag)
  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)