/*
 * Copyright (c) 2018 Intel Corporation
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a
 *  copy of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
 *  and/or sell copies of the Software, and to permit persons to whom the
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice (including the next
 *  paragraph) shall be included in all copies or substantial portions of the
 *  Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 *  IN THE SOFTWARE.
 */

#include "isl_gfx9.h"
#include "isl_gfx12.h"
#include "isl_priv.h"

/**
 * @brief Filter out tiling flags that are incompatible with the surface.
 *
 * The resultant outgoing @a flags is a subset of the incoming @a flags. The
 * outgoing flags may be empty (0x0) if the incoming flags were too
 * restrictive.
 *
 * For example, if the surface will be used for a display
 * (ISL_SURF_USAGE_DISPLAY_BIT), then this function filters out all tiling
 * flags except ISL_TILING_4_BIT, ISL_TILING_X_BIT, and ISL_TILING_LINEAR_BIT.
 */
void
isl_gfx125_filter_tiling(const struct isl_device *dev,
                         const struct isl_surf_init_info *restrict info,
                         isl_tiling_flags_t *flags)
{
   /* Clear flags unsupported on this hardware */
   assert(ISL_GFX_VERX10(dev) == 125);

   *flags &= ISL_TILING_LINEAR_BIT |
             ISL_TILING_X_BIT |
             ISL_TILING_4_BIT |
             ISL_TILING_64_BIT;

   if (isl_surf_usage_is_depth_or_stencil(info->usage)) {
      *flags &= ISL_TILING_4_BIT | ISL_TILING_64_BIT;

      /* We choose to avoid Tile64 for 3D depth/stencil buffers. The swizzle
       * for Tile64 is dependent on the image dimension. So, reads and writes
       * should specify the same dimension to consistently interpret the data.
       * This is not possible for 3D depth/stencil buffers however. Such
       * buffers can be sampled from with a 3D view, but rendering is only
       * possible with a 2D view due to the limitations of
       * 3DSTATE_(DEPTH|STENCIL)_BUFFER.
       */
      if (info->dim == ISL_SURF_DIM_3D)
         *flags &= ~ISL_TILING_64_BIT;
   }

   if (info->usage & ISL_SURF_USAGE_DISPLAY_BIT)
      *flags &= ~ISL_TILING_64_BIT;

   /* From RENDER_SURFACE_STATE::AuxiliarySurfaceMode,
    *
    *    MCS tiling format is always Tile4
    */
   if (info->usage & ISL_SURF_USAGE_MCS_BIT)
      *flags &= ISL_TILING_4_BIT;

   /* From RENDER_SURFACE_STATE::TileMode,
    *
    *    TILEMODE_XMAJOR is only allowed if Surface Type is SURFTYPE_2D.
    *
    * X-tiling is only allowed for 2D surfaces.
    */
   if (info->dim != ISL_SURF_DIM_2D)
      *flags &= ~ISL_TILING_X_BIT;

   /* From ATS-M PRMs, Volume 2d: Command Reference: Structures,
    * RENDER_SURFACE_STATE:TileMode :
    *
    *    "If Surface Type is SURFTYPE_1D this field must be TILEMODE_LINEAR,
    *     unless Sampler Legacy 1D Map Layout Disable is set to 0, in which
    *     case TILEMODE_YMAJOR is also allowed. Horizontal Alignment must be
    *     programmed for the required alignment between MIPs. MIP tails are
    *     not supported."
    *
    * Tile4 is the replacement for TileY0 on ACM.
    */
   if (info->dim == ISL_SURF_DIM_1D)
      *flags &= ISL_TILING_LINEAR_BIT | ISL_TILING_4_BIT;

   /* TILE64 does not work with YCRCB formats, according to bspec 58767:
    * "Packed YUV surface formats such as YCRCB_NORMAL, YCRCB_SWAPUVY etc.
    * will not support as Tile64"
    */
   if (isl_format_is_yuv(info->format))
      *flags &= ~ISL_TILING_64_BIT;

   /* Tile64 tilings for 3D have a different swizzling than a 2D surface. So
    * filter them out if the usage wants 2D/3D compatibility.
    */
   if (info->usage & ISL_SURF_USAGE_2D_3D_COMPATIBLE_BIT)
      *flags &= ~ISL_TILING_64_BIT;

   /* From RENDER_SURFACE_STATE::NumberofMultisamples,
    *
    *    This field must not be programmed to anything other than
    *    [MULTISAMPLECOUNT_1] unless the Tile Mode field is programmed to
    *    Tile64.
    *
    * Tile64 is required for multisampling.
    */
   if (info->samples > 1)
      *flags &= ISL_TILING_64_BIT;

   /* Tile64 is not defined for format sizes that are 24, 48, and 96 bpb. */
   if (isl_format_get_layout(info->format)->bpb % 3 == 0)
      *flags &= ~ISL_TILING_64_BIT;

   /* From 3DSTATE_CPSIZE_CONTROL_BUFFER::TiledMode,
    *
    *    - 3h       Tile4      4KB tile mode
    *    - 1h       Tile64     64KB tile mode
    *    - 2h, 0h   Reserved
    *
    * Tile4 and Tile64 are the only two valid values.
    */
   if (info->usage & ISL_SURF_USAGE_CPB_BIT)
      *flags &= ISL_TILING_4_BIT | ISL_TILING_64_BIT;
}

