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