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_gen8.h"
     25 #include "isl_priv.h"
     26 
     27 bool
     28 isl_gen8_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(info->samples >= 1);
     37 
     38    if (info->samples == 1) {
     39       *msaa_layout = ISL_MSAA_LAYOUT_NONE;
     40       return true;
     41    }
     42 
     43    /* From the Broadwell PRM >> Volume2d: Command Structures >>
     44     * RENDER_SURFACE_STATE Multisampled Surface Storage Format:
     45     *
     46     *    All multisampled render target surfaces must have this field set to
     47     *    MSFMT_MSS
     48     */
     49    if (info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT)
     50       require_array = true;
     51 
     52    /* From the Broadwell PRM >> Volume2d: Command Structures >>
     53     * RENDER_SURFACE_STATE Number of Multisamples:
     54     *
     55     *    - If this field is any value other than MULTISAMPLECOUNT_1, the
     56     *      Surface Type must be SURFTYPE_2D This field must be set to
     57     *      MULTISAMPLECOUNT_1 unless the surface is a Sampling Engine surface
     58     *      or Render Target surface.
     59     *
     60     *    - If this field is any value other than MULTISAMPLECOUNT_1, Surface
     61     *      Min LOD, Mip Count / LOD, and Resource Min LOD must be set to zero.
     62     */
     63    if (info->dim != ISL_SURF_DIM_2D)
     64       return false;
     65    if (info->levels > 1)
     66       return false;
     67 
     68    /* More obvious restrictions */
     69    if (isl_surf_usage_is_display(info->usage))
     70       return false;
     71    if (!isl_format_supports_multisampling(dev->info, info->format))
     72       return false;
     73 
     74    if (isl_surf_usage_is_depth_or_stencil(info->usage) ||
     75        (info->usage & ISL_SURF_USAGE_HIZ_BIT))
     76       require_interleaved = true;
     77 
     78    if (require_array && require_interleaved)
     79       return false;
     80 
     81    if (require_interleaved) {
     82       *msaa_layout = ISL_MSAA_LAYOUT_INTERLEAVED;
     83       return true;
     84    }
     85 
     86    *msaa_layout = ISL_MSAA_LAYOUT_ARRAY;
     87    return true;
     88 }
     89 
     90 /**
     91  * Choose horizontal subimage alignment, in units of surface elements.
     92  */
     93 static uint32_t
     94 gen8_choose_halign_el(const struct isl_device *dev,
     95                       const struct isl_surf_init_info *restrict info)
     96 {
     97    if (isl_format_is_compressed(info->format))
     98       return 1;
     99 
    100    /* From the Broadwell PRM, Volume 2d "Command Reference: Structures",
    101     * RENDER_SURFACE_STATE Surface Horizontal Alignment, p326:
    102     *
    103     *    - This field is intended to be set to HALIGN_8 only if the surface
    104     *      was rendered as a depth buffer with Z16 format or a stencil buffer.
    105     *      In this case it must be set to HALIGN_8 since these surfaces
    106     *      support only alignment of 8. [...]
    107     */
    108    if (isl_surf_info_is_z16(info))
    109       return 8;
    110    if (isl_surf_usage_is_stencil(info->usage))
    111       return 8;
    112 
    113    /* From the Broadwell PRM, Volume 2d "Command Reference: Structures",
    114     * RENDER_SURFACE_STATE Surface Horizontal Alignment, p326:
    115     *
    116     *      [...] For Z32 formats it must be set to HALIGN_4.
    117     */
    118    if (isl_surf_usage_is_depth(info->usage))
    119       return 4;
    120 
    121    if (!(info->usage & ISL_SURF_USAGE_DISABLE_AUX_BIT)) {
    122       /* From the Broadwell PRM, Volume 2d "Command Reference: Structures",
    123        * RENDER_SURFACE_STATE Surface Horizontal Alignment, p326:
    124        *
    125        *    - When Auxiliary Surface Mode is set to AUX_CCS_D or AUX_CCS_E,
    126        *      HALIGN 16 must be used.
    127        *
    128        * This case handles color surfaces that may own an auxiliary MCS, CCS_D,
    129        * or CCS_E. Depth buffers, including those that own an auxiliary HiZ
    130        * surface, are handled above and do not require HALIGN_16.
    131        */
    132       assert(!isl_surf_usage_is_depth(info->usage));
    133       return 16;
    134    }
    135 
    136    /* XXX(chadv): I believe the hardware requires each image to be
    137     * cache-aligned. If that's true, then defaulting to halign=4 is wrong for
    138     * many formats. Depending on the format's block size, we may need to
    139     * increase halign to 8.
    140     */
    141    return 4;
    142 }
    143 
    144 /**
    145  * Choose vertical subimage alignment, in units of surface elements.
    146  */
    147 static uint32_t
    148 gen8_choose_valign_el(const struct isl_device *dev,
    149                       const struct isl_surf_init_info *restrict info)
    150 {
    151    /* From the Broadwell PRM > Volume 2d: Command Reference: Structures
    152     * > RENDER_SURFACE_STATE Surface Vertical Alignment (p325):
    153     *
    154     *    - For Sampling Engine and Render Target Surfaces: This field
    155     *      specifies the vertical alignment requirement in elements for the
    156     *      surface. [...] An element is defined as a pixel in uncompresed
    157     *      surface formats, and as a compression block in compressed surface
    158     *      formats. For MSFMT_DEPTH_STENCIL type multisampled surfaces, an
    159     *      element is a sample.
    160     *
    161     *    - This field is intended to be set to VALIGN_4 if the surface was
    162     *      rendered as a depth buffer, for a multisampled (4x) render target,
    163     *      or for a multisampled (8x) render target, since these surfaces
    164     *      support only alignment of 4. Use of VALIGN_4 for other surfaces is
    165     *      supported, but increases memory usage.
    166     *
    167     *    - This field is intended to be set to VALIGN_8 only if the surface
    168     *       was rendered as a stencil buffer, since stencil buffer surfaces
    169     *       support only alignment of 8. If set to VALIGN_8, Surface Format
    170     *       must be R8_UINT.
    171     */
    172 
    173    if (isl_format_is_compressed(info->format))
    174       return 1;
    175 
    176    if (isl_surf_usage_is_stencil(info->usage))
    177       return 8;
    178 
    179    return 4;
    180 }
    181 
    182 void
    183 isl_gen8_choose_image_alignment_el(const struct isl_device *dev,
    184                                    const struct isl_surf_init_info *restrict info,
    185                                    enum isl_tiling tiling,
    186                                    enum isl_dim_layout dim_layout,
    187                                    enum isl_msaa_layout msaa_layout,
    188                                    struct isl_extent3d *image_align_el)
    189 {
    190    /* Handled by isl_choose_image_alignment_el */
    191    assert(info->format != ISL_FORMAT_HIZ);
    192 
    193    assert(!isl_tiling_is_std_y(tiling));
    194 
    195    const struct isl_format_layout *fmtl = isl_format_get_layout(info->format);
    196    if (fmtl->txc == ISL_TXC_CCS) {
    197       /*
    198        * Broadwell PRM Vol 7, "MCS Buffer for Render Target(s)" (p. 676):
    199        *
    200        *    "Mip-mapped and arrayed surfaces are supported with MCS buffer
    201        *    layout with these alignments in the RT space: Horizontal
    202        *    Alignment = 256 and Vertical Alignment = 128.
    203        */
    204       *image_align_el = isl_extent3d(256 / fmtl->bw, 128 / fmtl->bh, 1);
    205       return;
    206    }
    207 
    208    /* The below text from the Broadwell PRM provides some insight into the
    209     * hardware's requirements for LOD alignment.  From the Broadwell PRM >>
    210     * Volume 5: Memory Views >> Surface Layout >> 2D Surfaces:
    211     *
    212     *    These [2D surfaces] must adhere to the following memory organization
    213     *    rules:
    214     *
    215     *       - For non-compressed texture formats, each mipmap must start on an
    216     *         even row within the monolithic rectangular area. For
    217     *         1-texel-high mipmaps, this may require a row of padding below
    218     *         the previous mipmap. This restriction does not apply to any
    219     *         compressed texture formats; each subsequent (lower-res)
    220     *         compressed mipmap is positioned directly below the previous
    221     *         mipmap.
    222     *
    223     *       - Vertical alignment restrictions vary with memory tiling type:
    224     *         1 DWord for linear, 16-byte (DQWord) for tiled. (Note that tiled
    225     *         mipmaps are not required to start at the left edge of a tile
    226     *         row.)
    227     */
    228 
    229    *image_align_el = (struct isl_extent3d) {
    230       .w = gen8_choose_halign_el(dev, info),
    231       .h = gen8_choose_valign_el(dev, info),
    232       .d = 1,
    233    };
    234 }
    235