/*
 * Copyright 2015 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_gen7.h"
#include "isl_priv.h"

static bool
gen7_format_needs_valign2(const struct isl_device *dev,
                          enum isl_format format)
{
   assert(ISL_DEV_GEN(dev) == 7);

   /* From the Ivybridge PRM (2012-05-31), Volume 4, Part 1, Section 2.12.1,
    * RENDER_SURFACE_STATE Surface Vertical Alignment:
    *
    *    - Value of 1 [VALIGN_4] is not supported for format YCRCB_NORMAL
    *      (0x182), YCRCB_SWAPUVY (0x183), YCRCB_SWAPUV (0x18f), YCRCB_SWAPY
    *      (0x190)
    *
    *    - VALIGN_4 is not supported for surface format R32G32B32_FLOAT.
    *
    * The R32G32B32_FLOAT restriction is dropped on Haswell.
    */
   return isl_format_is_yuv(format) ||
          (format == ISL_FORMAT_R32G32B32_FLOAT && !ISL_DEV_IS_HASWELL(dev));
}

bool
isl_gen7_choose_msaa_layout(const struct isl_device *dev,
                            const struct isl_surf_init_info *info,
                            enum isl_tiling tiling,
                            enum isl_msaa_layout *msaa_layout)
{
   bool require_array = false;
   bool require_interleaved = false;

   assert(ISL_DEV_GEN(dev) == 7);
   assert(info->samples >= 1);

   if (info->samples == 1) {
      *msaa_layout = ISL_MSAA_LAYOUT_NONE;
      return true;
   }

   if (!isl_format_supports_multisampling(dev->info, info->format))
      return false;

   /* From the Ivybridge PRM, Volume 4 Part 1 p73, SURFACE_STATE, Number of
    * Multisamples:
    *
    *    - If this field is any value other than MULTISAMPLECOUNT_1, the
    *      Surface Type must be SURFTYPE_2D.
    *
    *    - If this field is any value other than MULTISAMPLECOUNT_1, Surface
    *      Min LOD, Mip Count / LOD, and Resource Min LOD must be set to zero
    */
   if (info->dim != ISL_SURF_DIM_2D)
      return false;
   if (info->levels > 1)
      return false;

   /* The Ivyrbridge PRM insists twice that signed integer formats cannot be
    * multisampled.
    *
    * From the Ivybridge PRM, Volume 4 Part 1 p73, SURFACE_STATE, Number of
    * Multisamples:
    *
    *    - This field must be set to MULTISAMPLECOUNT_1 for SINT MSRTs when
    *      all RT channels are not written.
    *
    * And errata from the Ivybridge PRM, Volume 4 Part 1 p77,
    * RENDER_SURFACE_STATE, MCS Enable:
    *
    *   This field must be set to 0 [MULTISAMPLECOUNT_1] for all SINT MSRTs
    *   when all RT channels are not written.
    *
    * Note that the above SINT restrictions apply only to *MSRTs* (that is,
    * *multisampled* render targets). The restrictions seem to permit an MCS
    * if the render target is singlesampled.
    *
    * Moreover, empirically it looks that hardware can render multisampled
    * surfaces with RGBA8I, RGBA16I and RGBA32I.
    */

   /* Multisampling requires vertical alignment of four. */
   if (info->samples > 1 && gen7_format_needs_valign2(dev, info->format))
      return false;

   /* More obvious restrictions */
   if (isl_surf_usage_is_display(info->usage))
      return false;
   if (tiling == ISL_TILING_LINEAR)
      return false;

   /* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
    * Suface Storage Format:
    *
    *    +---------------------+----------------------------------------------------------------+
    *    | MSFMT_MSS           | Multsampled surface was/is rendered as a render target         |
    *    | MSFMT_DEPTH_STENCIL | Multisampled surface was rendered as a depth or stencil buffer |
    *    +---------------------+----------------------------------------------------------------+
    *
    * In the table above, MSFMT_MSS refers to ISL_MSAA_LAYOUT_ARRAY, and
    * MSFMT_DEPTH_STENCIL refers to ISL_MSAA_LAYOUT_INTERLEAVED.
    */
   if (isl_surf_usage_is_depth_or_stencil(info->usage) ||
       (info->usage & ISL_SURF_USAGE_HIZ_BIT))
      require_interleaved = true;