void
isl_gfx125_choose_image_alignment_el(const struct isl_device *dev,
                                     const struct isl_surf_init_info *restrict info,
                                     const struct isl_tile_info *tile_info,
                                     enum isl_dim_layout dim_layout,
                                     enum isl_msaa_layout msaa_layout,
                                     struct isl_extent3d *image_align_el)
{
   enum isl_tiling tiling = tile_info->tiling;

   /* Handled by isl_choose_image_alignment_el */
   assert(info->format != ISL_FORMAT_GFX125_HIZ);

   const struct isl_format_layout *fmtl = isl_format_get_layout(info->format);

   if (tiling == ISL_TILING_64) {
      /* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
       *
       *   This field is ignored for Tile64 surface formats because horizontal
       *   alignment is always to the start of the next tile in that case.
       *
       * From RENDER_SURFACE_STATE::SurfaceQPitch,
       *
       *   Because MSAA is only supported for Tile64, QPitch must also be
       *   programmed to an aligned tile boundary for MSAA surfaces.
       *
       * Images in this surface must be tile-aligned.  The table on the Bspec
       * page, "2D/CUBE Alignment Requirement", shows that the vertical
       * alignment is also a tile height for non-MSAA as well.
       */
      *image_align_el = isl_extent3d(tile_info->logical_extent_el.w,
                                     tile_info->logical_extent_el.h,
                                     1);
   } else if (isl_surf_usage_is_depth(info->usage)) {
      /* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
       *
       *    - 16b Depth Surfaces Must Be HALIGN=16Bytes (8texels)
       *    - 32b Depth Surfaces Must Be HALIGN=32Bytes (8texels)
       *
       * From RENDER_SURFACE_STATE::SurfaceVerticalAlignment,
       *
       *    This field is intended to be set to VALIGN_4 if the surface
       *    was rendered as a depth buffer [...]
       *
       * and
       *
       *    This field should also be set to VALIGN_8 if the surface was
       *    rendered as a D16_UNORM depth buffer [...]
       */
      *image_align_el =
         info->format != ISL_FORMAT_R16_UNORM ?
         isl_extent3d(8, 4, 1) :
         isl_extent3d(8, 8, 1);
   } else if (isl_surf_usage_is_stencil(info->usage) ||
              isl_surf_usage_is_cpb(info->usage)) {
      /* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
       *
       *    - Stencil Surfaces (8b) Must be HALIGN=16Bytes (16texels)
       *
       * From RENDER_SURFACE_STATE::SurfaceVerticalAlignment,
       *
       *    This field is intended to be set to VALIGN_8 only if
       *    the surface was rendered as a stencil buffer, since stencil buffer
       *    surfaces support only alignment of 8.
       *
       * TODO: Cite docs for CPB.
       */
      *image_align_el = isl_extent3d(16, 8, 1);
   } else if (!isl_is_pow2(fmtl->bpb)) {
      /* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
       *
       *    - Linear Surfaces surfaces must use HALIGN=128, including 1D which
       *      is always Linear. For 24,48 and 96bpp this means 128texels.
       *    - Tiled 24bpp, 48bpp and 96bpp surfaces must use HALIGN=16
       */
      *image_align_el = tiling == ISL_TILING_LINEAR ?
         isl_extent3d(128, 4, 1) :
         isl_extent3d(16, 4, 1);
   } else if (_isl_surf_info_supports_ccs(dev, info->format, info->usage) ||
              tiling == ISL_TILING_LINEAR) {
      /* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
       *
       *    - Losslessly Compressed Surfaces Must be HALIGN=128 for all
       *      supported Bpp, if other restriction are not applied
       *    - Linear Surfaces surfaces must use HALIGN=128, including 1D which
       *      is always Linear.
       */
      *image_align_el = isl_extent3d(128 * 8 / fmtl->bpb, 4, 1);
   } else if (fmtl->bpb >= 64) {
      assert(fmtl->bpb == 64 || fmtl->bpb == 128);
      /* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
       *
       *    - 64bpe and 128bpe Surfaces Must Be HALIGN=64Bytes or 128Bytes (4,
       *      8 texels or 16 texels)
       *
       * HALIGN=128 is used for losslessly compressed or linear surfaces. For
       * other surface types, pick the smaller alignment of HALIGN=64 to save
       * space.
       */
      *image_align_el = isl_extent3d(64 * 8 / fmtl->bpb, 4, 1);
   } else {
      /* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
       *
       *    HALIGN=16Bytes(8 texels) is allowed only for 16b Depth, Stencil
       *    Surfaces (8b) and Tiled 24bpp, 48bpp and 96bpp surfaces
       *
       * HALIGN=16 would save the most space, but it is reserved for the cases
       * handled earlier in this if-ladder. Choose the next smallest alignment
       * possible, HALIGN=32.
       */
      *image_align_el = isl_extent3d(32 * 8 / fmtl->bpb, 4, 1);
   }
}

