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