ilo: add image_get_gen{6,7}_alignment()
authorChia-I Wu <olvaffe@gmail.com>
Mon, 29 Jun 2015 08:16:11 +0000 (16:16 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Wed, 1 Jul 2015 07:54:39 +0000 (15:54 +0800)
They replace img_init_alignments().

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

index c22c11974ea39f31561d202667f904cf7997d33c..d28cb075fb5b813dd52b4252ef324719d9326be2 100644 (file)
@@ -57,6 +57,9 @@ struct ilo_image_layout {
    enum gen_surface_tiling tiling;
 
    enum ilo_image_aux_type aux;
+
+   int align_i;
+   int align_j;
 };
 
 static enum ilo_image_walk_type
@@ -382,6 +385,154 @@ image_get_gen7_mcs_enable(const struct ilo_dev *dev,
    }
 }
 
+static void
+image_get_gen6_alignments(const struct ilo_dev *dev,
+                          const struct ilo_image_info *info,
+                          int *align_i, int *align_j)
+{
+   ILO_DEV_ASSERT(dev, 6, 6);
+
+   /*
+    * From the Sandy Bridge PRM, volume 1 part 1, page 113:
+    *
+    *     "surface format           align_i     align_j
+    *      YUV 4:2:2 formats        4           *see below
+    *      BC1-5                    4           4
+    *      FXT1                     8           4
+    *      all other formats        4           *see below"
+    *
+    *     "- align_j = 4 for any depth buffer
+    *      - align_j = 2 for separate stencil buffer
+    *      - align_j = 4 for any render target surface is multisampled (4x)
+    *      - align_j = 4 for any render target surface with Surface Vertical
+    *        Alignment = VALIGN_4
+    *      - align_j = 2 for any render target surface with Surface Vertical
+    *        Alignment = VALIGN_2
+    *      - align_j = 2 for all other render target surface
+    *      - align_j = 2 for any sampling engine surface with Surface Vertical
+    *        Alignment = VALIGN_2
+    *      - align_j = 4 for any sampling engine surface with Surface Vertical
+    *        Alignment = VALIGN_4"
+    *
+    * From the Sandy Bridge PRM, volume 4 part 1, page 86:
+    *
+    *     "This field (Surface Vertical Alignment) must be set to VALIGN_2 if
+    *      the Surface Format is 96 bits per element (BPE)."
+    *
+    * They can be rephrased as
+    *
+    *                                  align_i        align_j
+    *   compressed formats             block width    block height
+    *   GEN6_FORMAT_R8_UINT            4              2
+    *   other depth/stencil formats    4              4
+    *   4x multisampled                4              4
+    *   bpp 96                         4              2
+    *   others                         4              2 or 4
+    */
+
+   *align_i = (info->compressed) ? info->block_width : 4;
+   if (info->compressed) {
+      *align_j = info->block_height;
+   } else if (info->bind_zs) {
+      *align_j = (info->format == GEN6_FORMAT_R8_UINT) ? 2 : 4;
+   } else {
+      *align_j = (info->sample_count > 1 || info->block_size != 12) ? 4 : 2;
+   }
+}
+
+static void
+image_get_gen7_alignments(const struct ilo_dev *dev,
+                          const struct ilo_image_info *info,
+                          enum gen_surface_tiling tiling,
+                          int *align_i, int *align_j)
+{
+   int i, j;
+
+   ILO_DEV_ASSERT(dev, 7, 8);
+
+   /*
+    * From the Ivy Bridge PRM, volume 1 part 1, page 110:
+    *
+    *     "surface defined by      surface format     align_i     align_j
+    *      3DSTATE_DEPTH_BUFFER    D16_UNORM          8           4
+    *                              not D16_UNORM      4           4
+    *      3DSTATE_STENCIL_BUFFER  N/A                8           8
+    *      SURFACE_STATE           BC*, ETC*, EAC*    4           4
+    *                              FXT1               8           4
+    *                              all others         (set by SURFACE_STATE)"
+    *
+    * From the Ivy Bridge PRM, volume 4 part 1, page 63:
+    *
+    *     "- This field (Surface Vertical Aligment) is intended to be set to
+    *        VALIGN_4 if the surface was rendered as a depth buffer, for a
+    *        multisampled (4x) render target, or for a multisampled (8x)
+    *        render target, since these surfaces support only alignment of 4.
+    *      - Use of VALIGN_4 for other surfaces is supported, but uses more
+    *        memory.
+    *      - This field must be set to VALIGN_4 for all tiled Y Render Target
+    *        surfaces.
+    *      - Value of 1 is not supported for format YCRCB_NORMAL (0x182),
+    *        YCRCB_SWAPUVY (0x183), YCRCB_SWAPUV (0x18f), YCRCB_SWAPY (0x190)
+    *      - If Number of Multisamples is not MULTISAMPLECOUNT_1, this field
+    *        must be set to VALIGN_4."
+    *      - VALIGN_4 is not supported for surface format R32G32B32_FLOAT."
+    *
+    *     "- This field (Surface Horizontal Aligment) is intended to be set to
+    *        HALIGN_8 only if the surface was rendered as a depth buffer with
+    *        Z16 format or a stencil buffer, since these surfaces support only
+    *        alignment of 8.
+    *      - Use of HALIGN_8 for other surfaces is supported, but uses more
+    *        memory.
+    *      - This field must be set to HALIGN_4 if the Surface Format is BC*.
+    *      - This field must be set to HALIGN_8 if the Surface Format is
+    *        FXT1."
+    *
+    * They can be rephrased as
+    *
+    *                                  align_i        align_j
+    *  compressed formats              block width    block height
+    *  GEN6_FORMAT_R16_UNORM           8              4
+    *  GEN6_FORMAT_R8_UINT             8              8
+    *  other depth/stencil formats     4              4
+    *  2x or 4x multisampled           4 or 8         4
+    *  tiled Y                         4 or 8         4 (if rt)
+    *  GEN6_FORMAT_R32G32B32_FLOAT     4 or 8         2
+    *  others                          4 or 8         2 or 4
+    */
+   if (info->compressed) {
+      i = info->block_width;
+      j = info->block_height;
+   } else if (info->bind_zs) {
+      switch (info->format) {
+      case GEN6_FORMAT_R16_UNORM:
+         i = 8;
+         j = 4;
+         break;
+      case GEN6_FORMAT_R8_UINT:
+         i = 8;
+         j = 8;
+         break;
+      default:
+         i = 4;
+         j = 4;
+         break;
+      }
+   } else {
+      const bool valign_4 =
+         (info->sample_count > 1 || ilo_dev_gen(dev) >= ILO_GEN(8) ||
+          (tiling == GEN6_TILING_Y && info->bind_surface_dp_render));
+
+      if (ilo_dev_gen(dev) < ILO_GEN(8) && valign_4)
+         assert(info->format != GEN6_FORMAT_R32G32B32_FLOAT);
+
+      i = 4;
+      j = (valign_4) ? 4 : 2;
+   }
+
+   *align_i = i;
+   *align_j = j;
+}
+
 static bool
 image_get_gen6_layout(const struct ilo_dev *dev,
                       const struct ilo_image_info *info,
@@ -411,6 +562,29 @@ image_get_gen6_layout(const struct ilo_dev *dev,
    else
       layout->aux = ILO_IMAGE_AUX_NONE;
 
+   if (ilo_dev_gen(dev) >= ILO_GEN(7)) {
+      image_get_gen7_alignments(dev, info, layout->tiling,
+            &layout->align_i, &layout->align_j);
+   } else {
+      image_get_gen6_alignments(dev, info,
+            &layout->align_i, &layout->align_j);
+   }
+
+   /*
+    * the fact that align i and j are multiples of block width and height
+    * respectively is what makes the size of the bo a multiple of the block
+    * size, slices start at block boundaries, and many of the computations
+    * work.
+    */
+   assert(layout->align_i % info->block_width == 0);
+   assert(layout->align_j % info->block_height == 0);
+
+   /* make sure align() works */
+   assert(util_is_power_of_two(layout->align_i) &&
+          util_is_power_of_two(layout->align_j));
+   assert(util_is_power_of_two(info->block_width) &&
+          util_is_power_of_two(info->block_height));
+
    return true;
 }
 
@@ -660,164 +834,6 @@ img_init_lods(struct ilo_image *img,
    }
 }
 
