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>
36 #include <sys/ioctl.h>
39 #include "radeon_drm.h"
40 #include "radeon_surface.h"
42 #define ALIGN(value, alignment) (((value) + alignment - 1) & ~(alignment - 1))
43 #define MAX2(A, B) ((A) > (B) ? (A) : (B))
44 #define MIN2(A, B) ((A) < (B) ? (A) : (B))
46 /* keep this private */
87 typedef int (*hw_init_surface_t)(struct radeon_surface_manager *surf_man,
88 struct radeon_surface *surf);
89 typedef int (*hw_best_surface_t)(struct radeon_surface_manager *surf_man,
90 struct radeon_surface *surf);
92 struct radeon_hw_info {
101 uint32_t tile_mode_array[32];
103 uint32_t macrotile_mode_array[16];
106 struct radeon_surface_manager {
109 struct radeon_hw_info hw_info;
111 hw_init_surface_t surface_init;
112 hw_best_surface_t surface_best;
116 static int radeon_get_value(int fd, unsigned req, uint32_t *value)
118 struct drm_radeon_info info = {};
123 info.value = (uintptr_t)value;
124 r = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info,
125 sizeof(struct drm_radeon_info));
129 static int radeon_get_family(struct radeon_surface_manager *surf_man)
131 switch (surf_man->device_id) {
132 #define CHIPSET(pci_id, name, fam) case pci_id: surf_man->family = CHIP_##fam; break;
133 #include "r600_pci_ids.h"
141 static unsigned next_power_of_two(unsigned x)
146 return (1 << ((sizeof(unsigned) * 8) - __builtin_clz(x - 1)));
149 static unsigned mip_minify(unsigned size, unsigned level)
153 val = MAX2(1, size >> level);
155 val = next_power_of_two(val);
159 static void surf_minify(struct radeon_surface *surf,
160 struct radeon_surface_level *surflevel,
161 unsigned bpe, unsigned level,
162 uint32_t xalign, uint32_t yalign, uint32_t zalign,
165 surflevel->npix_x = mip_minify(surf->npix_x, level);
166 surflevel->npix_y = mip_minify(surf->npix_y, level);
167 surflevel->npix_z = mip_minify(surf->npix_z, level);
168 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
169 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
170 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
171 if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
172 !(surf->flags & RADEON_SURF_FMASK)) {
173 if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
174 surflevel->mode = RADEON_SURF_MODE_1D;
178 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign);
179 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign);
180 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign);
182 surflevel->offset = offset;
183 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
184 surflevel->slice_size = surflevel->pitch_bytes * surflevel->nblk_y;
186 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
189 /* ===========================================================================
192 static int r6_init_hw_info(struct radeon_surface_manager *surf_man)
194 uint32_t tiling_config;
195 drmVersionPtr version;
198 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
204 surf_man->hw_info.allow_2d = 0;
205 version = drmGetVersion(surf_man->fd);
206 if (version && version->version_minor >= 14) {
207 surf_man->hw_info.allow_2d = 1;
209 drmFreeVersion(version);
211 switch ((tiling_config & 0xe) >> 1) {
213 surf_man->hw_info.num_pipes = 1;
216 surf_man->hw_info.num_pipes = 2;
219 surf_man->hw_info.num_pipes = 4;
222 surf_man->hw_info.num_pipes = 8;
225 surf_man->hw_info.num_pipes = 8;
226 surf_man->hw_info.allow_2d = 0;
230 switch ((tiling_config & 0x30) >> 4) {
232 surf_man->hw_info.num_banks = 4;
235 surf_man->hw_info.num_banks = 8;
238 surf_man->hw_info.num_banks = 8;
239 surf_man->hw_info.allow_2d = 0;
243 switch ((tiling_config & 0xc0) >> 6) {
245 surf_man->hw_info.group_bytes = 256;
248 surf_man->hw_info.group_bytes = 512;
251 surf_man->hw_info.group_bytes = 256;
252 surf_man->hw_info.allow_2d = 0;
258 static int r6_surface_init_linear(struct radeon_surface_manager *surf_man,
259 struct radeon_surface *surf,
260 uint64_t offset, unsigned start_level)
262 uint32_t xalign, yalign, zalign;
265 /* compute alignment */
267 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
269 /* the 32 alignment is for scanout, cb or db but to allow texture to be
270 * easily bound as such we force this alignment to all surface
272 xalign = MAX2(1, surf_man->hw_info.group_bytes / surf->bpe);
275 if (surf->flags & RADEON_SURF_SCANOUT) {
276 xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
279 /* build mipmap tree */
280 for (i = start_level; i <= surf->last_level; i++) {
281 surf->level[i].mode = RADEON_SURF_MODE_LINEAR;
282 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
283 /* level0 and first mipmap need to have alignment */
284 offset = surf->bo_size;
286 offset = ALIGN(offset, surf->bo_alignment);
292 static int r6_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
293 struct radeon_surface *surf,
294 uint64_t offset, unsigned start_level)
296 uint32_t xalign, yalign, zalign;
299 /* compute alignment */
301 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
303 xalign = MAX2(64, surf_man->hw_info.group_bytes / surf->bpe);
307 /* build mipmap tree */
308 for (i = start_level; i <= surf->last_level; i++) {
309 surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
310 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
311 /* level0 and first mipmap need to have alignment */
312 offset = surf->bo_size;
314 offset = ALIGN(offset, surf->bo_alignment);
320 static int r6_surface_init_1d(struct radeon_surface_manager *surf_man,
321 struct radeon_surface *surf,
322 uint64_t offset, unsigned start_level)
324 uint32_t xalign, yalign, zalign, tilew;
327 /* compute alignment */
329 xalign = surf_man->hw_info.group_bytes / (tilew * surf->bpe * surf->nsamples);
330 xalign = MAX2(tilew, xalign);
333 if (surf->flags & RADEON_SURF_SCANOUT) {
334 xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
337 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
340 /* build mipmap tree */
341 for (i = start_level; i <= surf->last_level; i++) {
342 surf->level[i].mode = RADEON_SURF_MODE_1D;
343 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
344 /* level0 and first mipmap need to have alignment */
345 offset = surf->bo_size;
347 offset = ALIGN(offset, surf->bo_alignment);
353 static int r6_surface_init_2d(struct radeon_surface_manager *surf_man,
354 struct radeon_surface *surf,
355 uint64_t offset, unsigned start_level)
357 uint32_t xalign, yalign, zalign, tilew;
360 /* compute alignment */
363 xalign = (surf_man->hw_info.group_bytes * surf_man->hw_info.num_banks) /
364 (tilew * surf->bpe * surf->nsamples);
365 xalign = MAX2(tilew * surf_man->hw_info.num_banks, xalign);
366 yalign = tilew * surf_man->hw_info.num_pipes;
367 if (surf->flags & RADEON_SURF_SCANOUT) {
368 xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
372 MAX2(surf_man->hw_info.num_pipes *
373 surf_man->hw_info.num_banks *
374 surf->nsamples * surf->bpe * 64,
375 xalign * yalign * surf->nsamples * surf->bpe);
378 /* build mipmap tree */
379 for (i = start_level; i <= surf->last_level; i++) {
380 surf->level[i].mode = RADEON_SURF_MODE_2D;
381 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
382 if (surf->level[i].mode == RADEON_SURF_MODE_1D) {
383 return r6_surface_init_1d(surf_man, surf, offset, i);
385 /* level0 and first mipmap need to have alignment */
386 offset = surf->bo_size;
388 offset = ALIGN(offset, surf->bo_alignment);
394 static int r6_surface_init(struct radeon_surface_manager *surf_man,
395 struct radeon_surface *surf)
400 /* MSAA surfaces support the 2D mode only. */
401 if (surf->nsamples > 1) {
402 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
403 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
407 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
409 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
410 /* zbuffer only support 1D or 2D tiled surface */
412 case RADEON_SURF_MODE_1D:
413 case RADEON_SURF_MODE_2D:
416 mode = RADEON_SURF_MODE_1D;
417 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
418 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
423 /* force 1d on kernel that can't do 2d */
424 if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) {
425 if (surf->nsamples > 1) {
426 fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__);
429 mode = RADEON_SURF_MODE_1D;
430 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
431 surf->flags |= RADEON_SURF_SET(mode, MODE);
434 /* check surface dimension */
435 if (surf->npix_x > 8192 || surf->npix_y > 8192 || surf->npix_z > 8192) {
439 /* check mipmap last_level */
440 if (surf->last_level > 14) {
444 /* check tiling mode */
446 case RADEON_SURF_MODE_LINEAR:
447 r = r6_surface_init_linear(surf_man, surf, 0, 0);
449 case RADEON_SURF_MODE_LINEAR_ALIGNED:
450 r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
452 case RADEON_SURF_MODE_1D:
453 r = r6_surface_init_1d(surf_man, surf, 0, 0);
455 case RADEON_SURF_MODE_2D:
456 r = r6_surface_init_2d(surf_man, surf, 0, 0);
464 static int r6_surface_best(struct radeon_surface_manager *surf_man,
465 struct radeon_surface *surf)
467 /* no value to optimize for r6xx/r7xx */
472 /* ===========================================================================
475 static int eg_init_hw_info(struct radeon_surface_manager *surf_man)
477 uint32_t tiling_config;
478 drmVersionPtr version;
481 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
487 surf_man->hw_info.allow_2d = 0;
488 version = drmGetVersion(surf_man->fd);
489 if (version && version->version_minor >= 16) {
490 surf_man->hw_info.allow_2d = 1;
492 drmFreeVersion(version);
494 switch (tiling_config & 0xf) {
496 surf_man->hw_info.num_pipes = 1;
499 surf_man->hw_info.num_pipes = 2;
502 surf_man->hw_info.num_pipes = 4;
505 surf_man->hw_info.num_pipes = 8;
508 surf_man->hw_info.num_pipes = 8;
509 surf_man->hw_info.allow_2d = 0;
513 switch ((tiling_config & 0xf0) >> 4) {
515 surf_man->hw_info.num_banks = 4;
518 surf_man->hw_info.num_banks = 8;
521 surf_man->hw_info.num_banks = 16;
524 surf_man->hw_info.num_banks = 8;
525 surf_man->hw_info.allow_2d = 0;
529 switch ((tiling_config & 0xf00) >> 8) {
531 surf_man->hw_info.group_bytes = 256;
534 surf_man->hw_info.group_bytes = 512;
537 surf_man->hw_info.group_bytes = 256;
538 surf_man->hw_info.allow_2d = 0;
542 switch ((tiling_config & 0xf000) >> 12) {
544 surf_man->hw_info.row_size = 1024;
547 surf_man->hw_info.row_size = 2048;
550 surf_man->hw_info.row_size = 4096;
553 surf_man->hw_info.row_size = 4096;
554 surf_man->hw_info.allow_2d = 0;
560 static void eg_surf_minify(struct radeon_surface *surf,
561 struct radeon_surface_level *surflevel,
570 unsigned mtile_pr, mtile_ps;
572 surflevel->npix_x = mip_minify(surf->npix_x, level);
573 surflevel->npix_y = mip_minify(surf->npix_y, level);
574 surflevel->npix_z = mip_minify(surf->npix_z, level);
575 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
576 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
577 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
578 if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
579 !(surf->flags & RADEON_SURF_FMASK)) {
580 if (surflevel->nblk_x < mtilew || surflevel->nblk_y < mtileh) {
581 surflevel->mode = RADEON_SURF_MODE_1D;
585 surflevel->nblk_x = ALIGN(surflevel->nblk_x, mtilew);
586 surflevel->nblk_y = ALIGN(surflevel->nblk_y, mtileh);
587 surflevel->nblk_z = ALIGN(surflevel->nblk_z, 1);
589 /* macro tile per row */
590 mtile_pr = surflevel->nblk_x / mtilew;
591 /* macro tile per slice */
592 mtile_ps = (mtile_pr * surflevel->nblk_y) / mtileh;
594 surflevel->offset = offset;
595 surflevel->pitch_bytes = surflevel->nblk_x * bpe * slice_pt;
596 surflevel->slice_size = mtile_ps * mtileb * slice_pt;
598 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
601 static int eg_surface_init_1d(struct radeon_surface_manager *surf_man,
602 struct radeon_surface *surf,
603 struct radeon_surface_level *level,
605 uint64_t offset, unsigned start_level)
607 uint32_t xalign, yalign, zalign, tilew;
610 /* compute alignment */
612 xalign = surf_man->hw_info.group_bytes / (tilew * bpe * surf->nsamples);
613 xalign = MAX2(tilew, xalign);
616 if (surf->flags & RADEON_SURF_SCANOUT) {
617 xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
621 unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
622 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
625 offset = ALIGN(offset, alignment);
629 /* build mipmap tree */
630 for (i = start_level; i <= surf->last_level; i++) {
631 level[i].mode = RADEON_SURF_MODE_1D;
632 surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, offset);
633 /* level0 and first mipmap need to have alignment */
634 offset = surf->bo_size;
636 offset = ALIGN(offset, surf->bo_alignment);
642 static int eg_surface_init_2d(struct radeon_surface_manager *surf_man,
643 struct radeon_surface *surf,
644 struct radeon_surface_level *level,
645 unsigned bpe, unsigned tile_split,
646 uint64_t offset, unsigned start_level)
648 unsigned tilew, tileh, tileb;
649 unsigned mtilew, mtileh, mtileb;
653 /* compute tile values */
656 tileb = tilew * tileh * bpe * surf->nsamples;
657 /* slices per tile */
659 if (tileb > tile_split && tile_split) {
660 slice_pt = tileb / tile_split;
662 tileb = tileb / slice_pt;
664 /* macro tile width & height */
665 mtilew = (tilew * surf->bankw * surf_man->hw_info.num_pipes) * surf->mtilea;
666 mtileh = (tileh * surf->bankh * surf_man->hw_info.num_banks) / surf->mtilea;
667 /* macro tile bytes */
668 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
671 unsigned alignment = MAX2(256, mtileb);
672 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
675 offset = ALIGN(offset, alignment);
679 /* build mipmap tree */
680 for (i = start_level; i <= surf->last_level; i++) {
681 level[i].mode = RADEON_SURF_MODE_2D;
682 eg_surf_minify(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, mtileb, offset);
683 if (level[i].mode == RADEON_SURF_MODE_1D) {
684 return eg_surface_init_1d(surf_man, surf, level, bpe, offset, i);
686 /* level0 and first mipmap need to have alignment */
687 offset = surf->bo_size;
689 offset = ALIGN(offset, surf->bo_alignment);
695 static int eg_surface_sanity(struct radeon_surface_manager *surf_man,
696 struct radeon_surface *surf,
701 /* check surface dimension */
702 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
706 /* check mipmap last_level */
707 if (surf->last_level > 15) {
711 /* force 1d on kernel that can't do 2d */
712 if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) {
713 if (surf->nsamples > 1) {
714 fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__);
717 mode = RADEON_SURF_MODE_1D;
718 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
719 surf->flags |= RADEON_SURF_SET(mode, MODE);
722 /* check tile split */
723 if (mode == RADEON_SURF_MODE_2D) {
724 switch (surf->tile_split) {
736 switch (surf->mtilea) {
745 /* check aspect ratio */
746 if (surf_man->hw_info.num_banks < surf->mtilea) {
749 /* check bank width */
750 switch (surf->bankw) {
759 /* check bank height */
760 switch (surf->bankh) {
769 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
770 if ((tileb * surf->bankh * surf->bankw) < surf_man->hw_info.group_bytes) {
778 static int eg_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
779 struct radeon_surface *surf)
781 unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
782 int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
783 /* Old libdrm headers didn't have stencil_level in it. This prevents crashes. */
784 struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
785 struct radeon_surface_level *stencil_level =
786 (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
788 r = eg_surface_init_1d(surf_man, surf, surf->level, surf->bpe, 0, 0);
792 if (is_depth_stencil) {
793 r = eg_surface_init_1d(surf_man, surf, stencil_level, 1,
795 surf->stencil_offset = stencil_level[0].offset;
800 static int eg_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
801 struct radeon_surface *surf)
803 unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
804 int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
805 /* Old libdrm headers didn't have stencil_level in it. This prevents crashes. */
806 struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
807 struct radeon_surface_level *stencil_level =
808 (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
810 r = eg_surface_init_2d(surf_man, surf, surf->level, surf->bpe,
811 surf->tile_split, 0, 0);
815 if (is_depth_stencil) {
816 r = eg_surface_init_2d(surf_man, surf, stencil_level, 1,
817 surf->stencil_tile_split, surf->bo_size, 0);
818 surf->stencil_offset = stencil_level[0].offset;
823 static int eg_surface_init(struct radeon_surface_manager *surf_man,
824 struct radeon_surface *surf)
829 /* MSAA surfaces support the 2D mode only. */
830 if (surf->nsamples > 1) {
831 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
832 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
836 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
838 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
839 /* zbuffer only support 1D or 2D tiled surface */
841 case RADEON_SURF_MODE_1D:
842 case RADEON_SURF_MODE_2D:
845 mode = RADEON_SURF_MODE_1D;
846 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
847 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
852 r = eg_surface_sanity(surf_man, surf, mode);
857 surf->stencil_offset = 0;
858 surf->bo_alignment = 0;
860 /* check tiling mode */
862 case RADEON_SURF_MODE_LINEAR:
863 r = r6_surface_init_linear(surf_man, surf, 0, 0);
865 case RADEON_SURF_MODE_LINEAR_ALIGNED:
866 r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
868 case RADEON_SURF_MODE_1D:
869 r = eg_surface_init_1d_miptrees(surf_man, surf);
871 case RADEON_SURF_MODE_2D:
872 r = eg_surface_init_2d_miptrees(surf_man, surf);
880 static unsigned log2_int(unsigned x)
888 if ((unsigned)(1 << l) > x) {
895 /* compute best tile_split, bankw, bankh, mtilea
896 * depending on surface
898 static int eg_surface_best(struct radeon_surface_manager *surf_man,
899 struct radeon_surface *surf)
901 unsigned mode, tileb, h_over_w;
905 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
907 /* set some default value to avoid sanity check choking on them */
908 surf->tile_split = 1024;
911 surf->mtilea = surf_man->hw_info.num_banks;
912 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
913 for (; surf->bankh <= 8; surf->bankh *= 2) {
914 if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
918 if (surf->mtilea > 8) {
922 r = eg_surface_sanity(surf_man, surf, mode);
927 if (mode != RADEON_SURF_MODE_2D) {
928 /* nothing to do for non 2D tiled surface */
932 /* Tweak TILE_SPLIT for performance here. */
933 if (surf->nsamples > 1) {
934 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
935 switch (surf->nsamples) {
937 surf->tile_split = 128;
940 surf->tile_split = 128;
943 surf->tile_split = 256;
945 case 16: /* cayman only */
946 surf->tile_split = 512;
949 fprintf(stderr, "radeon: Wrong number of samples %i (%i)\n",
950 surf->nsamples, __LINE__);
953 surf->stencil_tile_split = 64;
955 /* tile split must be >= 256 for colorbuffer surfaces */
956 surf->tile_split = MAX2(surf->nsamples * surf->bpe * 64, 256);
957 if (surf->tile_split > 4096)
958 surf->tile_split = 4096;
961 /* set tile split to row size */
962 surf->tile_split = surf_man->hw_info.row_size;
963 surf->stencil_tile_split = surf_man->hw_info.row_size / 2;
966 /* bankw or bankh greater than 1 increase alignment requirement, not
967 * sure if it's worth using smaller bankw & bankh to stick with 2D
968 * tiling on small surface rather than falling back to 1D tiling.
969 * Use recommanded value based on tile size for now.
971 * fmask buffer has different optimal value figure them out once we
974 if (surf->flags & RADEON_SURF_SBUFFER) {
975 /* assume 1 bytes for stencil, we optimize for stencil as stencil
976 * and depth shares surface values
978 tileb = MIN2(surf->tile_split, 64 * surf->nsamples);
980 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
983 /* use bankw of 1 to minimize width alignment, might be interesting to
984 * increase it for large surface
999 /* double check the constraint */
1000 for (; surf->bankh <= 8; surf->bankh *= 2) {
1001 if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
1006 h_over_w = (((surf->bankh * surf_man->hw_info.num_banks) << 16) /
1007 (surf->bankw * surf_man->hw_info.num_pipes)) >> 16;
1008 surf->mtilea = 1 << (log2_int(h_over_w) >> 1);
1014 /* ===========================================================================
1015 * Southern Islands family
1017 #define SI__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f)
1018 #define SI__PIPE_CONFIG__ADDR_SURF_P2 0
1019 #define SI__PIPE_CONFIG__ADDR_SURF_P4_8x16 4
1020 #define SI__PIPE_CONFIG__ADDR_SURF_P4_16x16 5
1021 #define SI__PIPE_CONFIG__ADDR_SURF_P4_16x32 6
1022 #define SI__PIPE_CONFIG__ADDR_SURF_P4_32x32 7
1023 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8
1024 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9
1025 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10
1026 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11
1027 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12
1028 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13
1029 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14
1030 #define SI__GB_TILE_MODE__TILE_SPLIT(x) (((x) >> 11) & 0x7)
1031 #define SI__TILE_SPLIT__64B 0
1032 #define SI__TILE_SPLIT__128B 1
1033 #define SI__TILE_SPLIT__256B 2
1034 #define SI__TILE_SPLIT__512B 3
1035 #define SI__TILE_SPLIT__1024B 4
1036 #define SI__TILE_SPLIT__2048B 5
1037 #define SI__TILE_SPLIT__4096B 6
1038 #define SI__GB_TILE_MODE__BANK_WIDTH(x) (((x) >> 14) & 0x3)
1039 #define SI__BANK_WIDTH__1 0
1040 #define SI__BANK_WIDTH__2 1
1041 #define SI__BANK_WIDTH__4 2
1042 #define SI__BANK_WIDTH__8 3
1043 #define SI__GB_TILE_MODE__BANK_HEIGHT(x) (((x) >> 16) & 0x3)
1044 #define SI__BANK_HEIGHT__1 0
1045 #define SI__BANK_HEIGHT__2 1
1046 #define SI__BANK_HEIGHT__4 2
1047 #define SI__BANK_HEIGHT__8 3
1048 #define SI__GB_TILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 18) & 0x3)
1049 #define SI__MACRO_TILE_ASPECT__1 0
1050 #define SI__MACRO_TILE_ASPECT__2 1
1051 #define SI__MACRO_TILE_ASPECT__4 2
1052 #define SI__MACRO_TILE_ASPECT__8 3
1053 #define SI__GB_TILE_MODE__NUM_BANKS(x) (((x) >> 20) & 0x3)
1054 #define SI__NUM_BANKS__2_BANK 0
1055 #define SI__NUM_BANKS__4_BANK 1
1056 #define SI__NUM_BANKS__8_BANK 2
1057 #define SI__NUM_BANKS__16_BANK 3
1060 static void si_gb_tile_mode(uint32_t gb_tile_mode,
1061 unsigned *num_pipes,
1062 unsigned *num_banks,
1063 uint32_t *macro_tile_aspect,
1066 uint32_t *tile_split)
1069 switch (SI__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1070 case SI__PIPE_CONFIG__ADDR_SURF_P2:
1074 case SI__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1075 case SI__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1076 case SI__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1077 case SI__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1080 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1081 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1082 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1083 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1084 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1085 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1086 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1092 switch (SI__GB_TILE_MODE__NUM_BANKS(gb_tile_mode)) {
1094 case SI__NUM_BANKS__2_BANK:
1097 case SI__NUM_BANKS__4_BANK:
1100 case SI__NUM_BANKS__8_BANK:
1103 case SI__NUM_BANKS__16_BANK:
1108 if (macro_tile_aspect) {
1109 switch (SI__GB_TILE_MODE__MACRO_TILE_ASPECT(gb_tile_mode)) {
1111 case SI__MACRO_TILE_ASPECT__1:
1112 *macro_tile_aspect = 1;
1114 case SI__MACRO_TILE_ASPECT__2:
1115 *macro_tile_aspect = 2;
1117 case SI__MACRO_TILE_ASPECT__4:
1118 *macro_tile_aspect = 4;
1120 case SI__MACRO_TILE_ASPECT__8:
1121 *macro_tile_aspect = 8;
1126 switch (SI__GB_TILE_MODE__BANK_WIDTH(gb_tile_mode)) {
1128 case SI__BANK_WIDTH__1:
1131 case SI__BANK_WIDTH__2:
1134 case SI__BANK_WIDTH__4:
1137 case SI__BANK_WIDTH__8:
1143 switch (SI__GB_TILE_MODE__BANK_HEIGHT(gb_tile_mode)) {
1145 case SI__BANK_HEIGHT__1:
1148 case SI__BANK_HEIGHT__2:
1151 case SI__BANK_HEIGHT__4:
1154 case SI__BANK_HEIGHT__8:
1160 switch (SI__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1162 case SI__TILE_SPLIT__64B:
1165 case SI__TILE_SPLIT__128B:
1168 case SI__TILE_SPLIT__256B:
1171 case SI__TILE_SPLIT__512B:
1174 case SI__TILE_SPLIT__1024B:
1177 case SI__TILE_SPLIT__2048B:
1180 case SI__TILE_SPLIT__4096B:
1187 static int si_init_hw_info(struct radeon_surface_manager *surf_man)
1189 uint32_t tiling_config;
1190 drmVersionPtr version;
1193 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
1199 surf_man->hw_info.allow_2d = 0;
1200 version = drmGetVersion(surf_man->fd);
1201 if (version && version->version_minor >= 33) {
1202 if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array)) {
1203 surf_man->hw_info.allow_2d = 1;
1206 drmFreeVersion(version);
1208 switch (tiling_config & 0xf) {
1210 surf_man->hw_info.num_pipes = 1;
1213 surf_man->hw_info.num_pipes = 2;
1216 surf_man->hw_info.num_pipes = 4;
1219 surf_man->hw_info.num_pipes = 8;
1222 surf_man->hw_info.num_pipes = 8;
1223 surf_man->hw_info.allow_2d = 0;
1227 switch ((tiling_config & 0xf0) >> 4) {
1229 surf_man->hw_info.num_banks = 4;
1232 surf_man->hw_info.num_banks = 8;
1235 surf_man->hw_info.num_banks = 16;
1238 surf_man->hw_info.num_banks = 8;
1239 surf_man->hw_info.allow_2d = 0;
1243 switch ((tiling_config & 0xf00) >> 8) {
1245 surf_man->hw_info.group_bytes = 256;
1248 surf_man->hw_info.group_bytes = 512;
1251 surf_man->hw_info.group_bytes = 256;
1252 surf_man->hw_info.allow_2d = 0;
1256 switch ((tiling_config & 0xf000) >> 12) {
1258 surf_man->hw_info.row_size = 1024;
1261 surf_man->hw_info.row_size = 2048;
1264 surf_man->hw_info.row_size = 4096;
1267 surf_man->hw_info.row_size = 4096;
1268 surf_man->hw_info.allow_2d = 0;
1274 static int si_surface_sanity(struct radeon_surface_manager *surf_man,
1275 struct radeon_surface *surf,
1276 unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
1278 uint32_t gb_tile_mode;
1280 /* check surface dimension */
1281 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
1285 /* check mipmap last_level */
1286 if (surf->last_level > 15) {
1290 /* force 1d on kernel that can't do 2d */
1291 if (mode > RADEON_SURF_MODE_1D &&
1292 (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
1293 if (surf->nsamples > 1) {
1294 fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
1297 mode = RADEON_SURF_MODE_1D;
1298 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1299 surf->flags |= RADEON_SURF_SET(mode, MODE);
1302 if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
1306 if (!surf->tile_split) {
1311 surf->tile_split = 64;
1312 surf->stencil_tile_split = 64;
1316 case RADEON_SURF_MODE_2D:
1317 if (surf->flags & RADEON_SURF_SBUFFER) {
1318 switch (surf->nsamples) {
1320 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1323 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1326 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1329 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1334 /* retrieve tiling mode value */
1335 gb_tile_mode = surf_man->hw_info.tile_mode_array[*stencil_tile_mode];
1336 si_gb_tile_mode(gb_tile_mode, NULL, NULL, NULL, NULL, NULL, &surf->stencil_tile_split);
1338 if (surf->flags & RADEON_SURF_ZBUFFER) {
1339 switch (surf->nsamples) {
1341 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1344 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1347 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1350 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1355 } else if (surf->flags & RADEON_SURF_SCANOUT) {
1356 switch (surf->bpe) {
1358 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
1361 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
1367 switch (surf->bpe) {
1369 *tile_mode = SI_TILE_MODE_COLOR_2D_8BPP;
1372 *tile_mode = SI_TILE_MODE_COLOR_2D_16BPP;
1375 *tile_mode = SI_TILE_MODE_COLOR_2D_32BPP;
1379 *tile_mode = SI_TILE_MODE_COLOR_2D_64BPP;
1385 /* retrieve tiling mode value */
1386 gb_tile_mode = surf_man->hw_info.tile_mode_array[*tile_mode];
1387 si_gb_tile_mode(gb_tile_mode, NULL, NULL, &surf->mtilea, &surf->bankw, &surf->bankh, &surf->tile_split);
1389 case RADEON_SURF_MODE_1D:
1390 if (surf->flags & RADEON_SURF_SBUFFER) {
1391 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1393 if (surf->flags & RADEON_SURF_ZBUFFER) {
1394 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1395 } else if (surf->flags & RADEON_SURF_SCANOUT) {
1396 *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1398 *tile_mode = SI_TILE_MODE_COLOR_1D;
1401 case RADEON_SURF_MODE_LINEAR_ALIGNED:
1403 *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
1409 static void si_surf_minify(struct radeon_surface *surf,
1410 struct radeon_surface_level *surflevel,
1411 unsigned bpe, unsigned level,
1412 uint32_t xalign, uint32_t yalign, uint32_t zalign,
1413 uint32_t slice_align, unsigned offset)
1416 surflevel->npix_x = surf->npix_x;
1418 surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1420 surflevel->npix_y = mip_minify(surf->npix_y, level);
1421 surflevel->npix_z = mip_minify(surf->npix_z, level);
1423 if (level == 0 && surf->last_level > 0) {
1424 surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1425 surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1426 surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1428 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1429 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1430 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1433 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign);
1435 /* XXX: Texture sampling uses unexpectedly large pitches in some cases,
1436 * these are just guesses for the rules behind those
1438 if (level == 0 && surf->last_level == 0)
1439 /* Non-mipmap pitch padded to slice alignment */
1440 /* Using just bpe here breaks stencil blitting; surf->bpe works. */
1441 xalign = MAX2(xalign, slice_align / surf->bpe);
1442 else if (surflevel->mode == RADEON_SURF_MODE_LINEAR_ALIGNED)
1443 /* Small rows evenly distributed across slice */
1444 xalign = MAX2(xalign, slice_align / bpe / surflevel->nblk_y);
1446 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign);
1447 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign);
1449 surflevel->offset = offset;
1450 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
1451 surflevel->slice_size = ALIGN(surflevel->pitch_bytes * surflevel->nblk_y, slice_align);
1453 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1456 static void si_surf_minify_2d(struct radeon_surface *surf,
1457 struct radeon_surface_level *surflevel,
1458 unsigned bpe, unsigned level, unsigned slice_pt,
1459 uint32_t xalign, uint32_t yalign, uint32_t zalign,
1460 unsigned mtileb, unsigned offset)
1462 unsigned mtile_pr, mtile_ps;
1465 surflevel->npix_x = surf->npix_x;
1467 surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1469 surflevel->npix_y = mip_minify(surf->npix_y, level);
1470 surflevel->npix_z = mip_minify(surf->npix_z, level);
1472 if (level == 0 && surf->last_level > 0) {
1473 surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1474 surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1475 surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1477 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1478 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1479 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1482 if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
1483 !(surf->flags & RADEON_SURF_FMASK)) {
1484 if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
1485 surflevel->mode = RADEON_SURF_MODE_1D;
1489 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign);
1490 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign);
1491 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign);
1493 /* macro tile per row */
1494 mtile_pr = surflevel->nblk_x / xalign;
1495 /* macro tile per slice */
1496 mtile_ps = (mtile_pr * surflevel->nblk_y) / yalign;
1497 surflevel->offset = offset;
1498 surflevel->pitch_bytes = surflevel->nblk_x * bpe * slice_pt;
1499 surflevel->slice_size = mtile_ps * mtileb * slice_pt;
1501 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1504 static int si_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
1505 struct radeon_surface *surf,
1507 uint64_t offset, unsigned start_level)
1509 uint32_t xalign, yalign, zalign, slice_align;
1512 /* compute alignment */
1514 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
1516 xalign = MAX2(8, 64 / surf->bpe);
1519 slice_align = MAX2(64 * surf->bpe, surf_man->hw_info.group_bytes);
1521 /* build mipmap tree */
1522 for (i = start_level; i <= surf->last_level; i++) {
1523 surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
1524 si_surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, slice_align, offset);
1525 /* level0 and first mipmap need to have alignment */
1526 offset = surf->bo_size;
1528 offset = ALIGN(offset, surf->bo_alignment);
1530 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1531 surf->tiling_index[i] = tile_mode;
1537 static int si_surface_init_1d(struct radeon_surface_manager *surf_man,
1538 struct radeon_surface *surf,
1539 struct radeon_surface_level *level,
1540 unsigned bpe, unsigned tile_mode,
1541 uint64_t offset, unsigned start_level)
1543 uint32_t xalign, yalign, zalign, slice_align;
1544 unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
1547 /* compute alignment */
1551 slice_align = surf_man->hw_info.group_bytes;
1552 if (surf->flags & RADEON_SURF_SCANOUT) {
1553 xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
1556 if (start_level <= 1) {
1557 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1560 offset = ALIGN(offset, alignment);
1564 /* build mipmap tree */
1565 for (i = start_level; i <= surf->last_level; i++) {
1566 level[i].mode = RADEON_SURF_MODE_1D;
1567 si_surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, slice_align, offset);
1568 /* level0 and first mipmap need to have alignment */
1569 offset = surf->bo_size;
1571 offset = ALIGN(offset, alignment);
1573 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1574 if (surf->level == level) {
1575 surf->tiling_index[i] = tile_mode;
1576 /* it's ok because stencil is done after */
1577 surf->stencil_tiling_index[i] = tile_mode;
1579 surf->stencil_tiling_index[i] = tile_mode;
1586 static int si_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
1587 struct radeon_surface *surf,
1588 unsigned tile_mode, unsigned stencil_tile_mode)
1592 r = si_surface_init_1d(surf_man, surf, surf->level, surf->bpe, tile_mode, 0, 0);
1597 if (surf->flags & RADEON_SURF_SBUFFER) {
1598 r = si_surface_init_1d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode, surf->bo_size, 0);
1599 surf->stencil_offset = surf->stencil_level[0].offset;
1604 static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
1605 struct radeon_surface *surf,
1606 struct radeon_surface_level *level,
1607 unsigned bpe, unsigned tile_mode,
1608 unsigned num_pipes, unsigned num_banks,
1609 unsigned tile_split,
1611 unsigned start_level)
1613 uint64_t aligned_offset = offset;
1614 unsigned tilew, tileh, tileb;
1615 unsigned mtilew, mtileh, mtileb;
1619 /* compute tile values */
1622 tileb = tilew * tileh * bpe * surf->nsamples;
1623 /* slices per tile */
1625 if (tileb > tile_split && tile_split) {
1626 slice_pt = tileb / tile_split;
1628 tileb = tileb / slice_pt;
1630 /* macro tile width & height */
1631 mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
1632 mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
1634 /* macro tile bytes */
1635 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
1637 if (start_level <= 1) {
1638 unsigned alignment = MAX2(256, mtileb);
1639 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1641 if (aligned_offset) {
1642 aligned_offset = ALIGN(aligned_offset, alignment);
1646 /* build mipmap tree */
1647 for (i = start_level; i <= surf->last_level; i++) {
1648 level[i].mode = RADEON_SURF_MODE_2D;
1649 si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
1650 if (level[i].mode == RADEON_SURF_MODE_1D) {
1651 switch (tile_mode) {
1652 case SI_TILE_MODE_COLOR_2D_8BPP:
1653 case SI_TILE_MODE_COLOR_2D_16BPP:
1654 case SI_TILE_MODE_COLOR_2D_32BPP:
1655 case SI_TILE_MODE_COLOR_2D_64BPP:
1656 tile_mode = SI_TILE_MODE_COLOR_1D;
1658 case SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP:
1659 case SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP:
1660 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1662 case SI_TILE_MODE_DEPTH_STENCIL_2D:
1663 tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1668 return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
1670 /* level0 and first mipmap need to have alignment */
1671 aligned_offset = offset = surf->bo_size;
1673 aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
1675 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1676 if (surf->level == level) {
1677 surf->tiling_index[i] = tile_mode;
1678 /* it's ok because stencil is done after */
1679 surf->stencil_tiling_index[i] = tile_mode;
1681 surf->stencil_tiling_index[i] = tile_mode;
1688 static int si_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
1689 struct radeon_surface *surf,
1690 unsigned tile_mode, unsigned stencil_tile_mode)
1692 unsigned num_pipes, num_banks;
1693 uint32_t gb_tile_mode;
1696 /* retrieve tiling mode value */
1697 gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1698 si_gb_tile_mode(gb_tile_mode, &num_pipes, &num_banks, NULL, NULL, NULL, NULL);
1700 r = si_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode, num_pipes, num_banks, surf->tile_split, 0, 0);
1705 if (surf->flags & RADEON_SURF_SBUFFER) {
1706 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);
1707 surf->stencil_offset = surf->stencil_level[0].offset;
1712 static int si_surface_init(struct radeon_surface_manager *surf_man,
1713 struct radeon_surface *surf)
1715 unsigned mode, tile_mode, stencil_tile_mode;
1718 /* MSAA surfaces support the 2D mode only. */
1719 if (surf->nsamples > 1) {
1720 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1721 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
1725 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1727 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
1728 /* zbuffer only support 1D or 2D tiled surface */
1730 case RADEON_SURF_MODE_1D:
1731 case RADEON_SURF_MODE_2D:
1734 mode = RADEON_SURF_MODE_1D;
1735 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1736 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1741 r = si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1746 surf->stencil_offset = 0;
1747 surf->bo_alignment = 0;
1749 /* check tiling mode */
1751 case RADEON_SURF_MODE_LINEAR:
1752 r = r6_surface_init_linear(surf_man, surf, 0, 0);
1754 case RADEON_SURF_MODE_LINEAR_ALIGNED:
1755 r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
1757 case RADEON_SURF_MODE_1D:
1758 r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1760 case RADEON_SURF_MODE_2D:
1761 r = si_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1770 * depending on surface
1772 static int si_surface_best(struct radeon_surface_manager *surf_man,
1773 struct radeon_surface *surf)
1775 unsigned mode, tile_mode, stencil_tile_mode;
1778 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1780 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
1781 !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
1782 /* depth/stencil force 1d tiling for old mesa */
1783 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1784 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1787 return si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1791 /* ===========================================================================
1792 * Sea Islands family
1794 #define CIK__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f)
1795 #define CIK__PIPE_CONFIG__ADDR_SURF_P2 0
1796 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16 4
1797 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16 5
1798 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32 6
1799 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32 7
1800 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8
1801 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9
1802 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10
1803 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11
1804 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12
1805 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13
1806 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14
1807 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16 16
1808 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16 17
1809 #define CIK__GB_TILE_MODE__TILE_SPLIT(x) (((x) >> 11) & 0x7)
1810 #define CIK__TILE_SPLIT__64B 0
1811 #define CIK__TILE_SPLIT__128B 1
1812 #define CIK__TILE_SPLIT__256B 2
1813 #define CIK__TILE_SPLIT__512B 3
1814 #define CIK__TILE_SPLIT__1024B 4
1815 #define CIK__TILE_SPLIT__2048B 5
1816 #define CIK__TILE_SPLIT__4096B 6
1817 #define CIK__GB_TILE_MODE__SAMPLE_SPLIT(x) (((x) >> 25) & 0x3)
1818 #define CIK__SAMPLE_SPLIT__1 0
1819 #define CIK__SAMPLE_SPLIT__2 1
1820 #define CIK__SAMPLE_SPLIT__4 2
1821 #define CIK__SAMPLE_SPLIT__8 3
1822 #define CIK__GB_MACROTILE_MODE__BANK_WIDTH(x) ((x) & 0x3)
1823 #define CIK__BANK_WIDTH__1 0
1824 #define CIK__BANK_WIDTH__2 1
1825 #define CIK__BANK_WIDTH__4 2
1826 #define CIK__BANK_WIDTH__8 3
1827 #define CIK__GB_MACROTILE_MODE__BANK_HEIGHT(x) (((x) >> 2) & 0x3)
1828 #define CIK__BANK_HEIGHT__1 0
1829 #define CIK__BANK_HEIGHT__2 1
1830 #define CIK__BANK_HEIGHT__4 2
1831 #define CIK__BANK_HEIGHT__8 3
1832 #define CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 4) & 0x3)
1833 #define CIK__MACRO_TILE_ASPECT__1 0
1834 #define CIK__MACRO_TILE_ASPECT__2 1
1835 #define CIK__MACRO_TILE_ASPECT__4 2
1836 #define CIK__MACRO_TILE_ASPECT__8 3
1837 #define CIK__GB_MACROTILE_MODE__NUM_BANKS(x) (((x) >> 6) & 0x3)
1838 #define CIK__NUM_BANKS__2_BANK 0
1839 #define CIK__NUM_BANKS__4_BANK 1
1840 #define CIK__NUM_BANKS__8_BANK 2
1841 #define CIK__NUM_BANKS__16_BANK 3
1844 static void cik_get_2d_params(struct radeon_surface_manager *surf_man,
1845 unsigned bpe, unsigned nsamples, bool is_color,
1847 uint32_t *num_pipes,
1848 uint32_t *tile_split_ptr,
1849 uint32_t *num_banks,
1850 uint32_t *macro_tile_aspect,
1854 uint32_t gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1855 unsigned tileb_1x, tileb;
1856 unsigned gb_macrotile_mode;
1857 unsigned macrotile_index;
1858 unsigned tile_split, sample_split;
1861 switch (CIK__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1862 case CIK__PIPE_CONFIG__ADDR_SURF_P2:
1866 case CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1867 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1868 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1869 case CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1872 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1873 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1874 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1875 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1876 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1877 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1878 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1881 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16:
1882 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16:
1887 switch (CIK__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1889 case CIK__TILE_SPLIT__64B:
1892 case CIK__TILE_SPLIT__128B:
1895 case CIK__TILE_SPLIT__256B:
1898 case CIK__TILE_SPLIT__512B:
1901 case CIK__TILE_SPLIT__1024B:
1904 case CIK__TILE_SPLIT__2048B:
1907 case CIK__TILE_SPLIT__4096B:
1911 switch (CIK__GB_TILE_MODE__SAMPLE_SPLIT(gb_tile_mode)) {
1913 case CIK__SAMPLE_SPLIT__1:
1916 case CIK__SAMPLE_SPLIT__2:
1919 case CIK__SAMPLE_SPLIT__4:
1922 case CIK__SAMPLE_SPLIT__8:
1927 /* Adjust the tile split. */
1928 tileb_1x = 8 * 8 * bpe;
1930 tile_split = MAX2(256, sample_split * tileb_1x);
1932 tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
1934 /* Determine the macrotile index. */
1935 tileb = MIN2(tile_split, nsamples * tileb_1x);
1937 for (macrotile_index = 0; tileb > 64; macrotile_index++) {
1940 gb_macrotile_mode = surf_man->hw_info.macrotile_mode_array[macrotile_index];
1942 if (tile_split_ptr) {
1943 *tile_split_ptr = tile_split;
1946 switch (CIK__GB_MACROTILE_MODE__NUM_BANKS(gb_macrotile_mode)) {
1948 case CIK__NUM_BANKS__2_BANK:
1951 case CIK__NUM_BANKS__4_BANK:
1954 case CIK__NUM_BANKS__8_BANK:
1957 case CIK__NUM_BANKS__16_BANK:
1962 if (macro_tile_aspect) {
1963 switch (CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(gb_macrotile_mode)) {
1965 case CIK__MACRO_TILE_ASPECT__1:
1966 *macro_tile_aspect = 1;
1968 case CIK__MACRO_TILE_ASPECT__2:
1969 *macro_tile_aspect = 2;
1971 case CIK__MACRO_TILE_ASPECT__4:
1972 *macro_tile_aspect = 4;
1974 case CIK__MACRO_TILE_ASPECT__8:
1975 *macro_tile_aspect = 8;
1980 switch (CIK__GB_MACROTILE_MODE__BANK_WIDTH(gb_macrotile_mode)) {
1982 case CIK__BANK_WIDTH__1:
1985 case CIK__BANK_WIDTH__2:
1988 case CIK__BANK_WIDTH__4:
1991 case CIK__BANK_WIDTH__8:
1997 switch (CIK__GB_MACROTILE_MODE__BANK_HEIGHT(gb_macrotile_mode)) {
1999 case CIK__BANK_HEIGHT__1:
2002 case CIK__BANK_HEIGHT__2:
2005 case CIK__BANK_HEIGHT__4:
2008 case CIK__BANK_HEIGHT__8:
2015 static int cik_init_hw_info(struct radeon_surface_manager *surf_man)
2017 uint32_t tiling_config;
2018 drmVersionPtr version;
2021 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
2027 surf_man->hw_info.allow_2d = 0;
2028 version = drmGetVersion(surf_man->fd);
2029 if (version && version->version_minor >= 35) {
2030 if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array) &&
2031 !radeon_get_value(surf_man->fd, RADEON_INFO_CIK_MACROTILE_MODE_ARRAY, surf_man->hw_info.macrotile_mode_array)) {
2032 surf_man->hw_info.allow_2d = 1;
2035 drmFreeVersion(version);
2037 switch (tiling_config & 0xf) {
2039 surf_man->hw_info.num_pipes = 1;
2042 surf_man->hw_info.num_pipes = 2;
2045 surf_man->hw_info.num_pipes = 4;
2048 surf_man->hw_info.num_pipes = 8;
2051 surf_man->hw_info.num_pipes = 8;
2052 surf_man->hw_info.allow_2d = 0;
2056 switch ((tiling_config & 0xf0) >> 4) {
2058 surf_man->hw_info.num_banks = 4;
2061 surf_man->hw_info.num_banks = 8;
2064 surf_man->hw_info.num_banks = 16;
2067 surf_man->hw_info.num_banks = 8;
2068 surf_man->hw_info.allow_2d = 0;
2072 switch ((tiling_config & 0xf00) >> 8) {
2074 surf_man->hw_info.group_bytes = 256;
2077 surf_man->hw_info.group_bytes = 512;
2080 surf_man->hw_info.group_bytes = 256;
2081 surf_man->hw_info.allow_2d = 0;
2085 switch ((tiling_config & 0xf000) >> 12) {
2087 surf_man->hw_info.row_size = 1024;
2090 surf_man->hw_info.row_size = 2048;
2093 surf_man->hw_info.row_size = 4096;
2096 surf_man->hw_info.row_size = 4096;
2097 surf_man->hw_info.allow_2d = 0;
2103 static int cik_surface_sanity(struct radeon_surface_manager *surf_man,
2104 struct radeon_surface *surf,
2105 unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
2107 /* check surface dimension */
2108 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
2112 /* check mipmap last_level */
2113 if (surf->last_level > 15) {
2117 /* force 1d on kernel that can't do 2d */
2118 if (mode > RADEON_SURF_MODE_1D &&
2119 (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
2120 if (surf->nsamples > 1) {
2121 fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
2124 mode = RADEON_SURF_MODE_1D;
2125 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2126 surf->flags |= RADEON_SURF_SET(mode, MODE);
2129 if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
2133 if (!surf->tile_split) {
2138 surf->tile_split = 64;
2139 surf->stencil_tile_split = 64;
2143 case RADEON_SURF_MODE_2D: {
2144 if (surf->flags & RADEON_SURF_Z_OR_SBUFFER) {
2145 switch (surf->nsamples) {
2147 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64;
2151 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128;
2154 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256;
2160 if (surf->flags & RADEON_SURF_SBUFFER) {
2161 *stencil_tile_mode = *tile_mode;
2163 cik_get_2d_params(surf_man, 1, surf->nsamples, false,
2164 *stencil_tile_mode, NULL,
2165 &surf->stencil_tile_split,
2166 NULL, NULL, NULL, NULL);
2168 } else if (surf->flags & RADEON_SURF_SCANOUT) {
2169 *tile_mode = CIK_TILE_MODE_COLOR_2D_SCANOUT;
2171 *tile_mode = CIK_TILE_MODE_COLOR_2D;
2174 /* retrieve tiling mode values */
2175 cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
2176 !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), *tile_mode,
2177 NULL, &surf->tile_split, NULL, &surf->mtilea,
2178 &surf->bankw, &surf->bankh);
2181 case RADEON_SURF_MODE_1D:
2182 if (surf->flags & RADEON_SURF_SBUFFER) {
2183 *stencil_tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2185 if (surf->flags & RADEON_SURF_ZBUFFER) {
2186 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2187 } else if (surf->flags & RADEON_SURF_SCANOUT) {
2188 *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2190 *tile_mode = SI_TILE_MODE_COLOR_1D;
2193 case RADEON_SURF_MODE_LINEAR_ALIGNED:
2195 *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
2201 static int cik_surface_init_2d(struct radeon_surface_manager *surf_man,
2202 struct radeon_surface *surf,
2203 struct radeon_surface_level *level,
2204 unsigned bpe, unsigned tile_mode,
2205 unsigned tile_split,
2206 unsigned num_pipes, unsigned num_banks,
2208 unsigned start_level)
2210 uint64_t aligned_offset = offset;
2211 unsigned tilew, tileh, tileb_1x, tileb;
2212 unsigned mtilew, mtileh, mtileb;
2216 /* compute tile values */
2219 tileb_1x = tilew * tileh * bpe;
2221 tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
2223 tileb = surf->nsamples * tileb_1x;
2225 /* slices per tile */
2227 if (tileb > tile_split && tile_split) {
2228 slice_pt = tileb / tile_split;
2229 tileb = tileb / slice_pt;
2232 /* macro tile width & height */
2233 mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
2234 mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
2236 /* macro tile bytes */
2237 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
2239 if (start_level <= 1) {
2240 unsigned alignment = MAX2(256, mtileb);
2241 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
2243 if (aligned_offset) {
2244 aligned_offset = ALIGN(aligned_offset, alignment);
2248 /* build mipmap tree */
2249 for (i = start_level; i <= surf->last_level; i++) {
2250 level[i].mode = RADEON_SURF_MODE_2D;
2251 si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
2252 if (level[i].mode == RADEON_SURF_MODE_1D) {
2253 switch (tile_mode) {
2254 case CIK_TILE_MODE_COLOR_2D:
2255 tile_mode = SI_TILE_MODE_COLOR_1D;
2257 case CIK_TILE_MODE_COLOR_2D_SCANOUT:
2258 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2260 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64:
2261 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128:
2262 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256:
2263 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512:
2264 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE:
2265 tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2270 return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
2272 /* level0 and first mipmap need to have alignment */
2273 aligned_offset = offset = surf->bo_size;
2275 aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
2277 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
2278 if (surf->level == level) {
2279 surf->tiling_index[i] = tile_mode;
2280 /* it's ok because stencil is done after */
2281 surf->stencil_tiling_index[i] = tile_mode;
2283 surf->stencil_tiling_index[i] = tile_mode;
2290 static int cik_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
2291 struct radeon_surface *surf,
2292 unsigned tile_mode, unsigned stencil_tile_mode)
2295 uint32_t num_pipes, num_banks;
2297 cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
2298 !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), tile_mode,
2299 &num_pipes, NULL, &num_banks, NULL, NULL, NULL);
2301 r = cik_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode,
2302 surf->tile_split, num_pipes, num_banks, 0, 0);
2307 if (surf->flags & RADEON_SURF_SBUFFER) {
2308 r = cik_surface_init_2d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode,
2309 surf->stencil_tile_split, num_pipes, num_banks,
2311 surf->stencil_offset = surf->stencil_level[0].offset;
2316 static int cik_surface_init(struct radeon_surface_manager *surf_man,
2317 struct radeon_surface *surf)
2319 unsigned mode, tile_mode, stencil_tile_mode;
2322 /* MSAA surfaces support the 2D mode only. */
2323 if (surf->nsamples > 1) {
2324 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2325 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
2329 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2331 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
2332 /* zbuffer only support 1D or 2D tiled surface */
2334 case RADEON_SURF_MODE_1D:
2335 case RADEON_SURF_MODE_2D:
2338 mode = RADEON_SURF_MODE_1D;
2339 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2340 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2345 r = cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2350 surf->stencil_offset = 0;
2351 surf->bo_alignment = 0;
2353 /* check tiling mode */
2355 case RADEON_SURF_MODE_LINEAR:
2356 r = r6_surface_init_linear(surf_man, surf, 0, 0);
2358 case RADEON_SURF_MODE_LINEAR_ALIGNED:
2359 r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
2361 case RADEON_SURF_MODE_1D:
2362 r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2364 case RADEON_SURF_MODE_2D:
2365 r = cik_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2374 * depending on surface
2376 static int cik_surface_best(struct radeon_surface_manager *surf_man,
2377 struct radeon_surface *surf)
2379 unsigned mode, tile_mode, stencil_tile_mode;
2382 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2384 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
2385 !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
2386 /* depth/stencil force 1d tiling for old mesa */
2387 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2388 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2391 return cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2395 /* ===========================================================================
2398 struct radeon_surface_manager *radeon_surface_manager_new(int fd)
2400 struct radeon_surface_manager *surf_man;
2402 surf_man = calloc(1, sizeof(struct radeon_surface_manager));
2403 if (surf_man == NULL) {
2407 if (radeon_get_value(fd, RADEON_INFO_DEVICE_ID, &surf_man->device_id)) {
2410 if (radeon_get_family(surf_man)) {
2414 if (surf_man->family <= CHIP_RV740) {
2415 if (r6_init_hw_info(surf_man)) {
2418 surf_man->surface_init = &r6_surface_init;
2419 surf_man->surface_best = &r6_surface_best;
2420 } else if (surf_man->family <= CHIP_ARUBA) {
2421 if (eg_init_hw_info(surf_man)) {
2424 surf_man->surface_init = &eg_surface_init;
2425 surf_man->surface_best = &eg_surface_best;
2426 } else if (surf_man->family < CHIP_BONAIRE) {
2427 if (si_init_hw_info(surf_man)) {
2430 surf_man->surface_init = &si_surface_init;
2431 surf_man->surface_best = &si_surface_best;
2433 if (cik_init_hw_info(surf_man)) {
2436 surf_man->surface_init = &cik_surface_init;
2437 surf_man->surface_best = &cik_surface_best;
2446 void radeon_surface_manager_free(struct radeon_surface_manager *surf_man)
2451 static int radeon_surface_sanity(struct radeon_surface_manager *surf_man,
2452 struct radeon_surface *surf,
2456 if (surf_man == NULL || surf_man->surface_init == NULL || surf == NULL) {
2460 /* all dimension must be at least 1 ! */
2461 if (!surf->npix_x || !surf->npix_y || !surf->npix_z) {
2464 if (!surf->blk_w || !surf->blk_h || !surf->blk_d) {
2467 if (!surf->array_size) {
2470 /* array size must be a power of 2 */
2471 surf->array_size = next_power_of_two(surf->array_size);
2473 switch (surf->nsamples) {
2484 case RADEON_SURF_TYPE_1D:
2485 if (surf->npix_y > 1) {
2488 case RADEON_SURF_TYPE_2D:
2489 if (surf->npix_z > 1) {
2493 case RADEON_SURF_TYPE_CUBEMAP:
2494 if (surf->npix_z > 1) {
2497 /* deal with cubemap as they were texture array */
2498 if (surf_man->family >= CHIP_RV770) {
2499 surf->array_size = 8;
2501 surf->array_size = 6;
2504 case RADEON_SURF_TYPE_3D:
2506 case RADEON_SURF_TYPE_1D_ARRAY:
2507 if (surf->npix_y > 1) {
2510 case RADEON_SURF_TYPE_2D_ARRAY:
2518 int radeon_surface_init(struct radeon_surface_manager *surf_man,
2519 struct radeon_surface *surf)
2521 unsigned mode, type;
2524 type = RADEON_SURF_GET(surf->flags, TYPE);
2525 mode = RADEON_SURF_GET(surf->flags, MODE);
2527 r = radeon_surface_sanity(surf_man, surf, type, mode);
2531 return surf_man->surface_init(surf_man, surf);
2534 int radeon_surface_best(struct radeon_surface_manager *surf_man,
2535 struct radeon_surface *surf)
2537 unsigned mode, type;
2540 type = RADEON_SURF_GET(surf->flags, TYPE);
2541 mode = RADEON_SURF_GET(surf->flags, MODE);
2543 r = radeon_surface_sanity(surf_man, surf, type, mode);
2547 return surf_man->surface_best(surf_man, surf);