xref: /aosp_15_r20/external/mesa3d/src/intel/genxml/README (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard WorkerThis provides some background the design of the generated headers.  We
2*61046927SAndroid Build Coastguard Workerstarted out trying to generate bit fields but it evolved into the pack
3*61046927SAndroid Build Coastguard Workerfunctions because of a few limitations:
4*61046927SAndroid Build Coastguard Worker
5*61046927SAndroid Build Coastguard Worker  1) Bit fields still generate terrible code today. Even with modern
6*61046927SAndroid Build Coastguard Worker     optimizing compilers you get multiple load+mask+store operations
7*61046927SAndroid Build Coastguard Worker     to the same dword in memory as you set individual bits. The
8*61046927SAndroid Build Coastguard Worker     compiler also has to generate code to mask out overflowing values
9*61046927SAndroid Build Coastguard Worker     (for example, if you assign 200 to a 2 bit field). Our driver
10*61046927SAndroid Build Coastguard Worker     never writes overflowing values so that's not needed. On the
11*61046927SAndroid Build Coastguard Worker     other hand, most compiler recognize that the template struct we
12*61046927SAndroid Build Coastguard Worker     use is a temporary variable and copy propagate the individual
13*61046927SAndroid Build Coastguard Worker     fields and do amazing constant folding.  You should take a look
14*61046927SAndroid Build Coastguard Worker     at the code that gets generated when you compile in release mode
15*61046927SAndroid Build Coastguard Worker     with optimizations.
16*61046927SAndroid Build Coastguard Worker
17*61046927SAndroid Build Coastguard Worker  2) For some types we need to have overlapping bit fields. For
18*61046927SAndroid Build Coastguard Worker     example, some values are 64 byte aligned 32 bit offsets. The
19*61046927SAndroid Build Coastguard Worker     lower 5 bits of the offset are always zero, so the hw packs in a
20*61046927SAndroid Build Coastguard Worker     few misc bits in the lower 5 bits there. Other times a field can
21*61046927SAndroid Build Coastguard Worker     be either a u32 or a float. I tried to do this with overlapping
22*61046927SAndroid Build Coastguard Worker     anonymous unions and it became a big mess. Also, when using
23*61046927SAndroid Build Coastguard Worker     initializers, you can only initialize one union member so this
24*61046927SAndroid Build Coastguard Worker     just doesn't work with out approach.
25*61046927SAndroid Build Coastguard Worker
26*61046927SAndroid Build Coastguard Worker     The pack functions on the other hand allows us a great deal of
27*61046927SAndroid Build Coastguard Worker     flexibility in how we combine things. In the case of overlapping
28*61046927SAndroid Build Coastguard Worker     fields (the u32 and float case), if we only set one of them in
29*61046927SAndroid Build Coastguard Worker     the pack function, the compiler will recognize that the other is
30*61046927SAndroid Build Coastguard Worker     initialized to 0 and optimize out the code to or it it.
31*61046927SAndroid Build Coastguard Worker
32*61046927SAndroid Build Coastguard Worker  3) Bit fields (and certainly overlapping anonymous unions of bit
33*61046927SAndroid Build Coastguard Worker     fields) aren't generally stable across compilers in how they're
34*61046927SAndroid Build Coastguard Worker     laid out and aligned. Our pack functions let us control exactly
35*61046927SAndroid Build Coastguard Worker     how things get packed, using only simple and unambiguous bitwise
36*61046927SAndroid Build Coastguard Worker     shifting and or'ing that works on any compiler.
37*61046927SAndroid Build Coastguard Worker
38*61046927SAndroid Build Coastguard WorkerOnce we have the pack function it allows us to hook in various
39*61046927SAndroid Build Coastguard Workertransformations and validation as we go from template struct to dwords
40*61046927SAndroid Build Coastguard Workerin memory:
41*61046927SAndroid Build Coastguard Worker
42*61046927SAndroid Build Coastguard Worker  1) Validation: As I said above, our driver isn't supposed to write
43*61046927SAndroid Build Coastguard Worker     overflowing values to the fields, but we've of course had lots of
44*61046927SAndroid Build Coastguard Worker     cases where we make mistakes and write overflowing values. With
45*61046927SAndroid Build Coastguard Worker     the pack function, we can actually assert on that and catch it at
46*61046927SAndroid Build Coastguard Worker     runtime.  bitfields would just silently truncate.
47*61046927SAndroid Build Coastguard Worker
48*61046927SAndroid Build Coastguard Worker  2) Type conversions: some times it's just a matter of writing a
49*61046927SAndroid Build Coastguard Worker     float to a u32, but we also convert from bool to bits, from
50*61046927SAndroid Build Coastguard Worker     floats to fixed point integers.
51*61046927SAndroid Build Coastguard Worker
52*61046927SAndroid Build Coastguard Worker  3) Relocations: whenever we have a pointer from one buffer to
53*61046927SAndroid Build Coastguard Worker     another (for example a pointer from the meta data for a texture
54*61046927SAndroid Build Coastguard Worker     to the raw texture data), we have to tell the kernel about it so
55*61046927SAndroid Build Coastguard Worker     it can adjust the pointer to point to the final location. That
56*61046927SAndroid Build Coastguard Worker     means extra work we have to do extra work to record and annotate
57*61046927SAndroid Build Coastguard Worker     the dword location that holds the pointer. With bit fields, we'd
58*61046927SAndroid Build Coastguard Worker     have to call a function to do this, but with the pack function we
59*61046927SAndroid Build Coastguard Worker     generate code in the pack function to do this for us. That's a
60*61046927SAndroid Build Coastguard Worker     lot less error prone and less work.
61*61046927SAndroid Build Coastguard Worker
62*61046927SAndroid Build Coastguard WorkerKeeping genxml files tidy :
63*61046927SAndroid Build Coastguard Worker
64*61046927SAndroid Build Coastguard Worker   In order to spot differences easily between generations, we keep genxml files sorted.
65*61046927SAndroid Build Coastguard Worker   You can trigger the sort by running :
66*61046927SAndroid Build Coastguard Worker
67*61046927SAndroid Build Coastguard Worker      $ cd src/intel/genxml; ./gen_sort_tags.py
68*61046927SAndroid Build Coastguard Worker
69*61046927SAndroid Build Coastguard Worker   gen_sort_tags.py is the script that sorts genxml files using with
70*61046927SAndroid Build Coastguard Worker   the following rules :
71*61046927SAndroid Build Coastguard Worker
72*61046927SAndroid Build Coastguard Worker      1) Tags are grouped in the following order <enum>, <struct>,
73*61046927SAndroid Build Coastguard Worker         <instruction>, <register>
74*61046927SAndroid Build Coastguard Worker
75*61046927SAndroid Build Coastguard Worker      2) <field> tags are sorted through the value of their start attribute
76*61046927SAndroid Build Coastguard Worker
77*61046927SAndroid Build Coastguard Worker      3) Sort <struct> tags by dependency so that other scripts have
78*61046927SAndroid Build Coastguard Worker         everything properly ordered.
79