ilo: enable HiZ in more cases on GEN6
authorChia-I Wu <olvaffe@gmail.com>
Sun, 17 Aug 2014 06:13:35 +0000 (14:13 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Tue, 19 Aug 2014 11:53:37 +0000 (19:53 +0800)
With layer offsetting killed, we no longer need to restrict HiZ to
non-mipmapped and non-arary depth buffers.

src/gallium/drivers/ilo/ilo_gpe_gen6.c
src/gallium/drivers/ilo/ilo_layout.c
src/gallium/drivers/ilo/ilo_transfer.c

index 9c5c4c8cf34244c81e339ddd4fde40c3fa410379..c3ba9e371479ea8c7d4dbad7692d5bebe9a4e70b 100644 (file)
@@ -1075,6 +1075,7 @@ zs_init_info(const struct ilo_dev_info *dev,
       info->zs.bo = tex->bo;
       info->zs.stride = tex->layout.bo_stride;
       info->zs.tiling = tex->layout.tiling;
+      info->zs.offset = 0;
    }
 
    if (tex->separate_s8 || format == PIPE_FORMAT_S8_UINT) {
@@ -1095,12 +1096,27 @@ zs_init_info(const struct ilo_dev_info *dev,
       info->stencil.stride = s8_tex->layout.bo_stride * 2;
 
       info->stencil.tiling = s8_tex->layout.tiling;
+
+      if (dev->gen == ILO_GEN(6)) {
+         unsigned x, y;
+
+         assert(s8_tex->layout.walk == ILO_LAYOUT_WALK_LOD);
+
+         /* offset to the level */
+         ilo_layout_get_slice_pos(&s8_tex->layout, level, 0, &x, &y);
+         ilo_layout_pos_to_mem(&s8_tex->layout, x, y, &x, &y);
+         info->stencil.offset = ilo_layout_mem_to_raw(&s8_tex->layout, x, y);
+      }
    }
 
    if (ilo_texture_can_enable_hiz(tex, level, first_layer, num_layers)) {
       info->hiz.bo = tex->aux_bo;
       info->hiz.stride = tex->layout.aux_stride;
       info->hiz.tiling = INTEL_TILING_Y;
+
+      /* offset to the level */
+      if (dev->gen == ILO_GEN(6))
+         info->hiz.offset = tex->layout.aux_offsets[level];
    }
 
    info->width = tex->layout.width0;
index b6e958585a59a3af0bf5b16805956528a43d6e03..070ee21510730bc19021b4a4bffc76813e259918 100644 (file)
@@ -769,7 +769,6 @@ layout_want_hiz(const struct ilo_layout *layout,
    const struct pipe_resource *templ = params->templ;
    const struct util_format_description *desc =
       util_format_description(templ->format);
-   bool want_hiz = false;
 
    if (ilo_debug & ILO_DEBUG_NOHIZ)
       return false;
@@ -784,29 +783,19 @@ layout_want_hiz(const struct ilo_layout *layout,
    if (templ->usage == PIPE_USAGE_STAGING)
       return false;
 
-   if (params->dev->gen >= ILO_GEN(7)) {
-      want_hiz = true;
-   } else {
-      /*
-       * From the Sandy Bridge PRM, volume 2 part 1, page 312:
-       *
-       *     "The hierarchical depth buffer does not support the LOD field, it
-       *      is assumed by hardware to be zero. A separate hierarachical
-       *      depth buffer is required for each LOD used, and the
-       *      corresponding buffer's state delivered to hardware each time a
-       *      new depth buffer state with modified LOD is delivered."
-       *
-       * But we have a stronger requirement.  Because of layer offsetting
-       * (check out the callers of ilo_layout_get_slice_tile_offset()), we
-       * already have to require the texture to be non-mipmapped and
-       * non-array.
-       */
-      if (templ->last_level == 0 && templ->array_size == 1 &&
-          templ->depth0 == 1)
-         want_hiz = true;
-   }
+   /*
+    * As can be seen in layout_calculate_hiz_size(), HiZ may not be enabled
+    * for every level.  This is generally fine except on GEN6, where HiZ and
+    * separate stencil are enabled and disabled at the same time.  When the
+    * format is PIPE_FORMAT_Z32_FLOAT_S8X24_UINT, enabling and disabling HiZ
+    * can result in incompatible formats.
+    */
+   if (params->dev->gen == ILO_GEN(6) &&
+       templ->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT &&
+       templ->last_level)
+      return false;
 
-   return want_hiz;
+   return true;
 }
 
 static void
index d40dce8c541babc7506bb03399602f8f4df75b46..a38708d88a6b1ecd98128b3393673a165939a6f4 100644 (file)
  * correctly block when the resource is busy.
  */
 static bool
-resource_get_transfer_method(struct pipe_resource *res, unsigned usage,
+resource_get_transfer_method(struct pipe_resource *res,
+                             const struct pipe_transfer *transfer,
                              enum ilo_transfer_map_method *method)
 {
    const struct ilo_screen *is = ilo_screen(res->screen);
+   const unsigned usage = transfer->usage;
    enum ilo_transfer_map_method m;
    bool tiled;
 
@@ -89,15 +91,21 @@ resource_get_transfer_method(struct pipe_resource *res, unsigned usage,
    }
    else {
       struct ilo_texture *tex = ilo_texture(res);
-      bool need_convert = true;
+      bool need_convert = false;
 
       /* we may need to convert on the fly */
-      if (tex->separate_s8 || tex->layout.format == PIPE_FORMAT_S8_UINT)
-         m = ILO_TRANSFER_MAP_SW_ZS;
-      else if (tex->layout.format != tex->base.format)
+      if (tex->separate_s8 || tex->layout.format == PIPE_FORMAT_S8_UINT) {
+         /* on GEN6, separate stencil is enabled only when HiZ is */
+         if (is->dev.gen >= ILO_GEN(7) ||
+             ilo_texture_can_enable_hiz(tex, transfer->level,
+                transfer->box.z, transfer->box.depth)) {
+            m = ILO_TRANSFER_MAP_SW_ZS;
+            need_convert = true;
+         }
+      } else if (tex->layout.format != tex->base.format) {
          m = ILO_TRANSFER_MAP_SW_CONVERT;
-      else
-         need_convert = false;
+         need_convert = true;
+      }
 
       if (need_convert) {
          if (usage & (PIPE_TRANSFER_MAP_DIRECTLY | PIPE_TRANSFER_PERSISTENT))
@@ -1059,7 +1067,7 @@ choose_transfer_method(struct ilo_context *ilo, struct ilo_transfer *xfer)
    struct pipe_resource *res = xfer->base.resource;
    bool need_flush;
 
-   if (!resource_get_transfer_method(res, xfer->base.usage, &xfer->method))
+   if (!resource_get_transfer_method(res, &xfer->base, &xfer->method))
       return false;
 
    /* see if we can avoid blocking */