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