Home | History | Annotate | Download | only in drm
      1 /*
      2  * Copyright  2011 Red Hat All Rights Reserved.
      3  * Copyright  2014 Advanced Micro Devices, Inc.
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining
      7  * a copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
     16  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     17  * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
     18  * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     21  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     22  *
     23  * The above copyright notice and this permission notice (including the
     24  * next paragraph) shall be included in all copies or substantial portions
     25  * of the Software.
     26  */
     27 
     28 /* Contact:
     29  *     Marek Olk <maraeo (at) gmail.com>
     30  */
     31 
     32 #include "amdgpu_winsys.h"
     33 #include "util/u_format.h"
     34 
     35 #ifndef CIASICIDGFXENGINE_SOUTHERNISLAND
     36 #define CIASICIDGFXENGINE_SOUTHERNISLAND 0x0000000A
     37 #endif
     38 
     39 
     40 static int amdgpu_surface_sanity(const struct pipe_resource *tex)
     41 {
     42    /* all dimension must be at least 1 ! */
     43    if (!tex->width0 || !tex->height0 || !tex->depth0 ||
     44        !tex->array_size)
     45       return -EINVAL;
     46 
     47    switch (tex->nr_samples) {
     48    case 0:
     49    case 1:
     50    case 2:
     51    case 4:
     52    case 8:
     53       break;
     54    default:
     55       return -EINVAL;
     56    }
     57 
     58    switch (tex->target) {
     59    case PIPE_TEXTURE_1D:
     60       if (tex->height0 > 1)
     61          return -EINVAL;
     62       /* fall through */
     63    case PIPE_TEXTURE_2D:
     64    case PIPE_TEXTURE_RECT:
     65       if (tex->depth0 > 1 || tex->array_size > 1)
     66          return -EINVAL;
     67       break;
     68    case PIPE_TEXTURE_3D:
     69       if (tex->array_size > 1)
     70          return -EINVAL;
     71       break;
     72    case PIPE_TEXTURE_1D_ARRAY:
     73       if (tex->height0 > 1)
     74          return -EINVAL;
     75       /* fall through */
     76    case PIPE_TEXTURE_CUBE:
     77    case PIPE_TEXTURE_2D_ARRAY:
     78    case PIPE_TEXTURE_CUBE_ARRAY:
     79       if (tex->depth0 > 1)
     80          return -EINVAL;
     81       break;
     82    default:
     83       return -EINVAL;
     84    }
     85    return 0;
     86 }
     87 
     88 static void *ADDR_API allocSysMem(const ADDR_ALLOCSYSMEM_INPUT * pInput)
     89 {
     90    return malloc(pInput->sizeInBytes);
     91 }
     92 
     93 static ADDR_E_RETURNCODE ADDR_API freeSysMem(const ADDR_FREESYSMEM_INPUT * pInput)
     94 {
     95    free(pInput->pVirtAddr);
     96    return ADDR_OK;
     97 }
     98 
     99 ADDR_HANDLE amdgpu_addr_create(struct amdgpu_winsys *ws)
    100 {
    101    ADDR_CREATE_INPUT addrCreateInput = {0};
    102    ADDR_CREATE_OUTPUT addrCreateOutput = {0};
    103    ADDR_REGISTER_VALUE regValue = {0};
    104    ADDR_CREATE_FLAGS createFlags = {{0}};
    105    ADDR_E_RETURNCODE addrRet;
    106 
    107    addrCreateInput.size = sizeof(ADDR_CREATE_INPUT);
    108    addrCreateOutput.size = sizeof(ADDR_CREATE_OUTPUT);
    109 
    110    regValue.noOfBanks = ws->amdinfo.mc_arb_ramcfg & 0x3;
    111    regValue.gbAddrConfig = ws->amdinfo.gb_addr_cfg;
    112    regValue.noOfRanks = (ws->amdinfo.mc_arb_ramcfg & 0x4) >> 2;
    113 
    114    regValue.backendDisables = ws->amdinfo.backend_disable[0];
    115    regValue.pTileConfig = ws->amdinfo.gb_tile_mode;
    116    regValue.noOfEntries = ARRAY_SIZE(ws->amdinfo.gb_tile_mode);
    117    if (ws->info.chip_class == SI) {
    118       regValue.pMacroTileConfig = NULL;
    119       regValue.noOfMacroEntries = 0;
    120    } else {
    121       regValue.pMacroTileConfig = ws->amdinfo.gb_macro_tile_mode;
    122       regValue.noOfMacroEntries = ARRAY_SIZE(ws->amdinfo.gb_macro_tile_mode);
    123    }
    124 
    125    createFlags.value = 0;
    126    createFlags.useTileIndex = 1;
    127    createFlags.degradeBaseLevel = 1;
    128    createFlags.useHtileSliceAlign = 1;
    129 
    130    addrCreateInput.chipEngine = CIASICIDGFXENGINE_SOUTHERNISLAND;
    131    addrCreateInput.chipFamily = ws->family;
    132    addrCreateInput.chipRevision = ws->rev_id;
    133    addrCreateInput.createFlags = createFlags;
    134    addrCreateInput.callbacks.allocSysMem = allocSysMem;
    135    addrCreateInput.callbacks.freeSysMem = freeSysMem;
    136    addrCreateInput.callbacks.debugPrint = 0;
    137    addrCreateInput.regValue = regValue;
    138 
    139    addrRet = AddrCreate(&addrCreateInput, &addrCreateOutput);
    140    if (addrRet != ADDR_OK)
    141       return NULL;
    142 
    143    return addrCreateOutput.hLib;
    144 }
    145 
    146 static int compute_level(struct amdgpu_winsys *ws,
    147                          const struct pipe_resource *tex,
    148                          struct radeon_surf *surf, bool is_stencil,
    149                          unsigned level, bool compressed,
    150                          ADDR_COMPUTE_SURFACE_INFO_INPUT *AddrSurfInfoIn,
    151                          ADDR_COMPUTE_SURFACE_INFO_OUTPUT *AddrSurfInfoOut,
    152                          ADDR_COMPUTE_DCCINFO_INPUT *AddrDccIn,
    153                          ADDR_COMPUTE_DCCINFO_OUTPUT *AddrDccOut,
    154                          ADDR_COMPUTE_HTILE_INFO_INPUT *AddrHtileIn,
    155                          ADDR_COMPUTE_HTILE_INFO_OUTPUT *AddrHtileOut)
    156 {
    157    struct radeon_surf_level *surf_level;
    158    ADDR_E_RETURNCODE ret;
    159 
    160    AddrSurfInfoIn->mipLevel = level;
    161    AddrSurfInfoIn->width = u_minify(tex->width0, level);
    162    AddrSurfInfoIn->height = u_minify(tex->height0, level);
    163 
    164    if (tex->target == PIPE_TEXTURE_3D)
    165       AddrSurfInfoIn->numSlices = u_minify(tex->depth0, level);
    166    else if (tex->target == PIPE_TEXTURE_CUBE)
    167       AddrSurfInfoIn->numSlices = 6;
    168    else
    169       AddrSurfInfoIn->numSlices = tex->array_size;
    170 
    171    if (level > 0) {
    172       /* Set the base level pitch. This is needed for calculation
    173        * of non-zero levels. */
    174       if (is_stencil)
    175          AddrSurfInfoIn->basePitch = surf->stencil_level[0].nblk_x;
    176       else
    177          AddrSurfInfoIn->basePitch = surf->level[0].nblk_x;
    178 
    179       /* Convert blocks to pixels for compressed formats. */
    180       if (compressed)
    181          AddrSurfInfoIn->basePitch *= surf->blk_w;
    182    }
    183 
    184    ret = AddrComputeSurfaceInfo(ws->addrlib,
    185                                 AddrSurfInfoIn,
    186                                 AddrSurfInfoOut);
    187    if (ret != ADDR_OK) {
    188       return ret;
    189    }
    190 
    191    surf_level = is_stencil ? &surf->stencil_level[level] : &surf->level[level];
    192    surf_level->offset = align64(surf->surf_size, AddrSurfInfoOut->baseAlign);
    193    surf_level->slice_size = AddrSurfInfoOut->sliceSize;
    194    surf_level->nblk_x = AddrSurfInfoOut->pitch;
    195    surf_level->nblk_y = AddrSurfInfoOut->height;
    196 
    197    switch (AddrSurfInfoOut->tileMode) {
    198    case ADDR_TM_LINEAR_ALIGNED:
    199       surf_level->mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
    200       break;
    201    case ADDR_TM_1D_TILED_THIN1:
    202       surf_level->mode = RADEON_SURF_MODE_1D;
    203       break;
    204    case ADDR_TM_2D_TILED_THIN1:
    205       surf_level->mode = RADEON_SURF_MODE_2D;
    206       break;
    207    default:
    208       assert(0);
    209    }
    210 
    211    if (is_stencil)
    212       surf->stencil_tiling_index[level] = AddrSurfInfoOut->tileIndex;
    213    else
    214       surf->tiling_index[level] = AddrSurfInfoOut->tileIndex;
    215 
    216    surf->surf_size = surf_level->offset + AddrSurfInfoOut->surfSize;
    217 
    218    /* Clear DCC fields at the beginning. */
    219    surf_level->dcc_offset = 0;
    220 
    221    /* The previous level's flag tells us if we can use DCC for this level. */
    222    if (AddrSurfInfoIn->flags.dccCompatible &&
    223        (level == 0 || AddrDccOut->subLvlCompressible)) {
    224       AddrDccIn->colorSurfSize = AddrSurfInfoOut->surfSize;
    225       AddrDccIn->tileMode = AddrSurfInfoOut->tileMode;
    226       AddrDccIn->tileInfo = *AddrSurfInfoOut->pTileInfo;
    227       AddrDccIn->tileIndex = AddrSurfInfoOut->tileIndex;
    228       AddrDccIn->macroModeIndex = AddrSurfInfoOut->macroModeIndex;
    229 
    230       ret = AddrComputeDccInfo(ws->addrlib,
    231                                AddrDccIn,
    232                                AddrDccOut);
    233 
    234       if (ret == ADDR_OK) {
    235          surf_level->dcc_offset = surf->dcc_size;
    236          surf_level->dcc_fast_clear_size = AddrDccOut->dccFastClearSize;
    237          surf->num_dcc_levels = level + 1;
    238          surf->dcc_size = surf_level->dcc_offset + AddrDccOut->dccRamSize;
    239          surf->dcc_alignment = MAX2(surf->dcc_alignment, AddrDccOut->dccRamBaseAlign);
    240       }
    241    }
    242 
    243    /* TC-compatible HTILE. */
    244    if (!is_stencil &&
    245        AddrSurfInfoIn->flags.depth &&
    246        AddrSurfInfoIn->flags.tcCompatible &&
    247        surf_level->mode == RADEON_SURF_MODE_2D &&
    248        level == 0) {
    249       AddrHtileIn->flags.tcCompatible = 1;
    250       AddrHtileIn->pitch = AddrSurfInfoOut->pitch;
    251       AddrHtileIn->height = AddrSurfInfoOut->height;
    252       AddrHtileIn->numSlices = AddrSurfInfoOut->depth;
    253       AddrHtileIn->blockWidth = ADDR_HTILE_BLOCKSIZE_8;
    254       AddrHtileIn->blockHeight = ADDR_HTILE_BLOCKSIZE_8;
    255       AddrHtileIn->pTileInfo = AddrSurfInfoOut->pTileInfo;
    256       AddrHtileIn->tileIndex = AddrSurfInfoOut->tileIndex;
    257       AddrHtileIn->macroModeIndex = AddrSurfInfoOut->macroModeIndex;
    258 
    259       ret = AddrComputeHtileInfo(ws->addrlib,
    260                                  AddrHtileIn,
    261                                  AddrHtileOut);
    262 
    263       if (ret == ADDR_OK) {
    264          surf->htile_size = AddrHtileOut->htileBytes;
    265          surf->htile_alignment = AddrHtileOut->baseAlign;
    266       }
    267    }
    268 
    269    return 0;
    270 }
    271 
    272 #define   G_009910_MICRO_TILE_MODE(x)          (((x) >> 0) & 0x03)
    273 #define   G_009910_MICRO_TILE_MODE_NEW(x)      (((x) >> 22) & 0x07)
    274 
    275 static void set_micro_tile_mode(struct radeon_surf *surf,
    276                                 struct radeon_info *info)
    277 {
    278    uint32_t tile_mode = info->si_tile_mode_array[surf->tiling_index[0]];
    279 
    280    if (info->chip_class >= CIK)
    281       surf->micro_tile_mode = G_009910_MICRO_TILE_MODE_NEW(tile_mode);
    282    else
    283       surf->micro_tile_mode = G_009910_MICRO_TILE_MODE(tile_mode);
    284 }
    285 
    286 static unsigned cik_get_macro_tile_index(struct radeon_surf *surf)
    287 {
    288 	unsigned index, tileb;
    289 
    290 	tileb = 8 * 8 * surf->bpe;
    291 	tileb = MIN2(surf->tile_split, tileb);
    292 
    293 	for (index = 0; tileb > 64; index++)
    294 		tileb >>= 1;
    295 
    296 	assert(index < 16);
    297 	return index;
    298 }
    299 
    300 static int amdgpu_surface_init(struct radeon_winsys *rws,
    301                                const struct pipe_resource *tex,
    302                                unsigned flags, unsigned bpe,
    303                                enum radeon_surf_mode mode,
    304                                struct radeon_surf *surf)
    305 {
    306    struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws;
    307    unsigned level;
    308    bool compressed;
    309    ADDR_COMPUTE_SURFACE_INFO_INPUT AddrSurfInfoIn = {0};
    310    ADDR_COMPUTE_SURFACE_INFO_OUTPUT AddrSurfInfoOut = {0};
    311    ADDR_COMPUTE_DCCINFO_INPUT AddrDccIn = {0};
    312    ADDR_COMPUTE_DCCINFO_OUTPUT AddrDccOut = {0};
    313    ADDR_COMPUTE_HTILE_INFO_INPUT AddrHtileIn = {0};
    314    ADDR_COMPUTE_HTILE_INFO_OUTPUT AddrHtileOut = {0};
    315    ADDR_TILEINFO AddrTileInfoIn = {0};
    316    ADDR_TILEINFO AddrTileInfoOut = {0};
    317    int r;
    318 
    319    r = amdgpu_surface_sanity(tex);
    320    if (r)
    321       return r;
    322 
    323    AddrSurfInfoIn.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT);
    324    AddrSurfInfoOut.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT);
    325    AddrDccIn.size = sizeof(ADDR_COMPUTE_DCCINFO_INPUT);
    326    AddrDccOut.size = sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT);
    327    AddrHtileIn.size = sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT);
    328    AddrHtileOut.size = sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT);
    329    AddrSurfInfoOut.pTileInfo = &AddrTileInfoOut;
    330 
    331    surf->blk_w = util_format_get_blockwidth(tex->format);
    332    surf->blk_h = util_format_get_blockheight(tex->format);
    333    surf->bpe = bpe;
    334    surf->flags = flags;
    335 
    336    compressed = surf->blk_w == 4 && surf->blk_h == 4;
    337 
    338    /* MSAA and FMASK require 2D tiling. */
    339    if (tex->nr_samples > 1 ||
    340        (flags & RADEON_SURF_FMASK))
    341       mode = RADEON_SURF_MODE_2D;
    342 
    343    /* DB doesn't support linear layouts. */
    344    if (flags & (RADEON_SURF_Z_OR_SBUFFER) &&
    345        mode < RADEON_SURF_MODE_1D)
    346       mode = RADEON_SURF_MODE_1D;
    347 
    348    /* Set the requested tiling mode. */
    349    switch (mode) {
    350    case RADEON_SURF_MODE_LINEAR_ALIGNED:
    351       AddrSurfInfoIn.tileMode = ADDR_TM_LINEAR_ALIGNED;
    352       break;
    353    case RADEON_SURF_MODE_1D:
    354       AddrSurfInfoIn.tileMode = ADDR_TM_1D_TILED_THIN1;
    355       break;
    356    case RADEON_SURF_MODE_2D:
    357       AddrSurfInfoIn.tileMode = ADDR_TM_2D_TILED_THIN1;
    358       break;
    359    default:
    360       assert(0);
    361    }
    362 
    363    /* The format must be set correctly for the allocation of compressed
    364     * textures to work. In other cases, setting the bpp is sufficient. */
    365    if (compressed) {
    366       switch (bpe) {
    367       case 8:
    368          AddrSurfInfoIn.format = ADDR_FMT_BC1;
    369          break;
    370       case 16:
    371          AddrSurfInfoIn.format = ADDR_FMT_BC3;
    372          break;
    373       default:
    374          assert(0);
    375       }
    376    }
    377    else {
    378       AddrDccIn.bpp = AddrSurfInfoIn.bpp = bpe * 8;
    379    }
    380 
    381    AddrDccIn.numSamples = AddrSurfInfoIn.numSamples =
    382       tex->nr_samples ? tex->nr_samples : 1;
    383    AddrSurfInfoIn.tileIndex = -1;
    384 
    385    /* Set the micro tile type. */
    386    if (flags & RADEON_SURF_SCANOUT)
    387       AddrSurfInfoIn.tileType = ADDR_DISPLAYABLE;
    388    else if (flags & (RADEON_SURF_Z_OR_SBUFFER | RADEON_SURF_FMASK))
    389       AddrSurfInfoIn.tileType = ADDR_DEPTH_SAMPLE_ORDER;
    390    else
    391       AddrSurfInfoIn.tileType = ADDR_NON_DISPLAYABLE;
    392 
    393    AddrSurfInfoIn.flags.color = !(flags & RADEON_SURF_Z_OR_SBUFFER);
    394    AddrSurfInfoIn.flags.depth = (flags & RADEON_SURF_ZBUFFER) != 0;
    395    AddrSurfInfoIn.flags.cube = tex->target == PIPE_TEXTURE_CUBE;
    396    AddrSurfInfoIn.flags.fmask = (flags & RADEON_SURF_FMASK) != 0;
    397    AddrSurfInfoIn.flags.display = (flags & RADEON_SURF_SCANOUT) != 0;
    398    AddrSurfInfoIn.flags.pow2Pad = tex->last_level > 0;
    399    AddrSurfInfoIn.flags.tcCompatible = (flags & RADEON_SURF_TC_COMPATIBLE_HTILE) != 0;
    400 
    401    /* Only degrade the tile mode for space if TC-compatible HTILE hasn't been
    402     * requested, because TC-compatible HTILE requires 2D tiling.
    403     */
    404    AddrSurfInfoIn.flags.degrade4Space = !AddrSurfInfoIn.flags.tcCompatible &&
    405                                         !AddrSurfInfoIn.flags.fmask &&
    406                                         tex->nr_samples <= 1 &&
    407                                         (flags & RADEON_SURF_OPTIMIZE_FOR_SPACE);
    408    AddrSurfInfoIn.flags.opt4Space = AddrSurfInfoIn.flags.degrade4Space;
    409 
    410    /* DCC notes:
    411     * - If we add MSAA support, keep in mind that CB can't decompress 8bpp
    412     *   with samples >= 4.
    413     * - Mipmapped array textures have low performance (discovered by a closed
    414     *   driver team).
    415     */
    416    AddrSurfInfoIn.flags.dccCompatible = ws->info.chip_class >= VI &&
    417                                         !(flags & RADEON_SURF_Z_OR_SBUFFER) &&
    418                                         !(flags & RADEON_SURF_DISABLE_DCC) &&
    419                                         !compressed && AddrDccIn.numSamples <= 1 &&
    420                                         ((tex->array_size == 1 && tex->depth0 == 1) ||
    421                                          tex->last_level == 0);
    422 
    423    AddrSurfInfoIn.flags.noStencil = (flags & RADEON_SURF_SBUFFER) == 0;
    424    AddrSurfInfoIn.flags.compressZ = AddrSurfInfoIn.flags.depth;
    425 
    426    /* noStencil = 0 can result in a depth part that is incompatible with
    427     * mipmapped texturing. So set noStencil = 1 when mipmaps are requested (in
    428     * this case, we may end up setting stencil_adjusted).
    429     *
    430     * TODO: update addrlib to a newer version, remove this, and
    431     * use flags.matchStencilTileCfg = 1 as an alternative fix.
    432     */
    433   if (tex->last_level > 0)
    434       AddrSurfInfoIn.flags.noStencil = 1;
    435 
    436    /* Set preferred macrotile parameters. This is usually required
    437     * for shared resources. This is for 2D tiling only. */
    438    if (AddrSurfInfoIn.tileMode >= ADDR_TM_2D_TILED_THIN1 &&
    439        surf->bankw && surf->bankh && surf->mtilea && surf->tile_split) {
    440       assert(!(flags & RADEON_SURF_FMASK));
    441 
    442       /* If any of these parameters are incorrect, the calculation
    443        * will fail. */
    444       AddrTileInfoIn.banks = surf->num_banks;
    445       AddrTileInfoIn.bankWidth = surf->bankw;
    446       AddrTileInfoIn.bankHeight = surf->bankh;
    447       AddrTileInfoIn.macroAspectRatio = surf->mtilea;
    448       AddrTileInfoIn.tileSplitBytes = surf->tile_split;
    449       AddrTileInfoIn.pipeConfig = surf->pipe_config + 1; /* +1 compared to GB_TILE_MODE */
    450       AddrSurfInfoIn.flags.degrade4Space = 0;
    451       AddrSurfInfoIn.pTileInfo = &AddrTileInfoIn;
    452 
    453       /* If AddrSurfInfoIn.pTileInfo is set, Addrlib doesn't set
    454        * the tile index, because we are expected to know it if
    455        * we know the other parameters.
    456        *
    457        * This is something that can easily be fixed in Addrlib.
    458        * For now, just figure it out here.
    459        * Note that only 2D_TILE_THIN1 is handled here.
    460        */
    461       assert(!(flags & RADEON_SURF_Z_OR_SBUFFER));
    462       assert(AddrSurfInfoIn.tileMode == ADDR_TM_2D_TILED_THIN1);
    463 
    464       if (ws->info.chip_class == SI) {
    465          if (AddrSurfInfoIn.tileType == ADDR_DISPLAYABLE) {
    466             if (bpe == 2)
    467                AddrSurfInfoIn.tileIndex = 11; /* 16bpp */
    468             else
    469                AddrSurfInfoIn.tileIndex = 12; /* 32bpp */
    470          } else {
    471             if (bpe == 1)
    472                AddrSurfInfoIn.tileIndex = 14; /* 8bpp */
    473             else if (bpe == 2)
    474                AddrSurfInfoIn.tileIndex = 15; /* 16bpp */
    475             else if (bpe == 4)
    476                AddrSurfInfoIn.tileIndex = 16; /* 32bpp */
    477             else
    478                AddrSurfInfoIn.tileIndex = 17; /* 64bpp (and 128bpp) */
    479          }
    480       } else {
    481          /* CIK - VI */
    482          if (AddrSurfInfoIn.tileType == ADDR_DISPLAYABLE)
    483             AddrSurfInfoIn.tileIndex = 10; /* 2D displayable */
    484          else
    485             AddrSurfInfoIn.tileIndex = 14; /* 2D non-displayable */
    486 
    487          /* Addrlib doesn't set this if tileIndex is forced like above. */
    488          AddrSurfInfoOut.macroModeIndex = cik_get_macro_tile_index(surf);
    489       }
    490    }
    491 
    492    surf->num_dcc_levels = 0;
    493    surf->surf_size = 0;
    494    surf->dcc_size = 0;
    495    surf->dcc_alignment = 1;
    496    surf->htile_size = 0;
    497    surf->htile_alignment = 1;
    498 
    499    /* Calculate texture layout information. */
    500    for (level = 0; level <= tex->last_level; level++) {
    501       r = compute_level(ws, tex, surf, false, level, compressed,
    502                         &AddrSurfInfoIn, &AddrSurfInfoOut,
    503                         &AddrDccIn, &AddrDccOut, &AddrHtileIn, &AddrHtileOut);
    504       if (r)
    505          return r;
    506 
    507       if (level == 0) {
    508          surf->surf_alignment = AddrSurfInfoOut.baseAlign;
    509          surf->pipe_config = AddrSurfInfoOut.pTileInfo->pipeConfig - 1;
    510          set_micro_tile_mode(surf, &ws->info);
    511 
    512          /* For 2D modes only. */
    513          if (AddrSurfInfoOut.tileMode >= ADDR_TM_2D_TILED_THIN1) {
    514             surf->bankw = AddrSurfInfoOut.pTileInfo->bankWidth;
    515             surf->bankh = AddrSurfInfoOut.pTileInfo->bankHeight;
    516             surf->mtilea = AddrSurfInfoOut.pTileInfo->macroAspectRatio;
    517             surf->tile_split = AddrSurfInfoOut.pTileInfo->tileSplitBytes;
    518             surf->num_banks = AddrSurfInfoOut.pTileInfo->banks;
    519             surf->macro_tile_index = AddrSurfInfoOut.macroModeIndex;
    520          } else {
    521             surf->macro_tile_index = 0;
    522          }
    523       }
    524    }
    525 
    526    /* Calculate texture layout information for stencil. */
    527    if (flags & RADEON_SURF_SBUFFER) {
    528       AddrSurfInfoIn.bpp = 8;
    529       AddrSurfInfoIn.flags.depth = 0;
    530       AddrSurfInfoIn.flags.stencil = 1;
    531       AddrSurfInfoIn.flags.tcCompatible = 0;
    532       /* This will be ignored if AddrSurfInfoIn.pTileInfo is NULL. */
    533       AddrTileInfoIn.tileSplitBytes = surf->stencil_tile_split;
    534 
    535       for (level = 0; level <= tex->last_level; level++) {
    536          r = compute_level(ws, tex, surf, true, level, compressed,
    537                            &AddrSurfInfoIn, &AddrSurfInfoOut, &AddrDccIn, &AddrDccOut,
    538                            NULL, NULL);
    539          if (r)
    540             return r;
    541 
    542          /* DB uses the depth pitch for both stencil and depth. */
    543          if (surf->stencil_level[level].nblk_x != surf->level[level].nblk_x)
    544             surf->stencil_adjusted = true;
    545 
    546          if (level == 0) {
    547             /* For 2D modes only. */
    548             if (AddrSurfInfoOut.tileMode >= ADDR_TM_2D_TILED_THIN1) {
    549                surf->stencil_tile_split =
    550                      AddrSurfInfoOut.pTileInfo->tileSplitBytes;
    551             }
    552          }
    553       }
    554    }
    555 
    556    /* Recalculate the whole DCC miptree size including disabled levels.
    557     * This is what addrlib does, but calling addrlib would be a lot more
    558     * complicated.
    559     */
    560    if (surf->dcc_size && tex->last_level > 0) {
    561       surf->dcc_size = align64(surf->surf_size >> 8,
    562                                ws->info.pipe_interleave_bytes *
    563                                ws->info.num_tile_pipes);
    564    }
    565 
    566    /* Make sure HTILE covers the whole miptree, because the shader reads
    567     * TC-compatible HTILE even for levels where it's disabled by DB.
    568     */
    569    if (surf->htile_size && tex->last_level)
    570 	   surf->htile_size *= 2;
    571 
    572    surf->is_linear = surf->level[0].mode == RADEON_SURF_MODE_LINEAR_ALIGNED;
    573    return 0;
    574 }
    575 
    576 void amdgpu_surface_init_functions(struct amdgpu_winsys *ws)
    577 {
    578    ws->base.surface_init = amdgpu_surface_init;
    579 }
    580