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>
42 #include "radeon_drm.h"
43 #include "radeon_surface.h"
45 #define ALIGN(value, alignment) (((value) + alignment - 1) & ~(alignment - 1))
46 #define MAX2(A, B) ((A) > (B) ? (A) : (B))
47 #define MIN2(A, B) ((A) < (B) ? (A) : (B))
49 /* keep this private */
90 typedef int (*hw_init_surface_t)(struct radeon_surface_manager *surf_man,
91 struct radeon_surface *surf);
92 typedef int (*hw_best_surface_t)(struct radeon_surface_manager *surf_man,
93 struct radeon_surface *surf);
95 struct radeon_hw_info {
104 uint32_t tile_mode_array[32];
106 uint32_t macrotile_mode_array[16];
109 struct radeon_surface_manager {
112 struct radeon_hw_info hw_info;
114 hw_init_surface_t surface_init;
115 hw_best_surface_t surface_best;
119 static int radeon_get_value(int fd, unsigned req, uint32_t *value)
121 struct drm_radeon_info info = {};
126 info.value = (uintptr_t)value;
127 r = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info,
128 sizeof(struct drm_radeon_info));
132 static int radeon_get_family(struct radeon_surface_manager *surf_man)
134 switch (surf_man->device_id) {
135 #define CHIPSET(pci_id, name, fam) case pci_id: surf_man->family = CHIP_##fam; break;
136 #include "r600_pci_ids.h"
144 static unsigned next_power_of_two(unsigned x)
149 return (1 << ((sizeof(unsigned) * 8) - __builtin_clz(x - 1)));
152 static unsigned mip_minify(unsigned size, unsigned level)
156 val = MAX2(1, size >> level);
158 val = next_power_of_two(val);
162 static void surf_minify(struct radeon_surface *surf,
163 struct radeon_surface_level *surflevel,
164 unsigned bpe, unsigned level,
165 uint32_t xalign, uint32_t yalign, uint32_t zalign,
168 surflevel->npix_x = mip_minify(surf->npix_x, level);
169 surflevel->npix_y = mip_minify(surf->npix_y, level);
170 surflevel->npix_z = mip_minify(surf->npix_z, level);
171 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
172 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
173 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
174 if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
175 !(surf->flags & RADEON_SURF_FMASK)) {
176 if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
177 surflevel->mode = RADEON_SURF_MODE_1D;
181 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign);
182 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign);
183 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign);
185 surflevel->offset = offset;
186 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
187 surflevel->slice_size = surflevel->pitch_bytes * surflevel->nblk_y;
189 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
192 /* ===========================================================================
195 static int r6_init_hw_info(struct radeon_surface_manager *surf_man)
197 uint32_t tiling_config;
198 drmVersionPtr version;
201 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
207 surf_man->hw_info.allow_2d = 0;
208 version = drmGetVersion(surf_man->fd);
209 if (version && version->version_minor >= 14) {
210 surf_man->hw_info.allow_2d = 1;
212 drmFreeVersion(version);
214 switch ((tiling_config & 0xe) >> 1) {
216 surf_man->hw_info.num_pipes = 1;
219 surf_man->hw_info.num_pipes = 2;
222 surf_man->hw_info.num_pipes = 4;
225 surf_man->hw_info.num_pipes = 8;
228 surf_man->hw_info.num_pipes = 8;
229 surf_man->hw_info.allow_2d = 0;
233 switch ((tiling_config & 0x30) >> 4) {
235 surf_man->hw_info.num_banks = 4;
238 surf_man->hw_info.num_banks = 8;
241 surf_man->hw_info.num_banks = 8;
242 surf_man->hw_info.allow_2d = 0;
246 switch ((tiling_config & 0xc0) >> 6) {
248 surf_man->hw_info.group_bytes = 256;
251 surf_man->hw_info.group_bytes = 512;
254 surf_man->hw_info.group_bytes = 256;
255 surf_man->hw_info.allow_2d = 0;
261 static int r6_surface_init_linear(struct radeon_surface_manager *surf_man,
262 struct radeon_surface *surf,
263 uint64_t offset, unsigned start_level)
265 uint32_t xalign, yalign, zalign;
268 /* compute alignment */
270 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
272 /* the 32 alignment is for scanout, cb or db but to allow texture to be
273 * easily bound as such we force this alignment to all surface
275 xalign = MAX2(1, surf_man->hw_info.group_bytes / surf->bpe);
278 if (surf->flags & RADEON_SURF_SCANOUT) {
279 xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
282 /* build mipmap tree */
283 for (i = start_level; i <= surf->last_level; i++) {
284 surf->level[i].mode = RADEON_SURF_MODE_LINEAR;
285 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
286 /* level0 and first mipmap need to have alignment */
287 offset = surf->bo_size;
289 offset = ALIGN(offset, surf->bo_alignment);
295 static int r6_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
296 struct radeon_surface *surf,
297 uint64_t offset, unsigned start_level)
299 uint32_t xalign, yalign, zalign;
302 /* compute alignment */
304 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
306 xalign = MAX2(64, surf_man->hw_info.group_bytes / surf->bpe);
310 /* build mipmap tree */
311 for (i = start_level; i <= surf->last_level; i++) {
312 surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
313 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
314 /* level0 and first mipmap need to have alignment */
315 offset = surf->bo_size;
317 offset = ALIGN(offset, surf->bo_alignment);
323 static int r6_surface_init_1d(struct radeon_surface_manager *surf_man,
324 struct radeon_surface *surf,
325 uint64_t offset, unsigned start_level)
327 uint32_t xalign, yalign, zalign, tilew;
330 /* compute alignment */
332 xalign = surf_man->hw_info.group_bytes / (tilew * surf->bpe * surf->nsamples);
333 xalign = MAX2(tilew, xalign);
336 if (surf->flags & RADEON_SURF_SCANOUT) {
337 xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
340 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
343 /* build mipmap tree */
344 for (i = start_level; i <= surf->last_level; i++) {
345 surf->level[i].mode = RADEON_SURF_MODE_1D;
346 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
347 /* level0 and first mipmap need to have alignment */
348 offset = surf->bo_size;
350 offset = ALIGN(offset, surf->bo_alignment);
356 static int r6_surface_init_2d(struct radeon_surface_manager *surf_man,
357 struct radeon_surface *surf,
358 uint64_t offset, unsigned start_level)
360 uint32_t xalign, yalign, zalign, tilew;
363 /* compute alignment */
366 xalign = (surf_man->hw_info.group_bytes * surf_man->hw_info.num_banks) /
367 (tilew * surf->bpe * surf->nsamples);
368 xalign = MAX2(tilew * surf_man->hw_info.num_banks, xalign);
369 yalign = tilew * surf_man->hw_info.num_pipes;
370 if (surf->flags & RADEON_SURF_SCANOUT) {
371 xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
375 MAX2(surf_man->hw_info.num_pipes *
376 surf_man->hw_info.num_banks *
377 surf->nsamples * surf->bpe * 64,
378 xalign * yalign * surf->nsamples * surf->bpe);
381 /* build mipmap tree */
382 for (i = start_level; i <= surf->last_level; i++) {
383 surf->level[i].mode = RADEON_SURF_MODE_2D;
384 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
385 if (surf->level[i].mode == RADEON_SURF_MODE_1D) {
386 return r6_surface_init_1d(surf_man, surf, offset, i);
388 /* level0 and first mipmap need to have alignment */
389 offset = surf->bo_size;
391 offset = ALIGN(offset, surf->bo_alignment);
397 static int r6_surface_init(struct radeon_surface_manager *surf_man,
398 struct radeon_surface *surf)
403 /* MSAA surfaces support the 2D mode only. */
404 if (surf->nsamples > 1) {
405 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
406 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
410 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
412 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
413 /* zbuffer only support 1D or 2D tiled surface */
415 case RADEON_SURF_MODE_1D:
416 case RADEON_SURF_MODE_2D:
419 mode = RADEON_SURF_MODE_1D;
420 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
421 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
426 /* force 1d on kernel that can't do 2d */
427 if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) {
428 if (surf->nsamples > 1) {
429 fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__);
432 mode = RADEON_SURF_MODE_1D;
433 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
434 surf->flags |= RADEON_SURF_SET(mode, MODE);
437 /* check surface dimension */
438 if (surf->npix_x > 8192 || surf->npix_y > 8192 || surf->npix_z > 8192) {
442 /* check mipmap last_level */
443 if (surf->last_level > 14) {
447 /* check tiling mode */
449 case RADEON_SURF_MODE_LINEAR:
450 r = r6_surface_init_linear(surf_man, surf, 0, 0);
452 case RADEON_SURF_MODE_LINEAR_ALIGNED:
453 r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
455 case RADEON_SURF_MODE_1D:
456 r = r6_surface_init_1d(surf_man, surf, 0, 0);
458 case RADEON_SURF_MODE_2D:
459 r = r6_surface_init_2d(surf_man, surf, 0, 0);
467 static int r6_surface_best(struct radeon_surface_manager *surf_man,
468 struct radeon_surface *surf)
470 /* no value to optimize for r6xx/r7xx */
475 /* ===========================================================================
478 static int eg_init_hw_info(struct radeon_surface_manager *surf_man)
480 uint32_t tiling_config;
481 drmVersionPtr version;
484 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
490 surf_man->hw_info.allow_2d = 0;
491 version = drmGetVersion(surf_man->fd);
492 if (version && version->version_minor >= 16) {
493 surf_man->hw_info.allow_2d = 1;
495 drmFreeVersion(version);
497 switch (tiling_config & 0xf) {
499 surf_man->hw_info.num_pipes = 1;
502 surf_man->hw_info.num_pipes = 2;
505 surf_man->hw_info.num_pipes = 4;
508 surf_man->hw_info.num_pipes = 8;
511 surf_man->hw_info.num_pipes = 8;
512 surf_man->hw_info.allow_2d = 0;
516 switch ((tiling_config & 0xf0) >> 4) {
518 surf_man->hw_info.num_banks = 4;
521 surf_man->hw_info.num_banks = 8;
524 surf_man->hw_info.num_banks = 16;
527 surf_man->hw_info.num_banks = 8;
528 surf_man->hw_info.allow_2d = 0;
532 switch ((tiling_config & 0xf00) >> 8) {
534 surf_man->hw_info.group_bytes = 256;
537 surf_man->hw_info.group_bytes = 512;
540 surf_man->hw_info.group_bytes = 256;
541 surf_man->hw_info.allow_2d = 0;
545 switch ((tiling_config & 0xf000) >> 12) {
547 surf_man->hw_info.row_size = 1024;
550 surf_man->hw_info.row_size = 2048;
553 surf_man->hw_info.row_size = 4096;
556 surf_man->hw_info.row_size = 4096;
557 surf_man->hw_info.allow_2d = 0;
563 static void eg_surf_minify(struct radeon_surface *surf,
564 struct radeon_surface_level *surflevel,
573 unsigned mtile_pr, mtile_ps;
575 surflevel->npix_x = mip_minify(surf->npix_x, level);
576 surflevel->npix_y = mip_minify(surf->npix_y, level);
577 surflevel->npix_z = mip_minify(surf->npix_z, level);
578 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
579 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
580 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
581 if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
582 !(surf->flags & RADEON_SURF_FMASK)) {
583 if (surflevel->nblk_x < mtilew || surflevel->nblk_y < mtileh) {
584 surflevel->mode = RADEON_SURF_MODE_1D;
588 surflevel->nblk_x = ALIGN(surflevel->nblk_x, mtilew);
589 surflevel->nblk_y = ALIGN(surflevel->nblk_y, mtileh);
590 surflevel->nblk_z = ALIGN(surflevel->nblk_z, 1);
592 /* macro tile per row */
593 mtile_pr = surflevel->nblk_x / mtilew;
594 /* macro tile per slice */
595 mtile_ps = (mtile_pr * surflevel->nblk_y) / mtileh;
597 surflevel->offset = offset;
598 surflevel->pitch_bytes = surflevel->nblk_x * bpe * slice_pt;
599 surflevel->slice_size = mtile_ps * mtileb * slice_pt;
601 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
604 static int eg_surface_init_1d(struct radeon_surface_manager *surf_man,
605 struct radeon_surface *surf,
606 struct radeon_surface_level *level,
608 uint64_t offset, unsigned start_level)
610 uint32_t xalign, yalign, zalign, tilew;
613 /* compute alignment */
615 xalign = surf_man->hw_info.group_bytes / (tilew * bpe * surf->nsamples);
616 xalign = MAX2(tilew, xalign);
619 if (surf->flags & RADEON_SURF_SCANOUT) {
620 xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
624 unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
625 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
628 offset = ALIGN(offset, alignment);
632 /* build mipmap tree */
633 for (i = start_level; i <= surf->last_level; i++) {
634 level[i].mode = RADEON_SURF_MODE_1D;
635 surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, offset);
636 /* level0 and first mipmap need to have alignment */
637 offset = surf->bo_size;
639 offset = ALIGN(offset, surf->bo_alignment);
645 static int eg_surface_init_2d(struct radeon_surface_manager *surf_man,
646 struct radeon_surface *surf,
647 struct radeon_surface_level *level,
648 unsigned bpe, unsigned tile_split,
649 uint64_t offset, unsigned start_level)
651 unsigned tilew, tileh, tileb;
652 unsigned mtilew, mtileh, mtileb;
656 /* compute tile values */
659 tileb = tilew * tileh * bpe * surf->nsamples;
660 /* slices per tile */
662 if (tileb > tile_split && tile_split) {
663 slice_pt = tileb / tile_split;
665 tileb = tileb / slice_pt;
667 /* macro tile width & height */
668 mtilew = (tilew * surf->bankw * surf_man->hw_info.num_pipes) * surf->mtilea;
669 mtileh = (tileh * surf->bankh * surf_man->hw_info.num_banks) / surf->mtilea;
670 /* macro tile bytes */
671 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
674 unsigned alignment = MAX2(256, mtileb);
675 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
678 offset = ALIGN(offset, alignment);
682 /* build mipmap tree */
683 for (i = start_level; i <= surf->last_level; i++) {
684 level[i].mode = RADEON_SURF_MODE_2D;
685 eg_surf_minify(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, mtileb, offset);
686 if (level[i].mode == RADEON_SURF_MODE_1D) {
687 return eg_surface_init_1d(surf_man, surf, level, bpe, offset, i);
689 /* level0 and first mipmap need to have alignment */
690 offset = surf->bo_size;
692 offset = ALIGN(offset, surf->bo_alignment);
698 static int eg_surface_sanity(struct radeon_surface_manager *surf_man,
699 struct radeon_surface *surf,
704 /* check surface dimension */
705 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
709 /* check mipmap last_level */
710 if (surf->last_level > 15) {
714 /* force 1d on kernel that can't do 2d */
715 if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) {
716 if (surf->nsamples > 1) {
717 fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__);
720 mode = RADEON_SURF_MODE_1D;
721 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
722 surf->flags |= RADEON_SURF_SET(mode, MODE);
725 /* check tile split */
726 if (mode == RADEON_SURF_MODE_2D) {
727 switch (surf->tile_split) {
739 switch (surf->mtilea) {
748 /* check aspect ratio */
749 if (surf_man->hw_info.num_banks < surf->mtilea) {
752 /* check bank width */
753 switch (surf->bankw) {
762 /* check bank height */
763 switch (surf->bankh) {
772 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
773 if ((tileb * surf->bankh * surf->bankw) < surf_man->hw_info.group_bytes) {
781 static int eg_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
782 struct radeon_surface *surf)
784 unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
785 int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
786 /* Old libdrm headers didn't have stencil_level in it. This prevents crashes. */
787 struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
788 struct radeon_surface_level *stencil_level =
789 (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
791 r = eg_surface_init_1d(surf_man, surf, surf->level, surf->bpe, 0, 0);
795 if (is_depth_stencil) {
796 r = eg_surface_init_1d(surf_man, surf, stencil_level, 1,
798 surf->stencil_offset = stencil_level[0].offset;
803 static int eg_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
804 struct radeon_surface *surf)
806 unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
807 int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
808 /* Old libdrm headers didn't have stencil_level in it. This prevents crashes. */
809 struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
810 struct radeon_surface_level *stencil_level =
811 (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
813 r = eg_surface_init_2d(surf_man, surf, surf->level, surf->bpe,
814 surf->tile_split, 0, 0);
818 if (is_depth_stencil) {
819 r = eg_surface_init_2d(surf_man, surf, stencil_level, 1,
820 surf->stencil_tile_split, surf->bo_size, 0);
821 surf->stencil_offset = stencil_level[0].offset;
826 static int eg_surface_init(struct radeon_surface_manager *surf_man,
827 struct radeon_surface *surf)
832 /* MSAA surfaces support the 2D mode only. */
833 if (surf->nsamples > 1) {
834 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
835 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
839 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
841 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
842 /* zbuffer only support 1D or 2D tiled surface */
844 case RADEON_SURF_MODE_1D:
845 case RADEON_SURF_MODE_2D:
848 mode = RADEON_SURF_MODE_1D;
849 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
850 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
855 r = eg_surface_sanity(surf_man, surf, mode);
860 surf->stencil_offset = 0;
861 surf->bo_alignment = 0;
863 /* check tiling mode */
865 case RADEON_SURF_MODE_LINEAR:
866 r = r6_surface_init_linear(surf_man, surf, 0, 0);
868 case RADEON_SURF_MODE_LINEAR_ALIGNED:
869 r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
871 case RADEON_SURF_MODE_1D:
872 r = eg_surface_init_1d_miptrees(surf_man, surf);
874 case RADEON_SURF_MODE_2D:
875 r = eg_surface_init_2d_miptrees(surf_man, surf);
883 static unsigned log2_int(unsigned x)
891 if ((unsigned)(1 << l) > x) {
898 /* compute best tile_split, bankw, bankh, mtilea
899 * depending on surface
901 static int eg_surface_best(struct radeon_surface_manager *surf_man,
902 struct radeon_surface *surf)
904 unsigned mode, tileb, h_over_w;
908 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
910 /* set some default value to avoid sanity check choking on them */
911 surf->tile_split = 1024;
914 surf->mtilea = surf_man->hw_info.num_banks;
915 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
916 for (; surf->bankh <= 8; surf->bankh *= 2) {
917 if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
921 if (surf->mtilea > 8) {
925 r = eg_surface_sanity(surf_man, surf, mode);
930 if (mode != RADEON_SURF_MODE_2D) {
931 /* nothing to do for non 2D tiled surface */
935 /* Tweak TILE_SPLIT for performance here. */
936 if (surf->nsamples > 1) {
937 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
938 switch (surf->nsamples) {
940 surf->tile_split = 128;
943 surf->tile_split = 128;
946 surf->tile_split = 256;
948 case 16: /* cayman only */
949 surf->tile_split = 512;
952 fprintf(stderr, "radeon: Wrong number of samples %i (%i)\n",
953 surf->nsamples, __LINE__);
956 surf->stencil_tile_split = 64;
958 /* tile split must be >= 256 for colorbuffer surfaces */
959 surf->tile_split = MAX2(surf->nsamples * surf->bpe * 64, 256);
960 if (surf->tile_split > 4096)
961 surf->tile_split = 4096;
964 /* set tile split to row size */
965 surf->tile_split = surf_man->hw_info.row_size;
966 surf->stencil_tile_split = surf_man->hw_info.row_size / 2;
969 /* bankw or bankh greater than 1 increase alignment requirement, not
970 * sure if it's worth using smaller bankw & bankh to stick with 2D
971 * tiling on small surface rather than falling back to 1D tiling.
972 * Use recommanded value based on tile size for now.
974 * fmask buffer has different optimal value figure them out once we
977 if (surf->flags & RADEON_SURF_SBUFFER) {
978 /* assume 1 bytes for stencil, we optimize for stencil as stencil
979 * and depth shares surface values
981 tileb = MIN2(surf->tile_split, 64 * surf->nsamples);
983 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
986 /* use bankw of 1 to minimize width alignment, might be interesting to
987 * increase it for large surface
1002 /* double check the constraint */
1003 for (; surf->bankh <= 8; surf->bankh *= 2) {
1004 if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
1009 h_over_w = (((surf->bankh * surf_man->hw_info.num_banks) << 16) /
1010 (surf->bankw * surf_man->hw_info.num_pipes)) >> 16;
1011 surf->mtilea = 1 << (log2_int(h_over_w) >> 1);
1017 /* ===========================================================================
1018 * Southern Islands family
1020 #define SI__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f)
1021 #define SI__PIPE_CONFIG__ADDR_SURF_P2 0
1022 #define SI__PIPE_CONFIG__ADDR_SURF_P4_8x16 4
1023 #define SI__PIPE_CONFIG__ADDR_SURF_P4_16x16 5
1024 #define SI__PIPE_CONFIG__ADDR_SURF_P4_16x32 6
1025 #define SI__PIPE_CONFIG__ADDR_SURF_P4_32x32 7
1026 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8
1027 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9
1028 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10
1029 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11
1030 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12
1031 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13
1032 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14
1033 #define SI__GB_TILE_MODE__TILE_SPLIT(x) (((x) >> 11) & 0x7)
1034 #define SI__TILE_SPLIT__64B 0
1035 #define SI__TILE_SPLIT__128B 1
1036 #define SI__TILE_SPLIT__256B 2
1037 #define SI__TILE_SPLIT__512B 3
1038 #define SI__TILE_SPLIT__1024B 4
1039 #define SI__TILE_SPLIT__2048B 5
1040 #define SI__TILE_SPLIT__4096B 6
1041 #define SI__GB_TILE_MODE__BANK_WIDTH(x) (((x) >> 14) & 0x3)
1042 #define SI__BANK_WIDTH__1 0
1043 #define SI__BANK_WIDTH__2 1
1044 #define SI__BANK_WIDTH__4 2
1045 #define SI__BANK_WIDTH__8 3
1046 #define SI__GB_TILE_MODE__BANK_HEIGHT(x) (((x) >> 16) & 0x3)
1047 #define SI__BANK_HEIGHT__1 0
1048 #define SI__BANK_HEIGHT__2 1
1049 #define SI__BANK_HEIGHT__4 2
1050 #define SI__BANK_HEIGHT__8 3
1051 #define SI__GB_TILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 18) & 0x3)
1052 #define SI__MACRO_TILE_ASPECT__1 0
1053 #define SI__MACRO_TILE_ASPECT__2 1
1054 #define SI__MACRO_TILE_ASPECT__4 2
1055 #define SI__MACRO_TILE_ASPECT__8 3
1056 #define SI__GB_TILE_MODE__NUM_BANKS(x) (((x) >> 20) & 0x3)
1057 #define SI__NUM_BANKS__2_BANK 0
1058 #define SI__NUM_BANKS__4_BANK 1
1059 #define SI__NUM_BANKS__8_BANK 2
1060 #define SI__NUM_BANKS__16_BANK 3
1063 static void si_gb_tile_mode(uint32_t gb_tile_mode,
1064 unsigned *num_pipes,
1065 unsigned *num_banks,
1066 uint32_t *macro_tile_aspect,
1069 uint32_t *tile_split)
1072 switch (SI__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1073 case SI__PIPE_CONFIG__ADDR_SURF_P2:
1077 case SI__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1078 case SI__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1079 case SI__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1080 case SI__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1083 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1084 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1085 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1086 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1087 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1088 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1089 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1095 switch (SI__GB_TILE_MODE__NUM_BANKS(gb_tile_mode)) {
1097 case SI__NUM_BANKS__2_BANK:
1100 case SI__NUM_BANKS__4_BANK:
1103 case SI__NUM_BANKS__8_BANK:
1106 case SI__NUM_BANKS__16_BANK:
1111 if (macro_tile_aspect) {
1112 switch (SI__GB_TILE_MODE__MACRO_TILE_ASPECT(gb_tile_mode)) {
1114 case SI__MACRO_TILE_ASPECT__1:
1115 *macro_tile_aspect = 1;
1117 case SI__MACRO_TILE_ASPECT__2:
1118 *macro_tile_aspect = 2;
1120 case SI__MACRO_TILE_ASPECT__4:
1121 *macro_tile_aspect = 4;
1123 case SI__MACRO_TILE_ASPECT__8:
1124 *macro_tile_aspect = 8;
1129 switch (SI__GB_TILE_MODE__BANK_WIDTH(gb_tile_mode)) {
1131 case SI__BANK_WIDTH__1:
1134 case SI__BANK_WIDTH__2:
1137 case SI__BANK_WIDTH__4:
1140 case SI__BANK_WIDTH__8:
1146 switch (SI__GB_TILE_MODE__BANK_HEIGHT(gb_tile_mode)) {
1148 case SI__BANK_HEIGHT__1:
1151 case SI__BANK_HEIGHT__2:
1154 case SI__BANK_HEIGHT__4:
1157 case SI__BANK_HEIGHT__8:
1163 switch (SI__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1165 case SI__TILE_SPLIT__64B:
1168 case SI__TILE_SPLIT__128B:
1171 case SI__TILE_SPLIT__256B:
1174 case SI__TILE_SPLIT__512B:
1177 case SI__TILE_SPLIT__1024B:
1180 case SI__TILE_SPLIT__2048B:
1183 case SI__TILE_SPLIT__4096B:
1190 static int si_init_hw_info(struct radeon_surface_manager *surf_man)
1192 uint32_t tiling_config;
1193 drmVersionPtr version;
1196 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
1202 surf_man->hw_info.allow_2d = 0;
1203 version = drmGetVersion(surf_man->fd);
1204 if (version && version->version_minor >= 33) {
1205 if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array)) {
1206 surf_man->hw_info.allow_2d = 1;
1209 drmFreeVersion(version);
1211 switch (tiling_config & 0xf) {
1213 surf_man->hw_info.num_pipes = 1;
1216 surf_man->hw_info.num_pipes = 2;
1219 surf_man->hw_info.num_pipes = 4;
1222 surf_man->hw_info.num_pipes = 8;
1225 surf_man->hw_info.num_pipes = 8;
1226 surf_man->hw_info.allow_2d = 0;
1230 switch ((tiling_config & 0xf0) >> 4) {
1232 surf_man->hw_info.num_banks = 4;
1235 surf_man->hw_info.num_banks = 8;
1238 surf_man->hw_info.num_banks = 16;
1241 surf_man->hw_info.num_banks = 8;
1242 surf_man->hw_info.allow_2d = 0;
1246 switch ((tiling_config & 0xf00) >> 8) {
1248 surf_man->hw_info.group_bytes = 256;
1251 surf_man->hw_info.group_bytes = 512;
1254 surf_man->hw_info.group_bytes = 256;
1255 surf_man->hw_info.allow_2d = 0;
1259 switch ((tiling_config & 0xf000) >> 12) {
1261 surf_man->hw_info.row_size = 1024;
1264 surf_man->hw_info.row_size = 2048;
1267 surf_man->hw_info.row_size = 4096;
1270 surf_man->hw_info.row_size = 4096;
1271 surf_man->hw_info.allow_2d = 0;
1277 static int si_surface_sanity(struct radeon_surface_manager *surf_man,
1278 struct radeon_surface *surf,
1279 unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
1281 uint32_t gb_tile_mode;
1283 /* check surface dimension */
1284 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
1288 /* check mipmap last_level */
1289 if (surf->last_level > 15) {
1293 /* force 1d on kernel that can't do 2d */
1294 if (mode > RADEON_SURF_MODE_1D &&
1295 (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
1296 if (surf->nsamples > 1) {
1297 fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
1300 mode = RADEON_SURF_MODE_1D;
1301 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1302 surf->flags |= RADEON_SURF_SET(mode, MODE);
1305 if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
1309 if (!surf->tile_split) {
1314 surf->tile_split = 64;
1315 surf->stencil_tile_split = 64;
1319 case RADEON_SURF_MODE_2D:
1320 if (surf->flags & RADEON_SURF_SBUFFER) {
1321 switch (surf->nsamples) {
1323 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1326 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1329 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1332 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1337 /* retrieve tiling mode value */
1338 gb_tile_mode = surf_man->hw_info.tile_mode_array[*stencil_tile_mode];
1339 si_gb_tile_mode(gb_tile_mode, NULL, NULL, NULL, NULL, NULL, &surf->stencil_tile_split);
1341 if (surf->flags & RADEON_SURF_ZBUFFER) {
1342 switch (surf->nsamples) {
1344 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1347 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1350 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1353 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1358 } else if (surf->flags & RADEON_SURF_SCANOUT) {
1359 switch (surf->bpe) {
1361 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
1364 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
1370 switch (surf->bpe) {
1372 *tile_mode = SI_TILE_MODE_COLOR_2D_8BPP;
1375 *tile_mode = SI_TILE_MODE_COLOR_2D_16BPP;
1378 *tile_mode = SI_TILE_MODE_COLOR_2D_32BPP;
1382 *tile_mode = SI_TILE_MODE_COLOR_2D_64BPP;
1388 /* retrieve tiling mode value */
1389 gb_tile_mode = surf_man->hw_info.tile_mode_array[*tile_mode];
1390 si_gb_tile_mode(gb_tile_mode, NULL, NULL, &surf->mtilea, &surf->bankw, &surf->bankh, &surf->tile_split);
1392 case RADEON_SURF_MODE_1D:
1393 if (surf->flags & RADEON_SURF_SBUFFER) {
1394 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1396 if (surf->flags & RADEON_SURF_ZBUFFER) {
1397 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1398 } else if (surf->flags & RADEON_SURF_SCANOUT) {
1399 *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1401 *tile_mode = SI_TILE_MODE_COLOR_1D;
1404 case RADEON_SURF_MODE_LINEAR_ALIGNED:
1406 *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
1412 static void si_surf_minify(struct radeon_surface *surf,
1413 struct radeon_surface_level *surflevel,
1414 unsigned bpe, unsigned level,
1415 uint32_t xalign, uint32_t yalign, uint32_t zalign,
1416 uint32_t slice_align, unsigned offset)
1419 surflevel->npix_x = surf->npix_x;
1421 surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1423 surflevel->npix_y = mip_minify(surf->npix_y, level);
1424 surflevel->npix_z = mip_minify(surf->npix_z, level);
1426 if (level == 0 && surf->last_level > 0) {
1427 surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1428 surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1429 surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1431 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1432 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1433 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1436 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign);
1438 /* XXX: Texture sampling uses unexpectedly large pitches in some cases,
1439 * these are just guesses for the rules behind those
1441 if (level == 0 && surf->last_level == 0)
1442 /* Non-mipmap pitch padded to slice alignment */
1443 /* Using just bpe here breaks stencil blitting; surf->bpe works. */
1444 xalign = MAX2(xalign, slice_align / surf->bpe);
1445 else if (surflevel->mode == RADEON_SURF_MODE_LINEAR_ALIGNED)
1446 /* Small rows evenly distributed across slice */
1447 xalign = MAX2(xalign, slice_align / bpe / surflevel->nblk_y);
1449 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign);
1450 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign);
1452 surflevel->offset = offset;
1453 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
1454 surflevel->slice_size = ALIGN(surflevel->pitch_bytes * surflevel->nblk_y, slice_align);
1456 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1459 static void si_surf_minify_2d(struct radeon_surface *surf,
1460 struct radeon_surface_level *surflevel,
1461 unsigned bpe, unsigned level, unsigned slice_pt,
1462 uint32_t xalign, uint32_t yalign, uint32_t zalign,
1463 unsigned mtileb, unsigned offset)
1465 unsigned mtile_pr, mtile_ps;
1468 surflevel->npix_x = surf->npix_x;
1470 surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1472 surflevel->npix_y = mip_minify(surf->npix_y, level);
1473 surflevel->npix_z = mip_minify(surf->npix_z, level);
1475 if (level == 0 && surf->last_level > 0) {
1476 surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1477 surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1478 surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1480 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1481 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1482 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1485 if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
1486 !(surf->flags & RADEON_SURF_FMASK)) {
1487 if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
1488 surflevel->mode = RADEON_SURF_MODE_1D;
1492 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign);
1493 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign);
1494 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign);
1496 /* macro tile per row */
1497 mtile_pr = surflevel->nblk_x / xalign;
1498 /* macro tile per slice */
1499 mtile_ps = (mtile_pr * surflevel->nblk_y) / yalign;
1500 surflevel->offset = offset;
1501 surflevel->pitch_bytes = surflevel->nblk_x * bpe * slice_pt;
1502 surflevel->slice_size = mtile_ps * mtileb * slice_pt;
1504 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1507 static int si_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
1508 struct radeon_surface *surf,
1510 uint64_t offset, unsigned start_level)
1512 uint32_t xalign, yalign, zalign, slice_align;
1515 /* compute alignment */
1517 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
1519 xalign = MAX2(8, 64 / surf->bpe);
1522 slice_align = MAX2(64 * surf->bpe, surf_man->hw_info.group_bytes);
1524 /* build mipmap tree */
1525 for (i = start_level; i <= surf->last_level; i++) {
1526 surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
1527 si_surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, slice_align, offset);
1528 /* level0 and first mipmap need to have alignment */
1529 offset = surf->bo_size;
1531 offset = ALIGN(offset, surf->bo_alignment);
1533 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1534 surf->tiling_index[i] = tile_mode;
1540 static int si_surface_init_1d(struct radeon_surface_manager *surf_man,
1541 struct radeon_surface *surf,
1542 struct radeon_surface_level *level,
1543 unsigned bpe, unsigned tile_mode,
1544 uint64_t offset, unsigned start_level)
1546 uint32_t xalign, yalign, zalign, slice_align;
1547 unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
1550 /* compute alignment */
1554 slice_align = surf_man->hw_info.group_bytes;
1555 if (surf->flags & RADEON_SURF_SCANOUT) {
1556 xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
1559 if (start_level <= 1) {
1560 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1563 offset = ALIGN(offset, alignment);
1567 /* build mipmap tree */
1568 for (i = start_level; i <= surf->last_level; i++) {
1569 level[i].mode = RADEON_SURF_MODE_1D;
1570 si_surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, slice_align, offset);
1571 /* level0 and first mipmap need to have alignment */
1572 offset = surf->bo_size;
1574 offset = ALIGN(offset, alignment);
1576 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1577 if (surf->level == level) {
1578 surf->tiling_index[i] = tile_mode;
1579 /* it's ok because stencil is done after */
1580 surf->stencil_tiling_index[i] = tile_mode;
1582 surf->stencil_tiling_index[i] = tile_mode;
1589 static int si_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
1590 struct radeon_surface *surf,
1591 unsigned tile_mode, unsigned stencil_tile_mode)
1595 r = si_surface_init_1d(surf_man, surf, surf->level, surf->bpe, tile_mode, 0, 0);
1600 if (surf->flags & RADEON_SURF_SBUFFER) {
1601 r = si_surface_init_1d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode, surf->bo_size, 0);
1602 surf->stencil_offset = surf->stencil_level[0].offset;
1607 static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
1608 struct radeon_surface *surf,
1609 struct radeon_surface_level *level,
1610 unsigned bpe, unsigned tile_mode,
1611 unsigned num_pipes, unsigned num_banks,
1612 unsigned tile_split,
1614 unsigned start_level)
1616 uint64_t aligned_offset = offset;
1617 unsigned tilew, tileh, tileb;
1618 unsigned mtilew, mtileh, mtileb;
1622 /* compute tile values */
1625 tileb = tilew * tileh * bpe * surf->nsamples;
1626 /* slices per tile */
1628 if (tileb > tile_split && tile_split) {
1629 slice_pt = tileb / tile_split;
1631 tileb = tileb / slice_pt;
1633 /* macro tile width & height */
1634 mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
1635 mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
1637 /* macro tile bytes */
1638 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
1640 if (start_level <= 1) {
1641 unsigned alignment = MAX2(256, mtileb);
1642 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1644 if (aligned_offset) {
1645 aligned_offset = ALIGN(aligned_offset, alignment);
1649 /* build mipmap tree */
1650 for (i = start_level; i <= surf->last_level; i++) {
1651 level[i].mode = RADEON_SURF_MODE_2D;
1652 si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
1653 if (level[i].mode == RADEON_SURF_MODE_1D) {
1654 switch (tile_mode) {
1655 case SI_TILE_MODE_COLOR_2D_8BPP:
1656 case SI_TILE_MODE_COLOR_2D_16BPP:
1657 case SI_TILE_MODE_COLOR_2D_32BPP:
1658 case SI_TILE_MODE_COLOR_2D_64BPP:
1659 tile_mode = SI_TILE_MODE_COLOR_1D;
1661 case SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP:
1662 case SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP:
1663 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1665 case SI_TILE_MODE_DEPTH_STENCIL_2D:
1666 tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1671 return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
1673 /* level0 and first mipmap need to have alignment */
1674 aligned_offset = offset = surf->bo_size;
1676 aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
1678 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1679 if (surf->level == level) {
1680 surf->tiling_index[i] = tile_mode;
1681 /* it's ok because stencil is done after */
1682 surf->stencil_tiling_index[i] = tile_mode;
1684 surf->stencil_tiling_index[i] = tile_mode;
1691 static int si_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
1692 struct radeon_surface *surf,
1693 unsigned tile_mode, unsigned stencil_tile_mode)
1695 unsigned num_pipes, num_banks;
1696 uint32_t gb_tile_mode;
1699 /* retrieve tiling mode value */
1700 gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1701 si_gb_tile_mode(gb_tile_mode, &num_pipes, &num_banks, NULL, NULL, NULL, NULL);
1703 r = si_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode, num_pipes, num_banks, surf->tile_split, 0, 0);
1708 if (surf->flags & RADEON_SURF_SBUFFER) {
1709 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);
1710 surf->stencil_offset = surf->stencil_level[0].offset;
1715 static int si_surface_init(struct radeon_surface_manager *surf_man,
1716 struct radeon_surface *surf)
1718 unsigned mode, tile_mode, stencil_tile_mode;
1721 /* MSAA surfaces support the 2D mode only. */
1722 if (surf->nsamples > 1) {
1723 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1724 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
1728 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1730 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
1731 /* zbuffer only support 1D or 2D tiled surface */
1733 case RADEON_SURF_MODE_1D:
1734 case RADEON_SURF_MODE_2D:
1737 mode = RADEON_SURF_MODE_1D;
1738 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1739 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1744 r = si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1749 surf->stencil_offset = 0;
1750 surf->bo_alignment = 0;
1752 /* check tiling mode */
1754 case RADEON_SURF_MODE_LINEAR:
1755 r = r6_surface_init_linear(surf_man, surf, 0, 0);
1757 case RADEON_SURF_MODE_LINEAR_ALIGNED:
1758 r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
1760 case RADEON_SURF_MODE_1D:
1761 r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1763 case RADEON_SURF_MODE_2D:
1764 r = si_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1773 * depending on surface
1775 static int si_surface_best(struct radeon_surface_manager *surf_man,
1776 struct radeon_surface *surf)
1778 unsigned mode, tile_mode, stencil_tile_mode;
1781 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1783 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
1784 !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
1785 /* depth/stencil force 1d tiling for old mesa */
1786 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1787 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1790 return si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1794 /* ===========================================================================
1795 * Sea Islands family
1797 #define CIK__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f)
1798 #define CIK__PIPE_CONFIG__ADDR_SURF_P2 0
1799 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16 4
1800 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16 5
1801 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32 6
1802 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32 7
1803 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8
1804 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9
1805 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10
1806 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11
1807 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12
1808 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13
1809 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14
1810 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16 16
1811 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16 17
1812 #define CIK__GB_TILE_MODE__TILE_SPLIT(x) (((x) >> 11) & 0x7)
1813 #define CIK__TILE_SPLIT__64B 0
1814 #define CIK__TILE_SPLIT__128B 1
1815 #define CIK__TILE_SPLIT__256B 2
1816 #define CIK__TILE_SPLIT__512B 3
1817 #define CIK__TILE_SPLIT__1024B 4
1818 #define CIK__TILE_SPLIT__2048B 5
1819 #define CIK__TILE_SPLIT__4096B 6
1820 #define CIK__GB_TILE_MODE__SAMPLE_SPLIT(x) (((x) >> 25) & 0x3)
1821 #define CIK__SAMPLE_SPLIT__1 0
1822 #define CIK__SAMPLE_SPLIT__2 1
1823 #define CIK__SAMPLE_SPLIT__4 2
1824 #define CIK__SAMPLE_SPLIT__8 3
1825 #define CIK__GB_MACROTILE_MODE__BANK_WIDTH(x) ((x) & 0x3)
1826 #define CIK__BANK_WIDTH__1 0
1827 #define CIK__BANK_WIDTH__2 1
1828 #define CIK__BANK_WIDTH__4 2
1829 #define CIK__BANK_WIDTH__8 3
1830 #define CIK__GB_MACROTILE_MODE__BANK_HEIGHT(x) (((x) >> 2) & 0x3)
1831 #define CIK__BANK_HEIGHT__1 0
1832 #define CIK__BANK_HEIGHT__2 1
1833 #define CIK__BANK_HEIGHT__4 2
1834 #define CIK__BANK_HEIGHT__8 3
1835 #define CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 4) & 0x3)
1836 #define CIK__MACRO_TILE_ASPECT__1 0
1837 #define CIK__MACRO_TILE_ASPECT__2 1
1838 #define CIK__MACRO_TILE_ASPECT__4 2
1839 #define CIK__MACRO_TILE_ASPECT__8 3
1840 #define CIK__GB_MACROTILE_MODE__NUM_BANKS(x) (((x) >> 6) & 0x3)
1841 #define CIK__NUM_BANKS__2_BANK 0
1842 #define CIK__NUM_BANKS__4_BANK 1
1843 #define CIK__NUM_BANKS__8_BANK 2
1844 #define CIK__NUM_BANKS__16_BANK 3
1847 static void cik_get_2d_params(struct radeon_surface_manager *surf_man,
1848 unsigned bpe, unsigned nsamples, bool is_color,
1850 uint32_t *num_pipes,
1851 uint32_t *tile_split_ptr,
1852 uint32_t *num_banks,
1853 uint32_t *macro_tile_aspect,
1857 uint32_t gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1858 unsigned tileb_1x, tileb;
1859 unsigned gb_macrotile_mode;
1860 unsigned macrotile_index;
1861 unsigned tile_split, sample_split;
1864 switch (CIK__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1865 case CIK__PIPE_CONFIG__ADDR_SURF_P2:
1869 case CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1870 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1871 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1872 case CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1875 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1876 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1877 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1878 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1879 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1880 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1881 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1884 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16:
1885 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16:
1890 switch (CIK__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1892 case CIK__TILE_SPLIT__64B:
1895 case CIK__TILE_SPLIT__128B:
1898 case CIK__TILE_SPLIT__256B:
1901 case CIK__TILE_SPLIT__512B:
1904 case CIK__TILE_SPLIT__1024B:
1907 case CIK__TILE_SPLIT__2048B:
1910 case CIK__TILE_SPLIT__4096B:
1914 switch (CIK__GB_TILE_MODE__SAMPLE_SPLIT(gb_tile_mode)) {
1916 case CIK__SAMPLE_SPLIT__1:
1919 case CIK__SAMPLE_SPLIT__2:
1922 case CIK__SAMPLE_SPLIT__4:
1925 case CIK__SAMPLE_SPLIT__8:
1930 /* Adjust the tile split. */
1931 tileb_1x = 8 * 8 * bpe;
1933 tile_split = MAX2(256, sample_split * tileb_1x);
1935 tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
1937 /* Determine the macrotile index. */
1938 tileb = MIN2(tile_split, nsamples * tileb_1x);
1940 for (macrotile_index = 0; tileb > 64; macrotile_index++) {
1943 gb_macrotile_mode = surf_man->hw_info.macrotile_mode_array[macrotile_index];
1945 if (tile_split_ptr) {
1946 *tile_split_ptr = tile_split;
1949 switch (CIK__GB_MACROTILE_MODE__NUM_BANKS(gb_macrotile_mode)) {
1951 case CIK__NUM_BANKS__2_BANK:
1954 case CIK__NUM_BANKS__4_BANK:
1957 case CIK__NUM_BANKS__8_BANK:
1960 case CIK__NUM_BANKS__16_BANK:
1965 if (macro_tile_aspect) {
1966 switch (CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(gb_macrotile_mode)) {
1968 case CIK__MACRO_TILE_ASPECT__1:
1969 *macro_tile_aspect = 1;
1971 case CIK__MACRO_TILE_ASPECT__2:
1972 *macro_tile_aspect = 2;
1974 case CIK__MACRO_TILE_ASPECT__4:
1975 *macro_tile_aspect = 4;
1977 case CIK__MACRO_TILE_ASPECT__8:
1978 *macro_tile_aspect = 8;
1983 switch (CIK__GB_MACROTILE_MODE__BANK_WIDTH(gb_macrotile_mode)) {
1985 case CIK__BANK_WIDTH__1:
1988 case CIK__BANK_WIDTH__2:
1991 case CIK__BANK_WIDTH__4:
1994 case CIK__BANK_WIDTH__8:
2000 switch (CIK__GB_MACROTILE_MODE__BANK_HEIGHT(gb_macrotile_mode)) {
2002 case CIK__BANK_HEIGHT__1:
2005 case CIK__BANK_HEIGHT__2:
2008 case CIK__BANK_HEIGHT__4:
2011 case CIK__BANK_HEIGHT__8:
2018 static int cik_init_hw_info(struct radeon_surface_manager *surf_man)
2020 uint32_t tiling_config;
2021 drmVersionPtr version;
2024 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
2030 surf_man->hw_info.allow_2d = 0;
2031 version = drmGetVersion(surf_man->fd);
2032 if (version && version->version_minor >= 35) {
2033 if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array) &&
2034 !radeon_get_value(surf_man->fd, RADEON_INFO_CIK_MACROTILE_MODE_ARRAY, surf_man->hw_info.macrotile_mode_array)) {
2035 surf_man->hw_info.allow_2d = 1;
2038 drmFreeVersion(version);
2040 switch (tiling_config & 0xf) {
2042 surf_man->hw_info.num_pipes = 1;
2045 surf_man->hw_info.num_pipes = 2;
2048 surf_man->hw_info.num_pipes = 4;
2051 surf_man->hw_info.num_pipes = 8;
2054 surf_man->hw_info.num_pipes = 8;
2055 surf_man->hw_info.allow_2d = 0;
2059 switch ((tiling_config & 0xf0) >> 4) {
2061 surf_man->hw_info.num_banks = 4;
2064 surf_man->hw_info.num_banks = 8;
2067 surf_man->hw_info.num_banks = 16;
2070 surf_man->hw_info.num_banks = 8;
2071 surf_man->hw_info.allow_2d = 0;
2075 switch ((tiling_config & 0xf00) >> 8) {
2077 surf_man->hw_info.group_bytes = 256;
2080 surf_man->hw_info.group_bytes = 512;
2083 surf_man->hw_info.group_bytes = 256;
2084 surf_man->hw_info.allow_2d = 0;
2088 switch ((tiling_config & 0xf000) >> 12) {
2090 surf_man->hw_info.row_size = 1024;
2093 surf_man->hw_info.row_size = 2048;
2096 surf_man->hw_info.row_size = 4096;
2099 surf_man->hw_info.row_size = 4096;
2100 surf_man->hw_info.allow_2d = 0;
2106 static int cik_surface_sanity(struct radeon_surface_manager *surf_man,
2107 struct radeon_surface *surf,
2108 unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
2110 /* check surface dimension */
2111 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
2115 /* check mipmap last_level */
2116 if (surf->last_level > 15) {
2120 /* force 1d on kernel that can't do 2d */
2121 if (mode > RADEON_SURF_MODE_1D &&
2122 (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
2123 if (surf->nsamples > 1) {
2124 fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
2127 mode = RADEON_SURF_MODE_1D;
2128 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2129 surf->flags |= RADEON_SURF_SET(mode, MODE);
2132 if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
2136 if (!surf->tile_split) {
2141 surf->tile_split = 64;
2142 surf->stencil_tile_split = 64;
2146 case RADEON_SURF_MODE_2D: {
2147 if (surf->flags & RADEON_SURF_Z_OR_SBUFFER) {
2148 switch (surf->nsamples) {
2150 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64;
2154 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128;
2157 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256;
2163 if (surf->flags & RADEON_SURF_SBUFFER) {
2164 *stencil_tile_mode = *tile_mode;
2166 cik_get_2d_params(surf_man, 1, surf->nsamples, false,
2167 *stencil_tile_mode, NULL,
2168 &surf->stencil_tile_split,
2169 NULL, NULL, NULL, NULL);
2171 } else if (surf->flags & RADEON_SURF_SCANOUT) {
2172 *tile_mode = CIK_TILE_MODE_COLOR_2D_SCANOUT;
2174 *tile_mode = CIK_TILE_MODE_COLOR_2D;
2177 /* retrieve tiling mode values */
2178 cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
2179 !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), *tile_mode,
2180 NULL, &surf->tile_split, NULL, &surf->mtilea,
2181 &surf->bankw, &surf->bankh);
2184 case RADEON_SURF_MODE_1D:
2185 if (surf->flags & RADEON_SURF_SBUFFER) {
2186 *stencil_tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2188 if (surf->flags & RADEON_SURF_ZBUFFER) {
2189 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2190 } else if (surf->flags & RADEON_SURF_SCANOUT) {
2191 *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2193 *tile_mode = SI_TILE_MODE_COLOR_1D;
2196 case RADEON_SURF_MODE_LINEAR_ALIGNED:
2198 *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
2204 static int cik_surface_init_2d(struct radeon_surface_manager *surf_man,
2205 struct radeon_surface *surf,
2206 struct radeon_surface_level *level,
2207 unsigned bpe, unsigned tile_mode,
2208 unsigned tile_split,
2209 unsigned num_pipes, unsigned num_banks,
2211 unsigned start_level)
2213 uint64_t aligned_offset = offset;
2214 unsigned tilew, tileh, tileb_1x, tileb;
2215 unsigned mtilew, mtileh, mtileb;
2219 /* compute tile values */
2222 tileb_1x = tilew * tileh * bpe;
2224 tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
2226 tileb = surf->nsamples * tileb_1x;
2228 /* slices per tile */
2230 if (tileb > tile_split && tile_split) {
2231 slice_pt = tileb / tile_split;
2232 tileb = tileb / slice_pt;
2235 /* macro tile width & height */
2236 mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
2237 mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
2239 /* macro tile bytes */
2240 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
2242 if (start_level <= 1) {
2243 unsigned alignment = MAX2(256, mtileb);
2244 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
2246 if (aligned_offset) {
2247 aligned_offset = ALIGN(aligned_offset, alignment);
2251 /* build mipmap tree */
2252 for (i = start_level; i <= surf->last_level; i++) {
2253 level[i].mode = RADEON_SURF_MODE_2D;
2254 si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
2255 if (level[i].mode == RADEON_SURF_MODE_1D) {
2256 switch (tile_mode) {
2257 case CIK_TILE_MODE_COLOR_2D:
2258 tile_mode = SI_TILE_MODE_COLOR_1D;
2260 case CIK_TILE_MODE_COLOR_2D_SCANOUT:
2261 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2263 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64:
2264 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128:
2265 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256:
2266 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512:
2267 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE:
2268 tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2273 return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
2275 /* level0 and first mipmap need to have alignment */
2276 aligned_offset = offset = surf->bo_size;
2278 aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
2280 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
2281 if (surf->level == level) {
2282 surf->tiling_index[i] = tile_mode;
2283 /* it's ok because stencil is done after */
2284 surf->stencil_tiling_index[i] = tile_mode;
2286 surf->stencil_tiling_index[i] = tile_mode;
2293 static int cik_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
2294 struct radeon_surface *surf,
2295 unsigned tile_mode, unsigned stencil_tile_mode)
2298 uint32_t num_pipes, num_banks;
2300 cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
2301 !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), tile_mode,
2302 &num_pipes, NULL, &num_banks, NULL, NULL, NULL);
2304 r = cik_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode,
2305 surf->tile_split, num_pipes, num_banks, 0, 0);
2310 if (surf->flags & RADEON_SURF_SBUFFER) {
2311 r = cik_surface_init_2d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode,
2312 surf->stencil_tile_split, num_pipes, num_banks,
2314 surf->stencil_offset = surf->stencil_level[0].offset;
2319 static int cik_surface_init(struct radeon_surface_manager *surf_man,
2320 struct radeon_surface *surf)
2322 unsigned mode, tile_mode, stencil_tile_mode;
2325 /* MSAA surfaces support the 2D mode only. */
2326 if (surf->nsamples > 1) {
2327 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2328 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
2332 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2334 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
2335 /* zbuffer only support 1D or 2D tiled surface */
2337 case RADEON_SURF_MODE_1D:
2338 case RADEON_SURF_MODE_2D:
2341 mode = RADEON_SURF_MODE_1D;
2342 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2343 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2348 r = cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2353 surf->stencil_offset = 0;
2354 surf->bo_alignment = 0;
2356 /* check tiling mode */
2358 case RADEON_SURF_MODE_LINEAR:
2359 r = r6_surface_init_linear(surf_man, surf, 0, 0);
2361 case RADEON_SURF_MODE_LINEAR_ALIGNED:
2362 r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
2364 case RADEON_SURF_MODE_1D:
2365 r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2367 case RADEON_SURF_MODE_2D:
2368 r = cik_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2377 * depending on surface
2379 static int cik_surface_best(struct radeon_surface_manager *surf_man,
2380 struct radeon_surface *surf)
2382 unsigned mode, tile_mode, stencil_tile_mode;
2385 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2387 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
2388 !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
2389 /* depth/stencil force 1d tiling for old mesa */
2390 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2391 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2394 return cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2398 /* ===========================================================================
2401 drm_public struct radeon_surface_manager *
2402 radeon_surface_manager_new(int fd)
2404 struct radeon_surface_manager *surf_man;
2406 surf_man = calloc(1, sizeof(struct radeon_surface_manager));
2407 if (surf_man == NULL) {
2411 if (radeon_get_value(fd, RADEON_INFO_DEVICE_ID, &surf_man->device_id)) {
2414 if (radeon_get_family(surf_man)) {
2418 if (surf_man->family <= CHIP_RV740) {
2419 if (r6_init_hw_info(surf_man)) {
2422 surf_man->surface_init = &r6_surface_init;
2423 surf_man->surface_best = &r6_surface_best;
2424 } else if (surf_man->family <= CHIP_ARUBA) {
2425 if (eg_init_hw_info(surf_man)) {
2428 surf_man->surface_init = &eg_surface_init;
2429 surf_man->surface_best = &eg_surface_best;
2430 } else if (surf_man->family < CHIP_BONAIRE) {
2431 if (si_init_hw_info(surf_man)) {
2434 surf_man->surface_init = &si_surface_init;
2435 surf_man->surface_best = &si_surface_best;
2437 if (cik_init_hw_info(surf_man)) {
2440 surf_man->surface_init = &cik_surface_init;
2441 surf_man->surface_best = &cik_surface_best;
2451 radeon_surface_manager_free(struct radeon_surface_manager *surf_man)
2456 static int radeon_surface_sanity(struct radeon_surface_manager *surf_man,
2457 struct radeon_surface *surf,
2461 if (surf_man == NULL || surf_man->surface_init == NULL || surf == NULL) {
2465 /* all dimension must be at least 1 ! */
2466 if (!surf->npix_x || !surf->npix_y || !surf->npix_z) {
2469 if (!surf->blk_w || !surf->blk_h || !surf->blk_d) {
2472 if (!surf->array_size) {
2475 /* array size must be a power of 2 */
2476 surf->array_size = next_power_of_two(surf->array_size);
2478 switch (surf->nsamples) {
2489 case RADEON_SURF_TYPE_1D:
2490 if (surf->npix_y > 1) {
2493 case RADEON_SURF_TYPE_2D:
2494 if (surf->npix_z > 1) {
2498 case RADEON_SURF_TYPE_CUBEMAP:
2499 if (surf->npix_z > 1) {
2502 /* deal with cubemap as they were texture array */
2503 if (surf_man->family >= CHIP_RV770) {
2504 surf->array_size = 8;
2506 surf->array_size = 6;
2509 case RADEON_SURF_TYPE_3D:
2511 case RADEON_SURF_TYPE_1D_ARRAY:
2512 if (surf->npix_y > 1) {
2515 case RADEON_SURF_TYPE_2D_ARRAY:
2524 radeon_surface_init(struct radeon_surface_manager *surf_man,
2525 struct radeon_surface *surf)
2527 unsigned mode, type;
2530 type = RADEON_SURF_GET(surf->flags, TYPE);
2531 mode = RADEON_SURF_GET(surf->flags, MODE);
2533 r = radeon_surface_sanity(surf_man, surf, type, mode);
2537 return surf_man->surface_init(surf_man, surf);
2541 radeon_surface_best(struct radeon_surface_manager *surf_man,
2542 struct radeon_surface *surf)
2544 unsigned mode, type;
2547 type = RADEON_SURF_GET(surf->flags, TYPE);
2548 mode = RADEON_SURF_GET(surf->flags, MODE);
2550 r = radeon_surface_sanity(surf_man, surf, type, mode);
2554 return surf_man->surface_best(surf_man, surf);