1*61046927SAndroid Build Coastguard WorkerUnits 2*61046927SAndroid Build Coastguard Worker===== 3*61046927SAndroid Build Coastguard Worker 4*61046927SAndroid Build Coastguard WorkerAlmost every variable, function parameter, or struct field in ISL that carries 5*61046927SAndroid Build Coastguard Workera numeric value has explicit units associated with it. The units used in ISL 6*61046927SAndroid Build Coastguard Workerare as follows: 7*61046927SAndroid Build Coastguard Worker 8*61046927SAndroid Build Coastguard Worker * Pixels (*px*) 9*61046927SAndroid Build Coastguard Worker * Samples (*sa*) 10*61046927SAndroid Build Coastguard Worker * Elements (*el*) 11*61046927SAndroid Build Coastguard Worker * Tiles (*tl*) 12*61046927SAndroid Build Coastguard Worker * Bytes (*B*) 13*61046927SAndroid Build Coastguard Worker * Rows of some other unit size (*<unit>_rows*) 14*61046927SAndroid Build Coastguard Worker 15*61046927SAndroid Build Coastguard WorkerThese units are fundamental to ISL because they allow us to specify information 16*61046927SAndroid Build Coastguard Workerabout a surface in a canonical way that isn't dependent on hardware generation. 17*61046927SAndroid Build Coastguard WorkerEach field in an ISL data structure that stores any sort of dimension has a 18*61046927SAndroid Build Coastguard Workersuffix that declares the units for that particular value: ``_el`` for elements, 19*61046927SAndroid Build Coastguard Worker``_sa`` for samples, etc. If the units of the particular field aren't quite 20*61046927SAndroid Build Coastguard Workerwhat is wanted by the hardware, we do the conversion when we emit 21*61046927SAndroid Build Coastguard Worker``RENDER_SURFACE_STATE``. 22*61046927SAndroid Build Coastguard Worker 23*61046927SAndroid Build Coastguard WorkerThis is one of the primary differences between ISL and the old miptree code and 24*61046927SAndroid Build Coastguard Workerone of the core design principles of ISL. In the old miptree code, we tried to 25*61046927SAndroid Build Coastguard Workerkeep everything in the same units as the hardware expects but this lead to 26*61046927SAndroid Build Coastguard Workerunnecessary complications as the hardware evolved. One example of this 27*61046927SAndroid Build Coastguard Workerdifference is QPitch which specifies the distance between array slices. On 28*61046927SAndroid Build Coastguard WorkerBroadwell and earlier, QPitch field in ``RENDER_SURFACE_STATE`` was in 29*61046927SAndroid Build Coastguard Workerrows of samples. For block-compressed images, this meant it had to be 30*61046927SAndroid Build Coastguard Workera multiple of the block height. On Skylake, it changed to always being in rows 31*61046927SAndroid Build Coastguard Workerof elements so you have to divide the pitch in samples by the compression 32*61046927SAndroid Build Coastguard Workerblock height. Since the old surface state code tries to store things in 33*61046927SAndroid Build Coastguard Workerhardware units, everyone who ever reads ``brw_mipmap_tree.qpitch`` has 34*61046927SAndroid Build Coastguard Workerto change their interpretation based on hardware generation and whether or not 35*61046927SAndroid Build Coastguard Workerthe surface was block-compressed. In ISL, we have 36*61046927SAndroid Build Coastguard Worker:c:member:`isl_surf.array_pitch_el_rows` which, as the name says, is in rows 37*61046927SAndroid Build Coastguard Workerof elements. On Broadwell and earlier, we have to multiply by the block size 38*61046927SAndroid Build Coastguard Workerof the texture when we finally fill out the hardware packet. However, the 39*61046927SAndroid Build Coastguard Workerconsistency of always being in rows of elements makes any other users of the 40*61046927SAndroid Build Coastguard Workerfield much simpler because they never have to look at hardware generation or 41*61046927SAndroid Build Coastguard Workerwhether or not the image is block-compressed. 42*61046927SAndroid Build Coastguard Worker 43*61046927SAndroid Build Coastguard Worker**Pixels** are the most straightforward unit and are where everything starts. A 44*61046927SAndroid Build Coastguard Workerpixel simply corresponds to a single pixel (or texel if you prefer) in the 45*61046927SAndroid Build Coastguard Workersurface. For multisampled surfaces, a pixel may contain one or more samples. 46*61046927SAndroid Build Coastguard WorkerFor compressed textures, a compression block may contain one or more pixels. 47*61046927SAndroid Build Coastguard WorkerWhen initially creating a surface, everything passed to isl_surf_init is 48*61046927SAndroid Build Coastguard Workerimplicitly in terms of pixels because this is what all of the APIs use. 49*61046927SAndroid Build Coastguard Worker 50*61046927SAndroid Build Coastguard WorkerThe next unit in ISL's repertoire is **samples**. In a multisampled surface, 51*61046927SAndroid Build Coastguard Workereach pixel corresponds to some number of samples given by 52*61046927SAndroid Build Coastguard Worker:c:member:`isl_surf.samples`. The exact layout of the samples depends on 53*61046927SAndroid Build Coastguard Workerthe value of :c:member:`isl_surf.msaa_layout`. If the layout is 54*61046927SAndroid Build Coastguard Worker:c:enumerator:`isl_msaa_layout.ISL_MSAA_LAYOUT_ARRAY` then each logical array in 55*61046927SAndroid Build Coastguard Workerthe surface corresponds to :c:member:`isl_surf.samples` actual slices 56*61046927SAndroid Build Coastguard Workerin the resulting surface, one per array slice. If the layout is 57*61046927SAndroid Build Coastguard Worker:c:enumerator:`isl_msaa_layout.ISL_MSAA_LAYOUT_INTERLEAVED` then each pixel corresponds 58*61046927SAndroid Build Coastguard Workerto a 2x1, 2x2, 4x2, or 4x4 grid of samples. In order to aid in calculations, one of 59*61046927SAndroid Build Coastguard Workerthe first things ISL does is to compute :c:member:`isl_surf.phys_level0_sa` 60*61046927SAndroid Build Coastguard Workerwhich gives the dimensions of the base miplevel of the surface in samples. The 61*61046927SAndroid Build Coastguard Workertype of :c:member:`isl_surf.phys_level0_sa` is :c:struct:`isl_extent4d` 62*61046927SAndroid Build Coastguard Workerwhich allows us to express both the array and interleaved cases. Most of the 63*61046927SAndroid Build Coastguard Workercalculations of how the different miplevels and array slices are laid out is 64*61046927SAndroid Build Coastguard Workerdone in terms of samples. 65*61046927SAndroid Build Coastguard Worker 66*61046927SAndroid Build Coastguard WorkerNext, we have surface **elements**. An element is the basic unit of actual 67*61046927SAndroid Build Coastguard Workersurface memory. For multisampled textures, an element is equal to a single 68*61046927SAndroid Build Coastguard Workersample. For block compressed textures, an element corresponds to an entire 69*61046927SAndroid Build Coastguard Workercompression block. The conversion from samples to elements is given by dividing 70*61046927SAndroid Build Coastguard Workerby the block width and block height of the surface format. This is true 71*61046927SAndroid Build Coastguard Workerregardless of whether or not the surface is multisampled; for multisampled 72*61046927SAndroid Build Coastguard Workercompressed textures (these exist for certain auxiliary formats), the block 73*61046927SAndroid Build Coastguard Workerwidth and block height are expressed in samples. Pixels cannot be converted 74*61046927SAndroid Build Coastguard Workerdirectly to elements or vice versa; any conversion between pixels and elements 75*61046927SAndroid Build Coastguard Worker*must* go through samples. 76*61046927SAndroid Build Coastguard Worker 77*61046927SAndroid Build Coastguard WorkerThe final surface unit is **tiles**. A tile is a large rectangular block of 78*61046927SAndroid Build Coastguard Workersurface data that all fits in a single contiguous block of memory (usually a 4K 79*61046927SAndroid Build Coastguard Workeror 64K page, depending on tile format). Tiles are used to provide an 80*61046927SAndroid Build Coastguard Workerarrangement of the data in memory that yields better cache performance. The 81*61046927SAndroid Build Coastguard Workersize of a tile is always specified in surface elements. 82