summaryrefslogtreecommitdiff
path: root/src/asahi/lib/cmdbuf.xml
blob: 47b0767bc9d4826b427dcf0ac8318f924e286749 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
<agxml>
  <enum name="Channel">
    <value name="R" value="0"/>
    <value name="G" value="1"/>
    <value name="B" value="2"/>
    <value name="A" value="3"/>
    <value name="1" value="4"/>
    <value name="0" value="5"/>
  </enum>

  <enum name="ZS Func">
    <value name="Never" value="0"/>
    <value name="Less" value="1"/>
    <value name="Equal" value="2"/>
    <value name="Lequal" value="3"/>
    <value name="Greater" value="4"/>
    <value name="Not Equal" value="5"/>
    <value name="Gequal" value="6"/>
    <value name="Always" value="7"/>
  </enum>

  <enum name="Compare func">
    <value name="Lequal" value="0"/>
    <value name="Gequal" value="1"/>
    <value name="Less" value="2"/>
    <value name="Greater" value="3"/>
    <value name="Equal" value="4"/>
    <value name="Not Equal" value="5"/>
    <value name="Always" value="6"/>
    <value name="Never" value="7"/>
  </enum>

  <enum name="Stencil Op">
    <value name="Keep" value="0"/>
    <value name="Zero" value="1"/>
    <value name="Replace" value="2"/>
    <value name="Incr Sat" value="3"/>
    <value name="Decr Sat" value="4"/>
    <value name="Invert" value="5"/>
    <value name="Incr Wrap" value="6"/>
    <value name="Decr Wrap" value="7"/>
  </enum>

  <enum name="Polygon Mode">
    <value name="Fill" value="0"/>
    <value name="Line" value="1"/>
    <value name="Point" value="2"/>
  </enum>

  <enum name="Primitive">
    <value name="Points" value="0"/>
    <value name="Lines" value="1"/>
    <value name="Line strip" value="3"/>
    <value name="Line loop" value="5"/>
    <value name="Triangles" value="6"/>
    <value name="Triangle strip" value="9"/>
    <value name="Triangle fan" value="10"/>
    <value name="Quads" value="14"/> <!-- guess, confirm with piglit later XXX -->
    <value name="Quad strip" value="15"/> <!-- guess, confirm with piglit later XXX -->
  </enum>

  <enum name="Layout">
    <value name="Linear" value="0"/>
    <!-- Morton order with 64x64 tiles -->
    <value name="Tiled 64x64" value="2"/>
  </enum>

  <enum name="Channels">
    <value name="R8" value="0x00"/>
    <value name="R16" value="0x09"/>
    <value name="R8G8" value="0x0A"/>
    <value name="R5G6B5" value="0x0B"/>
    <value name="R4G4B4A4" value="0x0C"/>
    <value name="A1R5G5B5" value="0x0D"/>
    <value name="R5G5B5A1" value="0x0E"/>
    <value name="R32" value="0x21"/>
    <value name="R16G16" value="0x23"/>
    <value name="R11G11B10" value="0x25"/>
    <value name="R10G10B10A2" value="0x26"/>
    <value name="R9G9B9E5" value="0x27"/>
    <value name="R8G8B8A8" value="0x28"/>
    <value name="R32G32" value="0x31"/>
    <value name="R16G16B16A16" value="0x32"/>
    <value name="R32G32B32A32" value="0x38"/>
    <value name="GBGR 422" value="0x40"/> <!-- Subsampled, swizzle BRG1 -->
    <value name="BGRG 422" value="0x41"/> <!-- Subsampled, swizzle BRG1 -->

    <!-- Compressed -->
    <value name="PVRTC 2bpp" value="0x50"/>
    <value name="PVRTC 4bpp" value="0x51"/>

    <value name="ETC2 RGB8" value="0x58"/>
    <value name="ETC2 RGBA8" value="0x59"/>
    <value name="ETC2 RGB8A1" value="0x5A"/>
    <value name="EAC R11" value="0x5B"/>
    <value name="EAC RG11" value="0x5C"/>

    <value name="ASTC 4x4 LDR" value="0x60"/>
    <value name="ASTC 5x4 LDR" value="0x61"/>
    <value name="ASTC 5x5 LDR" value="0x62"/>
    <value name="ASTC 6x5 LDR" value="0x63"/>
    <value name="ASTC 6x6 LDR" value="0x64"/>
    <value name="ASTC 8x5 LDR" value="0x65"/>
    <value name="ASTC 8x6 LDR" value="0x66"/>
    <value name="ASTC 8x8 LDR" value="0x67"/>
    <value name="ASTC 10x5 LDR" value="0x68"/>
    <value name="ASTC 10x6 LDR" value="0x69"/>
    <value name="ASTC 10x8 LDR" value="0x6A"/>
    <value name="ASTC 10x10 LDR" value="0x6B"/>
    <value name="ASTC 12x10 LDR" value="0x6C"/>
    <value name="ASTC 12x12 LDR" value="0x6D"/>

    <value name="BC1" value="0x74"/>
    <value name="BC2" value="0x75"/>
    <value name="BC3" value="0x76"/>
    <value name="BC4" value="0x77"/>
    <value name="BC5" value="0x78"/>
    <value name="BC6H" value="0x79"/>
    <value name="BC6H Ufloat" value="0x7A"/>
    <value name="BC7" value="0x7B"/>
  </enum>

  <enum name="Texture Type">
    <value name="Unorm" value="0"/>
    <value name="Snorm" value="1"/>
    <value name="Uint" value="2"/>
    <value name="Sint" value="3"/>
    <value name="Float" value="4"/>
    <value name="XR" value="5"/>
  </enum>

  <struct name="Varying header" size="4">
    <field name="Triangle slots" size="8" start="0:0" type="uint"/>
    <field name="Point slots" size="8" start="0:8" type="uint"/>
  </struct>

  <enum name="Varying Type">
    <value name="Flat (first)" value="0"/>
    <value name="Flat (last)" value="2"/>
    <value name="Fragcoord W" value="3"/>
    <value name="Smooth" value="7"/>
    <value name="Fragcoord Z" value="11"/>
    <value name="Point coordinates" value="19"/>
  </enum>

  <struct name="Varying" size="4">
    <field name="Components" size="2" start="0" type="uint" modifier="minus(1)"/>
    <field name="Type" size="6" start="2" type="Varying Type" default="Smooth"/>
    <field name="Triangle slot" size="8" start="8" type="uint"/>
    <field name="Point slot" size="8" start="16" type="uint"/>
  </struct>

  <struct name="Format" size="2">
    <field name="Channels" size="7" start="0" type="Channels"/>
    <field name="Type" size="3" start="7" type="Texture Type"/>
  </struct>

  <struct name="Render Target" size="16">
    <field name="Unknown" size="4" start="0" type="hex" default="0x2"/>
    <field name="Layout" size="2" start="4" type="Layout"/>
    <field name="Format" size="10" start="6" type="Pixel Format"/>
    <field name="Swizzle R" size="2" start="16" type="Channel"/>
    <field name="Swizzle G" size="2" start="18" type="Channel"/>
    <field name="Swizzle B" size="2" start="20" type="Channel"/>
    <field name="Swizzle A" size="2" start="22" type="Channel"/>
    <field name="Width" size="14" start="24" type="uint" modifier="minus(1)"/>
    <field name="Height" size="14" start="38" type="uint" modifier="minus(1)"/>
    <field name="Unk 52" size="1" start="52" type="bool"/>
    <field name="Rotate 90" size="1" start="53" type="bool" default="false"/>
    <field name="Flip vertical" size="1" start="54" type="bool" default="false"/>
    <field name="Unk 55" size="9" start="55" type="hex"/>
    <field name="Buffer" size="36" start="64" type="address" modifier="shr(4)"/>
    <!-- N.b. sRGB is not specified here -->
    <!-- Off by 4? -->
    <field name="Stride" size="24" start="104" type="hex" prefix="AGX_RT_STRIDE">
      <value name="Tiled" value="0x100000"/>
    </field>
  </struct>

  <enum name="Texture dimension">
    <value name="2D" value="2"/>
    <value name="Cube" value="6"/>
  </enum>

  <!-- Payloads follow, right-shifted by 4 because of course -->
  <struct name="Texture" size="16">
    <field name="Dimension" size="4" start="0" type="Texture dimension" default="2D"/>
    <field name="Layout" size="2" start="4" type="Layout"/>
    <field name="Format" size="10" start="6" type="Pixel Format"/>
    <field name="Swizzle R" size="3" start="16" type="Channel" default="R"/>
    <field name="Swizzle G" size="3" start="19" type="Channel" default="G"/>
    <field name="Swizzle B" size="3" start="22" type="Channel" default="B"/>
    <field name="Swizzle A" size="3" start="25" type="Channel" default="A"/>
    <field name="Width" size="14" start="28" type="uint" modifier="minus(1)"/>
    <field name="Height" size="14" start="42" type="uint" modifier="minus(1)"/>
    <field name="Levels" size="6" start="60" type="uint" modifier="minus(1)"/>
    <field name="Address" size="36" start="66" type="hex" modifier="shr(4)"/>
    <!-- Unknown bit set by Metal when mipmapping. Might relate to a mechanism
    to switch tile size (or disable tiling altogether?) at small mip levels to
    reduce wasted memory due to padding. Causing test flakiness when set. -->
    <field name="Unk mipmapped" size="1" start="102" type="bool"/>
    <field name="Compression" size="2" start="106" type="hex"/> <!-- 0 for 64x64 tiling -->
    <field name="sRGB" size="1" start="108" type="bool"/>
    <field name="Unk 2" size="1" start="109" type="bool"/>
    <field name="Stride" size="18" start="110" type="hex" modifier="shr(4)"/>
  </struct>

  <enum name="Wrap">
    <value name="Clamp to edge" value="0"/>
    <value name="Repeat" value="1"/>
    <value name="Mirrored repeat" value="2"/>
    <value name="Clamp to border" value="3"/>
  </enum>

  <enum name="Mip filter">
    <value name="None" value="0"/>
    <value name="Nearest" value="1"/>
    <value name="Linear" value="2"/>
  </enum>

  <enum name="Border colour">
    <value name="Transparent black" value="0"/>
    <value name="Opaque black" value="1"/>
    <value name="Opaque white" value="2"/>
  </enum>

  <struct name="Sampler" size="8">
    <field name="Unk 1" size="2" start="17" type="hex" default="3"/>
    <field name="Unk 2" size="1" start="19" type="bool" default="true"/>
    <field name="Magnify linear" size="1" start="23" type="bool"/>
    <field name="Minify linear" size="1" start="25" type="bool"/>
    <field name="Mip filter" size="2" start="27" type="Mip filter"/>
    <field name="Wrap S" size="3" start="29" type="Wrap"/>
    <field name="Wrap T" size="3" start="32" type="Wrap"/>
    <field name="Wrap R" size="3" start="35" type="Wrap"/>
    <field name="Pixel coordinates" size="1" start="38" type="bool"/>
    <field name="Compare func" size="3" start="39" type="Compare func"/>
    <field name="Unk 3" size="1" start="42" type="hex" default="1"/>
    <field name="Border colour" size="2" start="55" type="Border colour"/>
  </struct>

  <!--- Identified by tag? -->
  <struct name="Viewport" size="40">
    <field name="Tag" size="32" start="0:0" type="hex" default="0xc00"/>

    <!-- Acts like a scissor at 32x32 tile boundaries, ignored unless clip tile is set -->
    <field name="Max tile X" size="9" start="1:0" type="uint" modifier="minus(1)"/>
    <field name="Min tile X" size="9" start="1:16" type="uint"/>
    <field name="Clip tile" size="1" start="1:31" type="bool"/>
    <field name="Max tile Y" size="9" start="2:0" type="uint" modifier="minus(1)"/>
    <field name="Min tile Y" size="9" start="2:16" type="uint"/>

    <!-- Used to convert clip space coordinates to NDC, does not clip -->
    <field name="Translate X" size="32" start="4:0" type="float"/>
    <field name="Scale X" size="32" start="5:0" type="float"/>
    <field name="Translate Y" size="32" start="6:0" type="float"/>
    <field name="Scale Y" size="32" start="7:0" type="float"/>

    <!-- Specifies an affine transformation from clip coordinates to viewport
    depth coordinates. For APIs with clip coordinates [0, 1], this cooresponds
    to near z and (far z - near z) respectively. In general, given clip
    coordinate z_in, the viewport depth is given as (z_in * scale_z) +
    translate_z.  For example, the default [0, 1] depth buffer in OpenGL with
    [-1, +1] clip coordinates is specified as scale = 1/2, bias = 1/2 -->
    <field name="Translate Z" size="32" start="8:0" type="float"/>
    <field name="Scale Z" size="32" start="9:0" type="float"/>
  </struct>

  <!--- Pointed to from the command buffer -->
  <struct name="Scissor" size="16">
    <field name="Max X" size="16" start="0:0" type="uint"/>
    <field name="Min X" size="16" start="0:16" type="uint"/>
    <field name="Max Y" size="16" start="1:0" type="uint"/>
    <field name="Min Y" size="16" start="1:16" type="uint"/>
    <field name="Min Z" size="32" start="2:0" type="float"/>
    <field name="Max Z" size="32" start="3:0" type="float"/>
  </struct>

  <struct name="Rasterizer face" size="8">
    <field name="Stencil reference" size="8" start="0:0" type="hex"/>
    <!-- line width is 4:4 fixed point with off-by-one applied -->
    <field name="Line width" size="8" start="0:8" type="hex"/>
    <field name="Polygon mode" size="2" start="0:18" type="Polygon Mode"/>
    <field name="Disable depth write" size="1" start="0:21" type="bool"/>
    <field name="Depth function" size="3" start="0:24" type="ZS Func"/>
    <field name="Stencil write mask" size="8" start="1:0" type="hex"/>
    <field name="Stencil read mask" size="8" start="1:8" type="hex"/>
    <field name="Depth pass" size="3" start="1:16" type="Stencil Op"/>
    <field name="Depth fail" size="3" start="1:19" type="Stencil Op"/>
    <field name="Stencil fail" size="3" start="1:22" type="Stencil Op"/>
    <field name="Stencil compare" size="3" start="1:25" type="ZS Func"/>
  </struct>

  <struct name="Rasterizer" size="28">
    <field name="Tag" size="32" start="0:0" type="hex" default="0x10000b5"/>
    <field name="Unk 1" size="1" start="1:9" type="hex" default="0x1"/>
    <field name="Scissor enable" size="1" start="1:16" type="bool"/>
    <field name="Unk ZS" size="1" start="1:18" type="hex" default="0x1"/>
    <field name="Unk 2" size="2" start="1:19" type="hex" default="0x0"/>
    <field name="Unk fill lines" size="1" start="1:26" type="hex" default="0x0"/> <!-- set when drawing LINES -->
    <field name="Front" size="64" start="2:0" type="Rasterizer face"/>
    <field name="Back" size="64" start="4:0" type="Rasterizer face"/>
  </struct>

  <struct name="Unknown face" size="4">
    <field name="Unknown" size="8" start="0:20" type="hex" default="0x7e"/>
    <field name="Lines" size="1" start="0:28" type="bool"/>
    <field name="Points" size="1" start="0:30" type="bool"/>
  </struct>

  <struct name="Unknown 4a" size="20">
    <field name="Tag" size="32" start="0:0" type="hex" default="0x200004a"/>
    <field name="Unk 1" size="1" start="1:9" type="bool" default="true"/>
    <field name="Lines or points" size="1" start="1:26" type="bool"/>
    <field name="Reads tilebuffer" size="1" start="1:29" type="bool"/>
    <field name="Sample mask from shader" size="1" start="1:30" type="bool"/>
    <field name="Front" size="32" start="2:0" type="Unknown face"/>
    <field name="Back" size="32" start="3:0" type="Unknown face"/>
    <!-- maybe sample mask -->
    <field name="Unk 4" size="32" start="4:0" type="hex" default="0x1ffff"/>
  </struct>

  <struct name="Cull" size="8">
    <field name="Tag" size="32" start="0:0" type="hex" default="0x200000"/>
    <field name="Cull front" size="1" start="1:0" type="bool"/>
    <field name="Cull back" size="1" start="1:1" type="bool"/>
    <field name="Unk GL 1" size="1" start="1:7" type="bool"/>
    <field name="Unk GL 2" size="1" start="1:8" type="bool"/>
    <field name="Depth clip" size="1" start="1:10" type="bool"/>
    <field name="Depth clamp" size="1" start="1:11" type="bool"/>
    <field name="Front face CCW" size="1" start="1:16" type="bool"/>
  </struct>

  <struct name="Interpolation" size="20">
    <field name="Tag" size="32" start="0:0" type="hex" default="0x100C0000"/>
    <field name="Varying count" size="32" start="1:0" type="uint"/>
  </struct>

  <struct name="Linkage" size="16">
    <field name="Tag" size="32" start="0:0" type="hex" default="0xC020000"/>
    <field name="Unk 1" size="32" start="1:0" type="hex" default="0x100"/>
    <field name="Unk 2" size="32" start="2:0" type="hex" default="0x0"/>
    <field name="Varying count" size="32" start="3:0" type="uint"/>
  </struct>

  <!-- Indexes into the array of scissor descriptors -->
  <struct name="Set scissor" size="8">
    <field name="Tag" size="32" start="0:0" type="hex" default="0x100"/>
    <field name="Index" size="32" start="1:0" type="uint"/>
  </struct>

  <!--- Commands valid within a pipeline -->
  <struct name="Bind uniform" size="8">
    <field name="Tag" size="8" start="0:0" type="hex" default="0x1d"/>
    <field name="Start (halfs)" size="8" start="0:8" type="uint"/>
    <field name="Unk" size="4" start="0:16" type="hex" default="0x0"/>
    <field name="Size (halfs)" size="4" start="0:20" type="uint"/>
    <field name="Buffer" size="40" start="0:24" type="address"/>
  </struct>

  <struct name="Bind texture" size="8">
    <field name="Tag" size="8" start="0:0" type="hex" default="0xdd"/>
    <field name="Start" size="8" start="0:8" type="uint"/>
    <field name="Count" size="4" start="0:20" type="uint"/>
    <field name="Buffer" size="40" start="0:24" type="address"/>
  </struct>

  <struct name="Bind sampler" size="8">
    <field name="Tag" size="8" start="0:0" type="hex" default="0x9d"/>
    <field name="Start" size="8" start="0:8" type="uint"/>
    <field name="Count" size="4" start="0:20" type="uint"/>
    <field name="Buffer" size="40" start="0:24" type="address"/>
  </struct>

  <enum name="Preshader mode">
    <value name="Preshader" value="3"/>
    <value name="No preshader" value="8"/>
  </enum>

  <struct name="Set shader" size="24">
    <field name="Tag" size="8" start="0:0" type="hex" default="0x4d"/>
    <field name="Unk 1" size="24" start="0:8" type="hex" default="0x90"/>
    <field name="Unk 2" size="8" start="1:0" type="hex" default="0x0d"/> <!-- TODO differs with stage -->
    <field name="Unk 2b" size="8" start="1:8" type="uint" default="4"/>
    <field name="Code" size="32" start="1:16" type="address"/>
    <field name="Unk 3" size="8" start="2:16" type="hex" default="0x8d"/>
    <field name="Register quadwords" size="5" start="2:24" type="uint"/> <!-- 0 for max -->
    <field name="Unk 3b" size="3" start="2:29" type="hex" default="0x0"/>
    <field name="Spill size" size="8" start="3:0" type="hex" default="0"/> <!-- TODO: determine relation, see docs/table.py -->
    <field name="Unk 4" size="12" start="3:8" type="hex" default="0x801"/>
    <field name="Preshader mode" size="4" start="3:20" type="Preshader mode" default="No preshader"/>
    <field name="Unk 6" size="8" start="3:24" type="hex" default="0x0"/>
    <field name="Preshader unk" size="16" start="4:0" type="hex" default="0x0"/>
    <field name="Preshader code" size="32" start="4:16" type="address"/>
    <field name="Unk 7" size="16" start="5:16" type="hex" default="0x0"/> <!-- blob is inconsistent -->
  </struct>

  <struct name="Fragment Parameters" size="4">
    <field name="Unk 1" size="24" start="0" type="hex" default="0x580100"/>
    <!-- Guess. Set if the shader does not write the sample mask (including by
        discard_fragment) -->
    <field name="Early-z testing" size="1" start="24" type="bool"/>
    <field name="Unk 2" size="1" start="25" type="bool" default="true"/>
    <field name="Unk 3" size="4" start="28" type="hex" default="0xf"/>
  </struct>

  <struct name="Set shader extended" size="32">
    <field name="Tag" size="8" start="0:0" type="hex" default="0x4d"/>
    <field name="Unk 1" size="24" start="0:8" type="hex" default="0x2010bd"/>
    <field name="Unk 2" size="8" start="1:0" type="hex" default="0x0d"/>
    <field name="Unk 2b" size="8" start="1:8" type="uint" default="5"/> <!-- 1 for other frag, 5 with discard? -->
    <field name="Code" size="32" start="1:16" type="address"/>
    <field name="Unk 3" size="8" start="2:16" type="hex" default="0x28d"/>
    <field name="Register quadwords" size="5" start="2:24" type="uint"/> <!-- 0 for max -->
    <field name="Unk 3b" size="3" start="2:29" type="hex" default="0x0"/>
    <field name="Fragment parameters" size="32" start="3:0" type="Fragment Parameters"/>
    <field name="Spill size" size="8" start="4:0" type="hex" default="0"/> <!-- TODO: determine relation, see docs/table.py -->
    <field name="Unk 4" size="12" start="4:8" type="hex" default="0x801"/>
    <field name="Preshader mode" size="4" start="4:20" type="Preshader mode" default="No preshader"/>
    <field name="Unk 6" size="8" start="4:24" type="hex" default="0x0"/>
    <field name="Preshader unk" size="16" start="5:0" type="hex" default="0x0"/>
    <field name="Preshader code" size="32" start="5:16" type="address"/>
    <field name="Unk 7" size="16" start="6:16" type="hex" default="0x0"/> <!-- blob is inconsistent -->
    <field name="Unk 8" size="32" start="7:0" type="hex" default="0x0"/> <!-- may not exist -->
  </struct>

  <!--- Command to bind a vertex pipeline, followed by subcommands. Counts are
	specified in 32-bit word units. Intepretation per-shader stage. -->
  <struct name="Bind pipeline" size="24">
    <field name="Tag" size="32" start="0:0" type="hex" default="0x4000002e">
      <value name="AGX_BIND_PIPELINE_VERTEX" value="0x4000002e"/>
      <value name="AGX_BIND_PIPELINE_FRAGMENT" value="0x800000"/>
    </field>
    <field name="Unk 1" size="4" start="1:0" type="hex" default="0x2"/>
    <field name="Sampler count" start="1:4" size="5" type="uint"/>
    <field name="Texture count" start="1:9" size="3" type="uint"/>
    <field name="Unk 2" size="4" start="1:12" type="hex" default="0x1"/>
    <field name="Input count" size="8" start="1:16" type="uint" default="0"/>
    <field name="Padding 1" size="8" start="1:24" type="hex" default="0x0"/>
    <field name="Pipeline" size="32" start="2:0" type="address"/>

    <!-- Overlaps -->
    <field name="FS Varyings" size="32" start="3:0" type="address"/>
    <field name="VS Output count 1" size="8" start="3:0" type="uint" default="0"/>
    <field name="VS Output count 2" size="8" start="3:8" type="uint" default="0"/>
    <field name="Padding 2" size="16" start="3:16" type="hex" default="0x0"/>

    <field name="Unk 3" size="32" start="5:0" type="address"/> <!-- C020000 -->
  </struct>

  <!-- Subcommands are packed inside sized records -->
  <struct name="Record" size="8">
    <field name="Pointer (hi)" size="8" start="0:0" type="hex"/>
    <field name="Size (words)" size="8" start="0:8" type="uint"/>
    <field name="Tag" size="16" start="0:16" type="hex" default="0x0000"/>
    <field name="Pointer (lo)" size="32" start="0:32" type="address"/>
  </struct>

  <!--- Command to issue a direct non-indexed draw -->
  <struct name="Draw" size="16">
    <field name="Unk" size="8" start="0:0" type="hex" default="0x0"/>
    <field name="Primitive" size="8" start="0:8" type="Primitive"/>
    <field name="Command" size="16" start="0:16" type="hex" default="0x61c0"/>
    <field name="Vertex count" size="32" start="1:0" type="uint"/>
    <field name="Instance count" size="32" start="2:0" type="uint"/> <!-- must be nonzero -->
    <field name="Vertex start" size="32" start="3:0" type="uint"/>
  </struct>

  <enum name="Index size">
    <value name="U8" value="0"/>
    <value name="U16" value="1"/>
    <value name="U32" value="2"/>
  </enum>

  <struct name="Indexed draw" size="32">
    <field name="Unk 1" size="8" start="0:0" type="hex" default="0x1"/>
    <field name="Command" size="24" start="0:8" type="hex" default="0x400000"/>
    <field name="Restart index" size="32" start="1:0" type="hex"/>
    <field name="Unk 2a" size="8" start="2:0" type="hex" default="0x15"/>
    <field name="Primitive" size="8" start="2:8" type="Primitive"/>
    <field name="Restart enable" size="1" start="2:16" type="bool"/> <!-- Metal sets this bit for strips -->
    <field name="Index size" size="3" start="2:17" type="Index size"/>
    <field name="Unk 2c" size="4" start="2:20" type="hex" default="0xF"/>
    <field name="Unk 2d" size="8" start="2:24" type="hex" default="0x61"/>
    <field name="Index buffer offset" size="32" start="3:0" type="hex"/>
    <field name="Index count" size="32" start="4:0" type="uint"/>
    <field name="Instance count" size="32" start="5:0" type="uint"/>
    <field name="Base vertex" size="32" start="6:0" type="uint"/>
    <field name="Index buffer size" size="32" start="7:0" type="uint" modifier="shr(2)"/>
  </struct>

  <!--- Command to launch a direct compute kernel -->
  <struct name="Launch" size="36">
    <field name="Command" size="32" start="0:0" type="hex" default="0x1002"/>
    <field name="Pipeline" size="32" start="1:0" type="address"/>
    <field name="Group count X" size="32" start="2:0" type="uint"/>
    <field name="Group count Y" size="32" start="3:0" type="uint"/>
    <field name="Group count Z" size="32" start="4:0" type="uint"/>
    <field name="Local size X" size="32" start="5:0" type="uint"/>
    <field name="Local size Y" size="32" start="6:0" type="uint"/>
    <field name="Local size Z" size="32" start="7:0" type="uint"/>
    <field name="Unk" size="32" start="8:0" type="hex" default="0x60000160"/>
  </struct>

  <!--- The rest of this file is likely software defined by macOS kernel -->
  <enum name="IOGPU Attachment Type">
    <value name="Colour" value="0xA"/>
    <value name="Depth" value="0xC"/>
  </enum>

  <struct name="IOGPU Header" size="192">
    <field name="Unk 0" start="0:0" size="32" default="0x10000" type="hex"/>
    <field name="Total size" start="1:0" size="32" type="uint"/>
    <field name="Unk 2" start="2:0" size="32" default="0x7" type="hex"/>
    <field name="Attachment offset 1" start="8:0" size="32" type="uint"/>
    <field name="Attachment length" start="9:0" size="32" type="uint"/>
    <field name="Attachment offset 2" start="10:0" size="32" type="uint"/>
    <field name="Unknown offset" start="11:0" size="32" type="uint"/>
    <field name="Unk 4" start="12:0" size="32" default="0x30" type="hex"/>
    <field name="Unk 5" start="13:0" size="32" default="0x01" type="hex"/>
    <field name="Encoder" start="14:0" size="64" type="address"/>
    <!-- if either deflake address is null, rendering gets flaky for high
         geometry counts -->
    <field name="Deflake 1" start="38:0" size="64" type="address"/>
    <field name="Deflake 2" start="40:0" size="64" type="address"/>
  </struct>

  <struct name="IOGPU Attachment" size="24">
    <field name="Unk 0" start="0:0" size="16" default="0x100" type="hex"/>
    <field name="Address" start="0:16" size="48" type="address"/>
    <field name="Type" start="2:16" size="16" type="IOGPU Attachment Type"/>
    <field name="Unk 1" start="3:0" size="32" type="hex"/>
    <field name="Unk 2" start="4:0" size="3" type="hex"/>
    <field name="Bytes per pixel" start="4:3" size="5" type="uint"/>
    <field name="Unk 3" start="4:16" size="4" type="hex" default="0xC"/>
    <!-- Percent of total attachment space used for this attachment, expressed
         in a decimal percentage [0, 100] <field name="Percent" start="5:16" -->
    <field name="Percent" start="5:16" size="16" type="uint"/>
  </struct>
</agxml>