   /* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
    * Suface Storage Format:
    *
    *    If the surface’s Number of Multisamples is MULTISAMPLECOUNT_8, Width
    *    is >= 8192 (meaning the actual surface width is >= 8193 pixels), this
    *    field must be set to MSFMT_MSS.
    */
   if (info->samples == 8 && info->width > 8192)
      require_array = true;

   /* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
    * Suface Storage Format:
    *
    *    If the surface’s Number of Multisamples is MULTISAMPLECOUNT_8,
    *    ((Depth+1) * (Height+1)) is > 4,194,304, OR if the surface’s Number
    *    of Multisamples is MULTISAMPLECOUNT_4, ((Depth+1) * (Height+1)) is
    *    > 8,388,608, this field must be set to MSFMT_DEPTH_STENCIL.
    */
   if ((info->samples == 8 && info->height > 4194304u) ||
       (info->samples == 4 && info->height > 8388608u))
      require_interleaved = true;

   /* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
    * Suface Storage Format:
    *
    *    This field must be set to MSFMT_DEPTH_STENCIL if Surface Format is
    *    one of the following: I24X8_UNORM, L24X8_UNORM, A24X8_UNORM, or
    *    R24_UNORM_X8_TYPELESS.
    */
   if (info->format == ISL_FORMAT_I24X8_UNORM ||
       info->format == ISL_FORMAT_L24X8_UNORM ||
       info->format == ISL_FORMAT_A24X8_UNORM ||
       info->format == ISL_FORMAT_R24_UNORM_X8_TYPELESS)
      require_interleaved = true;

   if (require_array && require_interleaved)
      return false;

   if (require_interleaved) {
      *msaa_layout = ISL_MSAA_LAYOUT_INTERLEAVED;
      return true;
   }

   /* Default to the array layout because it permits multisample
    * compression.
    */
   *msaa_layout = ISL_MSAA_LAYOUT_ARRAY;
   return true;
}

/**
 * @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_X_BIT and ISL_TILING_LINEAR_BIT.
 */
