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>
39 #include <sys/ioctl.h>
43 #include "radeon_drm.h"
44 #include "radeon_surface.h"
46 #define ALIGN(value, alignment) (((value) + alignment - 1) & ~(alignment - 1))
47 #define MAX2(A, B) ((A) > (B) ? (A) : (B))
48 #define MIN2(A, B) ((A) < (B) ? (A) : (B))
50 /* keep this private */
91 typedef int (*hw_init_surface_t)(struct radeon_surface_manager *surf_man,
92 struct radeon_surface *surf);
93 typedef int (*hw_best_surface_t)(struct radeon_surface_manager *surf_man,
94 struct radeon_surface *surf);
96 struct radeon_hw_info {
105 uint32_t tile_mode_array[32];
107 uint32_t macrotile_mode_array[16];
110 struct radeon_surface_manager {
113 struct radeon_hw_info hw_info;
115 hw_init_surface_t surface_init;
116 hw_best_surface_t surface_best;
120 static int radeon_get_value(int fd, unsigned req, uint32_t *value)
122 struct drm_radeon_info info = {};
127 info.value = (uintptr_t)value;
128 r = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info,
129 sizeof(struct drm_radeon_info));
133 static int radeon_get_family(struct radeon_surface_manager *surf_man)
135 switch (surf_man->device_id) {
136 #define CHIPSET(pci_id, name, fam) case pci_id: surf_man->family = CHIP_##fam; break;
137 #include "r600_pci_ids.h"
145 static unsigned next_power_of_two(unsigned x)
150 return (1 << ((sizeof(unsigned) * 8) - __builtin_clz(x - 1)));
153 static unsigned mip_minify(unsigned size, unsigned level)
157 val = MAX2(1, size >> level);
159 val = next_power_of_two(val);
163 static void surf_minify(struct radeon_surface *surf,
164 struct radeon_surface_level *surflevel,
165 unsigned bpe, unsigned level,
166 uint32_t xalign, uint32_t yalign, uint32_t zalign,
169 surflevel->npix_x = mip_minify(surf->npix_x, level);
170 surflevel->npix_y = mip_minify(surf->npix_y, level);
171 surflevel->npix_z = mip_minify(surf->npix_z, level);
172 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
173 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
174 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
175 if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
176 !(surf->flags & RADEON_SURF_FMASK)) {
177 if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
178 surflevel->mode = RADEON_SURF_MODE_1D;
182 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign);
183 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign);
184 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign);
186 surflevel->offset = offset;
187 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
188 surflevel->slice_size = surflevel->pitch_bytes * surflevel->nblk_y;
190 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
193 /* ===========================================================================
196 static int r6_init_hw_info(struct radeon_surface_manager *surf_man)
198 uint32_t tiling_config;
199 drmVersionPtr version;
202 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
208 surf_man->hw_info.allow_2d = 0;
209 version = drmGetVersion(surf_man->fd);
210 if (version && version->version_minor >= 14) {
211 surf_man->hw_info.allow_2d = 1;
213 drmFreeVersion(version);
215 switch ((tiling_config & 0xe) >> 1) {
217 surf_man->hw_info.num_pipes = 1;
220 surf_man->hw_info.num_pipes = 2;
223 surf_man->hw_info.num_pipes = 4;
226 surf_man->hw_info.num_pipes = 8;
229 surf_man->hw_info.num_pipes = 8;
230 surf_man->hw_info.allow_2d = 0;
234 switch ((tiling_config & 0x30) >> 4) {
236 surf_man->hw_info.num_banks = 4;
239 surf_man->hw_info.num_banks = 8;
242 surf_man->hw_info.num_banks = 8;
243 surf_man->hw_info.allow_2d = 0;
247 switch ((tiling_config & 0xc0) >> 6) {
249 surf_man->hw_info.group_bytes = 256;
252 surf_man->hw_info.group_bytes = 512;
255 surf_man->hw_info.group_bytes = 256;
256 surf_man->hw_info.allow_2d = 0;
262 static int r6_surface_init_linear(struct radeon_surface_manager *surf_man,
263 struct radeon_surface *surf,
264 uint64_t offset, unsigned start_level)
266 uint32_t xalign, yalign, zalign;
269 /* compute alignment */
271 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
273 /* the 32 alignment is for scanout, cb or db but to allow texture to be
274 * easily bound as such we force this alignment to all surface
276 xalign = MAX2(1, surf_man->hw_info.group_bytes / surf->bpe);
279 if (surf->flags & RADEON_SURF_SCANOUT) {
280 xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
283 /* build mipmap tree */
284 for (i = start_level; i <= surf->last_level; i++) {
285 surf->level[i].mode = RADEON_SURF_MODE_LINEAR;
286 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
287 /* level0 and first mipmap need to have alignment */
288 offset = surf->bo_size;
290 offset = ALIGN(offset, surf->bo_alignment);
296 static int r6_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
297 struct radeon_surface *surf,
298 uint64_t offset, unsigned start_level)
300 uint32_t xalign, yalign, zalign;
303 /* compute alignment */
305 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
307 xalign = MAX2(64, surf_man->hw_info.group_bytes / surf->bpe);
311 /* build mipmap tree */
312 for (i = start_level; i <= surf->last_level; i++) {
313 surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
314 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
315 /* level0 and first mipmap need to have alignment */
316 offset = surf->bo_size;
318 offset = ALIGN(offset, surf->bo_alignment);
324 static int r6_surface_init_1d(struct radeon_surface_manager *surf_man,
325 struct radeon_surface *surf,
326 uint64_t offset, unsigned start_level)
328 uint32_t xalign, yalign, zalign, tilew;
331 /* compute alignment */
333 xalign = surf_man->hw_info.group_bytes / (tilew * surf->bpe * surf->nsamples);
334 xalign = MAX2(tilew, xalign);
337 if (surf->flags & RADEON_SURF_SCANOUT) {
338 xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
341 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
344 /* build mipmap tree */
345 for (i = start_level; i <= surf->last_level; i++) {
346 surf->level[i].mode = RADEON_SURF_MODE_1D;
347 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
348 /* level0 and first mipmap need to have alignment */
349 offset = surf->bo_size;
351 offset = ALIGN(offset, surf->bo_alignment);
357 static int r6_surface_init_2d(struct radeon_surface_manager *surf_man,
358 struct radeon_surface *surf,
359 uint64_t offset, unsigned start_level)
361 uint32_t xalign, yalign, zalign, tilew;
364 /* compute alignment */
367 xalign = (surf_man->hw_info.group_bytes * surf_man->hw_info.num_banks) /
368 (tilew * surf->bpe * surf->nsamples);
369 xalign = MAX2(tilew * surf_man->hw_info.num_banks, xalign);
370 yalign = tilew * surf_man->hw_info.num_pipes;
371 if (surf->flags & RADEON_SURF_SCANOUT) {
372 xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
376 MAX2(surf_man->hw_info.num_pipes *
377 surf_man->hw_info.num_banks *
378 surf->nsamples * surf->bpe * 64,
379 xalign * yalign * surf->nsamples * surf->bpe);
382 /* build mipmap tree */
383 for (i = start_level; i <= surf->last_level; i++) {
384 surf->level[i].mode = RADEON_SURF_MODE_2D;
385 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
386 if (surf->level[i].mode == RADEON_SURF_MODE_1D) {
387 return r6_surface_init_1d(surf_man, surf, offset, i);
389 /* level0 and first mipmap need to have alignment */
390 offset = surf->bo_size;
392 offset = ALIGN(offset, surf->bo_alignment);
398 static int r6_surface_init(struct radeon_surface_manager *surf_man,
399 struct radeon_surface *surf)
404 /* MSAA surfaces support the 2D mode only. */
405 if (surf->nsamples > 1) {
406 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
407 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
411 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
413 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
414 /* zbuffer only support 1D or 2D tiled surface */
416 case RADEON_SURF_MODE_1D:
417 case RADEON_SURF_MODE_2D:
420 mode = RADEON_SURF_MODE_1D;
421 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
422 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
427 /* force 1d on kernel that can't do 2d */
428 if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) {
429 if (surf->nsamples > 1) {
430 fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__);
433 mode = RADEON_SURF_MODE_1D;
434 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
435 surf->flags |= RADEON_SURF_SET(mode, MODE);
438 /* check surface dimension */
439 if (surf->npix_x > 8192 || surf->npix_y > 8192 || surf->npix_z > 8192) {
443 /* check mipmap last_level */
444 if (surf->last_level > 14) {
448 /* check tiling mode */
450 case RADEON_SURF_MODE_LINEAR:
451 r = r6_surface_init_linear(surf_man, surf, 0, 0);
453 case RADEON_SURF_MODE_LINEAR_ALIGNED:
454 r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
456 case RADEON_SURF_MODE_1D:
457 r = r6_surface_init_1d(surf_man, surf, 0, 0);
459 case RADEON_SURF_MODE_2D:
460 r = r6_surface_init_2d(surf_man, surf, 0, 0);
468 static int r6_surface_best(struct radeon_surface_manager *surf_man,
469 struct radeon_surface *surf)
471 /* no value to optimize for r6xx/r7xx */
476 /* ===========================================================================
479 static int eg_init_hw_info(struct radeon_surface_manager *surf_man)
481 uint32_t tiling_config;
482 drmVersionPtr version;
485 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
491 surf_man->hw_info.allow_2d = 0;
492 version = drmGetVersion(surf_man->fd);
493 if (version && version->version_minor >= 16) {
494 surf_man->hw_info.allow_2d = 1;
496 drmFreeVersion(version);
498 switch (tiling_config & 0xf) {
500 surf_man->hw_info.num_pipes = 1;
503 surf_man->hw_info.num_pipes = 2;
506 surf_man->hw_info.num_pipes = 4;
509 surf_man->hw_info.num_pipes = 8;
512 surf_man->hw_info.num_pipes = 8;
513 surf_man->hw_info.allow_2d = 0;
517 switch ((tiling_config & 0xf0) >> 4) {
519 surf_man->hw_info.num_banks = 4;
522 surf_man->hw_info.num_banks = 8;
525 surf_man->hw_info.num_banks = 16;
528 surf_man->hw_info.num_banks = 8;
529 surf_man->hw_info.allow_2d = 0;
533 switch ((tiling_config & 0xf00) >> 8) {
535 surf_man->hw_info.group_bytes = 256;
538 surf_man->hw_info.group_bytes = 512;
541 surf_man->hw_info.group_bytes = 256;
542 surf_man->hw_info.allow_2d = 0;
546 switch ((tiling_config & 0xf000) >> 12) {
548 surf_man->hw_info.row_size = 1024;
551 surf_man->hw_info.row_size = 2048;
554 surf_man->hw_info.row_size = 4096;
557 surf_man->hw_info.row_size = 4096;
558 surf_man->hw_info.allow_2d = 0;
564 static void eg_surf_minify(struct radeon_surface *surf,
565 struct radeon_surface_level *surflevel,
574 unsigned mtile_pr, mtile_ps;
576 surflevel->npix_x = mip_minify(surf->npix_x, level);
577 surflevel->npix_y = mip_minify(surf->npix_y, level);
578 surflevel->npix_z = mip_minify(surf->npix_z, level);
579 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
580 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
581 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
582 if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
583 !(surf->flags & RADEON_SURF_FMASK)) {
584 if (surflevel->nblk_x < mtilew || surflevel->nblk_y < mtileh) {
585 surflevel->mode = RADEON_SURF_MODE_1D;
589 surflevel->nblk_x = ALIGN(surflevel->nblk_x, mtilew);
590 surflevel->nblk_y = ALIGN(surflevel->nblk_y, mtileh);
591 surflevel->nblk_z = ALIGN(surflevel->nblk_z, 1);
593 /* macro tile per row */
594 mtile_pr = surflevel->nblk_x / mtilew;
595 /* macro tile per slice */
596 mtile_ps = (mtile_pr * surflevel->nblk_y) / mtileh;
598 surflevel->offset = offset;
599 surflevel->pitch_bytes = surflevel->nblk_x * bpe * slice_pt;
600 surflevel->slice_size = mtile_ps * mtileb * slice_pt;
602 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
605 static int eg_surface_init_1d(struct radeon_surface_manager *surf_man,
606 struct radeon_surface *surf,
607 struct radeon_surface_level *level,
609 uint64_t offset, unsigned start_level)
611 uint32_t xalign, yalign, zalign, tilew;
614 /* compute alignment */
616 xalign = surf_man->hw_info.group_bytes / (tilew * bpe * surf->nsamples);
617 xalign = MAX2(tilew, xalign);
620 if (surf->flags & RADEON_SURF_SCANOUT) {
621 xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
625 unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
626 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
629 offset = ALIGN(offset, alignment);
633 /* build mipmap tree */
634 for (i = start_level; i <= surf->last_level; i++) {
635 level[i].mode = RADEON_SURF_MODE_1D;
636 surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, offset);
637 /* level0 and first mipmap need to have alignment */
638 offset = surf->bo_size;
640 offset = ALIGN(offset, surf->bo_alignment);
646 static int eg_surface_init_2d(struct radeon_surface_manager *surf_man,
647 struct radeon_surface *surf,
648 struct radeon_surface_level *level,
649 unsigned bpe, unsigned tile_split,
650 uint64_t offset, unsigned start_level)
652 unsigned tilew, tileh, tileb;
653 unsigned mtilew, mtileh, mtileb;
657 /* compute tile values */
660 tileb = tilew * tileh * bpe * surf->nsamples;
661 /* slices per tile */
663 if (tileb > tile_split && tile_split) {
664 slice_pt = tileb / tile_split;
666 tileb = tileb / slice_pt;
668 /* macro tile width & height */
669 mtilew = (tilew * surf->bankw * surf_man->hw_info.num_pipes) * surf->mtilea;
670 mtileh = (tileh * surf->bankh * surf_man->hw_info.num_banks) / surf->mtilea;
671 /* macro tile bytes */
672 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
675 unsigned alignment = MAX2(256, mtileb);
676 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
679 offset = ALIGN(offset, alignment);
683 /* build mipmap tree */
684 for (i = start_level; i <= surf->last_level; i++) {
685 level[i].mode = RADEON_SURF_MODE_2D;
686 eg_surf_minify(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, mtileb, offset);
687 if (level[i].mode == RADEON_SURF_MODE_1D) {
688 return eg_surface_init_1d(surf_man, surf, level, bpe, offset, i);
690 /* level0 and first mipmap need to have alignment */
691 offset = surf->bo_size;
693 offset = ALIGN(offset, surf->bo_alignment);
699 static int eg_surface_sanity(struct radeon_surface_manager *surf_man,
700 struct radeon_surface *surf,
705 /* check surface dimension */
706 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
710 /* check mipmap last_level */
711 if (surf->last_level > 15) {
715 /* force 1d on kernel that can't do 2d */
716 if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) {
717 if (surf->nsamples > 1) {
718 fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__);
721 mode = RADEON_SURF_MODE_1D;
722 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
723 surf->flags |= RADEON_SURF_SET(mode, MODE);
726 /* check tile split */
727 if (mode == RADEON_SURF_MODE_2D) {
728 switch (surf->tile_split) {
740 switch (surf->mtilea) {
749 /* check aspect ratio */
750 if (surf_man->hw_info.num_banks < surf->mtilea) {
753 /* check bank width */
754 switch (surf->bankw) {
763 /* check bank height */
764 switch (surf->bankh) {
773 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
774 if ((tileb * surf->bankh * surf->bankw) < surf_man->hw_info.group_bytes) {
782 static int eg_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
783 struct radeon_surface *surf)
785 unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
786 int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
787 /* Old libdrm headers didn't have stencil_level in it. This prevents crashes. */
788 struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
789 struct radeon_surface_level *stencil_level =
790 (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
792 r = eg_surface_init_1d(surf_man, surf, surf->level, surf->bpe, 0, 0);
796 if (is_depth_stencil) {
797 r = eg_surface_init_1d(surf_man, surf, stencil_level, 1,
799 surf->stencil_offset = stencil_level[0].offset;
804 static int eg_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
805 struct radeon_surface *surf)
807 unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
808 int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
809 /* Old libdrm headers didn't have stencil_level in it. This prevents crashes. */
810 struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
811 struct radeon_surface_level *stencil_level =
812 (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
814 r = eg_surface_init_2d(surf_man, surf, surf->level, surf->bpe,
815 surf->tile_split, 0, 0);
819 if (is_depth_stencil) {
820 r = eg_surface_init_2d(surf_man, surf, stencil_level, 1,
821 surf->stencil_tile_split, surf->bo_size, 0);
822 surf->stencil_offset = stencil_level[0].offset;
827 static int eg_surface_init(struct radeon_surface_manager *surf_man,
828 struct radeon_surface *surf)
833 /* MSAA surfaces support the 2D mode only. */
834 if (surf->nsamples > 1) {
835 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
836 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
840 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
842 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
843 /* zbuffer only support 1D or 2D tiled surface */
845 case RADEON_SURF_MODE_1D:
846 case RADEON_SURF_MODE_2D:
849 mode = RADEON_SURF_MODE_1D;
850 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
851 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
856 r = eg_surface_sanity(surf_man, surf, mode);
861 surf->stencil_offset = 0;
862 surf->bo_alignment = 0;
864 /* check tiling mode */
866 case RADEON_SURF_MODE_LINEAR:
867 r = r6_surface_init_linear(surf_man, surf, 0, 0);
869 case RADEON_SURF_MODE_LINEAR_ALIGNED:
870 r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
872 case RADEON_SURF_MODE_1D:
873 r = eg_surface_init_1d_miptrees(surf_man, surf);
875 case RADEON_SURF_MODE_2D:
876 r = eg_surface_init_2d_miptrees(surf_man, surf);
884 static unsigned log2_int(unsigned x)
892 if ((unsigned)(1 << l) > x) {
899 /* compute best tile_split, bankw, bankh, mtilea
900 * depending on surface
902 static int eg_surface_best(struct radeon_surface_manager *surf_man,
903 struct radeon_surface *surf)
905 unsigned mode, tileb, h_over_w;
909 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
911 /* set some default value to avoid sanity check choking on them */
912 surf->tile_split = 1024;
915 surf->mtilea = surf_man->hw_info.num_banks;
916 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
917 for (; surf->bankh <= 8; surf->bankh *= 2) {
918 if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
922 if (surf->mtilea > 8) {
926 r = eg_surface_sanity(surf_man, surf, mode);
931 if (mode != RADEON_SURF_MODE_2D) {
932 /* nothing to do for non 2D tiled surface */
936 /* Tweak TILE_SPLIT for performance here. */
937 if (surf->nsamples > 1) {
938 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
939 switch (surf->nsamples) {
941 surf->tile_split = 128;
944 surf->tile_split = 128;
947 surf->tile_split = 256;
949 case 16: /* cayman only */
950 surf->tile_split = 512;
953 fprintf(stderr, "radeon: Wrong number of samples %i (%i)\n",
954 surf->nsamples, __LINE__);
957 surf->stencil_tile_split = 64;
959 /* tile split must be >= 256 for colorbuffer surfaces */
960 surf->tile_split = MAX2(surf->nsamples * surf->bpe * 64, 256);
961 if (surf->tile_split > 4096)
962 surf->tile_split = 4096;
965 /* set tile split to row size */
966 surf->tile_split = surf_man->hw_info.row_size;
967 surf->stencil_tile_split = surf_man->hw_info.row_size / 2;
970 /* bankw or bankh greater than 1 increase alignment requirement, not
971 * sure if it's worth using smaller bankw & bankh to stick with 2D
972 * tiling on small surface rather than falling back to 1D tiling.
973 * Use recommanded value based on tile size for now.
975 * fmask buffer has different optimal value figure them out once we
978 if (surf->flags & RADEON_SURF_SBUFFER) {
979 /* assume 1 bytes for stencil, we optimize for stencil as stencil
980 * and depth shares surface values
982 tileb = MIN2(surf->tile_split, 64 * surf->nsamples);
984 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
987 /* use bankw of 1 to minimize width alignment, might be interesting to
988 * increase it for large surface
1003 /* double check the constraint */
1004 for (; surf->bankh <= 8; surf->bankh *= 2) {
1005 if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
1010 h_over_w = (((surf->bankh * surf_man->hw_info.num_banks) << 16) /
1011 (surf->bankw * surf_man->hw_info.num_pipes)) >> 16;
1012 surf->mtilea = 1 << (log2_int(h_over_w) >> 1);
1018 /* ===========================================================================
1019 * Southern Islands family
1021 #define SI__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f)
1022 #define SI__PIPE_CONFIG__ADDR_SURF_P2 0
1023 #define SI__PIPE_CONFIG__ADDR_SURF_P4_8x16 4
1024 #define SI__PIPE_CONFIG__ADDR_SURF_P4_16x16 5
1025 #define SI__PIPE_CONFIG__ADDR_SURF_P4_16x32 6
1026 #define SI__PIPE_CONFIG__ADDR_SURF_P4_32x32 7
1027 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8
1028 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9
1029 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10
1030 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11
1031 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12
1032 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13
1033 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14
1034 #define SI__GB_TILE_MODE__TILE_SPLIT(x) (((x) >> 11) & 0x7)
1035 #define SI__TILE_SPLIT__64B 0
1036 #define SI__TILE_SPLIT__128B 1
1037 #define SI__TILE_SPLIT__256B 2
1038 #define SI__TILE_SPLIT__512B 3
1039 #define SI__TILE_SPLIT__1024B 4
1040 #define SI__TILE_SPLIT__2048B 5
1041 #define SI__TILE_SPLIT__4096B 6
1042 #define SI__GB_TILE_MODE__BANK_WIDTH(x) (((x) >> 14) & 0x3)
1043 #define SI__BANK_WIDTH__1 0
1044 #define SI__BANK_WIDTH__2 1
1045 #define SI__BANK_WIDTH__4 2
1046 #define SI__BANK_WIDTH__8 3
1047 #define SI__GB_TILE_MODE__BANK_HEIGHT(x) (((x) >> 16) & 0x3)
1048 #define SI__BANK_HEIGHT__1 0
1049 #define SI__BANK_HEIGHT__2 1
1050 #define SI__BANK_HEIGHT__4 2
1051 #define SI__BANK_HEIGHT__8 3
1052 #define SI__GB_TILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 18) & 0x3)
1053 #define SI__MACRO_TILE_ASPECT__1 0
1054 #define SI__MACRO_TILE_ASPECT__2 1
1055 #define SI__MACRO_TILE_ASPECT__4 2
1056 #define SI__MACRO_TILE_ASPECT__8 3
1057 #define SI__GB_TILE_MODE__NUM_BANKS(x) (((x) >> 20) & 0x3)
1058 #define SI__NUM_BANKS__2_BANK 0
1059 #define SI__NUM_BANKS__4_BANK 1
1060 #define SI__NUM_BANKS__8_BANK 2
1061 #define SI__NUM_BANKS__16_BANK 3
1064 static void si_gb_tile_mode(uint32_t gb_tile_mode,
1065 unsigned *num_pipes,
1066 unsigned *num_banks,
1067 uint32_t *macro_tile_aspect,
1070 uint32_t *tile_split)
1073 switch (SI__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1074 case SI__PIPE_CONFIG__ADDR_SURF_P2:
1078 case SI__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1079 case SI__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1080 case SI__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1081 case SI__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1084 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1085 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1086 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1087 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1088 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1089 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1090 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1096 switch (SI__GB_TILE_MODE__NUM_BANKS(gb_tile_mode)) {
1098 case SI__NUM_BANKS__2_BANK:
1101 case SI__NUM_BANKS__4_BANK:
1104 case SI__NUM_BANKS__8_BANK:
1107 case SI__NUM_BANKS__16_BANK:
1112 if (macro_tile_aspect) {
1113 switch (SI__GB_TILE_MODE__MACRO_TILE_ASPECT(gb_tile_mode)) {
1115 case SI__MACRO_TILE_ASPECT__1:
1116 *macro_tile_aspect = 1;
1118 case SI__MACRO_TILE_ASPECT__2:
1119 *macro_tile_aspect = 2;
1121 case SI__MACRO_TILE_ASPECT__4:
1122 *macro_tile_aspect = 4;
1124 case SI__MACRO_TILE_ASPECT__8:
1125 *macro_tile_aspect = 8;
1130 switch (SI__GB_TILE_MODE__BANK_WIDTH(gb_tile_mode)) {
1132 case SI__BANK_WIDTH__1:
1135 case SI__BANK_WIDTH__2:
1138 case SI__BANK_WIDTH__4:
1141 case SI__BANK_WIDTH__8:
1147 switch (SI__GB_TILE_MODE__BANK_HEIGHT(gb_tile_mode)) {
1149 case SI__BANK_HEIGHT__1:
1152 case SI__BANK_HEIGHT__2:
1155 case SI__BANK_HEIGHT__4:
1158 case SI__BANK_HEIGHT__8:
1164 switch (SI__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1166 case SI__TILE_SPLIT__64B:
1169 case SI__TILE_SPLIT__128B:
1172 case SI__TILE_SPLIT__256B:
1175 case SI__TILE_SPLIT__512B:
1178 case SI__TILE_SPLIT__1024B:
1181 case SI__TILE_SPLIT__2048B:
1184 case SI__TILE_SPLIT__4096B:
1191 static int si_init_hw_info(struct radeon_surface_manager *surf_man)
1193 uint32_t tiling_config;
1194 drmVersionPtr version;
1197 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
1203 surf_man->hw_info.allow_2d = 0;
1204 version = drmGetVersion(surf_man->fd);
1205 if (version && version->version_minor >= 33) {
1206 if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array)) {
1207 surf_man->hw_info.allow_2d = 1;
1210 drmFreeVersion(version);
1212 switch (tiling_config & 0xf) {
1214 surf_man->hw_info.num_pipes = 1;
1217 surf_man->hw_info.num_pipes = 2;
1220 surf_man->hw_info.num_pipes = 4;
1223 surf_man->hw_info.num_pipes = 8;
1226 surf_man->hw_info.num_pipes = 8;
1227 surf_man->hw_info.allow_2d = 0;
1231 switch ((tiling_config & 0xf0) >> 4) {
1233 surf_man->hw_info.num_banks = 4;
1236 surf_man->hw_info.num_banks = 8;
1239 surf_man->hw_info.num_banks = 16;
1242 surf_man->hw_info.num_banks = 8;
1243 surf_man->hw_info.allow_2d = 0;
1247 switch ((tiling_config & 0xf00) >> 8) {
1249 surf_man->hw_info.group_bytes = 256;
1252 surf_man->hw_info.group_bytes = 512;
1255 surf_man->hw_info.group_bytes = 256;
1256 surf_man->hw_info.allow_2d = 0;
1260 switch ((tiling_config & 0xf000) >> 12) {
1262 surf_man->hw_info.row_size = 1024;
1265 surf_man->hw_info.row_size = 2048;
1268 surf_man->hw_info.row_size = 4096;
1271 surf_man->hw_info.row_size = 4096;
1272 surf_man->hw_info.allow_2d = 0;
1278 static int si_surface_sanity(struct radeon_surface_manager *surf_man,
1279 struct radeon_surface *surf,
1280 unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
1282 uint32_t gb_tile_mode;
1284 /* check surface dimension */
1285 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
1289 /* check mipmap last_level */
1290 if (surf->last_level > 15) {
1294 /* force 1d on kernel that can't do 2d */
1295 if (mode > RADEON_SURF_MODE_1D &&
1296 (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
1297 if (surf->nsamples > 1) {
1298 fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
1301 mode = RADEON_SURF_MODE_1D;
1302 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1303 surf->flags |= RADEON_SURF_SET(mode, MODE);
1306 if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
1310 if (!surf->tile_split) {
1315 surf->tile_split = 64;
1316 surf->stencil_tile_split = 64;
1320 case RADEON_SURF_MODE_2D:
1321 if (surf->flags & RADEON_SURF_SBUFFER) {
1322 switch (surf->nsamples) {
1324 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1327 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1330 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1333 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1338 /* retrieve tiling mode value */
1339 gb_tile_mode = surf_man->hw_info.tile_mode_array[*stencil_tile_mode];
1340 si_gb_tile_mode(gb_tile_mode, NULL, NULL, NULL, NULL, NULL, &surf->stencil_tile_split);
1342 if (surf->flags & RADEON_SURF_ZBUFFER) {
1343 switch (surf->nsamples) {
1345 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1348 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1351 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1354 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1359 } else if (surf->flags & RADEON_SURF_SCANOUT) {
1360 switch (surf->bpe) {
1362 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
1365 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
1371 switch (surf->bpe) {
1373 *tile_mode = SI_TILE_MODE_COLOR_2D_8BPP;
1376 *tile_mode = SI_TILE_MODE_COLOR_2D_16BPP;
1379 *tile_mode = SI_TILE_MODE_COLOR_2D_32BPP;
1383 *tile_mode = SI_TILE_MODE_COLOR_2D_64BPP;
1389 /* retrieve tiling mode value */
1390 gb_tile_mode = surf_man->hw_info.tile_mode_array[*tile_mode];
1391 si_gb_tile_mode(gb_tile_mode, NULL, NULL, &surf->mtilea, &surf->bankw, &surf->bankh, &surf->tile_split);
1393 case RADEON_SURF_MODE_1D:
1394 if (surf->flags & RADEON_SURF_SBUFFER) {
1395 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1397 if (surf->flags & RADEON_SURF_ZBUFFER) {
1398 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1399 } else if (surf->flags & RADEON_SURF_SCANOUT) {
1400 *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1402 *tile_mode = SI_TILE_MODE_COLOR_1D;
1405 case RADEON_SURF_MODE_LINEAR_ALIGNED:
1407 *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
1413 static void si_surf_minify(struct radeon_surface *surf,
1414 struct radeon_surface_level *surflevel,
1415 unsigned bpe, unsigned level,
1416 uint32_t xalign, uint32_t yalign, uint32_t zalign,
1417 uint32_t slice_align, unsigned offset)
1420 surflevel->npix_x = surf->npix_x;
1422 surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1424 surflevel->npix_y = mip_minify(surf->npix_y, level);
1425 surflevel->npix_z = mip_minify(surf->npix_z, level);
1427 if (level == 0 && surf->last_level > 0) {
1428 surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1429 surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1430 surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1432 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1433 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1434 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1437 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign);
1439 /* XXX: Texture sampling uses unexpectedly large pitches in some cases,
1440 * these are just guesses for the rules behind those
1442 if (level == 0 && surf->last_level == 0)
1443 /* Non-mipmap pitch padded to slice alignment */
1444 /* Using just bpe here breaks stencil blitting; surf->bpe works. */
1445 xalign = MAX2(xalign, slice_align / surf->bpe);
1446 else if (surflevel->mode == RADEON_SURF_MODE_LINEAR_ALIGNED)
1447 /* Small rows evenly distributed across slice */
1448 xalign = MAX2(xalign, slice_align / bpe / surflevel->nblk_y);
1450 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign);
1451 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign);
1453 surflevel->offset = offset;
1454 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
1455 surflevel->slice_size = ALIGN(surflevel->pitch_bytes * surflevel->nblk_y, slice_align);
1457 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1460 static void si_surf_minify_2d(struct radeon_surface *surf,
1461 struct radeon_surface_level *surflevel,
1462 unsigned bpe, unsigned level, unsigned slice_pt,
1463 uint32_t xalign, uint32_t yalign, uint32_t zalign,
1464 unsigned mtileb, unsigned offset)
1466 unsigned mtile_pr, mtile_ps;
1469 surflevel->npix_x = surf->npix_x;
1471 surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1473 surflevel->npix_y = mip_minify(surf->npix_y, level);
1474 surflevel->npix_z = mip_minify(surf->npix_z, level);
1476 if (level == 0 && surf->last_level > 0) {
1477 surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1478 surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1479 surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1481 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1482 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1483 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1486 if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
1487 !(surf->flags & RADEON_SURF_FMASK)) {
1488 if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
1489 surflevel->mode = RADEON_SURF_MODE_1D;
1493 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign);
1494 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign);
1495 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign);
1497 /* macro tile per row */
1498 mtile_pr = surflevel->nblk_x / xalign;
1499 /* macro tile per slice */
1500 mtile_ps = (mtile_pr * surflevel->nblk_y) / yalign;
1501 surflevel->offset = offset;
1502 surflevel->pitch_bytes = surflevel->nblk_x * bpe * slice_pt;
1503 surflevel->slice_size = mtile_ps * mtileb * slice_pt;
1505 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1508 static int si_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
1509 struct radeon_surface *surf,
1511 uint64_t offset, unsigned start_level)
1513 uint32_t xalign, yalign, zalign, slice_align;
1516 /* compute alignment */
1518 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
1520 xalign = MAX2(8, 64 / surf->bpe);
1523 slice_align = MAX2(64 * surf->bpe, surf_man->hw_info.group_bytes);
1525 /* build mipmap tree */
1526 for (i = start_level; i <= surf->last_level; i++) {
1527 surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
1528 si_surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, slice_align, offset);
1529 /* level0 and first mipmap need to have alignment */
1530 offset = surf->bo_size;
1532 offset = ALIGN(offset, surf->bo_alignment);
1534 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1535 surf->tiling_index[i] = tile_mode;
1541 static int si_surface_init_1d(struct radeon_surface_manager *surf_man,
1542 struct radeon_surface *surf,
1543 struct radeon_surface_level *level,
1544 unsigned bpe, unsigned tile_mode,
1545 uint64_t offset, unsigned start_level)
1547 uint32_t xalign, yalign, zalign, slice_align;
1548 unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
1551 /* compute alignment */
1555 slice_align = surf_man->hw_info.group_bytes;
1556 if (surf->flags & RADEON_SURF_SCANOUT) {
1557 xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
1560 if (start_level <= 1) {
1561 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1564 offset = ALIGN(offset, alignment);
1568 /* build mipmap tree */
1569 for (i = start_level; i <= surf->last_level; i++) {
1570 level[i].mode = RADEON_SURF_MODE_1D;
1571 si_surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, slice_align, offset);
1572 /* level0 and first mipmap need to have alignment */
1573 offset = surf->bo_size;
1575 offset = ALIGN(offset, alignment);
1577 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1578 if (surf->level == level) {
1579 surf->tiling_index[i] = tile_mode;
1580 /* it's ok because stencil is done after */
1581 surf->stencil_tiling_index[i] = tile_mode;
1583 surf->stencil_tiling_index[i] = tile_mode;
1590 static int si_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
1591 struct radeon_surface *surf,
1592 unsigned tile_mode, unsigned stencil_tile_mode)
1596 r = si_surface_init_1d(surf_man, surf, surf->level, surf->bpe, tile_mode, 0, 0);
1601 if (surf->flags & RADEON_SURF_SBUFFER) {
1602 r = si_surface_init_1d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode, surf->bo_size, 0);
1603 surf->stencil_offset = surf->stencil_level[0].offset;
1608 static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
1609 struct radeon_surface *surf,
1610 struct radeon_surface_level *level,
1611 unsigned bpe, unsigned tile_mode,
1612 unsigned num_pipes, unsigned num_banks,
1613 unsigned tile_split,
1615 unsigned start_level)
1617 uint64_t aligned_offset = offset;
1618 unsigned tilew, tileh, tileb;
1619 unsigned mtilew, mtileh, mtileb;
1623 /* compute tile values */
1626 tileb = tilew * tileh * bpe * surf->nsamples;
1627 /* slices per tile */
1629 if (tileb > tile_split && tile_split) {
1630 slice_pt = tileb / tile_split;
1632 tileb = tileb / slice_pt;
1634 /* macro tile width & height */
1635 mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
1636 mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
1638 /* macro tile bytes */
1639 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
1641 if (start_level <= 1) {
1642 unsigned alignment = MAX2(256, mtileb);
1643 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1645 if (aligned_offset) {
1646 aligned_offset = ALIGN(aligned_offset, alignment);
1650 /* build mipmap tree */
1651 for (i = start_level; i <= surf->last_level; i++) {
1652 level[i].mode = RADEON_SURF_MODE_2D;
1653 si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
1654 if (level[i].mode == RADEON_SURF_MODE_1D) {
1655 switch (tile_mode) {
1656 case SI_TILE_MODE_COLOR_2D_8BPP:
1657 case SI_TILE_MODE_COLOR_2D_16BPP:
1658 case SI_TILE_MODE_COLOR_2D_32BPP:
1659 case SI_TILE_MODE_COLOR_2D_64BPP:
1660 tile_mode = SI_TILE_MODE_COLOR_1D;
1662 case SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP:
1663 case SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP:
1664 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1666 case SI_TILE_MODE_DEPTH_STENCIL_2D:
1667 tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1672 return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
1674 /* level0 and first mipmap need to have alignment */
1675 aligned_offset = offset = surf->bo_size;
1677 aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
1679 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1680 if (surf->level == level) {
1681 surf->tiling_index[i] = tile_mode;
1682 /* it's ok because stencil is done after */
1683 surf->stencil_tiling_index[i] = tile_mode;
1685 surf->stencil_tiling_index[i] = tile_mode;
1692 static int si_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
1693 struct radeon_surface *surf,
1694 unsigned tile_mode, unsigned stencil_tile_mode)
1696 unsigned num_pipes, num_banks;
1697 uint32_t gb_tile_mode;
1700 /* retrieve tiling mode value */
1701 gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1702 si_gb_tile_mode(gb_tile_mode, &num_pipes, &num_banks, NULL, NULL, NULL, NULL);
1704 r = si_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode, num_pipes, num_banks, surf->tile_split, 0, 0);
1709 if (surf->flags & RADEON_SURF_SBUFFER) {
1710 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);
1711 surf->stencil_offset = surf->stencil_level[0].offset;
1716 static int si_surface_init(struct radeon_surface_manager *surf_man,
1717 struct radeon_surface *surf)
1719 unsigned mode, tile_mode, stencil_tile_mode;
1722 /* MSAA surfaces support the 2D mode only. */
1723 if (surf->nsamples > 1) {
1724 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1725 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
1729 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1731 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
1732 /* zbuffer only support 1D or 2D tiled surface */
1734 case RADEON_SURF_MODE_1D:
1735 case RADEON_SURF_MODE_2D:
1738 mode = RADEON_SURF_MODE_1D;
1739 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1740 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1745 r = si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1750 surf->stencil_offset = 0;
1751 surf->bo_alignment = 0;
1753 /* check tiling mode */
1755 case RADEON_SURF_MODE_LINEAR:
1756 r = r6_surface_init_linear(surf_man, surf, 0, 0);
1758 case RADEON_SURF_MODE_LINEAR_ALIGNED:
1759 r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
1761 case RADEON_SURF_MODE_1D:
1762 r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1764 case RADEON_SURF_MODE_2D:
1765 r = si_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1774 * depending on surface
1776 static int si_surface_best(struct radeon_surface_manager *surf_man,
1777 struct radeon_surface *surf)
1779 unsigned mode, tile_mode, stencil_tile_mode;
1782 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1784 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
1785 !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
1786 /* depth/stencil force 1d tiling for old mesa */
1787 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1788 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1791 return si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1795 /* ===========================================================================
1796 * Sea Islands family
1798 #define CIK__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f)
1799 #define CIK__PIPE_CONFIG__ADDR_SURF_P2 0
1800 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16 4
1801 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16 5
1802 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32 6
1803 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32 7
1804 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8
1805 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9
1806 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10
1807 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11
1808 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12
1809 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13
1810 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14
1811 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16 16
1812 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16 17
1813 #define CIK__GB_TILE_MODE__TILE_SPLIT(x) (((x) >> 11) & 0x7)
1814 #define CIK__TILE_SPLIT__64B 0
1815 #define CIK__TILE_SPLIT__128B 1
1816 #define CIK__TILE_SPLIT__256B 2
1817 #define CIK__TILE_SPLIT__512B 3
1818 #define CIK__TILE_SPLIT__1024B 4
1819 #define CIK__TILE_SPLIT__2048B 5
1820 #define CIK__TILE_SPLIT__4096B 6
1821 #define CIK__GB_TILE_MODE__SAMPLE_SPLIT(x) (((x) >> 25) & 0x3)
1822 #define CIK__SAMPLE_SPLIT__1 0
1823 #define CIK__SAMPLE_SPLIT__2 1
1824 #define CIK__SAMPLE_SPLIT__4 2
1825 #define CIK__SAMPLE_SPLIT__8 3
1826 #define CIK__GB_MACROTILE_MODE__BANK_WIDTH(x) ((x) & 0x3)
1827 #define CIK__BANK_WIDTH__1 0
1828 #define CIK__BANK_WIDTH__2 1
1829 #define CIK__BANK_WIDTH__4 2
1830 #define CIK__BANK_WIDTH__8 3
1831 #define CIK__GB_MACROTILE_MODE__BANK_HEIGHT(x) (((x) >> 2) & 0x3)
1832 #define CIK__BANK_HEIGHT__1 0
1833 #define CIK__BANK_HEIGHT__2 1
1834 #define CIK__BANK_HEIGHT__4 2
1835 #define CIK__BANK_HEIGHT__8 3
1836 #define CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 4) & 0x3)
1837 #define CIK__MACRO_TILE_ASPECT__1 0
1838 #define CIK__MACRO_TILE_ASPECT__2 1
1839 #define CIK__MACRO_TILE_ASPECT__4 2
1840 #define CIK__MACRO_TILE_ASPECT__8 3
1841 #define CIK__GB_MACROTILE_MODE__NUM_BANKS(x) (((x) >> 6) & 0x3)
1842 #define CIK__NUM_BANKS__2_BANK 0
1843 #define CIK__NUM_BANKS__4_BANK 1
1844 #define CIK__NUM_BANKS__8_BANK 2
1845 #define CIK__NUM_BANKS__16_BANK 3
1848 static void cik_get_2d_params(struct radeon_surface_manager *surf_man,
1849 unsigned bpe, unsigned nsamples, bool is_color,
1851 uint32_t *num_pipes,
1852 uint32_t *tile_split_ptr,
1853 uint32_t *num_banks,
1854 uint32_t *macro_tile_aspect,
1858 uint32_t gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1859 unsigned tileb_1x, tileb;
1860 unsigned gb_macrotile_mode;
1861 unsigned macrotile_index;
1862 unsigned tile_split, sample_split;
1865 switch (CIK__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1866 case CIK__PIPE_CONFIG__ADDR_SURF_P2:
1870 case CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1871 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1872 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1873 case CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1876 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1877 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1878 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1879 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1880 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1881 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1882 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1885 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16:
1886 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16:
1891 switch (CIK__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1893 case CIK__TILE_SPLIT__64B:
1896 case CIK__TILE_SPLIT__128B:
1899 case CIK__TILE_SPLIT__256B:
1902 case CIK__TILE_SPLIT__512B:
1905 case CIK__TILE_SPLIT__1024B:
1908 case CIK__TILE_SPLIT__2048B:
1911 case CIK__TILE_SPLIT__4096B:
1915 switch (CIK__GB_TILE_MODE__SAMPLE_SPLIT(gb_tile_mode)) {
1917 case CIK__SAMPLE_SPLIT__1:
1920 case CIK__SAMPLE_SPLIT__2:
1923 case CIK__SAMPLE_SPLIT__4:
1926 case CIK__SAMPLE_SPLIT__8:
1931 /* Adjust the tile split. */
1932 tileb_1x = 8 * 8 * bpe;
1934 tile_split = MAX2(256, sample_split * tileb_1x);
1936 tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
1938 /* Determine the macrotile index. */
1939 tileb = MIN2(tile_split, nsamples * tileb_1x);
1941 for (macrotile_index = 0; tileb > 64; macrotile_index++) {
1944 gb_macrotile_mode = surf_man->hw_info.macrotile_mode_array[macrotile_index];
1946 if (tile_split_ptr) {
1947 *tile_split_ptr = tile_split;
1950 switch (CIK__GB_MACROTILE_MODE__NUM_BANKS(gb_macrotile_mode)) {
1952 case CIK__NUM_BANKS__2_BANK:
1955 case CIK__NUM_BANKS__4_BANK:
1958 case CIK__NUM_BANKS__8_BANK:
1961 case CIK__NUM_BANKS__16_BANK:
1966 if (macro_tile_aspect) {
1967 switch (CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(gb_macrotile_mode)) {
1969 case CIK__MACRO_TILE_ASPECT__1:
1970 *macro_tile_aspect = 1;
1972 case CIK__MACRO_TILE_ASPECT__2:
1973 *macro_tile_aspect = 2;
1975 case CIK__MACRO_TILE_ASPECT__4:
1976 *macro_tile_aspect = 4;
1978 case CIK__MACRO_TILE_ASPECT__8:
1979 *macro_tile_aspect = 8;
1984 switch (CIK__GB_MACROTILE_MODE__BANK_WIDTH(gb_macrotile_mode)) {
1986 case CIK__BANK_WIDTH__1:
1989 case CIK__BANK_WIDTH__2:
1992 case CIK__BANK_WIDTH__4:
1995 case CIK__BANK_WIDTH__8:
2001 switch (CIK__GB_MACROTILE_MODE__BANK_HEIGHT(gb_macrotile_mode)) {
2003 case CIK__BANK_HEIGHT__1:
2006 case CIK__BANK_HEIGHT__2:
2009 case CIK__BANK_HEIGHT__4:
2012 case CIK__BANK_HEIGHT__8:
2019 static int cik_init_hw_info(struct radeon_surface_manager *surf_man)
2021 uint32_t tiling_config;
2022 drmVersionPtr version;
2025 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
2031 surf_man->hw_info.allow_2d = 0;
2032 version = drmGetVersion(surf_man->fd);
2033 if (version && version->version_minor >= 35) {
2034 if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array) &&
2035 !radeon_get_value(surf_man->fd, RADEON_INFO_CIK_MACROTILE_MODE_ARRAY, surf_man->hw_info.macrotile_mode_array)) {
2036 surf_man->hw_info.allow_2d = 1;
2039 drmFreeVersion(version);
2041 switch (tiling_config & 0xf) {
2043 surf_man->hw_info.num_pipes = 1;
2046 surf_man->hw_info.num_pipes = 2;
2049 surf_man->hw_info.num_pipes = 4;
2052 surf_man->hw_info.num_pipes = 8;
2055 surf_man->hw_info.num_pipes = 8;
2056 surf_man->hw_info.allow_2d = 0;
2060 switch ((tiling_config & 0xf0) >> 4) {
2062 surf_man->hw_info.num_banks = 4;
2065 surf_man->hw_info.num_banks = 8;
2068 surf_man->hw_info.num_banks = 16;
2071 surf_man->hw_info.num_banks = 8;
2072 surf_man->hw_info.allow_2d = 0;
2076 switch ((tiling_config & 0xf00) >> 8) {
2078 surf_man->hw_info.group_bytes = 256;
2081 surf_man->hw_info.group_bytes = 512;
2084 surf_man->hw_info.group_bytes = 256;
2085 surf_man->hw_info.allow_2d = 0;
2089 switch ((tiling_config & 0xf000) >> 12) {
2091 surf_man->hw_info.row_size = 1024;
2094 surf_man->hw_info.row_size = 2048;
2097 surf_man->hw_info.row_size = 4096;
2100 surf_man->hw_info.row_size = 4096;
2101 surf_man->hw_info.allow_2d = 0;
2107 static int cik_surface_sanity(struct radeon_surface_manager *surf_man,
2108 struct radeon_surface *surf,
2109 unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
2111 /* check surface dimension */
2112 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
2116 /* check mipmap last_level */
2117 if (surf->last_level > 15) {
2121 /* force 1d on kernel that can't do 2d */
2122 if (mode > RADEON_SURF_MODE_1D &&
2123 (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
2124 if (surf->nsamples > 1) {
2125 fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
2128 mode = RADEON_SURF_MODE_1D;
2129 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2130 surf->flags |= RADEON_SURF_SET(mode, MODE);
2133 if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
2137 if (!surf->tile_split) {
2142 surf->tile_split = 64;
2143 surf->stencil_tile_split = 64;
2147 case RADEON_SURF_MODE_2D: {
2148 if (surf->flags & RADEON_SURF_Z_OR_SBUFFER) {
2149 switch (surf->nsamples) {
2151 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64;
2155 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128;
2158 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256;
2164 if (surf->flags & RADEON_SURF_SBUFFER) {
2165 *stencil_tile_mode = *tile_mode;
2167 cik_get_2d_params(surf_man, 1, surf->nsamples, false,
2168 *stencil_tile_mode, NULL,
2169 &surf->stencil_tile_split,
2170 NULL, NULL, NULL, NULL);
2172 } else if (surf->flags & RADEON_SURF_SCANOUT) {
2173 *tile_mode = CIK_TILE_MODE_COLOR_2D_SCANOUT;
2175 *tile_mode = CIK_TILE_MODE_COLOR_2D;
2178 /* retrieve tiling mode values */
2179 cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
2180 !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), *tile_mode,
2181 NULL, &surf->tile_split, NULL, &surf->mtilea,
2182 &surf->bankw, &surf->bankh);
2185 case RADEON_SURF_MODE_1D:
2186 if (surf->flags & RADEON_SURF_SBUFFER) {
2187 *stencil_tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2189 if (surf->flags & RADEON_SURF_ZBUFFER) {
2190 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2191 } else if (surf->flags & RADEON_SURF_SCANOUT) {
2192 *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2194 *tile_mode = SI_TILE_MODE_COLOR_1D;
2197 case RADEON_SURF_MODE_LINEAR_ALIGNED:
2199 *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
2205 static int cik_surface_init_2d(struct radeon_surface_manager *surf_man,
2206 struct radeon_surface *surf,
2207 struct radeon_surface_level *level,
2208 unsigned bpe, unsigned tile_mode,
2209 unsigned tile_split,
2210 unsigned num_pipes, unsigned num_banks,
2212 unsigned start_level)
2214 uint64_t aligned_offset = offset;
2215 unsigned tilew, tileh, tileb_1x, tileb;
2216 unsigned mtilew, mtileh, mtileb;
2220 /* compute tile values */
2223 tileb_1x = tilew * tileh * bpe;
2225 tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
2227 tileb = surf->nsamples * tileb_1x;
2229 /* slices per tile */
2231 if (tileb > tile_split && tile_split) {
2232 slice_pt = tileb / tile_split;
2233 tileb = tileb / slice_pt;
2236 /* macro tile width & height */
2237 mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
2238 mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
2240 /* macro tile bytes */
2241 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
2243 if (start_level <= 1) {
2244 unsigned alignment = MAX2(256, mtileb);
2245 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
2247 if (aligned_offset) {
2248 aligned_offset = ALIGN(aligned_offset, alignment);
2252 /* build mipmap tree */
2253 for (i = start_level; i <= surf->last_level; i++) {
2254 level[i].mode = RADEON_SURF_MODE_2D;
2255 si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
2256 if (level[i].mode == RADEON_SURF_MODE_1D) {
2257 switch (tile_mode) {
2258 case CIK_TILE_MODE_COLOR_2D:
2259 tile_mode = SI_TILE_MODE_COLOR_1D;
2261 case CIK_TILE_MODE_COLOR_2D_SCANOUT:
2262 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2264 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64:
2265 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128:
2266 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256:
2267 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512:
2268 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE:
2269 tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2274 return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
2276 /* level0 and first mipmap need to have alignment */
2277 aligned_offset = offset = surf->bo_size;
2279 aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
2281 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
2282 if (surf->level == level) {
2283 surf->tiling_index[i] = tile_mode;
2284 /* it's ok because stencil is done after */
2285 surf->stencil_tiling_index[i] = tile_mode;
2287 surf->stencil_tiling_index[i] = tile_mode;
2294 static int cik_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
2295 struct radeon_surface *surf,
2296 unsigned tile_mode, unsigned stencil_tile_mode)
2299 uint32_t num_pipes, num_banks;
2301 cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
2302 !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), tile_mode,
2303 &num_pipes, NULL, &num_banks, NULL, NULL, NULL);
2305 r = cik_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode,
2306 surf->tile_split, num_pipes, num_banks, 0, 0);
2311 if (surf->flags & RADEON_SURF_SBUFFER) {
2312 r = cik_surface_init_2d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode,
2313 surf->stencil_tile_split, num_pipes, num_banks,
2315 surf->stencil_offset = surf->stencil_level[0].offset;
2320 static int cik_surface_init(struct radeon_surface_manager *surf_man,
2321 struct radeon_surface *surf)
2323 unsigned mode, tile_mode, stencil_tile_mode;
2326 /* MSAA surfaces support the 2D mode only. */
2327 if (surf->nsamples > 1) {
2328 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2329 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
2333 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2335 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
2336 /* zbuffer only support 1D or 2D tiled surface */
2338 case RADEON_SURF_MODE_1D:
2339 case RADEON_SURF_MODE_2D:
2342 mode = RADEON_SURF_MODE_1D;
2343 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2344 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2349 r = cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2354 surf->stencil_offset = 0;
2355 surf->bo_alignment = 0;
2357 /* check tiling mode */
2359 case RADEON_SURF_MODE_LINEAR:
2360 r = r6_surface_init_linear(surf_man, surf, 0, 0);
2362 case RADEON_SURF_MODE_LINEAR_ALIGNED:
2363 r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
2365 case RADEON_SURF_MODE_1D:
2366 r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2368 case RADEON_SURF_MODE_2D:
2369 r = cik_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2378 * depending on surface
2380 static int cik_surface_best(struct radeon_surface_manager *surf_man,
2381 struct radeon_surface *surf)
2383 unsigned mode, tile_mode, stencil_tile_mode;
2386 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2388 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
2389 !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
2390 /* depth/stencil force 1d tiling for old mesa */
2391 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2392 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2395 return cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2399 /* ===========================================================================
2402 drm_public struct radeon_surface_manager *
2403 radeon_surface_manager_new(int fd)
2405 struct radeon_surface_manager *surf_man;
2407 surf_man = calloc(1, sizeof(struct radeon_surface_manager));
2408 if (surf_man == NULL) {
2412 if (radeon_get_value(fd, RADEON_INFO_DEVICE_ID, &surf_man->device_id)) {
2415 if (radeon_get_family(surf_man)) {
2419 if (surf_man->family <= CHIP_RV740) {
2420 if (r6_init_hw_info(surf_man)) {
2423 surf_man->surface_init = &r6_surface_init;
2424 surf_man->surface_best = &r6_surface_best;
2425 } else if (surf_man->family <= CHIP_ARUBA) {
2426 if (eg_init_hw_info(surf_man)) {
2429 surf_man->surface_init = &eg_surface_init;
2430 surf_man->surface_best = &eg_surface_best;
2431 } else if (surf_man->family < CHIP_BONAIRE) {
2432 if (si_init_hw_info(surf_man)) {
2435 surf_man->surface_init = &si_surface_init;
2436 surf_man->surface_best = &si_surface_best;
2438 if (cik_init_hw_info(surf_man)) {
2441 surf_man->surface_init = &cik_surface_init;
2442 surf_man->surface_best = &cik_surface_best;
2452 radeon_surface_manager_free(struct radeon_surface_manager *surf_man)
2457 static int radeon_surface_sanity(struct radeon_surface_manager *surf_man,
2458 struct radeon_surface *surf,
2462 if (surf_man == NULL || surf_man->surface_init == NULL || surf == NULL) {
2466 /* all dimension must be at least 1 ! */
2467 if (!surf->npix_x || !surf->npix_y || !surf->npix_z) {
2470 if (!surf->blk_w || !surf->blk_h || !surf->blk_d) {
2473 if (!surf->array_size) {
2476 /* array size must be a power of 2 */
2477 surf->array_size = next_power_of_two(surf->array_size);
2479 switch (surf->nsamples) {
2490 case RADEON_SURF_TYPE_1D:
2491 if (surf->npix_y > 1) {
2494 case RADEON_SURF_TYPE_2D:
2495 if (surf->npix_z > 1) {
2499 case RADEON_SURF_TYPE_CUBEMAP:
2500 if (surf->npix_z > 1) {
2503 /* deal with cubemap as they were texture array */
2504 if (surf_man->family >= CHIP_RV770) {
2505 surf->array_size = 8;
2507 surf->array_size = 6;
2510 case RADEON_SURF_TYPE_3D:
2512 case RADEON_SURF_TYPE_1D_ARRAY:
2513 if (surf->npix_y > 1) {
2516 case RADEON_SURF_TYPE_2D_ARRAY:
2525 radeon_surface_init(struct radeon_surface_manager *surf_man,
2526 struct radeon_surface *surf)
2528 unsigned mode, type;
2531 type = RADEON_SURF_GET(surf->flags, TYPE);
2532 mode = RADEON_SURF_GET(surf->flags, MODE);
2534 r = radeon_surface_sanity(surf_man, surf, type, mode);
2538 return surf_man->surface_init(surf_man, surf);
2542 radeon_surface_best(struct radeon_surface_manager *surf_man,
2543 struct radeon_surface *surf)
2545 unsigned mode, type;
2548 type = RADEON_SURF_GET(surf->flags, TYPE);
2549 mode = RADEON_SURF_GET(surf->flags, MODE);
2551 r = radeon_surface_sanity(surf_man, surf, type, mode);
2555 return surf_man->surface_best(surf_man, surf);