17ec681f3SmrgHierarchical Depth (HiZ) 27ec681f3Smrg======================== 37ec681f3Smrg 47ec681f3SmrgTODO: Add detailed docs like we have for CCS 57ec681f3Smrg 67ec681f3SmrgHiZ/stencil on Sandy Bridge 77ec681f3Smrg--------------------------- 87ec681f3Smrg 97ec681f3SmrgProperly enabling HiZ on Sandy Bridge requires certain special considerations. 107ec681f3SmrgFrom the Sandy Bridge PRM Vol. 2, Pt. 1, 7.5.3 "Hierarchical Depth Buffer" (p. 117ec681f3Smrg312): 127ec681f3Smrg 137ec681f3Smrg The hierarchical depth buffer does not support the LOD field, it is assumed 147ec681f3Smrg by hardware to be zero. A separate hierarachical depth buffer is required 157ec681f3Smrg for each LOD used, and the corresponding buffer’s state delivered to 167ec681f3Smrg hardware each time a new depth buffer state with modified LOD is delivered. 177ec681f3Smrg 187ec681f3SmrgThe ``3DSTATE_STENCIL_BUFFER`` packet for separate stencil (required for HiZ) 197ec681f3Smrgon sandy bridge also lacks an LOD field. Empirically, the hardware doesn't 207ec681f3Smrgpull the stencil LOD from ``3DSTATE_DEPTH_BUFFER``, it's just always 0 like 217ec681f3Smrgwith HiZ. 227ec681f3Smrg 237ec681f3SmrgAs stated in the PRM, this means we need a separate HiZ or stencil buffer for 247ec681f3Smrgeach LOD. However, it's not quite as simple as that. If you ignore layered 257ec681f3Smrgrendering, things are pretty straightforward: you need one HiZ surface for each 267ec681f3Smrgmain surface slice With layered, rendering, however, we have to be a bit more 277ec681f3Smrgclever because we need a "real" array surface at each LOD. ISL solves this 287ec681f3Smrgwith a special miptree layout for layered rendering 297ec681f3Smrg:cpp:enumerator:`isl_dim_layout::ISL_DIM_LAYOUT_GFX6_STENCIL_HIZ` which lays 307ec681f3Smrgout the surface as a miptree of layered images instead of an array of miptrees. 317ec681f3SmrgSee the docs for 327ec681f3Smrg:cpp:enumerator:`isl_dim_layout::ISL_DIM_LAYOUT_GFX6_STENCIL_HIZ` for a nice 337ec681f3Smrgdescription along with an ASCII art diagram of the layout. 347ec681f3Smrg 357ec681f3SmrgAlso, neither ``3DSTATE_STENCIL_BUFFER`` nor ``3DSTATE_HIER_DEPTH_BUFFER`` have 367ec681f3Smrgtheir own surface dimensions or layout information on Sandy Bridge. They're 377ec681f3Smrgjust an address and a surface pitch. Instead, all that other information is 387ec681f3Smrgpulled from ``3DSTATE_DEPTH_BUFFER``. When you combine this with the lack of 397ec681f3SmrgLOD, this means that, technically, we have a full-sized single-LOD stencil or 407ec681f3SmrgHiZ surface at each miplevel of which only the upper left-hand corner of each 417ec681f3Smrgarray slice ever gets used. The net effect of this is that, in 427ec681f3Smrg:cpp:enumerator:`isl_dim_layout::ISL_DIM_LAYOUT_GFX6_STENCIL_HIZ`, all LODs 437ec681f3Smrgshare the same QPitch even though it's horribly wasteful. This is actually 447ec681f3Smrgpretty convenient for ISL because we only have the one 457ec681f3Smrg:cpp:member:`isl_surf::array_pitch_el_rows` field. 467ec681f3Smrg 477ec681f3SmrgDue to difficulties with plumbing relocation deltas through ISL's 487ec681f3Smrgdepth/stencil/hiz emit interface, we can't handle this all automatically in 497ec681f3SmrgISL. Instead, it's left up to the driver to do this offsetting. ISL does 507ec681f3Smrgprovide helpers for computing the offsets and they work fine with 517ec681f3Smrg:cpp:enumerator:`isl_dim_layout::ISL_DIM_LAYOUT_GFX6_STENCIL_HIZ` so all that's 527ec681f3Smrgreally required is to call the ISL helper and add the computed offset to the 537ec681f3SmrgHiZ or stencil buffer address. The following is an excerpt from BLORP where we 547ec681f3Smrgdo this as an example: 557ec681f3Smrg 567ec681f3Smrg.. code-block:: c 577ec681f3Smrg 587ec681f3Smrg struct blorp_address hiz_address = params->depth.aux_addr; 597ec681f3Smrg #if GFX_VER == 6 607ec681f3Smrg /* Sandy bridge hardware does not technically support mipmapped HiZ. 617ec681f3Smrg * However, we have a special layout that allows us to make it work 627ec681f3Smrg * anyway by manually offsetting to the specified miplevel. 637ec681f3Smrg */ 647ec681f3Smrg assert(info.hiz_surf->dim_layout == ISL_DIM_LAYOUT_GFX6_STENCIL_HIZ); 657ec681f3Smrg uint32_t offset_B; 667ec681f3Smrg isl_surf_get_image_offset_B_tile_sa(info.hiz_surf, 677ec681f3Smrg info.view->base_level, 0, 0, 687ec681f3Smrg &offset_B, NULL, NULL); 697ec681f3Smrg hiz_address.offset += offset_B; 707ec681f3Smrg #endif 717ec681f3Smrg 727ec681f3Smrg info.hiz_address = 737ec681f3Smrg blorp_emit_reloc(batch, dw + isl_dev->ds.hiz_offset / 4, 747ec681f3Smrg hiz_address, 0); 75