-static void
-img_init_alignments(struct ilo_image *img,
-                    const struct ilo_image_params *params)
-{
-   const struct ilo_image_info *info = params->info;
-
-   /*
-    * From the Sandy Bridge PRM, volume 1 part 1, page 113:
-    *
-    *     "surface format           align_i     align_j
-    *      YUV 4:2:2 formats        4           *see below
-    *      BC1-5                    4           4
-    *      FXT1                     8           4
-    *      all other formats        4           *see below"
-    *
-    *     "- align_j = 4 for any depth buffer
-    *      - align_j = 2 for separate stencil buffer
-    *      - align_j = 4 for any render target surface is multisampled (4x)
-    *      - align_j = 4 for any render target surface with Surface Vertical
-    *        Alignment = VALIGN_4
-    *      - align_j = 2 for any render target surface with Surface Vertical
-    *        Alignment = VALIGN_2
-    *      - align_j = 2 for all other render target surface
-    *      - align_j = 2 for any sampling engine surface with Surface Vertical
-    *        Alignment = VALIGN_2
-    *      - align_j = 4 for any sampling engine surface with Surface Vertical
-    *        Alignment = VALIGN_4"
-    *
-    * From the Sandy Bridge PRM, volume 4 part 1, page 86:
-    *
-    *     "This field (Surface Vertical Alignment) must be set to VALIGN_2 if
-    *      the Surface Format is 96 bits per element (BPE)."
-    *
-    * They can be rephrased as
-    *
-    *                                  align_i        align_j
-    *   compressed formats             block width    block height
-    *   GEN6_FORMAT_R8_UINT            4              2
-    *   other depth/stencil formats    4              4
-    *   4x multisampled                4              4
-    *   bpp 96                         4              2
-    *   others                         4              2 or 4
-    */
-
-   /*
-    * From the Ivy Bridge PRM, volume 1 part 1, page 110:
-    *
-    *     "surface defined by      surface format     align_i     align_j
-    *      3DSTATE_DEPTH_BUFFER    D16_UNORM          8           4
-    *                              not D16_UNORM      4           4
-    *      3DSTATE_STENCIL_BUFFER  N/A                8           8
-    *      SURFACE_STATE           BC*, ETC*, EAC*    4           4
-    *                              FXT1               8           4
-    *                              all others         (set by SURFACE_STATE)"
-    *
-    * From the Ivy Bridge PRM, volume 4 part 1, page 63:
-    *
-    *     "- This field (Surface Vertical Aligment) is intended to be set to
-    *        VALIGN_4 if the surface was rendered as a depth buffer, for a
-    *        multisampled (4x) render target, or for a multisampled (8x)
-    *        render target, since these surfaces support only alignment of 4.
-    *      - Use of VALIGN_4 for other surfaces is supported, but uses more
-    *        memory.
-    *      - This field must be set to VALIGN_4 for all tiled Y Render Target
-    *        surfaces.
-    *      - Value of 1 is not supported for format YCRCB_NORMAL (0x182),
-    *        YCRCB_SWAPUVY (0x183), YCRCB_SWAPUV (0x18f), YCRCB_SWAPY (0x190)
-    *      - If Number of Multisamples is not MULTISAMPLECOUNT_1, this field
-    *        must be set to VALIGN_4."
-    *      - VALIGN_4 is not supported for surface format R32G32B32_FLOAT."
-    *
-    *     "- This field (Surface Horizontal Aligment) is intended to be set to
-    *        HALIGN_8 only if the surface was rendered as a depth buffer with
-    *        Z16 format or a stencil buffer, since these surfaces support only
-    *        alignment of 8.
-    *      - Use of HALIGN_8 for other surfaces is supported, but uses more
-    *        memory.
-    *      - This field must be set to HALIGN_4 if the Surface Format is BC*.
-    *      - This field must be set to HALIGN_8 if the Surface Format is
-    *        FXT1."
-    *
-    * They can be rephrased as
-    *
-    *                                  align_i        align_j
-    *  compressed formats              block width    block height
-    *  GEN6_FORMAT_R16_UNORM           8              4
-    *  GEN6_FORMAT_R8_UINT             8              8
-    *  other depth/stencil formats     4              4
-    *  2x or 4x multisampled           4 or 8         4
-    *  tiled Y                         4 or 8         4 (if rt)
-    *  GEN6_FORMAT_R32G32B32_FLOAT     4 or 8         2
-    *  others                          4 or 8         2 or 4
-    */
-
-   if (info->compressed) {
-      /* this happens to be the case */
-      img->align_i = img->block_width;
-      img->align_j = img->block_height;
-   } else if (info->bind_zs) {
-      if (ilo_dev_gen(params->dev) >= ILO_GEN(7)) {
-         switch (img->format) {
-         case GEN6_FORMAT_R16_UNORM:
-            img->align_i = 8;
-            img->align_j = 4;
-            break;
-         case GEN6_FORMAT_R8_UINT:
-            img->align_i = 8;
-            img->align_j = 8;
-            break;
-         default:
-            img->align_i = 4;
-            img->align_j = 4;
-            break;
-         }
-      } else {
-         switch (img->format) {
-         case GEN6_FORMAT_R8_UINT:
-            img->align_i = 4;
-            img->align_j = 2;
-            break;
-         default:
-            img->align_i = 4;
-            img->align_j = 4;
-            break;
-         }
-      }
-   } else {
-      const bool valign_4 =
-         (info->sample_count > 1) ||
-         (ilo_dev_gen(params->dev) >= ILO_GEN(8)) ||
-         (ilo_dev_gen(params->dev) >= ILO_GEN(7) &&
-          img->tiling == GEN6_TILING_Y &&
-          info->bind_surface_dp_render);
-
-      if (ilo_dev_gen(params->dev) >= ILO_GEN(7) &&
-          ilo_dev_gen(params->dev) <= ILO_GEN(7.5) && valign_4)
-         assert(img->format != GEN6_FORMAT_R32G32B32_FLOAT);
-
-      img->align_i = 4;
-      img->align_j = (valign_4) ? 4 : 2;
-   }
-
-   /*
-    * the fact that align i and j are multiples of block width and height
-    * respectively is what makes the size of the bo a multiple of the block
-    * size, slices start at block boundaries, and many of the computations
-    * work.
-    */
-   assert(img->align_i % img->block_width == 0);
-   assert(img->align_j % img->block_height == 0);
-
-   /* make sure align() works */
-   assert(util_is_power_of_two(img->align_i) &&
-          util_is_power_of_two(img->align_j));
-   assert(util_is_power_of_two(img->block_width) &&
-          util_is_power_of_two(img->block_height));
-}
-
 static void
 img_init_size_and_format(struct ilo_image *img,
                          struct ilo_image_params *params)
@@ -1337,7 +1353,9 @@ img_init(struct ilo_image *img,
 
    img->aux.type = layout.aux;
 
-   img_init_alignments(img, params);
+   img->align_i = layout.align_i;
+   img->align_j = layout.align_j;
+
    img_init_lods(img, params);
    img_init_layer_height(img, params);