• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2016 Red Hat.
3  * Copyright © 2016 Bas Nieuwenhuizen
4  *
5  * based on amdgpu winsys.
6  * Copyright © 2011 Marek Olšák <maraeo@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 
radv_amdgpu_surface_sanity(const struct radeon_surf * surf)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 
radv_allocSysMem(const ADDR_ALLOCSYSMEM_INPUT * pInput)103 static void *ADDR_API radv_allocSysMem(const ADDR_ALLOCSYSMEM_INPUT * pInput)
104 {
105 	return malloc(pInput->sizeInBytes);
106 }
107 
radv_freeSysMem(const ADDR_FREESYSMEM_INPUT * pInput)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 
radv_amdgpu_addr_create(struct amdgpu_gpu_info * amdinfo,int family,int rev_id,enum chip_class chip_class)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 
radv_compute_level(ADDR_HANDLE addrlib,struct radeon_surf * surf,bool is_stencil,unsigned level,unsigned type,bool compressed,ADDR_COMPUTE_SURFACE_INFO_INPUT * AddrSurfInfoIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * AddrSurfInfoOut,ADDR_COMPUTE_DCCINFO_INPUT * AddrDccIn,ADDR_COMPUTE_DCCINFO_OUTPUT * AddrDccOut)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 
radv_set_micro_tile_mode(struct radeon_surf * surf,struct radeon_info * info)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 
cik_get_macro_tile_index(struct radeon_surf * surf)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 
radv_amdgpu_winsys_surface_init(struct radeon_winsys * _ws,struct radeon_surf * surf)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 
radv_amdgpu_winsys_surface_best(struct radeon_winsys * rws,struct radeon_surf * surf)527 static int radv_amdgpu_winsys_surface_best(struct radeon_winsys *rws,
528 					   struct radeon_surf *surf)
529 {
530 	return 0;
531 }
532 
radv_amdgpu_surface_init_functions(struct radv_amdgpu_winsys * ws)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