cf741049db826e4dfc44023a86302ce08ddcf3f0
[mesa.git] / src / amd / common / ac_surface.c
1 /*
2 * Copyright © 2011 Red Hat All Rights Reserved.
3 * Copyright © 2017 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 #include "ac_surface.h"
29 #include "amdgpu_id.h"
30 #include "util/macros.h"
31 #include "util/u_math.h"
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <amdgpu.h>
36 #include <amdgpu_drm.h>
37
38 #include "addrlib/addrinterface.h"
39
40 #ifndef CIASICIDGFXENGINE_SOUTHERNISLAND
41 #define CIASICIDGFXENGINE_SOUTHERNISLAND 0x0000000A
42 #endif
43
44 #ifndef CIASICIDGFXENGINE_ARCTICISLAND
45 #define CIASICIDGFXENGINE_ARCTICISLAND 0x0000000D
46 #endif
47
48 static void addrlib_family_rev_id(enum radeon_family family,
49 unsigned *addrlib_family,
50 unsigned *addrlib_revid)
51 {
52 switch (family) {
53 case CHIP_TAHITI:
54 *addrlib_family = FAMILY_SI;
55 *addrlib_revid = SI_TAHITI_P_A0;
56 break;
57 case CHIP_PITCAIRN:
58 *addrlib_family = FAMILY_SI;
59 *addrlib_revid = SI_PITCAIRN_PM_A0;
60 break;
61 case CHIP_VERDE:
62 *addrlib_family = FAMILY_SI;
63 *addrlib_revid = SI_CAPEVERDE_M_A0;
64 break;
65 case CHIP_OLAND:
66 *addrlib_family = FAMILY_SI;
67 *addrlib_revid = SI_OLAND_M_A0;
68 break;
69 case CHIP_HAINAN:
70 *addrlib_family = FAMILY_SI;
71 *addrlib_revid = SI_HAINAN_V_A0;
72 break;
73 case CHIP_BONAIRE:
74 *addrlib_family = FAMILY_CI;
75 *addrlib_revid = CI_BONAIRE_M_A0;
76 break;
77 case CHIP_KAVERI:
78 *addrlib_family = FAMILY_KV;
79 *addrlib_revid = KV_SPECTRE_A0;
80 break;
81 case CHIP_KABINI:
82 *addrlib_family = FAMILY_KV;
83 *addrlib_revid = KB_KALINDI_A0;
84 break;
85 case CHIP_HAWAII:
86 *addrlib_family = FAMILY_CI;
87 *addrlib_revid = CI_HAWAII_P_A0;
88 break;
89 case CHIP_MULLINS:
90 *addrlib_family = FAMILY_KV;
91 *addrlib_revid = ML_GODAVARI_A0;
92 break;
93 case CHIP_TONGA:
94 *addrlib_family = FAMILY_VI;
95 *addrlib_revid = VI_TONGA_P_A0;
96 break;
97 case CHIP_ICELAND:
98 *addrlib_family = FAMILY_VI;
99 *addrlib_revid = VI_ICELAND_M_A0;
100 break;
101 case CHIP_CARRIZO:
102 *addrlib_family = FAMILY_CZ;
103 *addrlib_revid = CARRIZO_A0;
104 break;
105 case CHIP_STONEY:
106 *addrlib_family = FAMILY_CZ;
107 *addrlib_revid = STONEY_A0;
108 break;
109 case CHIP_FIJI:
110 *addrlib_family = FAMILY_VI;
111 *addrlib_revid = VI_FIJI_P_A0;
112 break;
113 case CHIP_POLARIS10:
114 *addrlib_family = FAMILY_VI;
115 *addrlib_revid = VI_POLARIS10_P_A0;
116 break;
117 case CHIP_POLARIS11:
118 *addrlib_family = FAMILY_VI;
119 *addrlib_revid = VI_POLARIS11_M_A0;
120 break;
121 case CHIP_POLARIS12:
122 *addrlib_family = FAMILY_VI;
123 *addrlib_revid = VI_POLARIS12_V_A0;
124 break;
125 case CHIP_VEGA10:
126 *addrlib_family = FAMILY_AI;
127 *addrlib_revid = AI_VEGA10_P_A0;
128 break;
129 case CHIP_RAVEN:
130 *addrlib_family = FAMILY_RV;
131 *addrlib_revid = RAVEN_A0;
132 break;
133 default:
134 fprintf(stderr, "amdgpu: Unknown family.\n");
135 }
136 }
137
138 static void *ADDR_API allocSysMem(const ADDR_ALLOCSYSMEM_INPUT * pInput)
139 {
140 return malloc(pInput->sizeInBytes);
141 }
142
143 static ADDR_E_RETURNCODE ADDR_API freeSysMem(const ADDR_FREESYSMEM_INPUT * pInput)
144 {
145 free(pInput->pVirtAddr);
146 return ADDR_OK;
147 }
148
149 ADDR_HANDLE amdgpu_addr_create(enum radeon_family family,
150 const struct amdgpu_gpu_info *info)
151 {
152 ADDR_CREATE_INPUT addrCreateInput = {0};
153 ADDR_CREATE_OUTPUT addrCreateOutput = {0};
154 ADDR_REGISTER_VALUE regValue = {0};
155 ADDR_CREATE_FLAGS createFlags = {{0}};
156 ADDR_E_RETURNCODE addrRet;
157
158 addrCreateInput.size = sizeof(ADDR_CREATE_INPUT);
159 addrCreateOutput.size = sizeof(ADDR_CREATE_OUTPUT);
160
161 regValue.gbAddrConfig = info->gb_addr_cfg;
162 createFlags.value = 0;
163
164 addrlib_family_rev_id(family, &addrCreateInput.chipFamily, &addrCreateInput.chipRevision);
165 if (addrCreateInput.chipFamily == FAMILY_UNKNOWN)
166 return NULL;
167
168 if (addrCreateInput.chipFamily >= FAMILY_AI) {
169 addrCreateInput.chipEngine = CIASICIDGFXENGINE_ARCTICISLAND;
170 regValue.blockVarSizeLog2 = 0;
171 } else {
172 regValue.noOfBanks = info->mc_arb_ramcfg & 0x3;
173 regValue.noOfRanks = (info->mc_arb_ramcfg & 0x4) >> 2;
174
175 regValue.backendDisables = info->enabled_rb_pipes_mask;
176 regValue.pTileConfig = info->gb_tile_mode;
177 regValue.noOfEntries = ARRAY_SIZE(info->gb_tile_mode);
178 if (addrCreateInput.chipFamily == FAMILY_SI) {
179 regValue.pMacroTileConfig = NULL;
180 regValue.noOfMacroEntries = 0;
181 } else {
182 regValue.pMacroTileConfig = info->gb_macro_tile_mode;
183 regValue.noOfMacroEntries = ARRAY_SIZE(info->gb_macro_tile_mode);
184 }
185
186 createFlags.useTileIndex = 1;
187 createFlags.useHtileSliceAlign = 1;
188
189 addrCreateInput.chipEngine = CIASICIDGFXENGINE_SOUTHERNISLAND;
190 }
191
192 addrCreateInput.callbacks.allocSysMem = allocSysMem;
193 addrCreateInput.callbacks.freeSysMem = freeSysMem;
194 addrCreateInput.callbacks.debugPrint = 0;
195 addrCreateInput.createFlags = createFlags;
196 addrCreateInput.regValue = regValue;
197
198 addrRet = AddrCreate(&addrCreateInput, &addrCreateOutput);
199 if (addrRet != ADDR_OK)
200 return NULL;
201
202 return addrCreateOutput.hLib;
203 }
204
205 static int gfx6_compute_level(ADDR_HANDLE addrlib,
206 const struct ac_surf_config *config,
207 struct radeon_surf *surf, bool is_stencil,
208 unsigned level, bool compressed,
209 ADDR_COMPUTE_SURFACE_INFO_INPUT *AddrSurfInfoIn,
210 ADDR_COMPUTE_SURFACE_INFO_OUTPUT *AddrSurfInfoOut,
211 ADDR_COMPUTE_DCCINFO_INPUT *AddrDccIn,
212 ADDR_COMPUTE_DCCINFO_OUTPUT *AddrDccOut,
213 ADDR_COMPUTE_HTILE_INFO_INPUT *AddrHtileIn,
214 ADDR_COMPUTE_HTILE_INFO_OUTPUT *AddrHtileOut)
215 {
216 struct legacy_surf_level *surf_level;
217 ADDR_E_RETURNCODE ret;
218
219 AddrSurfInfoIn->mipLevel = level;
220 AddrSurfInfoIn->width = u_minify(config->info.width, level);
221 AddrSurfInfoIn->height = u_minify(config->info.height, level);
222
223 if (config->is_3d)
224 AddrSurfInfoIn->numSlices = u_minify(config->info.depth, level);
225 else if (config->is_cube)
226 AddrSurfInfoIn->numSlices = 6;
227 else
228 AddrSurfInfoIn->numSlices = config->info.array_size;
229
230 if (level > 0) {
231 /* Set the base level pitch. This is needed for calculation
232 * of non-zero levels. */
233 if (is_stencil)
234 AddrSurfInfoIn->basePitch = surf->u.legacy.stencil_level[0].nblk_x;
235 else
236 AddrSurfInfoIn->basePitch = surf->u.legacy.level[0].nblk_x;
237
238 /* Convert blocks to pixels for compressed formats. */
239 if (compressed)
240 AddrSurfInfoIn->basePitch *= surf->blk_w;
241 }
242
243 ret = AddrComputeSurfaceInfo(addrlib,
244 AddrSurfInfoIn,
245 AddrSurfInfoOut);
246 if (ret != ADDR_OK) {
247 return ret;
248 }
249
250 surf_level = is_stencil ? &surf->u.legacy.stencil_level[level] : &surf->u.legacy.level[level];
251 surf_level->offset = align64(surf->surf_size, AddrSurfInfoOut->baseAlign);
252 surf_level->slice_size = AddrSurfInfoOut->sliceSize;
253 surf_level->nblk_x = AddrSurfInfoOut->pitch;
254 surf_level->nblk_y = AddrSurfInfoOut->height;
255
256 switch (AddrSurfInfoOut->tileMode) {
257 case ADDR_TM_LINEAR_ALIGNED:
258 surf_level->mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
259 break;
260 case ADDR_TM_1D_TILED_THIN1:
261 surf_level->mode = RADEON_SURF_MODE_1D;
262 break;
263 case ADDR_TM_2D_TILED_THIN1:
264 surf_level->mode = RADEON_SURF_MODE_2D;
265 break;
266 default:
267 assert(0);
268 }
269
270 if (is_stencil)
271 surf->u.legacy.stencil_tiling_index[level] = AddrSurfInfoOut->tileIndex;
272 else
273 surf->u.legacy.tiling_index[level] = AddrSurfInfoOut->tileIndex;
274
275 surf->surf_size = surf_level->offset + AddrSurfInfoOut->surfSize;
276
277 /* Clear DCC fields at the beginning. */
278 surf_level->dcc_offset = 0;
279
280 /* The previous level's flag tells us if we can use DCC for this level. */
281 if (AddrSurfInfoIn->flags.dccCompatible &&
282 (level == 0 || AddrDccOut->subLvlCompressible)) {
283 AddrDccIn->colorSurfSize = AddrSurfInfoOut->surfSize;
284 AddrDccIn->tileMode = AddrSurfInfoOut->tileMode;
285 AddrDccIn->tileInfo = *AddrSurfInfoOut->pTileInfo;
286 AddrDccIn->tileIndex = AddrSurfInfoOut->tileIndex;
287 AddrDccIn->macroModeIndex = AddrSurfInfoOut->macroModeIndex;
288
289 ret = AddrComputeDccInfo(addrlib,
290 AddrDccIn,
291 AddrDccOut);
292
293 if (ret == ADDR_OK) {
294 surf_level->dcc_offset = surf->dcc_size;
295 surf_level->dcc_fast_clear_size = AddrDccOut->dccFastClearSize;
296 surf->num_dcc_levels = level + 1;
297 surf->dcc_size = surf_level->dcc_offset + AddrDccOut->dccRamSize;
298 surf->dcc_alignment = MAX2(surf->dcc_alignment, AddrDccOut->dccRamBaseAlign);
299 }
300 }
301
302 /* TC-compatible HTILE. */
303 if (!is_stencil &&
304 AddrSurfInfoIn->flags.depth &&
305 AddrSurfInfoIn->flags.tcCompatible &&
306 surf_level->mode == RADEON_SURF_MODE_2D &&
307 level == 0) {
308 AddrHtileIn->flags.tcCompatible = 1;
309 AddrHtileIn->pitch = AddrSurfInfoOut->pitch;
310 AddrHtileIn->height = AddrSurfInfoOut->height;
311 AddrHtileIn->numSlices = AddrSurfInfoOut->depth;
312 AddrHtileIn->blockWidth = ADDR_HTILE_BLOCKSIZE_8;
313 AddrHtileIn->blockHeight = ADDR_HTILE_BLOCKSIZE_8;
314 AddrHtileIn->pTileInfo = AddrSurfInfoOut->pTileInfo;
315 AddrHtileIn->tileIndex = AddrSurfInfoOut->tileIndex;
316 AddrHtileIn->macroModeIndex = AddrSurfInfoOut->macroModeIndex;
317
318 ret = AddrComputeHtileInfo(addrlib,
319 AddrHtileIn,
320 AddrHtileOut);
321
322 if (ret == ADDR_OK) {
323 surf->htile_size = AddrHtileOut->htileBytes;
324 surf->htile_alignment = AddrHtileOut->baseAlign;
325 }
326 }
327
328 return 0;
329 }
330
331 #define G_009910_MICRO_TILE_MODE(x) (((x) >> 0) & 0x03)
332 #define G_009910_MICRO_TILE_MODE_NEW(x) (((x) >> 22) & 0x07)
333
334 static void gfx6_set_micro_tile_mode(struct radeon_surf *surf,
335 const struct amdgpu_gpu_info *amdinfo)
336 {
337 uint32_t tile_mode = amdinfo->gb_tile_mode[surf->u.legacy.tiling_index[0]];
338
339 if (amdinfo->family_id >= AMDGPU_FAMILY_CI)
340 surf->micro_tile_mode = G_009910_MICRO_TILE_MODE_NEW(tile_mode);
341 else
342 surf->micro_tile_mode = G_009910_MICRO_TILE_MODE(tile_mode);
343 }
344
345 static unsigned cik_get_macro_tile_index(struct radeon_surf *surf)
346 {
347 unsigned index, tileb;
348
349 tileb = 8 * 8 * surf->bpe;
350 tileb = MIN2(surf->u.legacy.tile_split, tileb);
351
352 for (index = 0; tileb > 64; index++)
353 tileb >>= 1;
354
355 assert(index < 16);
356 return index;
357 }
358
359 /**
360 * Fill in the tiling information in \p surf based on the given surface config.
361 *
362 * The following fields of \p surf must be initialized by the caller:
363 * blk_w, blk_h, bpe, flags.
364 */
365 int gfx6_compute_surface(ADDR_HANDLE addrlib,
366 const struct ac_surf_config *config,
367 enum radeon_surf_mode mode,
368 struct radeon_surf *surf)
369 {
370 unsigned level;
371 bool compressed;
372 ADDR_COMPUTE_SURFACE_INFO_INPUT AddrSurfInfoIn = {0};
373 ADDR_COMPUTE_SURFACE_INFO_OUTPUT AddrSurfInfoOut = {0};
374 ADDR_COMPUTE_DCCINFO_INPUT AddrDccIn = {0};
375 ADDR_COMPUTE_DCCINFO_OUTPUT AddrDccOut = {0};
376 ADDR_COMPUTE_HTILE_INFO_INPUT AddrHtileIn = {0};
377 ADDR_COMPUTE_HTILE_INFO_OUTPUT AddrHtileOut = {0};
378 ADDR_TILEINFO AddrTileInfoIn = {0};
379 ADDR_TILEINFO AddrTileInfoOut = {0};
380 int r;
381
382 AddrSurfInfoIn.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT);
383 AddrSurfInfoOut.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT);
384 AddrDccIn.size = sizeof(ADDR_COMPUTE_DCCINFO_INPUT);
385 AddrDccOut.size = sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT);
386 AddrHtileIn.size = sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT);
387 AddrHtileOut.size = sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT);
388 AddrSurfInfoOut.pTileInfo = &AddrTileInfoOut;
389
390 compressed = surf->blk_w == 4 && surf->blk_h == 4;
391
392 /* MSAA and FMASK require 2D tiling. */
393 if (config->info.samples > 1 ||
394 (surf->flags & RADEON_SURF_FMASK))
395 mode = RADEON_SURF_MODE_2D;
396
397 /* DB doesn't support linear layouts. */
398 if (surf->flags & (RADEON_SURF_Z_OR_SBUFFER) &&
399 mode < RADEON_SURF_MODE_1D)
400 mode = RADEON_SURF_MODE_1D;
401
402 /* Set the requested tiling mode. */
403 switch (mode) {
404 case RADEON_SURF_MODE_LINEAR_ALIGNED:
405 AddrSurfInfoIn.tileMode = ADDR_TM_LINEAR_ALIGNED;
406 break;
407 case RADEON_SURF_MODE_1D:
408 AddrSurfInfoIn.tileMode = ADDR_TM_1D_TILED_THIN1;
409 break;
410 case RADEON_SURF_MODE_2D:
411 AddrSurfInfoIn.tileMode = ADDR_TM_2D_TILED_THIN1;
412 break;
413 default:
414 assert(0);
415 }
416
417 /* The format must be set correctly for the allocation of compressed
418 * textures to work. In other cases, setting the bpp is sufficient.
419 */
420 if (compressed) {
421 switch (surf->bpe) {
422 case 8:
423 AddrSurfInfoIn.format = ADDR_FMT_BC1;
424 break;
425 case 16:
426 AddrSurfInfoIn.format = ADDR_FMT_BC3;
427 break;
428 default:
429 assert(0);
430 }
431 }
432 else {
433 AddrDccIn.bpp = AddrSurfInfoIn.bpp = surf->bpe * 8;
434 }
435
436 AddrDccIn.numSamples = AddrSurfInfoIn.numSamples =
437 config->info.samples ? config->info.samples : 1;
438 AddrSurfInfoIn.tileIndex = -1;
439
440 /* Set the micro tile type. */
441 if (surf->flags & RADEON_SURF_SCANOUT)
442 AddrSurfInfoIn.tileType = ADDR_DISPLAYABLE;
443 else if (surf->flags & (RADEON_SURF_Z_OR_SBUFFER | RADEON_SURF_FMASK))
444 AddrSurfInfoIn.tileType = ADDR_DEPTH_SAMPLE_ORDER;
445 else
446 AddrSurfInfoIn.tileType = ADDR_NON_DISPLAYABLE;
447
448 AddrSurfInfoIn.flags.color = !(surf->flags & RADEON_SURF_Z_OR_SBUFFER);
449 AddrSurfInfoIn.flags.depth = (surf->flags & RADEON_SURF_ZBUFFER) != 0;
450 AddrSurfInfoIn.flags.cube = config->is_cube;
451 AddrSurfInfoIn.flags.fmask = (surf->flags & RADEON_SURF_FMASK) != 0;
452 AddrSurfInfoIn.flags.display = (surf->flags & RADEON_SURF_SCANOUT) != 0;
453 AddrSurfInfoIn.flags.pow2Pad = config->info.levels > 1;
454 AddrSurfInfoIn.flags.tcCompatible = (surf->flags & RADEON_SURF_TC_COMPATIBLE_HTILE) != 0;
455
456 /* Only degrade the tile mode for space if TC-compatible HTILE hasn't been
457 * requested, because TC-compatible HTILE requires 2D tiling.
458 */
459 AddrSurfInfoIn.flags.opt4Space = !AddrSurfInfoIn.flags.tcCompatible &&
460 !AddrSurfInfoIn.flags.fmask &&
461 config->info.samples <= 1 &&
462 (surf->flags & RADEON_SURF_OPTIMIZE_FOR_SPACE);
463
464 /* DCC notes:
465 * - If we add MSAA support, keep in mind that CB can't decompress 8bpp
466 * with samples >= 4.
467 * - Mipmapped array textures have low performance (discovered by a closed
468 * driver team).
469 */
470 AddrSurfInfoIn.flags.dccCompatible =
471 config->chip_class >= VI &&
472 !(surf->flags & RADEON_SURF_Z_OR_SBUFFER) &&
473 !(surf->flags & RADEON_SURF_DISABLE_DCC) &&
474 !compressed && AddrDccIn.numSamples <= 1 &&
475 ((config->info.array_size == 1 && config->info.depth == 1) ||
476 config->info.levels == 1);
477
478 AddrSurfInfoIn.flags.noStencil = (surf->flags & RADEON_SURF_SBUFFER) == 0;
479 AddrSurfInfoIn.flags.compressZ = AddrSurfInfoIn.flags.depth;
480
481 /* noStencil = 0 can result in a depth part that is incompatible with
482 * mipmapped texturing. So set noStencil = 1 when mipmaps are requested (in
483 * this case, we may end up setting stencil_adjusted).
484 *
485 * TODO: update addrlib to a newer version, remove this, and
486 * use flags.matchStencilTileCfg = 1 as an alternative fix.
487 */
488 if (config->info.levels > 1)
489 AddrSurfInfoIn.flags.noStencil = 1;
490
491 /* Set preferred macrotile parameters. This is usually required
492 * for shared resources. This is for 2D tiling only. */
493 if (AddrSurfInfoIn.tileMode >= ADDR_TM_2D_TILED_THIN1 &&
494 surf->u.legacy.bankw && surf->u.legacy.bankh &&
495 surf->u.legacy.mtilea && surf->u.legacy.tile_split) {
496 assert(!(surf->flags & RADEON_SURF_FMASK));
497
498 /* If any of these parameters are incorrect, the calculation
499 * will fail. */
500 AddrTileInfoIn.banks = surf->u.legacy.num_banks;
501 AddrTileInfoIn.bankWidth = surf->u.legacy.bankw;
502 AddrTileInfoIn.bankHeight = surf->u.legacy.bankh;
503 AddrTileInfoIn.macroAspectRatio = surf->u.legacy.mtilea;
504 AddrTileInfoIn.tileSplitBytes = surf->u.legacy.tile_split;
505 AddrTileInfoIn.pipeConfig = surf->u.legacy.pipe_config + 1; /* +1 compared to GB_TILE_MODE */
506 AddrSurfInfoIn.flags.opt4Space = 0;
507 AddrSurfInfoIn.pTileInfo = &AddrTileInfoIn;
508
509 /* If AddrSurfInfoIn.pTileInfo is set, Addrlib doesn't set
510 * the tile index, because we are expected to know it if
511 * we know the other parameters.
512 *
513 * This is something that can easily be fixed in Addrlib.
514 * For now, just figure it out here.
515 * Note that only 2D_TILE_THIN1 is handled here.
516 */
517 assert(!(surf->flags & RADEON_SURF_Z_OR_SBUFFER));
518 assert(AddrSurfInfoIn.tileMode == ADDR_TM_2D_TILED_THIN1);
519
520 if (config->chip_class == SI) {
521 if (AddrSurfInfoIn.tileType == ADDR_DISPLAYABLE) {
522 if (surf->bpe == 2)
523 AddrSurfInfoIn.tileIndex = 11; /* 16bpp */
524 else
525 AddrSurfInfoIn.tileIndex = 12; /* 32bpp */
526 } else {
527 if (surf->bpe == 1)
528 AddrSurfInfoIn.tileIndex = 14; /* 8bpp */
529 else if (surf->bpe == 2)
530 AddrSurfInfoIn.tileIndex = 15; /* 16bpp */
531 else if (surf->bpe == 4)
532 AddrSurfInfoIn.tileIndex = 16; /* 32bpp */
533 else
534 AddrSurfInfoIn.tileIndex = 17; /* 64bpp (and 128bpp) */
535 }
536 } else {
537 /* CIK - VI */
538 if (AddrSurfInfoIn.tileType == ADDR_DISPLAYABLE)
539 AddrSurfInfoIn.tileIndex = 10; /* 2D displayable */
540 else
541 AddrSurfInfoIn.tileIndex = 14; /* 2D non-displayable */
542
543 /* Addrlib doesn't set this if tileIndex is forced like above. */
544 AddrSurfInfoOut.macroModeIndex = cik_get_macro_tile_index(surf);
545 }
546 }
547
548 surf->num_dcc_levels = 0;
549 surf->surf_size = 0;
550 surf->dcc_size = 0;
551 surf->dcc_alignment = 1;
552 surf->htile_size = 0;
553 surf->htile_alignment = 1;
554
555 /* Calculate texture layout information. */
556 for (level = 0; level < config->info.levels; level++) {
557 r = gfx6_compute_level(addrlib, config, surf, false, level, compressed,
558 &AddrSurfInfoIn, &AddrSurfInfoOut,
559 &AddrDccIn, &AddrDccOut, &AddrHtileIn, &AddrHtileOut);
560 if (r)
561 return r;
562
563 if (level == 0) {
564 surf->surf_alignment = AddrSurfInfoOut.baseAlign;
565 surf->u.legacy.pipe_config = AddrSurfInfoOut.pTileInfo->pipeConfig - 1;
566 gfx6_set_micro_tile_mode(surf, config->amdinfo);
567
568 /* For 2D modes only. */
569 if (AddrSurfInfoOut.tileMode >= ADDR_TM_2D_TILED_THIN1) {
570 surf->u.legacy.bankw = AddrSurfInfoOut.pTileInfo->bankWidth;
571 surf->u.legacy.bankh = AddrSurfInfoOut.pTileInfo->bankHeight;
572 surf->u.legacy.mtilea = AddrSurfInfoOut.pTileInfo->macroAspectRatio;
573 surf->u.legacy.tile_split = AddrSurfInfoOut.pTileInfo->tileSplitBytes;
574 surf->u.legacy.num_banks = AddrSurfInfoOut.pTileInfo->banks;
575 surf->u.legacy.macro_tile_index = AddrSurfInfoOut.macroModeIndex;
576 } else {
577 surf->u.legacy.macro_tile_index = 0;
578 }
579 }
580 }
581
582 /* Calculate texture layout information for stencil. */
583 if (surf->flags & RADEON_SURF_SBUFFER) {
584 AddrSurfInfoIn.bpp = 8;
585 AddrSurfInfoIn.flags.depth = 0;
586 AddrSurfInfoIn.flags.stencil = 1;
587 AddrSurfInfoIn.flags.tcCompatible = 0;
588 /* This will be ignored if AddrSurfInfoIn.pTileInfo is NULL. */
589 AddrTileInfoIn.tileSplitBytes = surf->u.legacy.stencil_tile_split;
590
591 for (level = 0; level < config->info.levels; level++) {
592 r = gfx6_compute_level(addrlib, config, surf, true, level, compressed,
593 &AddrSurfInfoIn, &AddrSurfInfoOut,
594 &AddrDccIn, &AddrDccOut,
595 NULL, NULL);
596 if (r)
597 return r;
598
599 /* DB uses the depth pitch for both stencil and depth. */
600 if (surf->u.legacy.stencil_level[level].nblk_x !=
601 surf->u.legacy.level[level].nblk_x)
602 surf->u.legacy.stencil_adjusted = true;
603
604 if (level == 0) {
605 /* For 2D modes only. */
606 if (AddrSurfInfoOut.tileMode >= ADDR_TM_2D_TILED_THIN1) {
607 surf->u.legacy.stencil_tile_split =
608 AddrSurfInfoOut.pTileInfo->tileSplitBytes;
609 }
610 }
611 }
612 }
613
614 /* Recalculate the whole DCC miptree size including disabled levels.
615 * This is what addrlib does, but calling addrlib would be a lot more
616 * complicated.
617 */
618 if (surf->dcc_size && config->info.levels > 1) {
619 surf->dcc_size = align64(surf->surf_size >> 8,
620 config->pipe_interleave_bytes *
621 config->num_tile_pipes);
622 }
623
624 /* Make sure HTILE covers the whole miptree, because the shader reads
625 * TC-compatible HTILE even for levels where it's disabled by DB.
626 */
627 if (surf->htile_size && config->info.levels > 1)
628 surf->htile_size *= 2;
629
630 surf->is_linear = surf->u.legacy.level[0].mode == RADEON_SURF_MODE_LINEAR_ALIGNED;
631 return 0;
632 }