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