void
isl_gen6_filter_tiling(const struct isl_device *dev,
                       const struct isl_surf_init_info *restrict info,
                       isl_tiling_flags_t *flags)
{
   /* IVB+ requires separate stencil */
   assert(ISL_DEV_USE_SEPARATE_STENCIL(dev));

   /* Clear flags unsupported on this hardware */
   if (ISL_DEV_GEN(dev) < 9) {
      *flags &= ~ISL_TILING_Yf_BIT;
      *flags &= ~ISL_TILING_Ys_BIT;
   }

   /* And... clear the Yf and Ys bits anyway because Anvil doesn't support
    * them yet.
    */
   *flags &= ~ISL_TILING_Yf_BIT; /* FINISHME[SKL]: Support Yf */
   *flags &= ~ISL_TILING_Ys_BIT; /* FINISHME[SKL]: Support Ys */

   if (isl_surf_usage_is_depth(info->usage)) {
      /* Depth requires Y. */
      *flags &= ISL_TILING_ANY_Y_MASK;
   }

   if (isl_surf_usage_is_stencil(info->usage)) {
      if (ISL_DEV_GEN(dev) >= 12) {
         /* Stencil requires Y. */
         *flags &= ISL_TILING_ANY_Y_MASK;
      } else {
         /* Stencil requires W. */
         *flags &= ISL_TILING_W_BIT;
      }
   } else {
      *flags &= ~ISL_TILING_W_BIT;
   }

   /* From the SKL+ PRMs, RENDER_SURFACE_STATE:TileMode,
    *    If Surface Format is ASTC*, this field must be TILEMODE_YMAJOR.
    */
   if (isl_format_get_layout(info->format)->txc == ISL_TXC_ASTC)
      *flags &= ISL_TILING_Y0_BIT;

   /* MCS buffers are always Y-tiled */
   if (isl_format_get_layout(info->format)->txc == ISL_TXC_MCS)
      *flags &= ISL_TILING_Y0_BIT;

   if (info->usage & (ISL_SURF_USAGE_DISPLAY_ROTATE_90_BIT |
                      ISL_SURF_USAGE_DISPLAY_ROTATE_180_BIT |
                      ISL_SURF_USAGE_DISPLAY_ROTATE_270_BIT)) {
      assert(*flags & ISL_SURF_USAGE_DISPLAY_BIT);
      isl_finishme("%s:%s: handle rotated display surfaces",
                   __FILE__, __func__);
   }

   if (info->usage & (ISL_SURF_USAGE_DISPLAY_FLIP_X_BIT |
                      ISL_SURF_USAGE_DISPLAY_FLIP_Y_BIT)) {
      assert(*flags & ISL_SURF_USAGE_DISPLAY_BIT);
      isl_finishme("%s:%s: handle flipped display surfaces",
                   __FILE__, __func__);
   }

   if (info->usage & ISL_SURF_USAGE_DISPLAY_BIT) {
      if (ISL_DEV_GEN(dev) >= 12) {
         *flags &= (ISL_TILING_LINEAR_BIT | ISL_TILING_X_BIT |
                    ISL_TILING_Y0_BIT);
      } else if (ISL_DEV_GEN(dev) >= 9) {
         /* Note we let Yf even though it was cleared above. This is just for
          * completeness.
          */
         *flags &= (ISL_TILING_LINEAR_BIT | ISL_TILING_X_BIT |
                    ISL_TILING_Y0_BIT | ISL_TILING_Yf_BIT);
      } else {
         /* Before Skylake, the display engine does not accept Y */
         *flags &= (ISL_TILING_LINEAR_BIT | ISL_TILING_X_BIT);
      }
   }

   if (info->samples > 1) {
      /* From the Sandybridge PRM, Volume 4 Part 1, SURFACE_STATE Tiled
       * Surface:
       *
       *   For multisample render targets, this field must be 1 (true). MSRTs
       *   can only be tiled.
       *
       * From the Broadwell PRM >> Volume2d: Command Structures >>
       * RENDER_SURFACE_STATE Tile Mode:
       *
       *   If Number of Multisamples is not MULTISAMPLECOUNT_1, this field
       *   must be YMAJOR.
       *
       * As usual, though, stencil is special and requires W-tiling.
       */
      *flags &= (ISL_TILING_ANY_Y_MASK | ISL_TILING_W_BIT);
   }

   /* workaround */
   if (ISL_DEV_GEN(dev) == 7 &&
       gen7_format_needs_valign2(dev, info->format) &&
       (info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) &&
       info->samples == 1) {
      /* Y tiling is illegal. From the Ivybridge PRM, Vol4 Part1 2.12.2.1,
       * SURFACE_STATE Surface Vertical Alignment:
       *
       *     This field must be set to VALIGN_4 for all tiled Y Render Target
       *     surfaces.
       */
      *flags &= ~ISL_TILING_Y0_BIT;
   }

   /* From the Sandybridge PRM, Volume 1, Part 2, page 32:
    *
    *    "NOTE: 128BPE Format Color Buffer ( render target ) MUST be either
    *     TileX or Linear."
    *
    * This is necessary all the way back to 965, but is permitted on Gen7+.
    */
   if (ISL_DEV_GEN(dev) < 7 && isl_format_get_layout(info->format)->bpb >= 128)
      *flags &= ~ISL_TILING_Y0_BIT;

   /* From the BDW and SKL PRMs, Volume 2d,
    * RENDER_SURFACE_STATE::Width - Programming Notes:
    *
    *   A known issue exists if a primitive is rendered to the first 2 rows and
    *   last 2 columns of a 16K width surface. If any geometry is drawn inside
    *   this square it will be copied to column X=2 and X=3 (arrangement on Y
    *   position will stay the same). If any geometry exceeds the boundaries of
    *   this 2x2 region it will be drawn normally. The issue also only occurs
    *   if the surface has TileMode != Linear.
    *
    * [Internal documentation notes that this issue isn't present on SKL GT4.]
    * To prevent this rendering corruption, only allow linear tiling for
    * surfaces with widths greater than 16K-2 pixels.
    *
    * TODO: Is this an issue for multisampled surfaces as well?
    */
   if (info->width > 16382 && info->samples == 1 &&
       info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT &&
       (ISL_DEV_GEN(dev) == 8 ||
        (dev->info->is_skylake && dev->info->gt != 4))) {
          *flags &= ISL_TILING_LINEAR_BIT;
   }
}

