2 * Copyright © 2011 Red Hat All Rights Reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
14 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
16 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 * The above copyright notice and this permission notice (including the
22 * next paragraph) shall be included in all copies or substantial portions
27 * Jérôme Glisse <jglisse@redhat.com>
38 #include <sys/ioctl.h>
40 #include "libdrm_macros.h"
42 #include "radeon_drm.h"
43 #include "radeon_surface.h"
45 #define CIK_TILE_MODE_COLOR_2D 14
46 #define CIK_TILE_MODE_COLOR_2D_SCANOUT 10
47 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64 0
48 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128 1
49 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256 2
50 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512 3
51 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE 4
53 #define ALIGN(value, alignment) (((value) + alignment - 1) & ~(alignment - 1))
54 #define MAX2(A, B) ((A) > (B) ? (A) : (B))
55 #define MIN2(A, B) ((A) < (B) ? (A) : (B))
57 /* keep this private */
98 typedef int (*hw_init_surface_t)(struct radeon_surface_manager *surf_man,
99 struct radeon_surface *surf);
100 typedef int (*hw_best_surface_t)(struct radeon_surface_manager *surf_man,
101 struct radeon_surface *surf);
103 struct radeon_hw_info {
104 /* apply to r6, eg */
105 uint32_t group_bytes;
112 uint32_t tile_mode_array[32];
114 uint32_t macrotile_mode_array[16];
117 struct radeon_surface_manager {
120 struct radeon_hw_info hw_info;
122 hw_init_surface_t surface_init;
123 hw_best_surface_t surface_best;
127 static int radeon_get_value(int fd, unsigned req, uint32_t *value)
129 struct drm_radeon_info info = {};
134 info.value = (uintptr_t)value;
135 r = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info,
136 sizeof(struct drm_radeon_info));
140 static int radeon_get_family(struct radeon_surface_manager *surf_man)
142 switch (surf_man->device_id) {
143 #define CHIPSET(pci_id, name, fam) case pci_id: surf_man->family = CHIP_##fam; break;
144 #include "r600_pci_ids.h"
152 static unsigned next_power_of_two(unsigned x)
157 return (1 << ((sizeof(unsigned) * 8) - __builtin_clz(x - 1)));
160 static unsigned mip_minify(unsigned size, unsigned level)
164 val = MAX2(1, size >> level);
166 val = next_power_of_two(val);
170 static void surf_minify(struct radeon_surface *surf,
171 struct radeon_surface_level *surflevel,
172 unsigned bpe, unsigned level,
173 uint32_t xalign, uint32_t yalign, uint32_t zalign,
176 surflevel->npix_x = mip_minify(surf->npix_x, level);
177 surflevel->npix_y = mip_minify(surf->npix_y, level);
178 surflevel->npix_z = mip_minify(surf->npix_z, level);
179 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
180 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
181 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
182 if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
183 !(surf->flags & RADEON_SURF_FMASK)) {
184 if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
185 surflevel->mode = RADEON_SURF_MODE_1D;
189 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign);
190 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign);
191 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign);
193 surflevel->offset = offset;
194 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
195 surflevel->slice_size = (uint64_t)surflevel->pitch_bytes * surflevel->nblk_y;
197 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
200 /* ===========================================================================
203 static int r6_init_hw_info(struct radeon_surface_manager *surf_man)
205 uint32_t tiling_config;
206 drmVersionPtr version;
209 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
215 surf_man->hw_info.allow_2d = 0;
216 version = drmGetVersion(surf_man->fd);
217 if (version && version->version_minor >= 14) {
218 surf_man->hw_info.allow_2d = 1;
220 drmFreeVersion(version);
222 switch ((tiling_config & 0xe) >> 1) {
224 surf_man->hw_info.num_pipes = 1;
227 surf_man->hw_info.num_pipes = 2;
230 surf_man->hw_info.num_pipes = 4;
233 surf_man->hw_info.num_pipes = 8;
236 surf_man->hw_info.num_pipes = 8;
237 surf_man->hw_info.allow_2d = 0;
241 switch ((tiling_config & 0x30) >> 4) {
243 surf_man->hw_info.num_banks = 4;
246 surf_man->hw_info.num_banks = 8;
249 surf_man->hw_info.num_banks = 8;
250 surf_man->hw_info.allow_2d = 0;
254 switch ((tiling_config & 0xc0) >> 6) {
256 surf_man->hw_info.group_bytes = 256;
259 surf_man->hw_info.group_bytes = 512;
262 surf_man->hw_info.group_bytes = 256;
263 surf_man->hw_info.allow_2d = 0;
269 static int r6_surface_init_linear(struct radeon_surface_manager *surf_man,
270 struct radeon_surface *surf,
271 uint64_t offset, unsigned start_level)
273 uint32_t xalign, yalign, zalign;
276 /* compute alignment */
278 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
280 /* the 32 alignment is for scanout, cb or db but to allow texture to be
281 * easily bound as such we force this alignment to all surface
283 xalign = MAX2(1, surf_man->hw_info.group_bytes / surf->bpe);
286 if (surf->flags & RADEON_SURF_SCANOUT) {
287 xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
290 /* build mipmap tree */
291 for (i = start_level; i <= surf->last_level; i++) {
292 surf->level[i].mode = RADEON_SURF_MODE_LINEAR;
293 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
294 /* level0 and first mipmap need to have alignment */
295 offset = surf->bo_size;
297 offset = ALIGN(offset, surf->bo_alignment);
303 static int r6_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
304 struct radeon_surface *surf,
305 uint64_t offset, unsigned start_level)
307 uint32_t xalign, yalign, zalign;
310 /* compute alignment */
312 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
314 xalign = MAX2(64, surf_man->hw_info.group_bytes / surf->bpe);
318 /* build mipmap tree */
319 for (i = start_level; i <= surf->last_level; i++) {
320 surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
321 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
322 /* level0 and first mipmap need to have alignment */
323 offset = surf->bo_size;
325 offset = ALIGN(offset, surf->bo_alignment);
331 static int r6_surface_init_1d(struct radeon_surface_manager *surf_man,
332 struct radeon_surface *surf,
333 uint64_t offset, unsigned start_level)
335 uint32_t xalign, yalign, zalign, tilew;
338 /* compute alignment */
340 xalign = surf_man->hw_info.group_bytes / (tilew * surf->bpe * surf->nsamples);
341 xalign = MAX2(tilew, xalign);
344 if (surf->flags & RADEON_SURF_SCANOUT) {
345 xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
348 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
351 /* build mipmap tree */
352 for (i = start_level; i <= surf->last_level; i++) {
353 surf->level[i].mode = RADEON_SURF_MODE_1D;
354 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
355 /* level0 and first mipmap need to have alignment */
356 offset = surf->bo_size;
358 offset = ALIGN(offset, surf->bo_alignment);
364 static int r6_surface_init_2d(struct radeon_surface_manager *surf_man,
365 struct radeon_surface *surf,
366 uint64_t offset, unsigned start_level)
368 uint32_t xalign, yalign, zalign, tilew;
371 /* compute alignment */
374 xalign = (surf_man->hw_info.group_bytes * surf_man->hw_info.num_banks) /
375 (tilew * surf->bpe * surf->nsamples);
376 xalign = MAX2(tilew * surf_man->hw_info.num_banks, xalign);
377 if (surf->flags & RADEON_SURF_FMASK)
378 xalign = MAX2(128, xalign);
379 yalign = tilew * surf_man->hw_info.num_pipes;
380 if (surf->flags & RADEON_SURF_SCANOUT) {
381 xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
385 MAX2(surf_man->hw_info.num_pipes *
386 surf_man->hw_info.num_banks *
387 surf->nsamples * surf->bpe * 64,
388 xalign * yalign * surf->nsamples * surf->bpe);
391 /* build mipmap tree */
392 for (i = start_level; i <= surf->last_level; i++) {
393 surf->level[i].mode = RADEON_SURF_MODE_2D;
394 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
395 if (surf->level[i].mode == RADEON_SURF_MODE_1D) {
396 return r6_surface_init_1d(surf_man, surf, offset, i);
398 /* level0 and first mipmap need to have alignment */
399 offset = surf->bo_size;
401 offset = ALIGN(offset, surf->bo_alignment);
407 static int r6_surface_init(struct radeon_surface_manager *surf_man,
408 struct radeon_surface *surf)
413 /* MSAA surfaces support the 2D mode only. */
414 if (surf->nsamples > 1) {
415 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
416 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
420 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
422 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
423 /* zbuffer only support 1D or 2D tiled surface */
425 case RADEON_SURF_MODE_1D:
426 case RADEON_SURF_MODE_2D:
429 mode = RADEON_SURF_MODE_1D;
430 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
431 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
436 /* force 1d on kernel that can't do 2d */
437 if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) {
438 if (surf->nsamples > 1) {
439 fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__);
442 mode = RADEON_SURF_MODE_1D;
443 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
444 surf->flags |= RADEON_SURF_SET(mode, MODE);
447 /* check surface dimension */
448 if (surf->npix_x > 8192 || surf->npix_y > 8192 || surf->npix_z > 8192) {
452 /* check mipmap last_level */
453 if (surf->last_level > 14) {
457 /* check tiling mode */
459 case RADEON_SURF_MODE_LINEAR:
460 r = r6_surface_init_linear(surf_man, surf, 0, 0);
462 case RADEON_SURF_MODE_LINEAR_ALIGNED:
463 r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
465 case RADEON_SURF_MODE_1D:
466 r = r6_surface_init_1d(surf_man, surf, 0, 0);
468 case RADEON_SURF_MODE_2D:
469 r = r6_surface_init_2d(surf_man, surf, 0, 0);
477 static int r6_surface_best(struct radeon_surface_manager *surf_man,
478 struct radeon_surface *surf)
480 /* no value to optimize for r6xx/r7xx */
485 /* ===========================================================================
488 static int eg_init_hw_info(struct radeon_surface_manager *surf_man)
490 uint32_t tiling_config;
491 drmVersionPtr version;
494 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
500 surf_man->hw_info.allow_2d = 0;
501 version = drmGetVersion(surf_man->fd);
502 if (version && version->version_minor >= 16) {
503 surf_man->hw_info.allow_2d = 1;
505 drmFreeVersion(version);
507 switch (tiling_config & 0xf) {
509 surf_man->hw_info.num_pipes = 1;
512 surf_man->hw_info.num_pipes = 2;
515 surf_man->hw_info.num_pipes = 4;
518 surf_man->hw_info.num_pipes = 8;
521 surf_man->hw_info.num_pipes = 8;
522 surf_man->hw_info.allow_2d = 0;
526 switch ((tiling_config & 0xf0) >> 4) {
528 surf_man->hw_info.num_banks = 4;
531 surf_man->hw_info.num_banks = 8;
534 surf_man->hw_info.num_banks = 16;
537 surf_man->hw_info.num_banks = 8;
538 surf_man->hw_info.allow_2d = 0;
542 switch ((tiling_config & 0xf00) >> 8) {
544 surf_man->hw_info.group_bytes = 256;
547 surf_man->hw_info.group_bytes = 512;
550 surf_man->hw_info.group_bytes = 256;
551 surf_man->hw_info.allow_2d = 0;
555 switch ((tiling_config & 0xf000) >> 12) {
557 surf_man->hw_info.row_size = 1024;
560 surf_man->hw_info.row_size = 2048;
563 surf_man->hw_info.row_size = 4096;
566 surf_man->hw_info.row_size = 4096;
567 surf_man->hw_info.allow_2d = 0;
573 static void eg_surf_minify(struct radeon_surface *surf,
574 struct radeon_surface_level *surflevel,
583 unsigned mtile_pr, mtile_ps;
585 surflevel->npix_x = mip_minify(surf->npix_x, level);
586 surflevel->npix_y = mip_minify(surf->npix_y, level);
587 surflevel->npix_z = mip_minify(surf->npix_z, level);
588 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
589 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
590 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
591 if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
592 !(surf->flags & RADEON_SURF_FMASK)) {
593 if (surflevel->nblk_x < mtilew || surflevel->nblk_y < mtileh) {
594 surflevel->mode = RADEON_SURF_MODE_1D;
598 surflevel->nblk_x = ALIGN(surflevel->nblk_x, mtilew);
599 surflevel->nblk_y = ALIGN(surflevel->nblk_y, mtileh);
600 surflevel->nblk_z = ALIGN(surflevel->nblk_z, 1);
602 /* macro tile per row */
603 mtile_pr = surflevel->nblk_x / mtilew;
604 /* macro tile per slice */
605 mtile_ps = (mtile_pr * surflevel->nblk_y) / mtileh;
607 surflevel->offset = offset;
608 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
609 surflevel->slice_size = (uint64_t)mtile_ps * mtileb * slice_pt;
611 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
614 static int eg_surface_init_1d(struct radeon_surface_manager *surf_man,
615 struct radeon_surface *surf,
616 struct radeon_surface_level *level,
618 uint64_t offset, unsigned start_level)
620 uint32_t xalign, yalign, zalign, tilew;
623 /* compute alignment */
625 xalign = surf_man->hw_info.group_bytes / (tilew * bpe * surf->nsamples);
626 xalign = MAX2(tilew, xalign);
629 if (surf->flags & RADEON_SURF_SCANOUT) {
630 xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
634 unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
635 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
638 offset = ALIGN(offset, alignment);
642 /* build mipmap tree */
643 for (i = start_level; i <= surf->last_level; i++) {
644 level[i].mode = RADEON_SURF_MODE_1D;
645 surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, offset);
646 /* level0 and first mipmap need to have alignment */
647 offset = surf->bo_size;
649 offset = ALIGN(offset, surf->bo_alignment);
655 static int eg_surface_init_2d(struct radeon_surface_manager *surf_man,
656 struct radeon_surface *surf,
657 struct radeon_surface_level *level,
658 unsigned bpe, unsigned tile_split,
659 uint64_t offset, unsigned start_level)
661 unsigned tilew, tileh, tileb;
662 unsigned mtilew, mtileh, mtileb;
666 /* compute tile values */
669 tileb = tilew * tileh * bpe * surf->nsamples;
670 /* slices per tile */
672 if (tileb > tile_split && tile_split) {
673 slice_pt = tileb / tile_split;
675 tileb = tileb / slice_pt;
677 /* macro tile width & height */
678 mtilew = (tilew * surf->bankw * surf_man->hw_info.num_pipes) * surf->mtilea;
679 mtileh = (tileh * surf->bankh * surf_man->hw_info.num_banks) / surf->mtilea;
680 /* macro tile bytes */
681 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
684 unsigned alignment = MAX2(256, mtileb);
685 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
688 offset = ALIGN(offset, alignment);
692 /* build mipmap tree */
693 for (i = start_level; i <= surf->last_level; i++) {
694 level[i].mode = RADEON_SURF_MODE_2D;
695 eg_surf_minify(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, mtileb, offset);
696 if (level[i].mode == RADEON_SURF_MODE_1D) {
697 return eg_surface_init_1d(surf_man, surf, level, bpe, offset, i);
699 /* level0 and first mipmap need to have alignment */
700 offset = surf->bo_size;
702 offset = ALIGN(offset, surf->bo_alignment);
708 static int eg_surface_sanity(struct radeon_surface_manager *surf_man,
709 struct radeon_surface *surf,
714 /* check surface dimension */
715 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
719 /* check mipmap last_level */
720 if (surf->last_level > 15) {
724 /* force 1d on kernel that can't do 2d */
725 if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) {
726 if (surf->nsamples > 1) {
727 fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__);
730 mode = RADEON_SURF_MODE_1D;
731 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
732 surf->flags |= RADEON_SURF_SET(mode, MODE);
735 /* check tile split */
736 if (mode == RADEON_SURF_MODE_2D) {
737 switch (surf->tile_split) {
749 switch (surf->mtilea) {
758 /* check aspect ratio */
759 if (surf_man->hw_info.num_banks < surf->mtilea) {
762 /* check bank width */
763 switch (surf->bankw) {
772 /* check bank height */
773 switch (surf->bankh) {
782 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
783 if ((tileb * surf->bankh * surf->bankw) < surf_man->hw_info.group_bytes) {
791 static int eg_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
792 struct radeon_surface *surf)
794 unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
795 int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
796 /* Old libdrm_macros.headers didn't have stencil_level in it. This prevents crashes. */
797 struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
798 struct radeon_surface_level *stencil_level =
799 (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
801 r = eg_surface_init_1d(surf_man, surf, surf->level, surf->bpe, 0, 0);
805 if (is_depth_stencil) {
806 r = eg_surface_init_1d(surf_man, surf, stencil_level, 1,
808 surf->stencil_offset = stencil_level[0].offset;
813 static int eg_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
814 struct radeon_surface *surf)
816 unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
817 int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
818 /* Old libdrm_macros.headers didn't have stencil_level in it. This prevents crashes. */
819 struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
820 struct radeon_surface_level *stencil_level =
821 (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
823 r = eg_surface_init_2d(surf_man, surf, surf->level, surf->bpe,
824 surf->tile_split, 0, 0);
828 if (is_depth_stencil) {
829 r = eg_surface_init_2d(surf_man, surf, stencil_level, 1,
830 surf->stencil_tile_split, surf->bo_size, 0);
831 surf->stencil_offset = stencil_level[0].offset;
836 static int eg_surface_init(struct radeon_surface_manager *surf_man,
837 struct radeon_surface *surf)
842 /* MSAA surfaces support the 2D mode only. */
843 if (surf->nsamples > 1) {
844 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
845 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
849 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
851 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
852 /* zbuffer only support 1D or 2D tiled surface */
854 case RADEON_SURF_MODE_1D:
855 case RADEON_SURF_MODE_2D:
858 mode = RADEON_SURF_MODE_1D;
859 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
860 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
865 r = eg_surface_sanity(surf_man, surf, mode);
870 surf->stencil_offset = 0;
871 surf->bo_alignment = 0;
873 /* check tiling mode */
875 case RADEON_SURF_MODE_LINEAR:
876 r = r6_surface_init_linear(surf_man, surf, 0, 0);
878 case RADEON_SURF_MODE_LINEAR_ALIGNED:
879 r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
881 case RADEON_SURF_MODE_1D:
882 r = eg_surface_init_1d_miptrees(surf_man, surf);
884 case RADEON_SURF_MODE_2D:
885 r = eg_surface_init_2d_miptrees(surf_man, surf);
893 static unsigned log2_int(unsigned x)
901 if ((unsigned)(1 << l) > x) {
908 /* compute best tile_split, bankw, bankh, mtilea
909 * depending on surface
911 static int eg_surface_best(struct radeon_surface_manager *surf_man,
912 struct radeon_surface *surf)
914 unsigned mode, tileb, h_over_w;
918 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
920 /* set some default value to avoid sanity check choking on them */
921 surf->tile_split = 1024;
924 surf->mtilea = surf_man->hw_info.num_banks;
925 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
926 for (; surf->bankh <= 8; surf->bankh *= 2) {
927 if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
931 if (surf->mtilea > 8) {
935 r = eg_surface_sanity(surf_man, surf, mode);
940 if (mode != RADEON_SURF_MODE_2D) {
941 /* nothing to do for non 2D tiled surface */
945 /* Tweak TILE_SPLIT for performance here. */
946 if (surf->nsamples > 1) {
947 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
948 switch (surf->nsamples) {
950 surf->tile_split = 128;
953 surf->tile_split = 128;
956 surf->tile_split = 256;
958 case 16: /* cayman only */
959 surf->tile_split = 512;
962 fprintf(stderr, "radeon: Wrong number of samples %i (%i)\n",
963 surf->nsamples, __LINE__);
966 surf->stencil_tile_split = 64;
968 /* tile split must be >= 256 for colorbuffer surfaces,
969 * SAMPLE_SPLIT = tile_split / (bpe * 64), the optimal value is 2
971 surf->tile_split = MAX2(2 * surf->bpe * 64, 256);
972 if (surf->tile_split > 4096)
973 surf->tile_split = 4096;
976 /* set tile split to row size */
977 surf->tile_split = surf_man->hw_info.row_size;
978 surf->stencil_tile_split = surf_man->hw_info.row_size / 2;
981 /* bankw or bankh greater than 1 increase alignment requirement, not
982 * sure if it's worth using smaller bankw & bankh to stick with 2D
983 * tiling on small surface rather than falling back to 1D tiling.
984 * Use recommanded value based on tile size for now.
986 * fmask buffer has different optimal value figure them out once we
989 if (surf->flags & RADEON_SURF_SBUFFER) {
990 /* assume 1 bytes for stencil, we optimize for stencil as stencil
991 * and depth shares surface values
993 tileb = MIN2(surf->tile_split, 64 * surf->nsamples);
995 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
998 /* use bankw of 1 to minimize width alignment, might be interesting to
999 * increase it for large surface
1014 /* double check the constraint */
1015 for (; surf->bankh <= 8; surf->bankh *= 2) {
1016 if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
1021 h_over_w = (((surf->bankh * surf_man->hw_info.num_banks) << 16) /
1022 (surf->bankw * surf_man->hw_info.num_pipes)) >> 16;
1023 surf->mtilea = 1 << (log2_int(h_over_w) >> 1);
1029 /* ===========================================================================
1030 * Southern Islands family
1032 #define SI__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f)
1033 #define SI__PIPE_CONFIG__ADDR_SURF_P2 0
1034 #define SI__PIPE_CONFIG__ADDR_SURF_P4_8x16 4
1035 #define SI__PIPE_CONFIG__ADDR_SURF_P4_16x16 5
1036 #define SI__PIPE_CONFIG__ADDR_SURF_P4_16x32 6
1037 #define SI__PIPE_CONFIG__ADDR_SURF_P4_32x32 7
1038 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8
1039 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9
1040 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10
1041 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11
1042 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12
1043 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13
1044 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14
1045 #define SI__GB_TILE_MODE__TILE_SPLIT(x) (((x) >> 11) & 0x7)
1046 #define SI__TILE_SPLIT__64B 0
1047 #define SI__TILE_SPLIT__128B 1
1048 #define SI__TILE_SPLIT__256B 2
1049 #define SI__TILE_SPLIT__512B 3
1050 #define SI__TILE_SPLIT__1024B 4
1051 #define SI__TILE_SPLIT__2048B 5
1052 #define SI__TILE_SPLIT__4096B 6
1053 #define SI__GB_TILE_MODE__BANK_WIDTH(x) (((x) >> 14) & 0x3)
1054 #define SI__BANK_WIDTH__1 0
1055 #define SI__BANK_WIDTH__2 1
1056 #define SI__BANK_WIDTH__4 2
1057 #define SI__BANK_WIDTH__8 3
1058 #define SI__GB_TILE_MODE__BANK_HEIGHT(x) (((x) >> 16) & 0x3)
1059 #define SI__BANK_HEIGHT__1 0
1060 #define SI__BANK_HEIGHT__2 1
1061 #define SI__BANK_HEIGHT__4 2
1062 #define SI__BANK_HEIGHT__8 3
1063 #define SI__GB_TILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 18) & 0x3)
1064 #define SI__MACRO_TILE_ASPECT__1 0
1065 #define SI__MACRO_TILE_ASPECT__2 1
1066 #define SI__MACRO_TILE_ASPECT__4 2
1067 #define SI__MACRO_TILE_ASPECT__8 3
1068 #define SI__GB_TILE_MODE__NUM_BANKS(x) (((x) >> 20) & 0x3)
1069 #define SI__NUM_BANKS__2_BANK 0
1070 #define SI__NUM_BANKS__4_BANK 1
1071 #define SI__NUM_BANKS__8_BANK 2
1072 #define SI__NUM_BANKS__16_BANK 3
1075 static void si_gb_tile_mode(uint32_t gb_tile_mode,
1076 unsigned *num_pipes,
1077 unsigned *num_banks,
1078 uint32_t *macro_tile_aspect,
1081 uint32_t *tile_split)
1084 switch (SI__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1085 case SI__PIPE_CONFIG__ADDR_SURF_P2:
1089 case SI__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1090 case SI__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1091 case SI__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1092 case SI__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1095 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1096 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1097 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1098 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1099 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1100 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1101 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1107 switch (SI__GB_TILE_MODE__NUM_BANKS(gb_tile_mode)) {
1109 case SI__NUM_BANKS__2_BANK:
1112 case SI__NUM_BANKS__4_BANK:
1115 case SI__NUM_BANKS__8_BANK:
1118 case SI__NUM_BANKS__16_BANK:
1123 if (macro_tile_aspect) {
1124 switch (SI__GB_TILE_MODE__MACRO_TILE_ASPECT(gb_tile_mode)) {
1126 case SI__MACRO_TILE_ASPECT__1:
1127 *macro_tile_aspect = 1;
1129 case SI__MACRO_TILE_ASPECT__2:
1130 *macro_tile_aspect = 2;
1132 case SI__MACRO_TILE_ASPECT__4:
1133 *macro_tile_aspect = 4;
1135 case SI__MACRO_TILE_ASPECT__8:
1136 *macro_tile_aspect = 8;
1141 switch (SI__GB_TILE_MODE__BANK_WIDTH(gb_tile_mode)) {
1143 case SI__BANK_WIDTH__1:
1146 case SI__BANK_WIDTH__2:
1149 case SI__BANK_WIDTH__4:
1152 case SI__BANK_WIDTH__8:
1158 switch (SI__GB_TILE_MODE__BANK_HEIGHT(gb_tile_mode)) {
1160 case SI__BANK_HEIGHT__1:
1163 case SI__BANK_HEIGHT__2:
1166 case SI__BANK_HEIGHT__4:
1169 case SI__BANK_HEIGHT__8:
1175 switch (SI__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1177 case SI__TILE_SPLIT__64B:
1180 case SI__TILE_SPLIT__128B:
1183 case SI__TILE_SPLIT__256B:
1186 case SI__TILE_SPLIT__512B:
1189 case SI__TILE_SPLIT__1024B:
1192 case SI__TILE_SPLIT__2048B:
1195 case SI__TILE_SPLIT__4096B:
1202 static int si_init_hw_info(struct radeon_surface_manager *surf_man)
1204 uint32_t tiling_config;
1205 drmVersionPtr version;
1208 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
1214 surf_man->hw_info.allow_2d = 0;
1215 version = drmGetVersion(surf_man->fd);
1216 if (version && version->version_minor >= 33) {
1217 if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array)) {
1218 surf_man->hw_info.allow_2d = 1;
1221 drmFreeVersion(version);
1223 switch (tiling_config & 0xf) {
1225 surf_man->hw_info.num_pipes = 1;
1228 surf_man->hw_info.num_pipes = 2;
1231 surf_man->hw_info.num_pipes = 4;
1234 surf_man->hw_info.num_pipes = 8;
1237 surf_man->hw_info.num_pipes = 8;
1238 surf_man->hw_info.allow_2d = 0;
1242 switch ((tiling_config & 0xf0) >> 4) {
1244 surf_man->hw_info.num_banks = 4;
1247 surf_man->hw_info.num_banks = 8;
1250 surf_man->hw_info.num_banks = 16;
1253 surf_man->hw_info.num_banks = 8;
1254 surf_man->hw_info.allow_2d = 0;
1258 switch ((tiling_config & 0xf00) >> 8) {
1260 surf_man->hw_info.group_bytes = 256;
1263 surf_man->hw_info.group_bytes = 512;
1266 surf_man->hw_info.group_bytes = 256;
1267 surf_man->hw_info.allow_2d = 0;
1271 switch ((tiling_config & 0xf000) >> 12) {
1273 surf_man->hw_info.row_size = 1024;
1276 surf_man->hw_info.row_size = 2048;
1279 surf_man->hw_info.row_size = 4096;
1282 surf_man->hw_info.row_size = 4096;
1283 surf_man->hw_info.allow_2d = 0;
1289 static int si_surface_sanity(struct radeon_surface_manager *surf_man,
1290 struct radeon_surface *surf,
1291 unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
1293 uint32_t gb_tile_mode;
1295 /* check surface dimension */
1296 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
1300 /* check mipmap last_level */
1301 if (surf->last_level > 15) {
1305 /* force 1d on kernel that can't do 2d */
1306 if (mode > RADEON_SURF_MODE_1D &&
1307 (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
1308 if (surf->nsamples > 1) {
1309 fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
1312 mode = RADEON_SURF_MODE_1D;
1313 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1314 surf->flags |= RADEON_SURF_SET(mode, MODE);
1317 if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
1321 if (!surf->tile_split) {
1326 surf->tile_split = 64;
1327 surf->stencil_tile_split = 64;
1331 case RADEON_SURF_MODE_2D:
1332 if (surf->flags & RADEON_SURF_SBUFFER) {
1333 switch (surf->nsamples) {
1335 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1338 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1341 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1344 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1349 /* retrieve tiling mode value */
1350 gb_tile_mode = surf_man->hw_info.tile_mode_array[*stencil_tile_mode];
1351 si_gb_tile_mode(gb_tile_mode, NULL, NULL, NULL, NULL, NULL, &surf->stencil_tile_split);
1353 if (surf->flags & RADEON_SURF_ZBUFFER) {
1354 switch (surf->nsamples) {
1356 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1359 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1362 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1365 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1370 } else if (surf->flags & RADEON_SURF_SCANOUT) {
1371 switch (surf->bpe) {
1373 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
1376 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
1382 switch (surf->bpe) {
1384 *tile_mode = SI_TILE_MODE_COLOR_2D_8BPP;
1387 *tile_mode = SI_TILE_MODE_COLOR_2D_16BPP;
1390 *tile_mode = SI_TILE_MODE_COLOR_2D_32BPP;
1394 *tile_mode = SI_TILE_MODE_COLOR_2D_64BPP;
1400 /* retrieve tiling mode value */
1401 gb_tile_mode = surf_man->hw_info.tile_mode_array[*tile_mode];
1402 si_gb_tile_mode(gb_tile_mode, NULL, NULL, &surf->mtilea, &surf->bankw, &surf->bankh, &surf->tile_split);
1404 case RADEON_SURF_MODE_1D:
1405 if (surf->flags & RADEON_SURF_SBUFFER) {
1406 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1408 if (surf->flags & RADEON_SURF_ZBUFFER) {
1409 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1410 } else if (surf->flags & RADEON_SURF_SCANOUT) {
1411 *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1413 *tile_mode = SI_TILE_MODE_COLOR_1D;
1416 case RADEON_SURF_MODE_LINEAR_ALIGNED:
1418 *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
1424 static void si_surf_minify(struct radeon_surface *surf,
1425 struct radeon_surface_level *surflevel,
1426 unsigned bpe, unsigned level,
1427 uint32_t xalign, uint32_t yalign, uint32_t zalign,
1428 uint32_t slice_align, uint64_t offset)
1431 surflevel->npix_x = surf->npix_x;
1433 surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1435 surflevel->npix_y = mip_minify(surf->npix_y, level);
1436 surflevel->npix_z = mip_minify(surf->npix_z, level);
1438 if (level == 0 && surf->last_level > 0) {
1439 surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1440 surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1441 surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1443 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1444 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1445 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1448 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign);
1450 /* XXX: Texture sampling uses unexpectedly large pitches in some cases,
1451 * these are just guesses for the rules behind those
1453 if (level == 0 && surf->last_level == 0)
1454 /* Non-mipmap pitch padded to slice alignment */
1455 /* Using just bpe here breaks stencil blitting; surf->bpe works. */
1456 xalign = MAX2(xalign, slice_align / surf->bpe);
1457 else if (surflevel->mode == RADEON_SURF_MODE_LINEAR_ALIGNED)
1458 /* Small rows evenly distributed across slice */
1459 xalign = MAX2(xalign, slice_align / bpe / surflevel->nblk_y);
1461 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign);
1462 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign);
1464 surflevel->offset = offset;
1465 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
1466 surflevel->slice_size = ALIGN((uint64_t)surflevel->pitch_bytes * surflevel->nblk_y,
1467 (uint64_t)slice_align);
1469 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1472 static void si_surf_minify_2d(struct radeon_surface *surf,
1473 struct radeon_surface_level *surflevel,
1474 unsigned bpe, unsigned level, unsigned slice_pt,
1475 uint32_t xalign, uint32_t yalign, uint32_t zalign,
1476 unsigned mtileb, uint64_t offset)
1478 unsigned mtile_pr, mtile_ps;
1481 surflevel->npix_x = surf->npix_x;
1483 surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1485 surflevel->npix_y = mip_minify(surf->npix_y, level);
1486 surflevel->npix_z = mip_minify(surf->npix_z, level);
1488 if (level == 0 && surf->last_level > 0) {
1489 surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1490 surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1491 surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1493 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1494 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1495 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1498 if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
1499 !(surf->flags & RADEON_SURF_FMASK)) {
1500 if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
1501 surflevel->mode = RADEON_SURF_MODE_1D;
1505 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign);
1506 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign);
1507 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign);
1509 /* macro tile per row */
1510 mtile_pr = surflevel->nblk_x / xalign;
1511 /* macro tile per slice */
1512 mtile_ps = (mtile_pr * surflevel->nblk_y) / yalign;
1513 surflevel->offset = offset;
1514 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
1515 surflevel->slice_size = (uint64_t)mtile_ps * mtileb * slice_pt;
1517 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1520 static int si_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
1521 struct radeon_surface *surf,
1523 uint64_t offset, unsigned start_level)
1525 uint32_t xalign, yalign, zalign, slice_align;
1528 /* compute alignment */
1530 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
1532 xalign = MAX2(8, 64 / surf->bpe);
1535 slice_align = MAX2(64 * surf->bpe, surf_man->hw_info.group_bytes);
1537 /* build mipmap tree */
1538 for (i = start_level; i <= surf->last_level; i++) {
1539 surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
1540 si_surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, slice_align, offset);
1541 /* level0 and first mipmap need to have alignment */
1542 offset = surf->bo_size;
1544 offset = ALIGN(offset, surf->bo_alignment);
1546 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1547 surf->tiling_index[i] = tile_mode;
1553 static int si_surface_init_1d(struct radeon_surface_manager *surf_man,
1554 struct radeon_surface *surf,
1555 struct radeon_surface_level *level,
1556 unsigned bpe, unsigned tile_mode,
1557 uint64_t offset, unsigned start_level)
1559 uint32_t xalign, yalign, zalign, slice_align;
1560 unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
1563 /* compute alignment */
1567 slice_align = surf_man->hw_info.group_bytes;
1568 if (surf->flags & RADEON_SURF_SCANOUT) {
1569 xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
1572 if (start_level <= 1) {
1573 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1576 offset = ALIGN(offset, alignment);
1580 /* build mipmap tree */
1581 for (i = start_level; i <= surf->last_level; i++) {
1582 level[i].mode = RADEON_SURF_MODE_1D;
1583 si_surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, slice_align, offset);
1584 /* level0 and first mipmap need to have alignment */
1585 offset = surf->bo_size;
1587 offset = ALIGN(offset, alignment);
1589 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1590 if (surf->level == level) {
1591 surf->tiling_index[i] = tile_mode;
1592 /* it's ok because stencil is done after */
1593 surf->stencil_tiling_index[i] = tile_mode;
1595 surf->stencil_tiling_index[i] = tile_mode;
1602 static int si_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
1603 struct radeon_surface *surf,
1604 unsigned tile_mode, unsigned stencil_tile_mode)
1608 r = si_surface_init_1d(surf_man, surf, surf->level, surf->bpe, tile_mode, 0, 0);
1613 if (surf->flags & RADEON_SURF_SBUFFER) {
1614 r = si_surface_init_1d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode, surf->bo_size, 0);
1615 surf->stencil_offset = surf->stencil_level[0].offset;
1620 static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
1621 struct radeon_surface *surf,
1622 struct radeon_surface_level *level,
1623 unsigned bpe, unsigned tile_mode,
1624 unsigned num_pipes, unsigned num_banks,
1625 unsigned tile_split,
1627 unsigned start_level)
1629 uint64_t aligned_offset = offset;
1630 unsigned tilew, tileh, tileb;
1631 unsigned mtilew, mtileh, mtileb;
1635 /* compute tile values */
1638 tileb = tilew * tileh * bpe * surf->nsamples;
1639 /* slices per tile */
1641 if (tileb > tile_split && tile_split) {
1642 slice_pt = tileb / tile_split;
1644 tileb = tileb / slice_pt;
1646 /* macro tile width & height */
1647 mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
1648 mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
1650 /* macro tile bytes */
1651 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
1653 if (start_level <= 1) {
1654 unsigned alignment = MAX2(256, mtileb);
1655 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1657 if (aligned_offset) {
1658 aligned_offset = ALIGN(aligned_offset, alignment);
1662 /* build mipmap tree */
1663 for (i = start_level; i <= surf->last_level; i++) {
1664 level[i].mode = RADEON_SURF_MODE_2D;
1665 si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
1666 if (level[i].mode == RADEON_SURF_MODE_1D) {
1667 switch (tile_mode) {
1668 case SI_TILE_MODE_COLOR_2D_8BPP:
1669 case SI_TILE_MODE_COLOR_2D_16BPP:
1670 case SI_TILE_MODE_COLOR_2D_32BPP:
1671 case SI_TILE_MODE_COLOR_2D_64BPP:
1672 tile_mode = SI_TILE_MODE_COLOR_1D;
1674 case SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP:
1675 case SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP:
1676 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1678 case SI_TILE_MODE_DEPTH_STENCIL_2D:
1679 tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1684 return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
1686 /* level0 and first mipmap need to have alignment */
1687 aligned_offset = offset = surf->bo_size;
1689 aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
1691 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1692 if (surf->level == level) {
1693 surf->tiling_index[i] = tile_mode;
1694 /* it's ok because stencil is done after */
1695 surf->stencil_tiling_index[i] = tile_mode;
1697 surf->stencil_tiling_index[i] = tile_mode;
1704 static int si_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
1705 struct radeon_surface *surf,
1706 unsigned tile_mode, unsigned stencil_tile_mode)
1708 unsigned num_pipes, num_banks;
1709 uint32_t gb_tile_mode;
1712 /* retrieve tiling mode value */
1713 gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1714 si_gb_tile_mode(gb_tile_mode, &num_pipes, &num_banks, NULL, NULL, NULL, NULL);
1716 r = si_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode, num_pipes, num_banks, surf->tile_split, 0, 0);
1721 if (surf->flags & RADEON_SURF_SBUFFER) {
1722 r = si_surface_init_2d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode, num_pipes, num_banks, surf->stencil_tile_split, surf->bo_size, 0);
1723 surf->stencil_offset = surf->stencil_level[0].offset;
1728 static int si_surface_init(struct radeon_surface_manager *surf_man,
1729 struct radeon_surface *surf)
1731 unsigned mode, tile_mode, stencil_tile_mode;
1734 /* MSAA surfaces support the 2D mode only. */
1735 if (surf->nsamples > 1) {
1736 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1737 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
1741 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1743 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
1744 /* zbuffer only support 1D or 2D tiled surface */
1746 case RADEON_SURF_MODE_1D:
1747 case RADEON_SURF_MODE_2D:
1750 mode = RADEON_SURF_MODE_1D;
1751 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1752 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1757 r = si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1762 surf->stencil_offset = 0;
1763 surf->bo_alignment = 0;
1765 /* check tiling mode */
1767 case RADEON_SURF_MODE_LINEAR:
1768 r = r6_surface_init_linear(surf_man, surf, 0, 0);
1770 case RADEON_SURF_MODE_LINEAR_ALIGNED:
1771 r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
1773 case RADEON_SURF_MODE_1D:
1774 r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1776 case RADEON_SURF_MODE_2D:
1777 r = si_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1786 * depending on surface
1788 static int si_surface_best(struct radeon_surface_manager *surf_man,
1789 struct radeon_surface *surf)
1791 unsigned mode, tile_mode, stencil_tile_mode;
1794 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1796 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
1797 !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
1798 /* depth/stencil force 1d tiling for old mesa */
1799 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1800 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1803 return si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1807 /* ===========================================================================
1808 * Sea Islands family
1810 #define CIK__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f)
1811 #define CIK__PIPE_CONFIG__ADDR_SURF_P2 0
1812 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16 4
1813 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16 5
1814 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32 6
1815 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32 7
1816 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8
1817 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9
1818 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10
1819 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11
1820 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12
1821 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13
1822 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14
1823 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16 16
1824 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16 17
1825 #define CIK__GB_TILE_MODE__TILE_SPLIT(x) (((x) >> 11) & 0x7)
1826 #define CIK__TILE_SPLIT__64B 0
1827 #define CIK__TILE_SPLIT__128B 1
1828 #define CIK__TILE_SPLIT__256B 2
1829 #define CIK__TILE_SPLIT__512B 3
1830 #define CIK__TILE_SPLIT__1024B 4
1831 #define CIK__TILE_SPLIT__2048B 5
1832 #define CIK__TILE_SPLIT__4096B 6
1833 #define CIK__GB_TILE_MODE__SAMPLE_SPLIT(x) (((x) >> 25) & 0x3)
1834 #define CIK__SAMPLE_SPLIT__1 0
1835 #define CIK__SAMPLE_SPLIT__2 1
1836 #define CIK__SAMPLE_SPLIT__4 2
1837 #define CIK__SAMPLE_SPLIT__8 3
1838 #define CIK__GB_MACROTILE_MODE__BANK_WIDTH(x) ((x) & 0x3)
1839 #define CIK__BANK_WIDTH__1 0
1840 #define CIK__BANK_WIDTH__2 1
1841 #define CIK__BANK_WIDTH__4 2
1842 #define CIK__BANK_WIDTH__8 3
1843 #define CIK__GB_MACROTILE_MODE__BANK_HEIGHT(x) (((x) >> 2) & 0x3)
1844 #define CIK__BANK_HEIGHT__1 0
1845 #define CIK__BANK_HEIGHT__2 1
1846 #define CIK__BANK_HEIGHT__4 2
1847 #define CIK__BANK_HEIGHT__8 3
1848 #define CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 4) & 0x3)
1849 #define CIK__MACRO_TILE_ASPECT__1 0
1850 #define CIK__MACRO_TILE_ASPECT__2 1
1851 #define CIK__MACRO_TILE_ASPECT__4 2
1852 #define CIK__MACRO_TILE_ASPECT__8 3
1853 #define CIK__GB_MACROTILE_MODE__NUM_BANKS(x) (((x) >> 6) & 0x3)
1854 #define CIK__NUM_BANKS__2_BANK 0
1855 #define CIK__NUM_BANKS__4_BANK 1
1856 #define CIK__NUM_BANKS__8_BANK 2
1857 #define CIK__NUM_BANKS__16_BANK 3
1860 static void cik_get_2d_params(struct radeon_surface_manager *surf_man,
1861 unsigned bpe, unsigned nsamples, bool is_color,
1863 uint32_t *num_pipes,
1864 uint32_t *tile_split_ptr,
1865 uint32_t *num_banks,
1866 uint32_t *macro_tile_aspect,
1870 uint32_t gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1871 unsigned tileb_1x, tileb;
1872 unsigned gb_macrotile_mode;
1873 unsigned macrotile_index;
1874 unsigned tile_split, sample_split;
1877 switch (CIK__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1878 case CIK__PIPE_CONFIG__ADDR_SURF_P2:
1882 case CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1883 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1884 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1885 case CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1888 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1889 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1890 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1891 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1892 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1893 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1894 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1897 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16:
1898 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16:
1903 switch (CIK__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1905 case CIK__TILE_SPLIT__64B:
1908 case CIK__TILE_SPLIT__128B:
1911 case CIK__TILE_SPLIT__256B:
1914 case CIK__TILE_SPLIT__512B:
1917 case CIK__TILE_SPLIT__1024B:
1920 case CIK__TILE_SPLIT__2048B:
1923 case CIK__TILE_SPLIT__4096B:
1927 switch (CIK__GB_TILE_MODE__SAMPLE_SPLIT(gb_tile_mode)) {
1929 case CIK__SAMPLE_SPLIT__1:
1932 case CIK__SAMPLE_SPLIT__2:
1935 case CIK__SAMPLE_SPLIT__4:
1938 case CIK__SAMPLE_SPLIT__8:
1943 /* Adjust the tile split. */
1944 tileb_1x = 8 * 8 * bpe;
1946 tile_split = MAX2(256, sample_split * tileb_1x);
1948 tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
1950 /* Determine the macrotile index. */
1951 tileb = MIN2(tile_split, nsamples * tileb_1x);
1953 for (macrotile_index = 0; tileb > 64; macrotile_index++) {
1956 gb_macrotile_mode = surf_man->hw_info.macrotile_mode_array[macrotile_index];
1958 if (tile_split_ptr) {
1959 *tile_split_ptr = tile_split;
1962 switch (CIK__GB_MACROTILE_MODE__NUM_BANKS(gb_macrotile_mode)) {
1964 case CIK__NUM_BANKS__2_BANK:
1967 case CIK__NUM_BANKS__4_BANK:
1970 case CIK__NUM_BANKS__8_BANK:
1973 case CIK__NUM_BANKS__16_BANK:
1978 if (macro_tile_aspect) {
1979 switch (CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(gb_macrotile_mode)) {
1981 case CIK__MACRO_TILE_ASPECT__1:
1982 *macro_tile_aspect = 1;
1984 case CIK__MACRO_TILE_ASPECT__2:
1985 *macro_tile_aspect = 2;
1987 case CIK__MACRO_TILE_ASPECT__4:
1988 *macro_tile_aspect = 4;
1990 case CIK__MACRO_TILE_ASPECT__8:
1991 *macro_tile_aspect = 8;
1996 switch (CIK__GB_MACROTILE_MODE__BANK_WIDTH(gb_macrotile_mode)) {
1998 case CIK__BANK_WIDTH__1:
2001 case CIK__BANK_WIDTH__2:
2004 case CIK__BANK_WIDTH__4:
2007 case CIK__BANK_WIDTH__8:
2013 switch (CIK__GB_MACROTILE_MODE__BANK_HEIGHT(gb_macrotile_mode)) {
2015 case CIK__BANK_HEIGHT__1:
2018 case CIK__BANK_HEIGHT__2:
2021 case CIK__BANK_HEIGHT__4:
2024 case CIK__BANK_HEIGHT__8:
2031 static int cik_init_hw_info(struct radeon_surface_manager *surf_man)
2033 uint32_t tiling_config;
2034 drmVersionPtr version;
2037 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
2043 surf_man->hw_info.allow_2d = 0;
2044 version = drmGetVersion(surf_man->fd);
2045 if (version && version->version_minor >= 35) {
2046 if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array) &&
2047 !radeon_get_value(surf_man->fd, RADEON_INFO_CIK_MACROTILE_MODE_ARRAY, surf_man->hw_info.macrotile_mode_array)) {
2048 surf_man->hw_info.allow_2d = 1;
2051 drmFreeVersion(version);
2053 switch (tiling_config & 0xf) {
2055 surf_man->hw_info.num_pipes = 1;
2058 surf_man->hw_info.num_pipes = 2;
2061 surf_man->hw_info.num_pipes = 4;
2064 surf_man->hw_info.num_pipes = 8;
2067 surf_man->hw_info.num_pipes = 8;
2068 surf_man->hw_info.allow_2d = 0;
2072 switch ((tiling_config & 0xf0) >> 4) {
2074 surf_man->hw_info.num_banks = 4;
2077 surf_man->hw_info.num_banks = 8;
2080 surf_man->hw_info.num_banks = 16;
2083 surf_man->hw_info.num_banks = 8;
2084 surf_man->hw_info.allow_2d = 0;
2088 switch ((tiling_config & 0xf00) >> 8) {
2090 surf_man->hw_info.group_bytes = 256;
2093 surf_man->hw_info.group_bytes = 512;
2096 surf_man->hw_info.group_bytes = 256;
2097 surf_man->hw_info.allow_2d = 0;
2101 switch ((tiling_config & 0xf000) >> 12) {
2103 surf_man->hw_info.row_size = 1024;
2106 surf_man->hw_info.row_size = 2048;
2109 surf_man->hw_info.row_size = 4096;
2112 surf_man->hw_info.row_size = 4096;
2113 surf_man->hw_info.allow_2d = 0;
2119 static int cik_surface_sanity(struct radeon_surface_manager *surf_man,
2120 struct radeon_surface *surf,
2121 unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
2123 /* check surface dimension */
2124 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
2128 /* check mipmap last_level */
2129 if (surf->last_level > 15) {
2133 /* force 1d on kernel that can't do 2d */
2134 if (mode > RADEON_SURF_MODE_1D &&
2135 (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
2136 if (surf->nsamples > 1) {
2137 fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
2140 mode = RADEON_SURF_MODE_1D;
2141 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2142 surf->flags |= RADEON_SURF_SET(mode, MODE);
2145 if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
2149 if (!surf->tile_split) {
2154 surf->tile_split = 64;
2155 surf->stencil_tile_split = 64;
2159 case RADEON_SURF_MODE_2D: {
2160 if (surf->flags & RADEON_SURF_Z_OR_SBUFFER) {
2161 switch (surf->nsamples) {
2163 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64;
2167 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128;
2170 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256;
2176 if (surf->flags & RADEON_SURF_SBUFFER) {
2177 *stencil_tile_mode = *tile_mode;
2179 cik_get_2d_params(surf_man, 1, surf->nsamples, false,
2180 *stencil_tile_mode, NULL,
2181 &surf->stencil_tile_split,
2182 NULL, NULL, NULL, NULL);
2184 } else if (surf->flags & RADEON_SURF_SCANOUT) {
2185 *tile_mode = CIK_TILE_MODE_COLOR_2D_SCANOUT;
2187 *tile_mode = CIK_TILE_MODE_COLOR_2D;
2190 /* retrieve tiling mode values */
2191 cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
2192 !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), *tile_mode,
2193 NULL, &surf->tile_split, NULL, &surf->mtilea,
2194 &surf->bankw, &surf->bankh);
2197 case RADEON_SURF_MODE_1D:
2198 if (surf->flags & RADEON_SURF_SBUFFER) {
2199 *stencil_tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2201 if (surf->flags & RADEON_SURF_ZBUFFER) {
2202 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2203 } else if (surf->flags & RADEON_SURF_SCANOUT) {
2204 *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2206 *tile_mode = SI_TILE_MODE_COLOR_1D;
2209 case RADEON_SURF_MODE_LINEAR_ALIGNED:
2211 *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
2217 static int cik_surface_init_2d(struct radeon_surface_manager *surf_man,
2218 struct radeon_surface *surf,
2219 struct radeon_surface_level *level,
2220 unsigned bpe, unsigned tile_mode,
2221 unsigned tile_split,
2222 unsigned num_pipes, unsigned num_banks,
2224 unsigned start_level)
2226 uint64_t aligned_offset = offset;
2227 unsigned tilew, tileh, tileb_1x, tileb;
2228 unsigned mtilew, mtileh, mtileb;
2232 /* compute tile values */
2235 tileb_1x = tilew * tileh * bpe;
2237 tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
2239 tileb = surf->nsamples * tileb_1x;
2241 /* slices per tile */
2243 if (tileb > tile_split && tile_split) {
2244 slice_pt = tileb / tile_split;
2245 tileb = tileb / slice_pt;
2248 /* macro tile width & height */
2249 mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
2250 mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
2252 /* macro tile bytes */
2253 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
2255 if (start_level <= 1) {
2256 unsigned alignment = MAX2(256, mtileb);
2257 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
2259 if (aligned_offset) {
2260 aligned_offset = ALIGN(aligned_offset, alignment);
2264 /* build mipmap tree */
2265 for (i = start_level; i <= surf->last_level; i++) {
2266 level[i].mode = RADEON_SURF_MODE_2D;
2267 si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
2268 if (level[i].mode == RADEON_SURF_MODE_1D) {
2269 switch (tile_mode) {
2270 case CIK_TILE_MODE_COLOR_2D:
2271 tile_mode = SI_TILE_MODE_COLOR_1D;
2273 case CIK_TILE_MODE_COLOR_2D_SCANOUT:
2274 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2276 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64:
2277 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128:
2278 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256:
2279 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512:
2280 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE:
2281 tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2286 return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
2288 /* level0 and first mipmap need to have alignment */
2289 aligned_offset = offset = surf->bo_size;
2291 aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
2293 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
2294 if (surf->level == level) {
2295 surf->tiling_index[i] = tile_mode;
2296 /* it's ok because stencil is done after */
2297 surf->stencil_tiling_index[i] = tile_mode;
2299 surf->stencil_tiling_index[i] = tile_mode;
2306 static int cik_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
2307 struct radeon_surface *surf,
2308 unsigned tile_mode, unsigned stencil_tile_mode)
2311 uint32_t num_pipes, num_banks;
2313 cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
2314 !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), tile_mode,
2315 &num_pipes, NULL, &num_banks, NULL, NULL, NULL);
2317 r = cik_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode,
2318 surf->tile_split, num_pipes, num_banks, 0, 0);
2323 if (surf->flags & RADEON_SURF_SBUFFER) {
2324 r = cik_surface_init_2d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode,
2325 surf->stencil_tile_split, num_pipes, num_banks,
2327 surf->stencil_offset = surf->stencil_level[0].offset;
2332 static int cik_surface_init(struct radeon_surface_manager *surf_man,
2333 struct radeon_surface *surf)
2335 unsigned mode, tile_mode, stencil_tile_mode;
2338 /* MSAA surfaces support the 2D mode only. */
2339 if (surf->nsamples > 1) {
2340 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2341 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
2345 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2347 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
2348 /* zbuffer only support 1D or 2D tiled surface */
2350 case RADEON_SURF_MODE_1D:
2351 case RADEON_SURF_MODE_2D:
2354 mode = RADEON_SURF_MODE_1D;
2355 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2356 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2361 r = cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2366 surf->stencil_offset = 0;
2367 surf->bo_alignment = 0;
2369 /* check tiling mode */
2371 case RADEON_SURF_MODE_LINEAR:
2372 r = r6_surface_init_linear(surf_man, surf, 0, 0);
2374 case RADEON_SURF_MODE_LINEAR_ALIGNED:
2375 r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
2377 case RADEON_SURF_MODE_1D:
2378 r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2380 case RADEON_SURF_MODE_2D:
2381 r = cik_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2390 * depending on surface
2392 static int cik_surface_best(struct radeon_surface_manager *surf_man,
2393 struct radeon_surface *surf)
2395 unsigned mode, tile_mode, stencil_tile_mode;
2398 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2400 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
2401 !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
2402 /* depth/stencil force 1d tiling for old mesa */
2403 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2404 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2407 return cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2411 /* ===========================================================================
2414 struct radeon_surface_manager *
2415 radeon_surface_manager_new(int fd)
2417 struct radeon_surface_manager *surf_man;
2419 surf_man = calloc(1, sizeof(struct radeon_surface_manager));
2420 if (surf_man == NULL) {
2424 if (radeon_get_value(fd, RADEON_INFO_DEVICE_ID, &surf_man->device_id)) {
2427 if (radeon_get_family(surf_man)) {
2431 if (surf_man->family <= CHIP_RV740) {
2432 if (r6_init_hw_info(surf_man)) {
2435 surf_man->surface_init = &r6_surface_init;
2436 surf_man->surface_best = &r6_surface_best;
2437 } else if (surf_man->family <= CHIP_ARUBA) {
2438 if (eg_init_hw_info(surf_man)) {
2441 surf_man->surface_init = &eg_surface_init;
2442 surf_man->surface_best = &eg_surface_best;
2443 } else if (surf_man->family < CHIP_BONAIRE) {
2444 if (si_init_hw_info(surf_man)) {
2447 surf_man->surface_init = &si_surface_init;
2448 surf_man->surface_best = &si_surface_best;
2450 if (cik_init_hw_info(surf_man)) {
2453 surf_man->surface_init = &cik_surface_init;
2454 surf_man->surface_best = &cik_surface_best;
2464 radeon_surface_manager_free(struct radeon_surface_manager *surf_man)
2469 static int radeon_surface_sanity(struct radeon_surface_manager *surf_man,
2470 struct radeon_surface *surf,
2474 if (surf_man == NULL || surf_man->surface_init == NULL || surf == NULL) {
2478 /* all dimension must be at least 1 ! */
2479 if (!surf->npix_x || !surf->npix_y || !surf->npix_z) {
2482 if (!surf->blk_w || !surf->blk_h || !surf->blk_d) {
2485 if (!surf->array_size) {
2488 /* array size must be a power of 2 */
2489 surf->array_size = next_power_of_two(surf->array_size);
2491 switch (surf->nsamples) {
2502 case RADEON_SURF_TYPE_1D:
2503 if (surf->npix_y > 1) {
2506 case RADEON_SURF_TYPE_2D:
2507 if (surf->npix_z > 1) {
2511 case RADEON_SURF_TYPE_CUBEMAP:
2512 if (surf->npix_z > 1) {
2515 /* deal with cubemap as they were texture array */
2516 if (surf_man->family >= CHIP_RV770) {
2517 surf->array_size = 8;
2519 surf->array_size = 6;
2522 case RADEON_SURF_TYPE_3D:
2524 case RADEON_SURF_TYPE_1D_ARRAY:
2525 if (surf->npix_y > 1) {
2528 case RADEON_SURF_TYPE_2D_ARRAY:
2537 radeon_surface_init(struct radeon_surface_manager *surf_man,
2538 struct radeon_surface *surf)
2540 unsigned mode, type;
2543 type = RADEON_SURF_GET(surf->flags, TYPE);
2544 mode = RADEON_SURF_GET(surf->flags, MODE);
2546 r = radeon_surface_sanity(surf_man, surf, type, mode);
2550 return surf_man->surface_init(surf_man, surf);
2554 radeon_surface_best(struct radeon_surface_manager *surf_man,
2555 struct radeon_surface *surf)
2557 unsigned mode, type;
2560 type = RADEON_SURF_GET(surf->flags, TYPE);
2561 mode = RADEON_SURF_GET(surf->flags, MODE);
2563 r = radeon_surface_sanity(surf_man, surf, type, mode);
2567 return surf_man->surface_best(surf_man, surf);