/*1* Copyright 2015 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "isl_gfx8.h"24#include "isl_gfx9.h"25#include "isl_priv.h"2627/**28* Calculate the surface's subimage alignment, in units of surface samples,29* for the standard tiling formats Yf and Ys.30*/31static void32gfx9_calc_std_image_alignment_sa(const struct isl_device *dev,33const struct isl_surf_init_info *restrict info,34enum isl_tiling tiling,35enum isl_msaa_layout msaa_layout,36struct isl_extent3d *align_sa)37{38const struct isl_format_layout *fmtl = isl_format_get_layout(info->format);3940assert(isl_tiling_is_std_y(tiling));4142const uint32_t bpb = fmtl->bpb;43const uint32_t is_Ys = tiling == ISL_TILING_Ys;4445switch (info->dim) {46case ISL_SURF_DIM_1D:47/* See the Skylake BSpec > Memory Views > Common Surface Formats > Surface48* Layout and Tiling > 1D Surfaces > 1D Alignment Requirements.49*/50*align_sa = (struct isl_extent3d) {51.w = 1 << (12 - (ffs(bpb) - 4) + (4 * is_Ys)),52.h = 1,53.d = 1,54};55return;56case ISL_SURF_DIM_2D:57/* See the Skylake BSpec > Memory Views > Common Surface Formats >58* Surface Layout and Tiling > 2D Surfaces > 2D/CUBE Alignment59* Requirements.60*/61*align_sa = (struct isl_extent3d) {62.w = 1 << (6 - ((ffs(bpb) - 4) / 2) + (4 * is_Ys)),63.h = 1 << (6 - ((ffs(bpb) - 3) / 2) + (4 * is_Ys)),64.d = 1,65};6667if (is_Ys) {68/* FINISHME(chadv): I don't trust this code. Untested. */69isl_finishme("%s:%s: [SKL+] multisample TileYs", __FILE__, __func__);7071switch (msaa_layout) {72case ISL_MSAA_LAYOUT_NONE:73case ISL_MSAA_LAYOUT_INTERLEAVED:74break;75case ISL_MSAA_LAYOUT_ARRAY:76align_sa->w >>= (ffs(info->samples) - 0) / 2;77align_sa->h >>= (ffs(info->samples) - 1) / 2;78break;79}80}81return;8283case ISL_SURF_DIM_3D:84/* See the Skylake BSpec > Memory Views > Common Surface Formats > Surface85* Layout and Tiling > 1D Surfaces > 1D Alignment Requirements.86*/87*align_sa = (struct isl_extent3d) {88.w = 1 << (4 - ((ffs(bpb) - 2) / 3) + (4 * is_Ys)),89.h = 1 << (4 - ((ffs(bpb) - 4) / 3) + (2 * is_Ys)),90.d = 1 << (4 - ((ffs(bpb) - 3) / 3) + (2 * is_Ys)),91};92return;93}9495unreachable("bad isl_surface_type");96}9798void99isl_gfx9_choose_image_alignment_el(const struct isl_device *dev,100const struct isl_surf_init_info *restrict info,101enum isl_tiling tiling,102enum isl_dim_layout dim_layout,103enum isl_msaa_layout msaa_layout,104struct isl_extent3d *image_align_el)105{106/* Handled by isl_choose_image_alignment_el */107assert(info->format != ISL_FORMAT_HIZ);108109const struct isl_format_layout *fmtl = isl_format_get_layout(info->format);110if (fmtl->txc == ISL_TXC_CCS) {111/* Sky Lake PRM Vol. 7, "MCS Buffer for Render Target(s)" (p. 632):112*113* "Mip-mapped and arrayed surfaces are supported with MCS buffer114* layout with these alignments in the RT space: Horizontal115* Alignment = 128 and Vertical Alignment = 64."116*/117*image_align_el = isl_extent3d(128 / fmtl->bw, 64 / fmtl->bh, 1);118return;119}120121/* This BSpec text provides some insight into the hardware's alignment122* requirements [Skylake BSpec > Memory Views > Common Surface Formats >123* Surface Layout and Tiling > 2D Surfaces]:124*125* An LOD must be aligned to a cache-line except for some special cases126* related to Planar YUV surfaces. In general, the cache-alignment127* restriction implies there is a minimum height for an LOD of 4 texels.128* So, LODs which are smaller than 4 high are padded.129*130* From the Skylake BSpec, RENDER_SURFACE_STATE Surface Vertical Alignment:131*132* - For Sampling Engine and Render Target Surfaces: This field133* specifies the vertical alignment requirement in elements for the134* surface. [...] An element is defined as a pixel in uncompresed135* surface formats, and as a compression block in compressed surface136* formats. For MSFMT_DEPTH_STENCIL type multisampled surfaces, an137* element is a sample.138*139* - This field is used for 2D, CUBE, and 3D surface alignment when Tiled140* Resource Mode is TRMODE_NONE (Tiled Resource Mode is disabled).141* This field is ignored for 1D surfaces and also when Tiled Resource142* Mode is not TRMODE_NONE (e.g. Tiled Resource Mode is enabled).143*144* See the appropriate Alignment table in the "Surface Layout and145* Tiling" section under Common Surface Formats for the table of146* alignment values for Tiled Resrouces.147*148* - For uncompressed surfaces, the units of "j" are rows of pixels on149* the physical surface. For compressed texture formats, the units of150* "j" are in compression blocks, thus each increment in "j" is equal151* to h pixels, where h is the height of the compression block in152* pixels.153*154* - Valid Values: VALIGN_4, VALIGN_8, VALIGN_16155*156* From the Skylake BSpec, RENDER_SURFACE_STATE Surface Horizontal157* Alignment:158*159* - For uncompressed surfaces, the units of "i" are pixels on the160* physical surface. For compressed texture formats, the units of "i"161* are in compression blocks, thus each increment in "i" is equal to162* w pixels, where w is the width of the compression block in pixels.163*164* - Valid Values: HALIGN_4, HALIGN_8, HALIGN_16165*/166167if (isl_tiling_is_std_y(tiling)) {168struct isl_extent3d image_align_sa;169gfx9_calc_std_image_alignment_sa(dev, info, tiling, msaa_layout,170&image_align_sa);171172*image_align_el = isl_extent3d_sa_to_el(info->format, image_align_sa);173return;174}175176if (dim_layout == ISL_DIM_LAYOUT_GFX9_1D) {177/* See the Skylake BSpec > Memory Views > Common Surface Formats > Surface178* Layout and Tiling > 1D Surfaces > 1D Alignment Requirements.179*/180*image_align_el = isl_extent3d(64, 1, 1);181return;182}183184if (isl_format_is_compressed(info->format)) {185/* On Gfx9, the meaning of RENDER_SURFACE_STATE's186* SurfaceHorizontalAlignment and SurfaceVerticalAlignment changed for187* compressed formats. They now indicate a multiple of the compression188* block. For example, if the compression mode is ETC2 then HALIGN_4189* indicates a horizontal alignment of 16 pixels.190*191* To avoid wasting memory, choose the smallest alignment possible:192* HALIGN_4 and VALIGN_4.193*/194*image_align_el = isl_extent3d(4, 4, 1);195return;196}197198isl_gfx8_choose_image_alignment_el(dev, info, tiling, dim_layout,199msaa_layout, image_align_el);200}201202203