2 * Copyright © 2011 Red Hat All Rights Reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
14 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
16 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 * The above copyright notice and this permission notice (including the
22 * next paragraph) shall be included in all copies or substantial portions
27 * Jérôme Glisse <jglisse@redhat.com>
38 #include <sys/ioctl.h>
40 #include "libdrm_macros.h"
42 #include "radeon_drm.h"
43 #include "radeon_surface.h"
45 #define 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 if (surf->flags & RADEON_SURF_FMASK)
370 xalign = MAX2(128, xalign);
371 yalign = tilew * surf_man->hw_info.num_pipes;
372 if (surf->flags & RADEON_SURF_SCANOUT) {
373 xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
377 MAX2(surf_man->hw_info.num_pipes *
378 surf_man->hw_info.num_banks *
379 surf->nsamples * surf->bpe * 64,
380 xalign * yalign * surf->nsamples * surf->bpe);
383 /* build mipmap tree */
384 for (i = start_level; i <= surf->last_level; i++) {
385 surf->level[i].mode = RADEON_SURF_MODE_2D;
386 surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
387 if (surf->level[i].mode == RADEON_SURF_MODE_1D) {
388 return r6_surface_init_1d(surf_man, surf, offset, i);
390 /* level0 and first mipmap need to have alignment */
391 offset = surf->bo_size;
393 offset = ALIGN(offset, surf->bo_alignment);
399 static int r6_surface_init(struct radeon_surface_manager *surf_man,
400 struct radeon_surface *surf)
405 /* MSAA surfaces support the 2D mode only. */
406 if (surf->nsamples > 1) {
407 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
408 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
412 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
414 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
415 /* zbuffer only support 1D or 2D tiled surface */
417 case RADEON_SURF_MODE_1D:
418 case RADEON_SURF_MODE_2D:
421 mode = RADEON_SURF_MODE_1D;
422 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
423 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
428 /* force 1d on kernel that can't do 2d */
429 if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) {
430 if (surf->nsamples > 1) {
431 fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__);
434 mode = RADEON_SURF_MODE_1D;
435 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
436 surf->flags |= RADEON_SURF_SET(mode, MODE);
439 /* check surface dimension */
440 if (surf->npix_x > 8192 || surf->npix_y > 8192 || surf->npix_z > 8192) {
444 /* check mipmap last_level */
445 if (surf->last_level > 14) {
449 /* check tiling mode */
451 case RADEON_SURF_MODE_LINEAR:
452 r = r6_surface_init_linear(surf_man, surf, 0, 0);
454 case RADEON_SURF_MODE_LINEAR_ALIGNED:
455 r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
457 case RADEON_SURF_MODE_1D:
458 r = r6_surface_init_1d(surf_man, surf, 0, 0);
460 case RADEON_SURF_MODE_2D:
461 r = r6_surface_init_2d(surf_man, surf, 0, 0);
469 static int r6_surface_best(struct radeon_surface_manager *surf_man,
470 struct radeon_surface *surf)
472 /* no value to optimize for r6xx/r7xx */
477 /* ===========================================================================
480 static int eg_init_hw_info(struct radeon_surface_manager *surf_man)
482 uint32_t tiling_config;
483 drmVersionPtr version;
486 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
492 surf_man->hw_info.allow_2d = 0;
493 version = drmGetVersion(surf_man->fd);
494 if (version && version->version_minor >= 16) {
495 surf_man->hw_info.allow_2d = 1;
497 drmFreeVersion(version);
499 switch (tiling_config & 0xf) {
501 surf_man->hw_info.num_pipes = 1;
504 surf_man->hw_info.num_pipes = 2;
507 surf_man->hw_info.num_pipes = 4;
510 surf_man->hw_info.num_pipes = 8;
513 surf_man->hw_info.num_pipes = 8;
514 surf_man->hw_info.allow_2d = 0;
518 switch ((tiling_config & 0xf0) >> 4) {
520 surf_man->hw_info.num_banks = 4;
523 surf_man->hw_info.num_banks = 8;
526 surf_man->hw_info.num_banks = 16;
529 surf_man->hw_info.num_banks = 8;
530 surf_man->hw_info.allow_2d = 0;
534 switch ((tiling_config & 0xf00) >> 8) {
536 surf_man->hw_info.group_bytes = 256;
539 surf_man->hw_info.group_bytes = 512;
542 surf_man->hw_info.group_bytes = 256;
543 surf_man->hw_info.allow_2d = 0;
547 switch ((tiling_config & 0xf000) >> 12) {
549 surf_man->hw_info.row_size = 1024;
552 surf_man->hw_info.row_size = 2048;
555 surf_man->hw_info.row_size = 4096;
558 surf_man->hw_info.row_size = 4096;
559 surf_man->hw_info.allow_2d = 0;
565 static void eg_surf_minify(struct radeon_surface *surf,
566 struct radeon_surface_level *surflevel,
575 unsigned mtile_pr, mtile_ps;
577 surflevel->npix_x = mip_minify(surf->npix_x, level);
578 surflevel->npix_y = mip_minify(surf->npix_y, level);
579 surflevel->npix_z = mip_minify(surf->npix_z, level);
580 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
581 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
582 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
583 if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
584 !(surf->flags & RADEON_SURF_FMASK)) {
585 if (surflevel->nblk_x < mtilew || surflevel->nblk_y < mtileh) {
586 surflevel->mode = RADEON_SURF_MODE_1D;
590 surflevel->nblk_x = ALIGN(surflevel->nblk_x, mtilew);
591 surflevel->nblk_y = ALIGN(surflevel->nblk_y, mtileh);
592 surflevel->nblk_z = ALIGN(surflevel->nblk_z, 1);
594 /* macro tile per row */
595 mtile_pr = surflevel->nblk_x / mtilew;
596 /* macro tile per slice */
597 mtile_ps = (mtile_pr * surflevel->nblk_y) / mtileh;
599 surflevel->offset = offset;
600 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
601 surflevel->slice_size = mtile_ps * mtileb * slice_pt;
603 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
606 static int eg_surface_init_1d(struct radeon_surface_manager *surf_man,
607 struct radeon_surface *surf,
608 struct radeon_surface_level *level,
610 uint64_t offset, unsigned start_level)
612 uint32_t xalign, yalign, zalign, tilew;
615 /* compute alignment */
617 xalign = surf_man->hw_info.group_bytes / (tilew * bpe * surf->nsamples);
618 xalign = MAX2(tilew, xalign);
621 if (surf->flags & RADEON_SURF_SCANOUT) {
622 xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
626 unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
627 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
630 offset = ALIGN(offset, alignment);
634 /* build mipmap tree */
635 for (i = start_level; i <= surf->last_level; i++) {
636 level[i].mode = RADEON_SURF_MODE_1D;
637 surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, offset);
638 /* level0 and first mipmap need to have alignment */
639 offset = surf->bo_size;
641 offset = ALIGN(offset, surf->bo_alignment);
647 static int eg_surface_init_2d(struct radeon_surface_manager *surf_man,
648 struct radeon_surface *surf,
649 struct radeon_surface_level *level,
650 unsigned bpe, unsigned tile_split,
651 uint64_t offset, unsigned start_level)
653 unsigned tilew, tileh, tileb;
654 unsigned mtilew, mtileh, mtileb;
658 /* compute tile values */
661 tileb = tilew * tileh * bpe * surf->nsamples;
662 /* slices per tile */
664 if (tileb > tile_split && tile_split) {
665 slice_pt = tileb / tile_split;
667 tileb = tileb / slice_pt;
669 /* macro tile width & height */
670 mtilew = (tilew * surf->bankw * surf_man->hw_info.num_pipes) * surf->mtilea;
671 mtileh = (tileh * surf->bankh * surf_man->hw_info.num_banks) / surf->mtilea;
672 /* macro tile bytes */
673 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
676 unsigned alignment = MAX2(256, mtileb);
677 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
680 offset = ALIGN(offset, alignment);
684 /* build mipmap tree */
685 for (i = start_level; i <= surf->last_level; i++) {
686 level[i].mode = RADEON_SURF_MODE_2D;
687 eg_surf_minify(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, mtileb, offset);
688 if (level[i].mode == RADEON_SURF_MODE_1D) {
689 return eg_surface_init_1d(surf_man, surf, level, bpe, offset, i);
691 /* level0 and first mipmap need to have alignment */
692 offset = surf->bo_size;
694 offset = ALIGN(offset, surf->bo_alignment);
700 static int eg_surface_sanity(struct radeon_surface_manager *surf_man,
701 struct radeon_surface *surf,
706 /* check surface dimension */
707 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
711 /* check mipmap last_level */
712 if (surf->last_level > 15) {
716 /* force 1d on kernel that can't do 2d */
717 if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) {
718 if (surf->nsamples > 1) {
719 fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__);
722 mode = RADEON_SURF_MODE_1D;
723 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
724 surf->flags |= RADEON_SURF_SET(mode, MODE);
727 /* check tile split */
728 if (mode == RADEON_SURF_MODE_2D) {
729 switch (surf->tile_split) {
741 switch (surf->mtilea) {
750 /* check aspect ratio */
751 if (surf_man->hw_info.num_banks < surf->mtilea) {
754 /* check bank width */
755 switch (surf->bankw) {
764 /* check bank height */
765 switch (surf->bankh) {
774 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
775 if ((tileb * surf->bankh * surf->bankw) < surf_man->hw_info.group_bytes) {
783 static int eg_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
784 struct radeon_surface *surf)
786 unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
787 int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
788 /* Old libdrm_macros.headers didn't have stencil_level in it. This prevents crashes. */
789 struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
790 struct radeon_surface_level *stencil_level =
791 (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
793 r = eg_surface_init_1d(surf_man, surf, surf->level, surf->bpe, 0, 0);
797 if (is_depth_stencil) {
798 r = eg_surface_init_1d(surf_man, surf, stencil_level, 1,
800 surf->stencil_offset = stencil_level[0].offset;
805 static int eg_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
806 struct radeon_surface *surf)
808 unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
809 int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
810 /* Old libdrm_macros.headers didn't have stencil_level in it. This prevents crashes. */
811 struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
812 struct radeon_surface_level *stencil_level =
813 (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
815 r = eg_surface_init_2d(surf_man, surf, surf->level, surf->bpe,
816 surf->tile_split, 0, 0);
820 if (is_depth_stencil) {
821 r = eg_surface_init_2d(surf_man, surf, stencil_level, 1,
822 surf->stencil_tile_split, surf->bo_size, 0);
823 surf->stencil_offset = stencil_level[0].offset;
828 static int eg_surface_init(struct radeon_surface_manager *surf_man,
829 struct radeon_surface *surf)
834 /* MSAA surfaces support the 2D mode only. */
835 if (surf->nsamples > 1) {
836 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
837 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
841 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
843 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
844 /* zbuffer only support 1D or 2D tiled surface */
846 case RADEON_SURF_MODE_1D:
847 case RADEON_SURF_MODE_2D:
850 mode = RADEON_SURF_MODE_1D;
851 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
852 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
857 r = eg_surface_sanity(surf_man, surf, mode);
862 surf->stencil_offset = 0;
863 surf->bo_alignment = 0;
865 /* check tiling mode */
867 case RADEON_SURF_MODE_LINEAR:
868 r = r6_surface_init_linear(surf_man, surf, 0, 0);
870 case RADEON_SURF_MODE_LINEAR_ALIGNED:
871 r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
873 case RADEON_SURF_MODE_1D:
874 r = eg_surface_init_1d_miptrees(surf_man, surf);
876 case RADEON_SURF_MODE_2D:
877 r = eg_surface_init_2d_miptrees(surf_man, surf);
885 static unsigned log2_int(unsigned x)
893 if ((unsigned)(1 << l) > x) {
900 /* compute best tile_split, bankw, bankh, mtilea
901 * depending on surface
903 static int eg_surface_best(struct radeon_surface_manager *surf_man,
904 struct radeon_surface *surf)
906 unsigned mode, tileb, h_over_w;
910 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
912 /* set some default value to avoid sanity check choking on them */
913 surf->tile_split = 1024;
916 surf->mtilea = surf_man->hw_info.num_banks;
917 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
918 for (; surf->bankh <= 8; surf->bankh *= 2) {
919 if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
923 if (surf->mtilea > 8) {
927 r = eg_surface_sanity(surf_man, surf, mode);
932 if (mode != RADEON_SURF_MODE_2D) {
933 /* nothing to do for non 2D tiled surface */
937 /* Tweak TILE_SPLIT for performance here. */
938 if (surf->nsamples > 1) {
939 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
940 switch (surf->nsamples) {
942 surf->tile_split = 128;
945 surf->tile_split = 128;
948 surf->tile_split = 256;
950 case 16: /* cayman only */
951 surf->tile_split = 512;
954 fprintf(stderr, "radeon: Wrong number of samples %i (%i)\n",
955 surf->nsamples, __LINE__);
958 surf->stencil_tile_split = 64;
960 /* tile split must be >= 256 for colorbuffer surfaces */
961 surf->tile_split = MAX2(surf->nsamples * surf->bpe * 64, 256);
962 if (surf->tile_split > 4096)
963 surf->tile_split = 4096;
966 /* set tile split to row size */
967 surf->tile_split = surf_man->hw_info.row_size;
968 surf->stencil_tile_split = surf_man->hw_info.row_size / 2;
971 /* bankw or bankh greater than 1 increase alignment requirement, not
972 * sure if it's worth using smaller bankw & bankh to stick with 2D
973 * tiling on small surface rather than falling back to 1D tiling.
974 * Use recommanded value based on tile size for now.
976 * fmask buffer has different optimal value figure them out once we
979 if (surf->flags & RADEON_SURF_SBUFFER) {
980 /* assume 1 bytes for stencil, we optimize for stencil as stencil
981 * and depth shares surface values
983 tileb = MIN2(surf->tile_split, 64 * surf->nsamples);
985 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
988 /* use bankw of 1 to minimize width alignment, might be interesting to
989 * increase it for large surface
1004 /* double check the constraint */
1005 for (; surf->bankh <= 8; surf->bankh *= 2) {
1006 if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
1011 h_over_w = (((surf->bankh * surf_man->hw_info.num_banks) << 16) /
1012 (surf->bankw * surf_man->hw_info.num_pipes)) >> 16;
1013 surf->mtilea = 1 << (log2_int(h_over_w) >> 1);
1019 /* ===========================================================================
1020 * Southern Islands family
1022 #define SI__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f)
1023 #define SI__PIPE_CONFIG__ADDR_SURF_P2 0
1024 #define SI__PIPE_CONFIG__ADDR_SURF_P4_8x16 4
1025 #define SI__PIPE_CONFIG__ADDR_SURF_P4_16x16 5
1026 #define SI__PIPE_CONFIG__ADDR_SURF_P4_16x32 6
1027 #define SI__PIPE_CONFIG__ADDR_SURF_P4_32x32 7
1028 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8
1029 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9
1030 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10
1031 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11
1032 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12
1033 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13
1034 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14
1035 #define SI__GB_TILE_MODE__TILE_SPLIT(x) (((x) >> 11) & 0x7)
1036 #define SI__TILE_SPLIT__64B 0
1037 #define SI__TILE_SPLIT__128B 1
1038 #define SI__TILE_SPLIT__256B 2
1039 #define SI__TILE_SPLIT__512B 3
1040 #define SI__TILE_SPLIT__1024B 4
1041 #define SI__TILE_SPLIT__2048B 5
1042 #define SI__TILE_SPLIT__4096B 6
1043 #define SI__GB_TILE_MODE__BANK_WIDTH(x) (((x) >> 14) & 0x3)
1044 #define SI__BANK_WIDTH__1 0
1045 #define SI__BANK_WIDTH__2 1
1046 #define SI__BANK_WIDTH__4 2
1047 #define SI__BANK_WIDTH__8 3
1048 #define SI__GB_TILE_MODE__BANK_HEIGHT(x) (((x) >> 16) & 0x3)
1049 #define SI__BANK_HEIGHT__1 0
1050 #define SI__BANK_HEIGHT__2 1
1051 #define SI__BANK_HEIGHT__4 2
1052 #define SI__BANK_HEIGHT__8 3
1053 #define SI__GB_TILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 18) & 0x3)
1054 #define SI__MACRO_TILE_ASPECT__1 0
1055 #define SI__MACRO_TILE_ASPECT__2 1
1056 #define SI__MACRO_TILE_ASPECT__4 2
1057 #define SI__MACRO_TILE_ASPECT__8 3
1058 #define SI__GB_TILE_MODE__NUM_BANKS(x) (((x) >> 20) & 0x3)
1059 #define SI__NUM_BANKS__2_BANK 0
1060 #define SI__NUM_BANKS__4_BANK 1
1061 #define SI__NUM_BANKS__8_BANK 2
1062 #define SI__NUM_BANKS__16_BANK 3
1065 static void si_gb_tile_mode(uint32_t gb_tile_mode,
1066 unsigned *num_pipes,
1067 unsigned *num_banks,
1068 uint32_t *macro_tile_aspect,
1071 uint32_t *tile_split)
1074 switch (SI__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1075 case SI__PIPE_CONFIG__ADDR_SURF_P2:
1079 case SI__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1080 case SI__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1081 case SI__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1082 case SI__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1085 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1086 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1087 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1088 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1089 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1090 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1091 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1097 switch (SI__GB_TILE_MODE__NUM_BANKS(gb_tile_mode)) {
1099 case SI__NUM_BANKS__2_BANK:
1102 case SI__NUM_BANKS__4_BANK:
1105 case SI__NUM_BANKS__8_BANK:
1108 case SI__NUM_BANKS__16_BANK:
1113 if (macro_tile_aspect) {
1114 switch (SI__GB_TILE_MODE__MACRO_TILE_ASPECT(gb_tile_mode)) {
1116 case SI__MACRO_TILE_ASPECT__1:
1117 *macro_tile_aspect = 1;
1119 case SI__MACRO_TILE_ASPECT__2:
1120 *macro_tile_aspect = 2;
1122 case SI__MACRO_TILE_ASPECT__4:
1123 *macro_tile_aspect = 4;
1125 case SI__MACRO_TILE_ASPECT__8:
1126 *macro_tile_aspect = 8;
1131 switch (SI__GB_TILE_MODE__BANK_WIDTH(gb_tile_mode)) {
1133 case SI__BANK_WIDTH__1:
1136 case SI__BANK_WIDTH__2:
1139 case SI__BANK_WIDTH__4:
1142 case SI__BANK_WIDTH__8:
1148 switch (SI__GB_TILE_MODE__BANK_HEIGHT(gb_tile_mode)) {
1150 case SI__BANK_HEIGHT__1:
1153 case SI__BANK_HEIGHT__2:
1156 case SI__BANK_HEIGHT__4:
1159 case SI__BANK_HEIGHT__8:
1165 switch (SI__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1167 case SI__TILE_SPLIT__64B:
1170 case SI__TILE_SPLIT__128B:
1173 case SI__TILE_SPLIT__256B:
1176 case SI__TILE_SPLIT__512B:
1179 case SI__TILE_SPLIT__1024B:
1182 case SI__TILE_SPLIT__2048B:
1185 case SI__TILE_SPLIT__4096B:
1192 static int si_init_hw_info(struct radeon_surface_manager *surf_man)
1194 uint32_t tiling_config;
1195 drmVersionPtr version;
1198 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
1204 surf_man->hw_info.allow_2d = 0;
1205 version = drmGetVersion(surf_man->fd);
1206 if (version && version->version_minor >= 33) {
1207 if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array)) {
1208 surf_man->hw_info.allow_2d = 1;
1211 drmFreeVersion(version);
1213 switch (tiling_config & 0xf) {
1215 surf_man->hw_info.num_pipes = 1;
1218 surf_man->hw_info.num_pipes = 2;
1221 surf_man->hw_info.num_pipes = 4;
1224 surf_man->hw_info.num_pipes = 8;
1227 surf_man->hw_info.num_pipes = 8;
1228 surf_man->hw_info.allow_2d = 0;
1232 switch ((tiling_config & 0xf0) >> 4) {
1234 surf_man->hw_info.num_banks = 4;
1237 surf_man->hw_info.num_banks = 8;
1240 surf_man->hw_info.num_banks = 16;
1243 surf_man->hw_info.num_banks = 8;
1244 surf_man->hw_info.allow_2d = 0;
1248 switch ((tiling_config & 0xf00) >> 8) {
1250 surf_man->hw_info.group_bytes = 256;
1253 surf_man->hw_info.group_bytes = 512;
1256 surf_man->hw_info.group_bytes = 256;
1257 surf_man->hw_info.allow_2d = 0;
1261 switch ((tiling_config & 0xf000) >> 12) {
1263 surf_man->hw_info.row_size = 1024;
1266 surf_man->hw_info.row_size = 2048;
1269 surf_man->hw_info.row_size = 4096;
1272 surf_man->hw_info.row_size = 4096;
1273 surf_man->hw_info.allow_2d = 0;
1279 static int si_surface_sanity(struct radeon_surface_manager *surf_man,
1280 struct radeon_surface *surf,
1281 unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
1283 uint32_t gb_tile_mode;
1285 /* check surface dimension */
1286 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
1290 /* check mipmap last_level */
1291 if (surf->last_level > 15) {
1295 /* force 1d on kernel that can't do 2d */
1296 if (mode > RADEON_SURF_MODE_1D &&
1297 (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
1298 if (surf->nsamples > 1) {
1299 fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
1302 mode = RADEON_SURF_MODE_1D;
1303 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1304 surf->flags |= RADEON_SURF_SET(mode, MODE);
1307 if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
1311 if (!surf->tile_split) {
1316 surf->tile_split = 64;
1317 surf->stencil_tile_split = 64;
1321 case RADEON_SURF_MODE_2D:
1322 if (surf->flags & RADEON_SURF_SBUFFER) {
1323 switch (surf->nsamples) {
1325 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1328 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1331 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1334 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1339 /* retrieve tiling mode value */
1340 gb_tile_mode = surf_man->hw_info.tile_mode_array[*stencil_tile_mode];
1341 si_gb_tile_mode(gb_tile_mode, NULL, NULL, NULL, NULL, NULL, &surf->stencil_tile_split);
1343 if (surf->flags & RADEON_SURF_ZBUFFER) {
1344 switch (surf->nsamples) {
1346 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1349 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1352 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1355 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1360 } else if (surf->flags & RADEON_SURF_SCANOUT) {
1361 switch (surf->bpe) {
1363 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
1366 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
1372 switch (surf->bpe) {
1374 *tile_mode = SI_TILE_MODE_COLOR_2D_8BPP;
1377 *tile_mode = SI_TILE_MODE_COLOR_2D_16BPP;
1380 *tile_mode = SI_TILE_MODE_COLOR_2D_32BPP;
1384 *tile_mode = SI_TILE_MODE_COLOR_2D_64BPP;
1390 /* retrieve tiling mode value */
1391 gb_tile_mode = surf_man->hw_info.tile_mode_array[*tile_mode];
1392 si_gb_tile_mode(gb_tile_mode, NULL, NULL, &surf->mtilea, &surf->bankw, &surf->bankh, &surf->tile_split);
1394 case RADEON_SURF_MODE_1D:
1395 if (surf->flags & RADEON_SURF_SBUFFER) {
1396 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1398 if (surf->flags & RADEON_SURF_ZBUFFER) {
1399 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1400 } else if (surf->flags & RADEON_SURF_SCANOUT) {
1401 *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1403 *tile_mode = SI_TILE_MODE_COLOR_1D;
1406 case RADEON_SURF_MODE_LINEAR_ALIGNED:
1408 *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
1414 static void si_surf_minify(struct radeon_surface *surf,
1415 struct radeon_surface_level *surflevel,
1416 unsigned bpe, unsigned level,
1417 uint32_t xalign, uint32_t yalign, uint32_t zalign,
1418 uint32_t slice_align, unsigned offset)
1421 surflevel->npix_x = surf->npix_x;
1423 surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1425 surflevel->npix_y = mip_minify(surf->npix_y, level);
1426 surflevel->npix_z = mip_minify(surf->npix_z, level);
1428 if (level == 0 && surf->last_level > 0) {
1429 surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1430 surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1431 surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1433 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1434 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1435 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1438 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign);
1440 /* XXX: Texture sampling uses unexpectedly large pitches in some cases,
1441 * these are just guesses for the rules behind those
1443 if (level == 0 && surf->last_level == 0)
1444 /* Non-mipmap pitch padded to slice alignment */
1445 /* Using just bpe here breaks stencil blitting; surf->bpe works. */
1446 xalign = MAX2(xalign, slice_align / surf->bpe);
1447 else if (surflevel->mode == RADEON_SURF_MODE_LINEAR_ALIGNED)
1448 /* Small rows evenly distributed across slice */
1449 xalign = MAX2(xalign, slice_align / bpe / surflevel->nblk_y);
1451 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign);
1452 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign);
1454 surflevel->offset = offset;
1455 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
1456 surflevel->slice_size = ALIGN(surflevel->pitch_bytes * surflevel->nblk_y, slice_align);
1458 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1461 static void si_surf_minify_2d(struct radeon_surface *surf,
1462 struct radeon_surface_level *surflevel,
1463 unsigned bpe, unsigned level, unsigned slice_pt,
1464 uint32_t xalign, uint32_t yalign, uint32_t zalign,
1465 unsigned mtileb, unsigned offset)
1467 unsigned mtile_pr, mtile_ps;
1470 surflevel->npix_x = surf->npix_x;
1472 surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1474 surflevel->npix_y = mip_minify(surf->npix_y, level);
1475 surflevel->npix_z = mip_minify(surf->npix_z, level);
1477 if (level == 0 && surf->last_level > 0) {
1478 surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1479 surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1480 surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1482 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1483 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1484 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1487 if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
1488 !(surf->flags & RADEON_SURF_FMASK)) {
1489 if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
1490 surflevel->mode = RADEON_SURF_MODE_1D;
1494 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign);
1495 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign);
1496 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign);
1498 /* macro tile per row */
1499 mtile_pr = surflevel->nblk_x / xalign;
1500 /* macro tile per slice */
1501 mtile_ps = (mtile_pr * surflevel->nblk_y) / yalign;
1502 surflevel->offset = offset;
1503 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
1504 surflevel->slice_size = mtile_ps * mtileb * slice_pt;
1506 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1509 static int si_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
1510 struct radeon_surface *surf,
1512 uint64_t offset, unsigned start_level)
1514 uint32_t xalign, yalign, zalign, slice_align;
1517 /* compute alignment */
1519 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
1521 xalign = MAX2(8, 64 / surf->bpe);
1524 slice_align = MAX2(64 * surf->bpe, surf_man->hw_info.group_bytes);
1526 /* build mipmap tree */
1527 for (i = start_level; i <= surf->last_level; i++) {
1528 surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
1529 si_surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, slice_align, offset);
1530 /* level0 and first mipmap need to have alignment */
1531 offset = surf->bo_size;
1533 offset = ALIGN(offset, surf->bo_alignment);
1535 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1536 surf->tiling_index[i] = tile_mode;
1542 static int si_surface_init_1d(struct radeon_surface_manager *surf_man,
1543 struct radeon_surface *surf,
1544 struct radeon_surface_level *level,
1545 unsigned bpe, unsigned tile_mode,
1546 uint64_t offset, unsigned start_level)
1548 uint32_t xalign, yalign, zalign, slice_align;
1549 unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
1552 /* compute alignment */
1556 slice_align = surf_man->hw_info.group_bytes;
1557 if (surf->flags & RADEON_SURF_SCANOUT) {
1558 xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
1561 if (start_level <= 1) {
1562 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1565 offset = ALIGN(offset, alignment);
1569 /* build mipmap tree */
1570 for (i = start_level; i <= surf->last_level; i++) {
1571 level[i].mode = RADEON_SURF_MODE_1D;
1572 si_surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, slice_align, offset);
1573 /* level0 and first mipmap need to have alignment */
1574 offset = surf->bo_size;
1576 offset = ALIGN(offset, alignment);
1578 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1579 if (surf->level == level) {
1580 surf->tiling_index[i] = tile_mode;
1581 /* it's ok because stencil is done after */
1582 surf->stencil_tiling_index[i] = tile_mode;
1584 surf->stencil_tiling_index[i] = tile_mode;
1591 static int si_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
1592 struct radeon_surface *surf,
1593 unsigned tile_mode, unsigned stencil_tile_mode)
1597 r = si_surface_init_1d(surf_man, surf, surf->level, surf->bpe, tile_mode, 0, 0);
1602 if (surf->flags & RADEON_SURF_SBUFFER) {
1603 r = si_surface_init_1d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode, surf->bo_size, 0);
1604 surf->stencil_offset = surf->stencil_level[0].offset;
1609 static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
1610 struct radeon_surface *surf,
1611 struct radeon_surface_level *level,
1612 unsigned bpe, unsigned tile_mode,
1613 unsigned num_pipes, unsigned num_banks,
1614 unsigned tile_split,
1616 unsigned start_level)
1618 uint64_t aligned_offset = offset;
1619 unsigned tilew, tileh, tileb;
1620 unsigned mtilew, mtileh, mtileb;
1624 /* compute tile values */
1627 tileb = tilew * tileh * bpe * surf->nsamples;
1628 /* slices per tile */
1630 if (tileb > tile_split && tile_split) {
1631 slice_pt = tileb / tile_split;
1633 tileb = tileb / slice_pt;
1635 /* macro tile width & height */
1636 mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
1637 mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
1639 /* macro tile bytes */
1640 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
1642 if (start_level <= 1) {
1643 unsigned alignment = MAX2(256, mtileb);
1644 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1646 if (aligned_offset) {
1647 aligned_offset = ALIGN(aligned_offset, alignment);
1651 /* build mipmap tree */
1652 for (i = start_level; i <= surf->last_level; i++) {
1653 level[i].mode = RADEON_SURF_MODE_2D;
1654 si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
1655 if (level[i].mode == RADEON_SURF_MODE_1D) {
1656 switch (tile_mode) {
1657 case SI_TILE_MODE_COLOR_2D_8BPP:
1658 case SI_TILE_MODE_COLOR_2D_16BPP:
1659 case SI_TILE_MODE_COLOR_2D_32BPP:
1660 case SI_TILE_MODE_COLOR_2D_64BPP:
1661 tile_mode = SI_TILE_MODE_COLOR_1D;
1663 case SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP:
1664 case SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP:
1665 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1667 case SI_TILE_MODE_DEPTH_STENCIL_2D:
1668 tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1673 return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
1675 /* level0 and first mipmap need to have alignment */
1676 aligned_offset = offset = surf->bo_size;
1678 aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
1680 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1681 if (surf->level == level) {
1682 surf->tiling_index[i] = tile_mode;
1683 /* it's ok because stencil is done after */
1684 surf->stencil_tiling_index[i] = tile_mode;
1686 surf->stencil_tiling_index[i] = tile_mode;
1693 static int si_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
1694 struct radeon_surface *surf,
1695 unsigned tile_mode, unsigned stencil_tile_mode)
1697 unsigned num_pipes, num_banks;
1698 uint32_t gb_tile_mode;
1701 /* retrieve tiling mode value */
1702 gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1703 si_gb_tile_mode(gb_tile_mode, &num_pipes, &num_banks, NULL, NULL, NULL, NULL);
1705 r = si_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode, num_pipes, num_banks, surf->tile_split, 0, 0);
1710 if (surf->flags & RADEON_SURF_SBUFFER) {
1711 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);
1712 surf->stencil_offset = surf->stencil_level[0].offset;
1717 static int si_surface_init(struct radeon_surface_manager *surf_man,
1718 struct radeon_surface *surf)
1720 unsigned mode, tile_mode, stencil_tile_mode;
1723 /* MSAA surfaces support the 2D mode only. */
1724 if (surf->nsamples > 1) {
1725 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1726 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
1730 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1732 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
1733 /* zbuffer only support 1D or 2D tiled surface */
1735 case RADEON_SURF_MODE_1D:
1736 case RADEON_SURF_MODE_2D:
1739 mode = RADEON_SURF_MODE_1D;
1740 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1741 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1746 r = si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1751 surf->stencil_offset = 0;
1752 surf->bo_alignment = 0;
1754 /* check tiling mode */
1756 case RADEON_SURF_MODE_LINEAR:
1757 r = r6_surface_init_linear(surf_man, surf, 0, 0);
1759 case RADEON_SURF_MODE_LINEAR_ALIGNED:
1760 r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
1762 case RADEON_SURF_MODE_1D:
1763 r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1765 case RADEON_SURF_MODE_2D:
1766 r = si_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1775 * depending on surface
1777 static int si_surface_best(struct radeon_surface_manager *surf_man,
1778 struct radeon_surface *surf)
1780 unsigned mode, tile_mode, stencil_tile_mode;
1783 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1785 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
1786 !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
1787 /* depth/stencil force 1d tiling for old mesa */
1788 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1789 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1792 return si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1796 /* ===========================================================================
1797 * Sea Islands family
1799 #define CIK__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f)
1800 #define CIK__PIPE_CONFIG__ADDR_SURF_P2 0
1801 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16 4
1802 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16 5
1803 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32 6
1804 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32 7
1805 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8
1806 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9
1807 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10
1808 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11
1809 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12
1810 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13
1811 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14
1812 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16 16
1813 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16 17
1814 #define CIK__GB_TILE_MODE__TILE_SPLIT(x) (((x) >> 11) & 0x7)
1815 #define CIK__TILE_SPLIT__64B 0
1816 #define CIK__TILE_SPLIT__128B 1
1817 #define CIK__TILE_SPLIT__256B 2
1818 #define CIK__TILE_SPLIT__512B 3
1819 #define CIK__TILE_SPLIT__1024B 4
1820 #define CIK__TILE_SPLIT__2048B 5
1821 #define CIK__TILE_SPLIT__4096B 6
1822 #define CIK__GB_TILE_MODE__SAMPLE_SPLIT(x) (((x) >> 25) & 0x3)
1823 #define CIK__SAMPLE_SPLIT__1 0
1824 #define CIK__SAMPLE_SPLIT__2 1
1825 #define CIK__SAMPLE_SPLIT__4 2
1826 #define CIK__SAMPLE_SPLIT__8 3
1827 #define CIK__GB_MACROTILE_MODE__BANK_WIDTH(x) ((x) & 0x3)
1828 #define CIK__BANK_WIDTH__1 0
1829 #define CIK__BANK_WIDTH__2 1
1830 #define CIK__BANK_WIDTH__4 2
1831 #define CIK__BANK_WIDTH__8 3
1832 #define CIK__GB_MACROTILE_MODE__BANK_HEIGHT(x) (((x) >> 2) & 0x3)
1833 #define CIK__BANK_HEIGHT__1 0
1834 #define CIK__BANK_HEIGHT__2 1
1835 #define CIK__BANK_HEIGHT__4 2
1836 #define CIK__BANK_HEIGHT__8 3
1837 #define CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 4) & 0x3)
1838 #define CIK__MACRO_TILE_ASPECT__1 0
1839 #define CIK__MACRO_TILE_ASPECT__2 1
1840 #define CIK__MACRO_TILE_ASPECT__4 2
1841 #define CIK__MACRO_TILE_ASPECT__8 3
1842 #define CIK__GB_MACROTILE_MODE__NUM_BANKS(x) (((x) >> 6) & 0x3)
1843 #define CIK__NUM_BANKS__2_BANK 0
1844 #define CIK__NUM_BANKS__4_BANK 1
1845 #define CIK__NUM_BANKS__8_BANK 2
1846 #define CIK__NUM_BANKS__16_BANK 3
1849 static void cik_get_2d_params(struct radeon_surface_manager *surf_man,
1850 unsigned bpe, unsigned nsamples, bool is_color,
1852 uint32_t *num_pipes,
1853 uint32_t *tile_split_ptr,
1854 uint32_t *num_banks,
1855 uint32_t *macro_tile_aspect,
1859 uint32_t gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1860 unsigned tileb_1x, tileb;
1861 unsigned gb_macrotile_mode;
1862 unsigned macrotile_index;
1863 unsigned tile_split, sample_split;
1866 switch (CIK__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1867 case CIK__PIPE_CONFIG__ADDR_SURF_P2:
1871 case CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1872 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1873 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1874 case CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1877 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1878 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1879 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1880 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1881 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1882 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1883 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1886 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16:
1887 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16:
1892 switch (CIK__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1894 case CIK__TILE_SPLIT__64B:
1897 case CIK__TILE_SPLIT__128B:
1900 case CIK__TILE_SPLIT__256B:
1903 case CIK__TILE_SPLIT__512B:
1906 case CIK__TILE_SPLIT__1024B:
1909 case CIK__TILE_SPLIT__2048B:
1912 case CIK__TILE_SPLIT__4096B:
1916 switch (CIK__GB_TILE_MODE__SAMPLE_SPLIT(gb_tile_mode)) {
1918 case CIK__SAMPLE_SPLIT__1:
1921 case CIK__SAMPLE_SPLIT__2:
1924 case CIK__SAMPLE_SPLIT__4:
1927 case CIK__SAMPLE_SPLIT__8:
1932 /* Adjust the tile split. */
1933 tileb_1x = 8 * 8 * bpe;
1935 tile_split = MAX2(256, sample_split * tileb_1x);
1937 tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
1939 /* Determine the macrotile index. */
1940 tileb = MIN2(tile_split, nsamples * tileb_1x);
1942 for (macrotile_index = 0; tileb > 64; macrotile_index++) {
1945 gb_macrotile_mode = surf_man->hw_info.macrotile_mode_array[macrotile_index];
1947 if (tile_split_ptr) {
1948 *tile_split_ptr = tile_split;
1951 switch (CIK__GB_MACROTILE_MODE__NUM_BANKS(gb_macrotile_mode)) {
1953 case CIK__NUM_BANKS__2_BANK:
1956 case CIK__NUM_BANKS__4_BANK:
1959 case CIK__NUM_BANKS__8_BANK:
1962 case CIK__NUM_BANKS__16_BANK:
1967 if (macro_tile_aspect) {
1968 switch (CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(gb_macrotile_mode)) {
1970 case CIK__MACRO_TILE_ASPECT__1:
1971 *macro_tile_aspect = 1;
1973 case CIK__MACRO_TILE_ASPECT__2:
1974 *macro_tile_aspect = 2;
1976 case CIK__MACRO_TILE_ASPECT__4:
1977 *macro_tile_aspect = 4;
1979 case CIK__MACRO_TILE_ASPECT__8:
1980 *macro_tile_aspect = 8;
1985 switch (CIK__GB_MACROTILE_MODE__BANK_WIDTH(gb_macrotile_mode)) {
1987 case CIK__BANK_WIDTH__1:
1990 case CIK__BANK_WIDTH__2:
1993 case CIK__BANK_WIDTH__4:
1996 case CIK__BANK_WIDTH__8:
2002 switch (CIK__GB_MACROTILE_MODE__BANK_HEIGHT(gb_macrotile_mode)) {
2004 case CIK__BANK_HEIGHT__1:
2007 case CIK__BANK_HEIGHT__2:
2010 case CIK__BANK_HEIGHT__4:
2013 case CIK__BANK_HEIGHT__8:
2020 static int cik_init_hw_info(struct radeon_surface_manager *surf_man)
2022 uint32_t tiling_config;
2023 drmVersionPtr version;
2026 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
2032 surf_man->hw_info.allow_2d = 0;
2033 version = drmGetVersion(surf_man->fd);
2034 if (version && version->version_minor >= 35) {
2035 if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array) &&
2036 !radeon_get_value(surf_man->fd, RADEON_INFO_CIK_MACROTILE_MODE_ARRAY, surf_man->hw_info.macrotile_mode_array)) {
2037 surf_man->hw_info.allow_2d = 1;
2040 drmFreeVersion(version);
2042 switch (tiling_config & 0xf) {
2044 surf_man->hw_info.num_pipes = 1;
2047 surf_man->hw_info.num_pipes = 2;
2050 surf_man->hw_info.num_pipes = 4;
2053 surf_man->hw_info.num_pipes = 8;
2056 surf_man->hw_info.num_pipes = 8;
2057 surf_man->hw_info.allow_2d = 0;
2061 switch ((tiling_config & 0xf0) >> 4) {
2063 surf_man->hw_info.num_banks = 4;
2066 surf_man->hw_info.num_banks = 8;
2069 surf_man->hw_info.num_banks = 16;
2072 surf_man->hw_info.num_banks = 8;
2073 surf_man->hw_info.allow_2d = 0;
2077 switch ((tiling_config & 0xf00) >> 8) {
2079 surf_man->hw_info.group_bytes = 256;
2082 surf_man->hw_info.group_bytes = 512;
2085 surf_man->hw_info.group_bytes = 256;
2086 surf_man->hw_info.allow_2d = 0;
2090 switch ((tiling_config & 0xf000) >> 12) {
2092 surf_man->hw_info.row_size = 1024;
2095 surf_man->hw_info.row_size = 2048;
2098 surf_man->hw_info.row_size = 4096;
2101 surf_man->hw_info.row_size = 4096;
2102 surf_man->hw_info.allow_2d = 0;
2108 static int cik_surface_sanity(struct radeon_surface_manager *surf_man,
2109 struct radeon_surface *surf,
2110 unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
2112 /* check surface dimension */
2113 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
2117 /* check mipmap last_level */
2118 if (surf->last_level > 15) {
2122 /* force 1d on kernel that can't do 2d */
2123 if (mode > RADEON_SURF_MODE_1D &&
2124 (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
2125 if (surf->nsamples > 1) {
2126 fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
2129 mode = RADEON_SURF_MODE_1D;
2130 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2131 surf->flags |= RADEON_SURF_SET(mode, MODE);
2134 if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
2138 if (!surf->tile_split) {
2143 surf->tile_split = 64;
2144 surf->stencil_tile_split = 64;
2148 case RADEON_SURF_MODE_2D: {
2149 if (surf->flags & RADEON_SURF_Z_OR_SBUFFER) {
2150 switch (surf->nsamples) {
2152 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64;
2156 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128;
2159 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256;
2165 if (surf->flags & RADEON_SURF_SBUFFER) {
2166 *stencil_tile_mode = *tile_mode;
2168 cik_get_2d_params(surf_man, 1, surf->nsamples, false,
2169 *stencil_tile_mode, NULL,
2170 &surf->stencil_tile_split,
2171 NULL, NULL, NULL, NULL);
2173 } else if (surf->flags & RADEON_SURF_SCANOUT) {
2174 *tile_mode = CIK_TILE_MODE_COLOR_2D_SCANOUT;
2176 *tile_mode = CIK_TILE_MODE_COLOR_2D;
2179 /* retrieve tiling mode values */
2180 cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
2181 !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), *tile_mode,
2182 NULL, &surf->tile_split, NULL, &surf->mtilea,
2183 &surf->bankw, &surf->bankh);
2186 case RADEON_SURF_MODE_1D:
2187 if (surf->flags & RADEON_SURF_SBUFFER) {
2188 *stencil_tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2190 if (surf->flags & RADEON_SURF_ZBUFFER) {
2191 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2192 } else if (surf->flags & RADEON_SURF_SCANOUT) {
2193 *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2195 *tile_mode = SI_TILE_MODE_COLOR_1D;
2198 case RADEON_SURF_MODE_LINEAR_ALIGNED:
2200 *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
2206 static int cik_surface_init_2d(struct radeon_surface_manager *surf_man,
2207 struct radeon_surface *surf,
2208 struct radeon_surface_level *level,
2209 unsigned bpe, unsigned tile_mode,
2210 unsigned tile_split,
2211 unsigned num_pipes, unsigned num_banks,
2213 unsigned start_level)
2215 uint64_t aligned_offset = offset;
2216 unsigned tilew, tileh, tileb_1x, tileb;
2217 unsigned mtilew, mtileh, mtileb;
2221 /* compute tile values */
2224 tileb_1x = tilew * tileh * bpe;
2226 tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
2228 tileb = surf->nsamples * tileb_1x;
2230 /* slices per tile */
2232 if (tileb > tile_split && tile_split) {
2233 slice_pt = tileb / tile_split;
2234 tileb = tileb / slice_pt;
2237 /* macro tile width & height */
2238 mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
2239 mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
2241 /* macro tile bytes */
2242 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
2244 if (start_level <= 1) {
2245 unsigned alignment = MAX2(256, mtileb);
2246 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
2248 if (aligned_offset) {
2249 aligned_offset = ALIGN(aligned_offset, alignment);
2253 /* build mipmap tree */
2254 for (i = start_level; i <= surf->last_level; i++) {
2255 level[i].mode = RADEON_SURF_MODE_2D;
2256 si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
2257 if (level[i].mode == RADEON_SURF_MODE_1D) {
2258 switch (tile_mode) {
2259 case CIK_TILE_MODE_COLOR_2D:
2260 tile_mode = SI_TILE_MODE_COLOR_1D;
2262 case CIK_TILE_MODE_COLOR_2D_SCANOUT:
2263 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2265 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64:
2266 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128:
2267 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256:
2268 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512:
2269 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE:
2270 tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2275 return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
2277 /* level0 and first mipmap need to have alignment */
2278 aligned_offset = offset = surf->bo_size;
2280 aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
2282 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
2283 if (surf->level == level) {
2284 surf->tiling_index[i] = tile_mode;
2285 /* it's ok because stencil is done after */
2286 surf->stencil_tiling_index[i] = tile_mode;
2288 surf->stencil_tiling_index[i] = tile_mode;
2295 static int cik_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
2296 struct radeon_surface *surf,
2297 unsigned tile_mode, unsigned stencil_tile_mode)
2300 uint32_t num_pipes, num_banks;
2302 cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
2303 !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), tile_mode,
2304 &num_pipes, NULL, &num_banks, NULL, NULL, NULL);
2306 r = cik_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode,
2307 surf->tile_split, num_pipes, num_banks, 0, 0);
2312 if (surf->flags & RADEON_SURF_SBUFFER) {
2313 r = cik_surface_init_2d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode,
2314 surf->stencil_tile_split, num_pipes, num_banks,
2316 surf->stencil_offset = surf->stencil_level[0].offset;
2321 static int cik_surface_init(struct radeon_surface_manager *surf_man,
2322 struct radeon_surface *surf)
2324 unsigned mode, tile_mode, stencil_tile_mode;
2327 /* MSAA surfaces support the 2D mode only. */
2328 if (surf->nsamples > 1) {
2329 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2330 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
2334 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2336 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
2337 /* zbuffer only support 1D or 2D tiled surface */
2339 case RADEON_SURF_MODE_1D:
2340 case RADEON_SURF_MODE_2D:
2343 mode = RADEON_SURF_MODE_1D;
2344 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2345 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2350 r = cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2355 surf->stencil_offset = 0;
2356 surf->bo_alignment = 0;
2358 /* check tiling mode */
2360 case RADEON_SURF_MODE_LINEAR:
2361 r = r6_surface_init_linear(surf_man, surf, 0, 0);
2363 case RADEON_SURF_MODE_LINEAR_ALIGNED:
2364 r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
2366 case RADEON_SURF_MODE_1D:
2367 r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2369 case RADEON_SURF_MODE_2D:
2370 r = cik_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2379 * depending on surface
2381 static int cik_surface_best(struct radeon_surface_manager *surf_man,
2382 struct radeon_surface *surf)
2384 unsigned mode, tile_mode, stencil_tile_mode;
2387 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2389 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
2390 !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
2391 /* depth/stencil force 1d tiling for old mesa */
2392 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2393 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2396 return cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2400 /* ===========================================================================
2403 drm_public struct radeon_surface_manager *
2404 radeon_surface_manager_new(int fd)
2406 struct radeon_surface_manager *surf_man;
2408 surf_man = calloc(1, sizeof(struct radeon_surface_manager));
2409 if (surf_man == NULL) {
2413 if (radeon_get_value(fd, RADEON_INFO_DEVICE_ID, &surf_man->device_id)) {
2416 if (radeon_get_family(surf_man)) {
2420 if (surf_man->family <= CHIP_RV740) {
2421 if (r6_init_hw_info(surf_man)) {
2424 surf_man->surface_init = &r6_surface_init;
2425 surf_man->surface_best = &r6_surface_best;
2426 } else if (surf_man->family <= CHIP_ARUBA) {
2427 if (eg_init_hw_info(surf_man)) {
2430 surf_man->surface_init = &eg_surface_init;
2431 surf_man->surface_best = &eg_surface_best;
2432 } else if (surf_man->family < CHIP_BONAIRE) {
2433 if (si_init_hw_info(surf_man)) {
2436 surf_man->surface_init = &si_surface_init;
2437 surf_man->surface_best = &si_surface_best;
2439 if (cik_init_hw_info(surf_man)) {
2442 surf_man->surface_init = &cik_surface_init;
2443 surf_man->surface_best = &cik_surface_best;
2453 radeon_surface_manager_free(struct radeon_surface_manager *surf_man)
2458 static int radeon_surface_sanity(struct radeon_surface_manager *surf_man,
2459 struct radeon_surface *surf,
2463 if (surf_man == NULL || surf_man->surface_init == NULL || surf == NULL) {
2467 /* all dimension must be at least 1 ! */
2468 if (!surf->npix_x || !surf->npix_y || !surf->npix_z) {
2471 if (!surf->blk_w || !surf->blk_h || !surf->blk_d) {
2474 if (!surf->array_size) {
2477 /* array size must be a power of 2 */
2478 surf->array_size = next_power_of_two(surf->array_size);
2480 switch (surf->nsamples) {
2491 case RADEON_SURF_TYPE_1D:
2492 if (surf->npix_y > 1) {
2495 case RADEON_SURF_TYPE_2D:
2496 if (surf->npix_z > 1) {
2500 case RADEON_SURF_TYPE_CUBEMAP:
2501 if (surf->npix_z > 1) {
2504 /* deal with cubemap as they were texture array */
2505 if (surf_man->family >= CHIP_RV770) {
2506 surf->array_size = 8;
2508 surf->array_size = 6;
2511 case RADEON_SURF_TYPE_3D:
2513 case RADEON_SURF_TYPE_1D_ARRAY:
2514 if (surf->npix_y > 1) {
2517 case RADEON_SURF_TYPE_2D_ARRAY:
2526 radeon_surface_init(struct radeon_surface_manager *surf_man,
2527 struct radeon_surface *surf)
2529 unsigned mode, type;
2532 type = RADEON_SURF_GET(surf->flags, TYPE);
2533 mode = RADEON_SURF_GET(surf->flags, MODE);
2535 r = radeon_surface_sanity(surf_man, surf, type, mode);
2539 return surf_man->surface_init(surf_man, surf);
2543 radeon_surface_best(struct radeon_surface_manager *surf_man,
2544 struct radeon_surface *surf)
2546 unsigned mode, type;
2549 type = RADEON_SURF_GET(surf->flags, TYPE);
2550 mode = RADEON_SURF_GET(surf->flags, MODE);
2552 r = radeon_surface_sanity(surf_man, surf, type, mode);
2556 return surf_man->surface_best(surf_man, surf);