void
isl_gfx12_choose_image_alignment_el(const struct isl_device *dev,
                                    const struct isl_surf_init_info *restrict info,
                                    const struct isl_tile_info *tile_info,
                                    enum isl_dim_layout dim_layout,
                                    enum isl_msaa_layout msaa_layout,
                                    struct isl_extent3d *image_align_el)
{
   enum isl_tiling tiling = tile_info->tiling;

   /* Handled by isl_choose_image_alignment_el */
   assert(info->format != ISL_FORMAT_HIZ);

   if (isl_tiling_is_std_y(tiling)) {
      /* From RENDER_SURFACE_STATE::SurfaceHorizontalAlignment,
       *
       *   This field is ignored for Tile64 surface formats because horizontal
       *   alignment is always to the start of the next tile in that case.
       *
       * From RENDER_SURFACE_STATE::SurfaceQPitch,
       *
       *   Because MSAA is only supported for Tile64, QPitch must also be
       *   programmed to an aligned tile boundary for MSAA surfaces.
       *
       * Images in this surface must be tile-aligned.  The table on the Bspec
       * page, "2D/CUBE Alignment Requirement", shows that the vertical
       * alignment is also a tile height for non-MSAA as well.
       */
      *image_align_el = isl_extent3d(tile_info->logical_extent_el.w,
                                     tile_info->logical_extent_el.h,
                                     1);
   } else if (isl_surf_usage_is_depth(info->usage)) {
      /* The alignment parameters for depth buffers are summarized in the
       * following table:
       *
       *     Surface Format  |    MSAA     | Align Width | Align Height
       *    -----------------+-------------+-------------+--------------
       *       D16_UNORM     | 1x, 4x, 16x |      8      |      8
       *     ----------------+-------------+-------------+--------------
       *       D16_UNORM     |   2x, 8x    |     16      |      4
       *     ----------------+-------------+-------------+--------------
       *         other       |     any     |      8      |      4
       *    -----------------+-------------+-------------+--------------
       */
      assert(isl_is_pow2(info->samples));
      *image_align_el =
         info->format != ISL_FORMAT_R16_UNORM ?
         isl_extent3d(8, 4, 1) :
         (info->samples == 2 || info->samples == 8 ?
          isl_extent3d(16, 4, 1) : isl_extent3d(8, 8, 1));
   } else if (isl_surf_usage_is_stencil(info->usage)) {
      *image_align_el = isl_extent3d(16, 8, 1);
   } else {
      isl_gfx9_choose_image_alignment_el(dev, info, tile_info, dim_layout,
                                         msaa_layout, image_align_el);
   }
}