void
isl_gen7_choose_image_alignment_el(const struct isl_device *dev,
                                   const struct isl_surf_init_info *restrict info,
                                   enum isl_tiling tiling,
                                   enum isl_dim_layout dim_layout,
                                   enum isl_msaa_layout msaa_layout,
                                   struct isl_extent3d *image_align_el)
{
   assert(ISL_DEV_GEN(dev) == 7);

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

   /* IVB+ does not support combined depthstencil. */
   assert(!isl_surf_usage_is_depth_and_stencil(info->usage));

   /* From the Ivy Bridge PRM, Vol. 2, Part 2, Section 6.18.4.4,
    * "Alignment unit size", the alignment parameters are summarized in the
    * following table:
    *
    *     Surface Defined By | Surface Format  | Align Width | Align Height
    *    --------------------+-----------------+-------------+--------------
    *       DEPTH_BUFFER     |   D16_UNORM     |      8      |      4
    *                        |     other       |      4      |      4
    *    --------------------+-----------------+-------------+--------------
    *       STENCIL_BUFFER   |      N/A        |      8      |      8
    *    --------------------+-----------------+-------------+--------------
    *       SURFACE_STATE    | BC*, ETC*, EAC* |      4      |      4
    *                        |      FXT1       |      8      |      4
    *                        |   all others    |   HALIGN    |   VALIGN
    *    -------------------------------------------------------------------
    */
   if (isl_surf_usage_is_depth(info->usage)) {
      *image_align_el = info->format == ISL_FORMAT_R16_UNORM ?
                        isl_extent3d(8, 4, 1) : isl_extent3d(4, 4, 1);
      return;
   } else if (isl_surf_usage_is_stencil(info->usage)) {
      *image_align_el = isl_extent3d(8, 8, 1);
      return;
   } else if (isl_format_is_compressed(info->format)) {
      /* Compressed formats all have alignment equal to block size. */
      *image_align_el = isl_extent3d(1, 1, 1);
      return;
   }

   /* Everything after this point is in the "set by Surface Horizontal or
    * Vertical Alignment" case.  Now it's just a matter of applying
    * restrictions.
    */

   /* There are no restrictions on halign beyond what's given in the table
    * above.  We set it to the minimum value of 4 because that uses the least
    * memory.
    */
   const uint32_t halign = 4;

   bool require_valign4 = false;

   /* From the Ivybridge PRM, Volume 4, Part 1, Section 2.12.1:
    * RENDER_SURFACE_STATE Surface Vertical Alignment:
    *
    *    * This field 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.
    *
    *    * 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."
    *
    * The first restriction is already handled by the table above and the
    * second restriction is redundant with the fifth.
    */
   if (info->samples > 1)
      require_valign4 = true;

   if (tiling == ISL_TILING_Y0 &&
       (info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT))
      require_valign4 = true;

   assert(!(require_valign4 && gen7_format_needs_valign2(dev, info->format)));

   /* We default to VALIGN_2 because it uses the least memory. */
   const uint32_t valign = require_valign4 ? 4 : 2;

   *image_align_el = isl_extent3d(halign, valign, 1);
}
