1Hierarchical Depth (HiZ) 2======================== 3 4TODO: Add detailed docs like we have for CCS 5 6HiZ/stencil on Sandy Bridge 7--------------------------- 8 9Properly enabling HiZ on Sandy Bridge requires certain special considerations. 10From the Sandy Bridge PRM Vol. 2, Pt. 1, 7.5.3 "Hierarchical Depth Buffer" (p. 11312): 12 13 The hierarchical depth buffer does not support the LOD field, it is assumed 14 by hardware to be zero. A separate hierarachical depth buffer is required 15 for each LOD used, and the corresponding buffer’s state delivered to 16 hardware each time a new depth buffer state with modified LOD is delivered. 17 18The ``3DSTATE_STENCIL_BUFFER`` packet for separate stencil (required for HiZ) 19on sandy bridge also lacks an LOD field. Empirically, the hardware doesn't 20pull the stencil LOD from ``3DSTATE_DEPTH_BUFFER``, it's just always 0 like 21with HiZ. 22 23As stated in the PRM, this means we need a separate HiZ or stencil buffer for 24each LOD. However, it's not quite as simple as that. If you ignore layered 25rendering, things are pretty straightforward: you need one HiZ surface for each 26main surface slice With layered, rendering, however, we have to be a bit more 27clever because we need a "real" array surface at each LOD. ISL solves this 28with a special miptree layout for layered rendering 29:cpp:enumerator:`isl_dim_layout::ISL_DIM_LAYOUT_GFX6_STENCIL_HIZ` which lays 30out the surface as a miptree of layered images instead of an array of miptrees. 31See the docs for 32:cpp:enumerator:`isl_dim_layout::ISL_DIM_LAYOUT_GFX6_STENCIL_HIZ` for a nice 33description along with an ASCII art diagram of the layout. 34 35Also, neither ``3DSTATE_STENCIL_BUFFER`` nor ``3DSTATE_HIER_DEPTH_BUFFER`` have 36their own surface dimensions or layout information on Sandy Bridge. They're 37just an address and a surface pitch. Instead, all that other information is 38pulled from ``3DSTATE_DEPTH_BUFFER``. When you combine this with the lack of 39LOD, this means that, technically, we have a full-sized single-LOD stencil or 40HiZ surface at each miplevel of which only the upper left-hand corner of each 41array slice ever gets used. The net effect of this is that, in 42:cpp:enumerator:`isl_dim_layout::ISL_DIM_LAYOUT_GFX6_STENCIL_HIZ`, all LODs 43share the same QPitch even though it's horribly wasteful. This is actually 44pretty convenient for ISL because we only have the one 45:cpp:member:`isl_surf::array_pitch_el_rows` field. 46 47Due to difficulties with plumbing relocation deltas through ISL's 48depth/stencil/hiz emit interface, we can't handle this all automatically in 49ISL. Instead, it's left up to the driver to do this offsetting. ISL does 50provide helpers for computing the offsets and they work fine with 51:cpp:enumerator:`isl_dim_layout::ISL_DIM_LAYOUT_GFX6_STENCIL_HIZ` so all that's 52really required is to call the ISL helper and add the computed offset to the 53HiZ or stencil buffer address. The following is an excerpt from BLORP where we 54do this as an example: 55 56.. code-block:: c 57 58 struct blorp_address hiz_address = params->depth.aux_addr; 59 #if GFX_VER == 6 60 /* Sandy bridge hardware does not technically support mipmapped HiZ. 61 * However, we have a special layout that allows us to make it work 62 * anyway by manually offsetting to the specified miplevel. 63 */ 64 assert(info.hiz_surf->dim_layout == ISL_DIM_LAYOUT_GFX6_STENCIL_HIZ); 65 uint32_t offset_B; 66 isl_surf_get_image_offset_B_tile_sa(info.hiz_surf, 67 info.view->base_level, 0, 0, 68 &offset_B, NULL, NULL); 69 hiz_address.offset += offset_B; 70 #endif 71 72 info.hiz_address = 73 blorp_emit_reloc(batch, dw + isl_dev->ds.hiz_offset / 4, 74 hiz_address, 0); 75