Home | History | Annotate | Download | only in isl
      1 /*
      2  * Copyright 2015 Intel Corporation
      3  *
      4  *  Permission is hereby granted, free of charge, to any person obtaining a
      5  *  copy of this software and associated documentation files (the "Software"),
      6  *  to deal in the Software without restriction, including without limitation
      7  *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  *  and/or sell copies of the Software, and to permit persons to whom the
      9  *  Software is furnished to do so, subject to the following conditions:
     10  *
     11  *  The above copyright notice and this permission notice (including the next
     12  *  paragraph) shall be included in all copies or substantial portions of the
     13  *  Software.
     14  *
     15  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     21  *  IN THE SOFTWARE.
     22  */
     23 
     24 #include "isl_gen7.h"
     25 #include "isl_priv.h"
     26 
     27 bool
     28 isl_gen7_choose_msaa_layout(const struct isl_device *dev,
     29                             const struct isl_surf_init_info *info,
     30                             enum isl_tiling tiling,
     31                             enum isl_msaa_layout *msaa_layout)
     32 {
     33    bool require_array = false;
     34    bool require_interleaved = false;
     35 
     36    assert(ISL_DEV_GEN(dev) == 7);
     37    assert(info->samples >= 1);
     38 
     39    if (info->samples == 1) {
     40       *msaa_layout = ISL_MSAA_LAYOUT_NONE;
     41       return true;
     42    }
     43 
     44    if (!isl_format_supports_multisampling(dev->info, info->format))
     45       return false;
     46 
     47    /* From the Ivybridge PRM, Volume 4 Part 1 p73, SURFACE_STATE, Number of
     48     * Multisamples:
     49     *
     50     *    - If this field is any value other than MULTISAMPLECOUNT_1, the
     51     *      Surface Type must be SURFTYPE_2D.
     52     *
     53     *    - If this field is any value other than MULTISAMPLECOUNT_1, Surface
     54     *      Min LOD, Mip Count / LOD, and Resource Min LOD must be set to zero
     55     */
     56    if (info->dim != ISL_SURF_DIM_2D)
     57       return false;
     58    if (info->levels > 1)
     59       return false;
     60 
     61    /* The Ivyrbridge PRM insists twice that signed integer formats cannot be
     62     * multisampled.
     63     *
     64     * From the Ivybridge PRM, Volume 4 Part 1 p73, SURFACE_STATE, Number of
     65     * Multisamples:
     66     *
     67     *    - This field must be set to MULTISAMPLECOUNT_1 for SINT MSRTs when
     68     *      all RT channels are not written.
     69     *
     70     * And errata from the Ivybridge PRM, Volume 4 Part 1 p77,
     71     * RENDER_SURFACE_STATE, MCS Enable:
     72     *
     73     *   This field must be set to 0 [MULTISAMPLECOUNT_1] for all SINT MSRTs
     74     *   when all RT channels are not written.
     75     *
     76     * Note that the above SINT restrictions apply only to *MSRTs* (that is,
     77     * *multisampled* render targets). The restrictions seem to permit an MCS
     78     * if the render target is singlesampled.
     79     */
     80    if (isl_format_has_sint_channel(info->format))
     81       return false;
     82 
     83    /* More obvious restrictions */
     84    if (isl_surf_usage_is_display(info->usage))
     85       return false;
     86    if (tiling == ISL_TILING_LINEAR)
     87       return false;
     88 
     89    /* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
     90     * Suface Storage Format:
     91     *
     92     *    +---------------------+----------------------------------------------------------------+
     93     *    | MSFMT_MSS           | Multsampled surface was/is rendered as a render target         |
     94     *    | MSFMT_DEPTH_STENCIL | Multisampled surface was rendered as a depth or stencil buffer |
     95     *    +---------------------+----------------------------------------------------------------+
     96     *
     97     * In the table above, MSFMT_MSS refers to ISL_MSAA_LAYOUT_ARRAY, and
     98     * MSFMT_DEPTH_STENCIL refers to ISL_MSAA_LAYOUT_INTERLEAVED.
     99     */
    100    if (isl_surf_usage_is_depth_or_stencil(info->usage) ||
    101        (info->usage & ISL_SURF_USAGE_HIZ_BIT))
    102       require_interleaved = true;
    103 
    104    /* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
    105     * Suface Storage Format:
    106     *
    107     *    If the surfaces Number of Multisamples is MULTISAMPLECOUNT_8, Width
    108     *    is >= 8192 (meaning the actual surface width is >= 8193 pixels), this
    109     *    field must be set to MSFMT_MSS.
    110     */
    111    if (info->samples == 8 && info->width == 8192)
    112       require_array = true;
    113 
    114    /* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
    115     * Suface Storage Format:
    116     *
    117     *    If the surfaces Number of Multisamples is MULTISAMPLECOUNT_8,
    118     *    ((Depth+1) * (Height+1)) is > 4,194,304, OR if the surfaces Number
    119     *    of Multisamples is MULTISAMPLECOUNT_4, ((Depth+1) * (Height+1)) is
    120     *    > 8,388,608, this field must be set to MSFMT_DEPTH_STENCIL.
    121     */
    122    if ((info->samples == 8 && info->height > 4194304u) ||
    123        (info->samples == 4 && info->height > 8388608u))
    124       require_interleaved = true;
    125 
    126    /* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
    127     * Suface Storage Format:
    128     *
    129     *    This field must be set to MSFMT_DEPTH_STENCIL if Surface Format is
    130     *    one of the following: I24X8_UNORM, L24X8_UNORM, A24X8_UNORM, or
    131     *    R24_UNORM_X8_TYPELESS.
    132     */
    133    if (info->format == ISL_FORMAT_I24X8_UNORM ||
    134        info->format == ISL_FORMAT_L24X8_UNORM ||
    135        info->format == ISL_FORMAT_A24X8_UNORM ||
    136        info->format == ISL_FORMAT_R24_UNORM_X8_TYPELESS)
    137       require_interleaved = true;
    138 
    139    if (require_array && require_interleaved)
    140       return false;
    141 
    142    if (require_interleaved) {
    143       *msaa_layout = ISL_MSAA_LAYOUT_INTERLEAVED;
    144       return true;
    145    }
    146 
    147    /* Default to the array layout because it permits multisample
    148     * compression.
    149     */
    150    *msaa_layout = ISL_MSAA_LAYOUT_ARRAY;
    151    return true;
    152 }
    153 
    154 static bool
    155 gen7_format_needs_valign2(const struct isl_device *dev,
    156                           enum isl_format format)
    157 {
    158    assert(ISL_DEV_GEN(dev) == 7);
    159 
    160    /* From the Ivybridge PRM (2012-05-31), Volume 4, Part 1, Section 2.12.1,
    161     * RENDER_SURFACE_STATE Surface Vertical Alignment:
    162     *
    163     *    - Value of 1 [VALIGN_4] is not supported for format YCRCB_NORMAL
    164     *      (0x182), YCRCB_SWAPUVY (0x183), YCRCB_SWAPUV (0x18f), YCRCB_SWAPY
    165     *      (0x190)
    166     *
    167     *    - VALIGN_4 is not supported for surface format R32G32B32_FLOAT.
    168     */
    169    return isl_format_is_yuv(format) ||
    170           format == ISL_FORMAT_R32G32B32_FLOAT;
    171 }
    172 
    173 /**
    174  * @brief Filter out tiling flags that are incompatible with the surface.
    175  *
    176  * The resultant outgoing @a flags is a subset of the incoming @a flags. The
    177  * outgoing flags may be empty (0x0) if the incoming flags were too
    178  * restrictive.
    179  *
    180  * For example, if the surface will be used for a display
    181  * (ISL_SURF_USAGE_DISPLAY_BIT), then this function filters out all tiling
    182  * flags except ISL_TILING_X_BIT and ISL_TILING_LINEAR_BIT.
    183  */
    184 void
    185 isl_gen6_filter_tiling(const struct isl_device *dev,
    186                        const struct isl_surf_init_info *restrict info,
    187                        isl_tiling_flags_t *flags)
    188 {
    189    /* IVB+ requires separate stencil */
    190    assert(ISL_DEV_USE_SEPARATE_STENCIL(dev));
    191 
    192    /* Clear flags unsupported on this hardware */
    193    if (ISL_DEV_GEN(dev) < 9) {
    194       *flags &= ~ISL_TILING_Yf_BIT;
    195       *flags &= ~ISL_TILING_Ys_BIT;
    196    }
    197 
    198    /* And... clear the Yf and Ys bits anyway because Anvil doesn't support
    199     * them yet.
    200     */
    201    *flags &= ~ISL_TILING_Yf_BIT; /* FINISHME[SKL]: Support Yf */
    202    *flags &= ~ISL_TILING_Ys_BIT; /* FINISHME[SKL]: Support Ys */
    203 
    204    if (isl_surf_usage_is_depth(info->usage)) {
    205       /* Depth requires Y. */
    206       *flags &= ISL_TILING_ANY_Y_MASK;
    207    }
    208 
    209    /* Separate stencil requires W tiling, and W tiling requires separate
    210     * stencil.
    211     */
    212    if (isl_surf_usage_is_stencil(info->usage)) {
    213       *flags &= ISL_TILING_W_BIT;
    214    } else {
    215       *flags &= ~ISL_TILING_W_BIT;
    216    }
    217 
    218    /* From the SKL+ PRMs, RENDER_SURFACE_STATE:TileMode,
    219     *    If Surface Format is ASTC*, this field must be TILEMODE_YMAJOR.
    220     */
    221    if (isl_format_get_layout(info->format)->txc == ISL_TXC_ASTC)
    222       *flags &= ISL_TILING_Y0_BIT;
    223 
    224    /* MCS buffers are always Y-tiled */
    225    if (isl_format_get_layout(info->format)->txc == ISL_TXC_MCS)
    226       *flags &= ISL_TILING_Y0_BIT;
    227 
    228    if (info->usage & (ISL_SURF_USAGE_DISPLAY_ROTATE_90_BIT |
    229                       ISL_SURF_USAGE_DISPLAY_ROTATE_180_BIT |
    230                       ISL_SURF_USAGE_DISPLAY_ROTATE_270_BIT)) {
    231       assert(*flags & ISL_SURF_USAGE_DISPLAY_BIT);
    232       isl_finishme("%s:%s: handle rotated display surfaces",
    233                    __FILE__, __func__);
    234    }
    235 
    236    if (info->usage & (ISL_SURF_USAGE_DISPLAY_FLIP_X_BIT |
    237                       ISL_SURF_USAGE_DISPLAY_FLIP_Y_BIT)) {
    238       assert(*flags & ISL_SURF_USAGE_DISPLAY_BIT);
    239       isl_finishme("%s:%s: handle flipped display surfaces",
    240                    __FILE__, __func__);
    241    }
    242 
    243    if (info->usage & ISL_SURF_USAGE_DISPLAY_BIT) {
    244       /* Before Skylake, the display engine does not accept Y */
    245       /* FINISHME[SKL]: Y tiling for display surfaces */
    246       *flags &= (ISL_TILING_LINEAR_BIT | ISL_TILING_X_BIT);
    247    }
    248 
    249    if (info->samples > 1) {
    250       /* From the Sandybridge PRM, Volume 4 Part 1, SURFACE_STATE Tiled
    251        * Surface:
    252        *
    253        *   For multisample render targets, this field must be 1 (true). MSRTs
    254        *   can only be tiled.
    255        *
    256        * From the Broadwell PRM >> Volume2d: Command Structures >>
    257        * RENDER_SURFACE_STATE Tile Mode:
    258        *
    259        *   If Number of Multisamples is not MULTISAMPLECOUNT_1, this field
    260        *   must be YMAJOR.
    261        *
    262        * As usual, though, stencil is special and requires W-tiling.
    263        */
    264       *flags &= (ISL_TILING_ANY_Y_MASK | ISL_TILING_W_BIT);
    265    }
    266 
    267    /* workaround */
    268    if (ISL_DEV_GEN(dev) == 7 &&
    269        gen7_format_needs_valign2(dev, info->format) &&
    270        (info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) &&
    271        info->samples == 1) {
    272       /* Y tiling is illegal. From the Ivybridge PRM, Vol4 Part1 2.12.2.1,
    273        * SURFACE_STATE Surface Vertical Alignment:
    274        *
    275        *     This field must be set to VALIGN_4 for all tiled Y Render Target
    276        *     surfaces.
    277        */
    278       *flags &= ~ISL_TILING_Y0_BIT;
    279    }
    280 
    281    /* From the Sandybridge PRM, Volume 1, Part 2, page 32:
    282     *
    283     *    "NOTE: 128BPE Format Color Buffer ( render target ) MUST be either
    284     *     TileX or Linear."
    285     *
    286     * This is necessary all the way back to 965, but is permitted on Gen7+.
    287     */
    288    if (ISL_DEV_GEN(dev) < 7 && isl_format_get_layout(info->format)->bpb >= 128)
    289       *flags &= ~ISL_TILING_Y0_BIT;
    290 }
    291 
    292 /**
    293  * Choose horizontal subimage alignment, in units of surface elements.
    294  */
    295 static uint32_t
    296 gen7_choose_halign_el(const struct isl_device *dev,
    297                       const struct isl_surf_init_info *restrict info)
    298 {
    299    if (isl_format_is_compressed(info->format))
    300       return 1;
    301 
    302    /* From the Ivybridge PRM (2012-05-31), Volume 4, Part 1, Section 2.12.1,
    303     * RENDER_SURFACE_STATE Surface Hoizontal Alignment:
    304     *
    305     *    - This field is intended to be set to HALIGN_8 only if the surface
    306     *      was rendered as a depth buffer with Z16 format or a stencil buffer,
    307     *      since these surfaces support only alignment of 8. Use of HALIGN_8
    308     *      for other surfaces is supported, but uses more memory.
    309     */
    310    if (isl_surf_info_is_z16(info) ||
    311        isl_surf_usage_is_stencil(info->usage))
    312       return 8;
    313 
    314    return 4;
    315 }
    316 
    317 /**
    318  * Choose vertical subimage alignment, in units of surface elements.
    319  */
    320 static uint32_t
    321 gen7_choose_valign_el(const struct isl_device *dev,
    322                       const struct isl_surf_init_info *restrict info,
    323                       enum isl_tiling tiling)
    324 {
    325    MAYBE_UNUSED bool require_valign2 = false;
    326    bool require_valign4 = false;
    327 
    328    if (isl_format_is_compressed(info->format))
    329       return 1;
    330 
    331    if (gen7_format_needs_valign2(dev, info->format))
    332       require_valign2 = true;
    333 
    334    /* From the Ivybridge PRM, Volume 4, Part 1, Section 2.12.1:
    335     * RENDER_SURFACE_STATE Surface Vertical Alignment:
    336     *
    337     *    - This field is intended to be set to VALIGN_4 if the surface was
    338     *      rendered as a depth buffer, for a multisampled (4x) render target,
    339     *      or for a multisampled (8x) render target, since these surfaces
    340     *      support only alignment of 4.  Use of VALIGN_4 for other surfaces is
    341     *      supported, but uses more memory.  This field must be set to
    342     *      VALIGN_4 for all tiled Y Render Target surfaces.
    343     *
    344     */
    345    if (isl_surf_usage_is_depth(info->usage) ||
    346        info->samples > 1 ||
    347        ((info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) &&
    348         tiling == ISL_TILING_Y0)) {
    349       require_valign4 = true;
    350    }
    351 
    352    if (isl_surf_usage_is_stencil(info->usage)) {
    353       /* The Ivybridge PRM states that the stencil buffer's vertical alignment
    354        * is 8 [Ivybridge PRM, Volume 1, Part 1, Section 6.18.4.4 Alignment
    355        * Unit Size]. However, valign=8 is outside the set of valid values of
    356        * RENDER_SURFACE_STATE.SurfaceVerticalAlignment, which is VALIGN_2
    357        * (0x0) and VALIGN_4 (0x1).
    358        *
    359        * The PRM is generally confused about the width, height, and alignment
    360        * of the stencil buffer; and this confusion appears elsewhere. For
    361        * example, the following PRM text effectively converts the stencil
    362        * buffer's 8-pixel alignment to a 4-pixel alignment [Ivybridge PRM,
    363        * Volume 1, Part 1, Section
    364        * 6.18.4.2 Base Address and LOD Calculation]:
    365        *
    366        *    For separate stencil buffer, the width must be mutiplied by 2 and
    367        *    height divided by 2 as follows:
    368        *
    369        *       w_L = 2*i*ceil(W_L/i)
    370        *       h_L = 1/2*j*ceil(H_L/j)
    371        *
    372        * The root of the confusion is that, in W tiling, each pair of rows is
    373        * interleaved into one.
    374        *
    375        * FINISHME(chadv): Decide to set valign=4 or valign=8 after isl's API
    376        * is more polished.
    377        */
    378       require_valign4 = true;
    379    }
    380 
    381    assert(!require_valign2 || !require_valign4);
    382 
    383    if (require_valign4)
    384       return 4;
    385 
    386    /* Prefer VALIGN_2 because it conserves memory. */
    387    return 2;
    388 }
    389 
    390 void
    391 isl_gen7_choose_image_alignment_el(const struct isl_device *dev,
    392                                    const struct isl_surf_init_info *restrict info,
    393                                    enum isl_tiling tiling,
    394                                    enum isl_dim_layout dim_layout,
    395                                    enum isl_msaa_layout msaa_layout,
    396                                    struct isl_extent3d *image_align_el)
    397 {
    398    assert(ISL_DEV_GEN(dev) == 7);
    399 
    400    /* Handled by isl_choose_image_alignment_el */
    401    assert(info->format != ISL_FORMAT_HIZ);
    402 
    403    /* IVB+ does not support combined depthstencil. */
    404    assert(!isl_surf_usage_is_depth_and_stencil(info->usage));
    405 
    406    *image_align_el = (struct isl_extent3d) {
    407       .w = gen7_choose_halign_el(dev, info),
    408       .h = gen7_choose_valign_el(dev, info, tiling),
    409       .d = 1,
    410    };
    411 }
    412