ilo: add image_get_gen6_layout()
authorChia-I Wu <olvaffe@gmail.com>
Mon, 29 Jun 2015 08:02:52 +0000 (16:02 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Wed, 1 Jul 2015 07:54:39 +0000 (15:54 +0800)
It replaces only img_init_walk() right now.  It will replace all img_init_*().

src/gallium/drivers/ilo/core/ilo_image.c

index 3209674154b1aa939a84cd4d856d681737d234cc..d4adffc181b6c4082b878afa9e5627dd32a721a2 100644 (file)
@@ -49,6 +49,102 @@ struct ilo_image_params {
    unsigned max_x, max_y;
 };
 
+struct ilo_image_layout {
+   enum ilo_image_walk_type walk;
+   bool interleaved_samples;
+};
+
+static enum ilo_image_walk_type
+image_get_gen6_walk(const struct ilo_dev *dev,
+                    const struct ilo_image_info *info)
+{
+   ILO_DEV_ASSERT(dev, 6, 6);
+
+   /* TODO we want LODs to be page-aligned */
+   if (info->type == GEN6_SURFTYPE_3D)
+      return ILO_IMAGE_WALK_3D;
+
+   /*
+    * From the Sandy Bridge PRM, volume 1 part 1, page 115:
+    *
+    *     "The separate stencil buffer does not support mip mapping, thus the
+    *      storage for LODs other than LOD 0 is not needed. The following
+    *      QPitch equation applies only to the separate stencil buffer:
+    *
+    *        QPitch = h_0"
+    *
+    * Use ILO_IMAGE_WALK_LOD and manually offset to the (page-aligned) levels
+    * when bound.
+    */
+   if (info->bind_zs && info->format == GEN6_FORMAT_R8_UINT)
+      return ILO_IMAGE_WALK_LOD;
+
+   /* compact spacing is not supported otherwise */
+   return ILO_IMAGE_WALK_LAYER;
+}
+
+static enum ilo_image_walk_type
+image_get_gen7_walk(const struct ilo_dev *dev,
+                    const struct ilo_image_info *info)
+{
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   if (info->type == GEN6_SURFTYPE_3D)
+      return ILO_IMAGE_WALK_3D;
+
+   /*
+    * From the Ivy Bridge PRM, volume 1 part 1, page 111:
+    *
+    *     "note that the depth buffer and stencil buffer have an implied value
+    *      of ARYSPC_FULL"
+    *
+    * From the Ivy Bridge PRM, volume 4 part 1, page 66:
+    *
+    *     "If Multisampled Surface Storage Format is MSFMT_MSS and Number of
+    *      Multisamples is not MULTISAMPLECOUNT_1, this field (Surface Array
+    *      Spacing) must be set to ARYSPC_LOD0."
+    */
+   if (info->sample_count > 1)
+      assert(info->level_count == 1);
+   return (info->bind_zs || info->level_count > 1) ?
+      ILO_IMAGE_WALK_LAYER : ILO_IMAGE_WALK_LOD;
+}
+
+static bool
+image_get_gen6_interleaved_samples(const struct ilo_dev *dev,
+                                   const struct ilo_image_info *info)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   /*
+    * Gen6 supports only interleaved samples.  It is not explicitly stated,
+    * but on Gen7+, render targets are expected to be UMS/CMS (samples
+    * non-interleaved) and depth/stencil buffers are expected to be IMS
+    * (samples interleaved).
+    *
+    * See "Multisampled Surface Storage Format" field of SURFACE_STATE.
+    */
+   return (ilo_dev_gen(dev) == ILO_GEN(6) || info->bind_zs);
+}
+
+static bool
+image_get_gen6_layout(const struct ilo_dev *dev,
+                      const struct ilo_image_info *info,
+                      struct ilo_image_layout *layout)
+{
+   ILO_DEV_ASSERT(dev, 6, 8);
+
+   if (ilo_dev_gen(dev) >= ILO_GEN(7))
+      layout->walk = image_get_gen7_walk(dev, info);
+   else
+      layout->walk = image_get_gen6_walk(dev, info);
+
+   layout->interleaved_samples =
+      image_get_gen6_interleaved_samples(dev, info);
+
+   return true;
+}
+
 static void
 img_get_slice_size(const struct ilo_image *img,
                    const struct ilo_image_params *params,
@@ -492,87 +588,6 @@ img_init_tiling(struct ilo_image *img,
       img->tiling = GEN6_TILING_NONE;
 }
 
-static void
-img_init_walk_gen7(struct ilo_image *img,
-                   const struct ilo_image_params *params)
-{
-   const struct ilo_image_info *info = params->info;
-
-   /*
-    * It is not explicitly states, but render targets are expected to be
-    * UMS/CMS (samples non-interleaved) and depth/stencil buffers are expected
-    * to be IMS (samples interleaved).
-    *
-    * See "Multisampled Surface Storage Format" field of SURFACE_STATE.
-    */
-   if (info->bind_zs) {
-      /*
-       * From the Ivy Bridge PRM, volume 1 part 1, page 111:
-       *
-       *     "note that the depth buffer and stencil buffer have an implied
-       *      value of ARYSPC_FULL"
-       */
-      img->walk = (info->type == GEN6_SURFTYPE_3D) ?
-         ILO_IMAGE_WALK_3D : ILO_IMAGE_WALK_LAYER;
-
-      img->interleaved_samples = true;
-   } else {
-      /*
-       * From the Ivy Bridge PRM, volume 4 part 1, page 66:
-       *
-       *     "If Multisampled Surface Storage Format is MSFMT_MSS and Number
-       *      of Multisamples is not MULTISAMPLECOUNT_1, this field (Surface
-       *      Array Spacing) must be set to ARYSPC_LOD0."
-       *
-       * As multisampled resources are not mipmapped, we never use
-       * ARYSPC_FULL for them.
-       */
-      if (info->sample_count > 1)
-         assert(info->level_count == 1);
-
-      img->walk =
-         (info->type == GEN6_SURFTYPE_3D) ? ILO_IMAGE_WALK_3D :
-         (info->level_count > 1) ? ILO_IMAGE_WALK_LAYER :
-         ILO_IMAGE_WALK_LOD;
-
-      img->interleaved_samples = false;
-   }
-}
-
-static void
-img_init_walk_gen6(struct ilo_image *img,
-                   const struct ilo_image_params *params)
-{
-   /*
-    * From the Sandy Bridge PRM, volume 1 part 1, page 115:
-    *
-    *     "The separate stencil buffer does not support mip mapping, thus the
-    *      storage for LODs other than LOD 0 is not needed. The following
-    *      QPitch equation applies only to the separate stencil buffer:
-    *
-    *        QPitch = h_0"
-    *
-    * GEN6 does not support compact spacing otherwise.
-    */
-   img->walk =
-      (params->info->type == GEN6_SURFTYPE_3D) ? ILO_IMAGE_WALK_3D :
-      (img->format == GEN6_FORMAT_R8_UINT) ? ILO_IMAGE_WALK_LOD :
-      ILO_IMAGE_WALK_LAYER;
-
-   /* GEN6 supports only interleaved samples */
-   img->interleaved_samples = true;
-}
-
-static void
-img_init_walk(struct ilo_image *img,
-              const struct ilo_image_params *params)
-{
-   if (ilo_dev_gen(params->dev) >= ILO_GEN(7))
-      img_init_walk_gen7(img, params);
-   else
-      img_init_walk_gen6(img, params);
-}
-
 static unsigned
 img_get_valid_tilings(const struct ilo_image *img,
                       const struct ilo_image_params *params)
@@ -1265,11 +1280,21 @@ static bool
 img_init(struct ilo_image *img,
          struct ilo_image_params *params)
 {
+   struct ilo_image_layout layout;
+
+   memset(&layout, 0, sizeof(layout));
+
+   if (!image_get_gen6_layout(params->dev, params->info, &layout))
+      return false;
+
    /* there are hard dependencies between every function here */
 
    img_init_size_and_format(img, params);
    img_init_aux(img, params);
-   img_init_walk(img, params);
+
+   img->walk = layout.walk;
+   img->interleaved_samples = layout.interleaved_samples;
+
    img_init_tiling(img, params);
    img_init_alignments(img, params);
    img_init_lods(img, params);