<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Jun 1, 2017 at 2:40 AM, Pohjolainen, Topi <span dir="ltr"><<a href="mailto:topi.pohjolainen@gmail.com" target="_blank">topi.pohjolainen@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Tue, May 30, 2017 at 05:55:17PM -0700, Jason Ekstrand wrote:<br>
> ---<br>
>  src/intel/isl/isl.c | 162 ++++++++++++++++++++++++++++++<wbr>++++++++++++++++++++--<br>
>  src/intel/isl/isl.h |  40 +++++++++++++<br>
>  2 files changed, 197 insertions(+), 5 deletions(-)<br>
><br>
> diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c<br>
> index 77b8a40..e4d7901 100644<br>
> --- a/src/intel/isl/isl.c<br>
> +++ b/src/intel/isl/isl.c<br>
> @@ -479,6 +479,12 @@ isl_choose_array_pitch_span(<wbr>const struct isl_device *dev,<br>
>         * compact QPitch possible in order to conserve memory.<br>
>         */<br>
>        return ISL_ARRAY_PITCH_SPAN_COMPACT;<br>
> +<br>
> +   case ISL_DIM_LAYOUT_GEN6_STENCIL_<wbr>HIZ:<br>
> +      /* Each array image in the gen6 stencil of HiZ surface is compact in the<br>
> +       * sense that every LOD is a compact array of the same size as LOD0.<br>
> +       */<br>
> +      return ISL_ARRAY_PITCH_SPAN_COMPACT;<br>
>     }<br>
><br>
>     unreachable("bad isl_dim_layout");<br>
> @@ -510,10 +516,15 @@ isl_choose_image_alignment_el(<wbr>const struct isl_device *dev,<br>
>        return;<br>
>     } else if (info->format == ISL_FORMAT_HIZ) {<br>
>        assert(ISL_DEV_GEN(dev) >= 6);<br>
> -      /* HiZ surfaces are always aligned to 16x8 pixels in the primary surface<br>
> -       * which works out to 2x2 HiZ elments.<br>
> -       */<br>
> -      *image_align_el = isl_extent3d(2, 2, 1);<br>
> +      if (ISL_DEV_GEN(dev) == 6) {<br>
> +         /* HiZ surfaces on Sandy Bridge are packed tightly. */<br>
> +         *image_align_el = isl_extent3d(1, 1, 1);<br>
> +      } else {<br>
> +         /* On gen7+, HiZ surfaces are always aligned to 16x8 pixels in the<br>
> +          * primary surface which works out to 2x2 HiZ elments.<br>
> +          */<br>
> +         *image_align_el = isl_extent3d(2, 2, 1);<br>
> +      }<br>
>        return;<br>
>     }<br>
><br>
> @@ -540,6 +551,11 @@ isl_surf_choose_dim_layout(<wbr>const struct isl_device *dev,<br>
>                             enum isl_surf_dim logical_dim,<br>
>                             enum isl_tiling tiling)<br>
>  {<br>
> +   /* Sandy bridge needs a special layout for HiZ and stencil. */<br>
> +   if (ISL_DEV_GEN(dev) == 6 &&<br>
> +       (tiling == ISL_TILING_W || tiling == ISL_TILING_HIZ))<br>
> +      return ISL_DIM_LAYOUT_GEN6_STENCIL_<wbr>HIZ;<br>
> +<br>
>     if (ISL_DEV_GEN(dev) >= 9) {<br>
>        switch (logical_dim) {<br>
>        case ISL_SURF_DIM_1D:<br>
> @@ -608,6 +624,7 @@ isl_calc_phys_level0_extent_<wbr>sa(const struct isl_device *dev,<br>
><br>
>        case ISL_DIM_LAYOUT_GEN9_1D:<br>
>        case ISL_DIM_LAYOUT_GEN4_2D:<br>
> +      case ISL_DIM_LAYOUT_GEN6_STENCIL_<wbr>HIZ:<br>
>           *phys_level0_sa = (struct isl_extent4d) {<br>
>              .w = isl_align_npot(info->width, fmtl->bw),<br>
>              .h = fmtl->bh,<br>
> @@ -619,7 +636,8 @@ isl_calc_phys_level0_extent_<wbr>sa(const struct isl_device *dev,<br>
>        break;<br>
><br>
>     case ISL_SURF_DIM_2D:<br>
> -      assert(dim_layout == ISL_DIM_LAYOUT_GEN4_2D);<br>
> +      assert(dim_layout == ISL_DIM_LAYOUT_GEN4_2D ||<br>
> +             dim_layout == ISL_DIM_LAYOUT_GEN6_STENCIL_<wbr>HIZ);<br>
><br>
>        if (tiling == ISL_TILING_Ys && info->samples > 1)<br>
>           isl_finishme("%s:%s: multisample TileYs layout", __FILE__, __func__);<br>
> @@ -684,6 +702,7 @@ isl_calc_phys_level0_extent_<wbr>sa(const struct isl_device *dev,<br>
><br>
>        switch (dim_layout) {<br>
>        case ISL_DIM_LAYOUT_GEN9_1D:<br>
> +      case ISL_DIM_LAYOUT_GEN6_STENCIL_<wbr>HIZ:<br>
>           unreachable("bad isl_dim_layout");<br>
><br>
>        case ISL_DIM_LAYOUT_GEN4_2D:<br>
> @@ -969,6 +988,67 @@ isl_calc_phys_total_extent_el_<wbr>gen4_3d(<br>
><br>
>  /**<br>
>   * A variant of isl_calc_phys_slice0_extent_<wbr>sa() specific to<br>
> + * ISL_DIM_LAYOUT_GEN6_STENCIL_<wbr>HIZ.<br>
> + */<br>
> +static void<br>
> +isl_calc_phys_total_extent_<wbr>el_gen6_stencil_hiz(<br>
> +      const struct isl_device *dev,<br>
> +      const struct isl_surf_init_info *restrict info,<br>
> +      const struct isl_tile_info *tile_info,<br>
> +      const struct isl_extent3d *image_align_sa,<br>
> +      const struct isl_extent4d *phys_level0_sa,<br>
> +      uint32_t *array_pitch_el_rows,<br>
> +      struct isl_extent2d *phys_total_el)<br>
> +{<br>
> +   const struct isl_format_layout *fmtl = isl_format_get_layout(info-><wbr>format);<br>
> +<br>
> +   const struct isl_extent2d tile_extent_sa = {<br>
> +      .w = tile_info->logical_extent_el.w * fmtl->bw,<br>
> +      .h = tile_info->logical_extent_el.h * fmtl->bh,<br>
> +   };<br>
> +   /* Tile size is a multiple of image alignment */<br>
> +   assert(tile_extent_sa.w % image_align_sa->w == 0);<br>
> +   assert(tile_extent_sa.h % image_align_sa->h == 0);<br>
> +<br>
> +   const uint32_t W0 = phys_level0_sa->w;<br>
> +   const uint32_t H0 = phys_level0_sa->h;<br>
> +<br>
> +   /* Each image has the same height as LOD0 because the hardware thinks<br>
> +    * everything is LOD0<br>
> +    */<br>
> +   const uint32_t H = isl_align(H0, image_align_sa->h) * phys_level0_sa->a;<br>
> +<br>
> +   uint32_t slice_top_w = 0;<br>
> +   uint32_t slice_bottom_w = 0;<br>
> +   uint32_t slice_h = 0;<br>
<br>
</div></div>I don't really understand why slice_bottom_w and slice_h are prefixed with<br>
slice, I would rather call them total_bottom_w and total_h.<br><div><div class="h5"></div></div></blockquote><div><br></div><div>Yeah, "total" is better.  "slice" was just a carry-over from my initial copy+paste of the gen4_2d code.  I'll fix it.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
> +<br>
> +   for (uint32_t l = 0; l < info->levels; ++l) {<br>
> +      const uint32_t W = isl_minify(W0, l);<br>
> +<br>
> +      const uint32_t w = isl_align(W, tile_extent_sa.w);<br>
> +      const uint32_t h = isl_align(H, tile_extent_sa.h);<br>
> +<br>
> +      if (l == 0) {<br>
> +         slice_top_w = w;<br>
> +         slice_h = h;<br>
> +      } else if (l == 1) {<br>
> +         slice_bottom_w = w;<br>
> +         slice_h += h;<br>
> +      } else {<br>
> +         slice_bottom_w += w;<br>
> +      }<br>
> +   }<br>
> +<br>
> +   *array_pitch_el_rows =<br>
> +      isl_assert_div(isl_align(H0, image_align_sa->h), fmtl->bh);<br>
> +   *phys_total_el = (struct isl_extent2d) {<br>
> +      .w = isl_assert_div(MAX(slice_top_<wbr>w, slice_bottom_w), fmtl->bw),<br>
> +      .h = isl_assert_div(slice_h, fmtl->bh),<br>
> +   };<br>
> +}<br>
> +<br>
> +/**<br>
> + * A variant of isl_calc_phys_slice0_extent_<wbr>sa() specific to<br>
>   * ISL_DIM_LAYOUT_GEN9_1D.<br>
>   */<br>
>  static void<br>
> @@ -1035,6 +1115,14 @@ isl_calc_phys_total_extent_el(<wbr>const struct isl_device *dev,<br>
>                                              array_pitch_el_rows,<br>
>                                              total_extent_el);<br>
>        return;<br>
> +   case ISL_DIM_LAYOUT_GEN6_STENCIL_<wbr>HIZ:<br>
> +      assert(array_pitch_span == ISL_ARRAY_PITCH_SPAN_COMPACT);<br>
> +      isl_calc_phys_total_extent_el_<wbr>gen6_stencil_hiz(dev, info, tile_info,<br>
> +                                                     image_align_sa,<br>
> +                                                     phys_level0_sa,<br>
> +                                                     array_pitch_el_rows,<br>
> +                                                     total_extent_el);<br>
> +      return;<br>
>     case ISL_DIM_LAYOUT_GEN4_3D:<br>
>        assert(array_pitch_span == ISL_ARRAY_PITCH_SPAN_COMPACT);<br>
>        isl_calc_phys_total_extent_el_<wbr>gen4_3d(dev, info,<br>
> @@ -1892,6 +1980,65 @@ get_image_offset_sa_gen4_3d(<wbr>const struct isl_surf *surf,<br>
>     *y_offset_sa = y;<br>
>  }<br>
><br>
> +static void<br>
> +get_image_offset_sa_gen6_<wbr>stencil_hiz(const struct isl_surf *surf,<br>
> +                                     uint32_t level,<br>
> +                                     uint32_t logical_array_layer,<br>
> +                                     uint32_t *x_offset_sa,<br>
> +                                     uint32_t *y_offset_sa)<br>
> +{<br>
> +   assert(level < surf->levels);<br>
> +   assert(surf->logical_level0_<wbr>px.depth == 1);<br>
> +   assert(logical_array_layer < surf->logical_level0_px.array_<wbr>len);<br>
> +<br>
> +   const struct isl_format_layout *fmtl = isl_format_get_layout(surf-><wbr>format);<br>
> +<br>
> +   const struct isl_extent3d image_align_sa =<br>
> +      isl_surf_get_image_alignment_<wbr>sa(surf);<br>
> +<br>
> +   struct isl_tile_info tile_info;<br>
> +   isl_tiling_get_info(surf-><wbr>tiling, fmtl->bpb, &tile_info);<br>
> +   const struct isl_extent2d tile_extent_sa = {<br>
> +      .w = tile_info.logical_extent_el.w * fmtl->bw,<br>
> +      .h = tile_info.logical_extent_el.h * fmtl->bh,<br>
> +   };<br>
> +   /* Tile size is a multiple of image alignment */<br>
> +   assert(tile_extent_sa.w % image_align_sa.w == 0);<br>
> +   assert(tile_extent_sa.h % image_align_sa.h == 0);<br>
> +<br>
> +   const uint32_t W0 = surf->phys_level0_sa.w;<br>
> +   const uint32_t H0 = surf->phys_level0_sa.h;<br>
> +<br>
> +   /* Each image has the same height as LOD0 because the hardware thinks<br>
> +    * everything is LOD0<br>
> +    */<br>
> +   const uint32_t H = isl_align(H0, image_align_sa.h);<br>
> +<br>
> +   /* Quick sanity check for consistency */<br>
> +   if (surf->phys_level0_sa.array_<wbr>len > 1)<br>
> +      assert(surf->array_pitch_el_<wbr>rows == isl_assert_div(H, fmtl->bh));<br>
> +<br>
> +   uint32_t x = 0, y = 0;<br>
> +   for (uint32_t l = 0; l < level; ++l) {<br>
> +      const uint32_t W = isl_minify(W0, l);<br>
> +<br>
> +      const uint32_t w = isl_align(W, tile_extent_sa.w);<br>
> +      const uint32_t h = isl_align(H * surf->phys_level0_sa.a,<br>
> +                                   tile_extent_sa.h);<br>
> +<br>
> +      if (l == 0) {<br>
> +         y += h;<br>
> +      } else {<br>
> +         x += w;<br>
<br>
</div></div>For "l == 1", "x" should still be zero?<br><div><div class="h5"></div></div></blockquote><div><br></div><div>Yes, that's correct.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
> +      }<br>
> +   }<br>
> +<br>
> +   y += H * logical_array_layer;<br>
> +<br>
> +   *x_offset_sa = x;<br>
> +   *y_offset_sa = y;<br>
> +}<br>
> +<br>
>  /**<br>
>   * A variant of isl_surf_get_image_offset_sa() specific to<br>
>   * ISL_DIM_LAYOUT_GEN9_1D.<br>
> @@ -1961,6 +2108,11 @@ isl_surf_get_image_offset_sa(<wbr>const struct isl_surf *surf,<br>
>                                    logical_z_offset_px,<br>
>                                    x_offset_sa, y_offset_sa);<br>
>        break;<br>
> +   case ISL_DIM_LAYOUT_GEN6_STENCIL_<wbr>HIZ:<br>
> +      get_image_offset_sa_gen6_<wbr>stencil_hiz(surf, level, logical_array_layer +<br>
> +                                           logical_z_offset_px,<br>
> +                                           x_offset_sa, y_offset_sa);<br>
> +      break;<br>
><br>
>     default:<br>
>        unreachable("not reached");<br>
> diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h<br>
> index 008ab5e..4bb3de7 100644<br>
> --- a/src/intel/isl/isl.h<br>
> +++ b/src/intel/isl/isl.h<br>
> @@ -528,6 +528,46 @@ enum isl_dim_layout {<br>
>     ISL_DIM_LAYOUT_GEN4_3D,<br>
><br>
>     /**<br>
> +    * Special layout used for HiZ and stencil on Sandy Bridge to work around<br>
> +    * the hardware's lack of mipmap support.  On gen6, HiZ and stencil buffers<br>
> +    * work the same as on gen7+ except that they don't technically support<br>
> +    * mipmapping.  That does not, however, stop us from doing it.  As far as<br>
> +    * Sandy Bridge hardware is concerned, HiZ and stencil always operates on a<br>
> +    * single miplevel 2D (possibly array) image.  The dimensions of that image<br>
> +    * are NOT minified.<br>
> +    *<br>
> +    * In order to implement HiZ and stencil on Sandy Bridge, we create one<br>
> +    * full-sized 2D (possibly array) image for every LOD with every image<br>
> +    * aligned to a page boundary.  When the surface is used with the stencil<br>
> +    * or HiZ hardware, we manually offset to the image for the given LOD.<br>
> +    *<br>
> +    * As a memory saving measure,  we pretend that the width of each miplevel<br>
> +    * is minified and we place LOD1 and above below LOD0 but horizontally<br>
> +    * adjacent to each other.  When considered as full-sized images, LOD1 and<br>
> +    * above technically overlap.  However, since we only write to part of that<br>
> +    * image, the hardware will never notice the overlap.<br>
> +    *<br>
> +    * This layout looks something like this:<br>
> +    *<br>
> +    *   +---------+<br>
> +    *   |         |<br>
> +    *   |         |<br>
> +    *   +---------+<br>
> +    *   |         |<br>
> +    *   |         |<br>
> +    *   +---------+<br>
> +    *<br>
> +    *   +----+ +-+ .<br>
> +    *   |    | +-+<br>
> +    *   +----+<br>
> +    *<br>
> +    *   +----+ +-+ .<br>
> +    *   |    | +-+<br>
> +    *   +----+<br>
> +    */<br>
> +   ISL_DIM_LAYOUT_GEN6_STENCIL_<wbr>HIZ,<br>
> +<br>
> +   /**<br>
>      * For details, see the Skylake BSpec >> Memory Views >> Common Surface<br>
>      * Formats >> Surface Layout and Tiling >> » 1D Surfaces.<br>
>      */<br>
> --<br>
> 2.5.0.400.gff86faf<br>
><br>
</div></div>> ______________________________<wbr>_________________<br>
> mesa-dev mailing list<br>
> <a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> <a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</blockquote></div><br></div></div>