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 = (uint64_t)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 = (uint64_t)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 * SAMPLE_SPLIT = tile_split / (bpe * 64), the optimal value is 2
963 surf->tile_split = MAX2(2 * surf->bpe * 64, 256);
964 if (surf->tile_split > 4096)
965 surf->tile_split = 4096;
968 /* set tile split to row size */
969 surf->tile_split = surf_man->hw_info.row_size;
970 surf->stencil_tile_split = surf_man->hw_info.row_size / 2;
973 /* bankw or bankh greater than 1 increase alignment requirement, not
974 * sure if it's worth using smaller bankw & bankh to stick with 2D
975 * tiling on small surface rather than falling back to 1D tiling.
976 * Use recommanded value based on tile size for now.
978 * fmask buffer has different optimal value figure them out once we
981 if (surf->flags & RADEON_SURF_SBUFFER) {
982 /* assume 1 bytes for stencil, we optimize for stencil as stencil
983 * and depth shares surface values
985 tileb = MIN2(surf->tile_split, 64 * surf->nsamples);
987 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
990 /* use bankw of 1 to minimize width alignment, might be interesting to
991 * increase it for large surface
1006 /* double check the constraint */
1007 for (; surf->bankh <= 8; surf->bankh *= 2) {
1008 if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
1013 h_over_w = (((surf->bankh * surf_man->hw_info.num_banks) << 16) /
1014 (surf->bankw * surf_man->hw_info.num_pipes)) >> 16;
1015 surf->mtilea = 1 << (log2_int(h_over_w) >> 1);
1021 /* ===========================================================================
1022 * Southern Islands family
1024 #define SI__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f)
1025 #define SI__PIPE_CONFIG__ADDR_SURF_P2 0
1026 #define SI__PIPE_CONFIG__ADDR_SURF_P4_8x16 4
1027 #define SI__PIPE_CONFIG__ADDR_SURF_P4_16x16 5
1028 #define SI__PIPE_CONFIG__ADDR_SURF_P4_16x32 6
1029 #define SI__PIPE_CONFIG__ADDR_SURF_P4_32x32 7
1030 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8
1031 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9
1032 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10
1033 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11
1034 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12
1035 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13
1036 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14
1037 #define SI__GB_TILE_MODE__TILE_SPLIT(x) (((x) >> 11) & 0x7)
1038 #define SI__TILE_SPLIT__64B 0
1039 #define SI__TILE_SPLIT__128B 1
1040 #define SI__TILE_SPLIT__256B 2
1041 #define SI__TILE_SPLIT__512B 3
1042 #define SI__TILE_SPLIT__1024B 4
1043 #define SI__TILE_SPLIT__2048B 5
1044 #define SI__TILE_SPLIT__4096B 6
1045 #define SI__GB_TILE_MODE__BANK_WIDTH(x) (((x) >> 14) & 0x3)
1046 #define SI__BANK_WIDTH__1 0
1047 #define SI__BANK_WIDTH__2 1
1048 #define SI__BANK_WIDTH__4 2
1049 #define SI__BANK_WIDTH__8 3
1050 #define SI__GB_TILE_MODE__BANK_HEIGHT(x) (((x) >> 16) & 0x3)
1051 #define SI__BANK_HEIGHT__1 0
1052 #define SI__BANK_HEIGHT__2 1
1053 #define SI__BANK_HEIGHT__4 2
1054 #define SI__BANK_HEIGHT__8 3
1055 #define SI__GB_TILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 18) & 0x3)
1056 #define SI__MACRO_TILE_ASPECT__1 0
1057 #define SI__MACRO_TILE_ASPECT__2 1
1058 #define SI__MACRO_TILE_ASPECT__4 2
1059 #define SI__MACRO_TILE_ASPECT__8 3
1060 #define SI__GB_TILE_MODE__NUM_BANKS(x) (((x) >> 20) & 0x3)
1061 #define SI__NUM_BANKS__2_BANK 0
1062 #define SI__NUM_BANKS__4_BANK 1
1063 #define SI__NUM_BANKS__8_BANK 2
1064 #define SI__NUM_BANKS__16_BANK 3
1067 static void si_gb_tile_mode(uint32_t gb_tile_mode,
1068 unsigned *num_pipes,
1069 unsigned *num_banks,
1070 uint32_t *macro_tile_aspect,
1073 uint32_t *tile_split)
1076 switch (SI__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1077 case SI__PIPE_CONFIG__ADDR_SURF_P2:
1081 case SI__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1082 case SI__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1083 case SI__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1084 case SI__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1087 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1088 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1089 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1090 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1091 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1092 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1093 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1099 switch (SI__GB_TILE_MODE__NUM_BANKS(gb_tile_mode)) {
1101 case SI__NUM_BANKS__2_BANK:
1104 case SI__NUM_BANKS__4_BANK:
1107 case SI__NUM_BANKS__8_BANK:
1110 case SI__NUM_BANKS__16_BANK:
1115 if (macro_tile_aspect) {
1116 switch (SI__GB_TILE_MODE__MACRO_TILE_ASPECT(gb_tile_mode)) {
1118 case SI__MACRO_TILE_ASPECT__1:
1119 *macro_tile_aspect = 1;
1121 case SI__MACRO_TILE_ASPECT__2:
1122 *macro_tile_aspect = 2;
1124 case SI__MACRO_TILE_ASPECT__4:
1125 *macro_tile_aspect = 4;
1127 case SI__MACRO_TILE_ASPECT__8:
1128 *macro_tile_aspect = 8;
1133 switch (SI__GB_TILE_MODE__BANK_WIDTH(gb_tile_mode)) {
1135 case SI__BANK_WIDTH__1:
1138 case SI__BANK_WIDTH__2:
1141 case SI__BANK_WIDTH__4:
1144 case SI__BANK_WIDTH__8:
1150 switch (SI__GB_TILE_MODE__BANK_HEIGHT(gb_tile_mode)) {
1152 case SI__BANK_HEIGHT__1:
1155 case SI__BANK_HEIGHT__2:
1158 case SI__BANK_HEIGHT__4:
1161 case SI__BANK_HEIGHT__8:
1167 switch (SI__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1169 case SI__TILE_SPLIT__64B:
1172 case SI__TILE_SPLIT__128B:
1175 case SI__TILE_SPLIT__256B:
1178 case SI__TILE_SPLIT__512B:
1181 case SI__TILE_SPLIT__1024B:
1184 case SI__TILE_SPLIT__2048B:
1187 case SI__TILE_SPLIT__4096B:
1194 static int si_init_hw_info(struct radeon_surface_manager *surf_man)
1196 uint32_t tiling_config;
1197 drmVersionPtr version;
1200 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
1206 surf_man->hw_info.allow_2d = 0;
1207 version = drmGetVersion(surf_man->fd);
1208 if (version && version->version_minor >= 33) {
1209 if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array)) {
1210 surf_man->hw_info.allow_2d = 1;
1213 drmFreeVersion(version);
1215 switch (tiling_config & 0xf) {
1217 surf_man->hw_info.num_pipes = 1;
1220 surf_man->hw_info.num_pipes = 2;
1223 surf_man->hw_info.num_pipes = 4;
1226 surf_man->hw_info.num_pipes = 8;
1229 surf_man->hw_info.num_pipes = 8;
1230 surf_man->hw_info.allow_2d = 0;
1234 switch ((tiling_config & 0xf0) >> 4) {
1236 surf_man->hw_info.num_banks = 4;
1239 surf_man->hw_info.num_banks = 8;
1242 surf_man->hw_info.num_banks = 16;
1245 surf_man->hw_info.num_banks = 8;
1246 surf_man->hw_info.allow_2d = 0;
1250 switch ((tiling_config & 0xf00) >> 8) {
1252 surf_man->hw_info.group_bytes = 256;
1255 surf_man->hw_info.group_bytes = 512;
1258 surf_man->hw_info.group_bytes = 256;
1259 surf_man->hw_info.allow_2d = 0;
1263 switch ((tiling_config & 0xf000) >> 12) {
1265 surf_man->hw_info.row_size = 1024;
1268 surf_man->hw_info.row_size = 2048;
1271 surf_man->hw_info.row_size = 4096;
1274 surf_man->hw_info.row_size = 4096;
1275 surf_man->hw_info.allow_2d = 0;
1281 static int si_surface_sanity(struct radeon_surface_manager *surf_man,
1282 struct radeon_surface *surf,
1283 unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
1285 uint32_t gb_tile_mode;
1287 /* check surface dimension */
1288 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
1292 /* check mipmap last_level */
1293 if (surf->last_level > 15) {
1297 /* force 1d on kernel that can't do 2d */
1298 if (mode > RADEON_SURF_MODE_1D &&
1299 (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
1300 if (surf->nsamples > 1) {
1301 fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
1304 mode = RADEON_SURF_MODE_1D;
1305 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1306 surf->flags |= RADEON_SURF_SET(mode, MODE);
1309 if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
1313 if (!surf->tile_split) {
1318 surf->tile_split = 64;
1319 surf->stencil_tile_split = 64;
1323 case RADEON_SURF_MODE_2D:
1324 if (surf->flags & RADEON_SURF_SBUFFER) {
1325 switch (surf->nsamples) {
1327 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1330 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1333 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1336 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1341 /* retrieve tiling mode value */
1342 gb_tile_mode = surf_man->hw_info.tile_mode_array[*stencil_tile_mode];
1343 si_gb_tile_mode(gb_tile_mode, NULL, NULL, NULL, NULL, NULL, &surf->stencil_tile_split);
1345 if (surf->flags & RADEON_SURF_ZBUFFER) {
1346 switch (surf->nsamples) {
1348 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1351 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1354 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1357 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1362 } else if (surf->flags & RADEON_SURF_SCANOUT) {
1363 switch (surf->bpe) {
1365 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
1368 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
1374 switch (surf->bpe) {
1376 *tile_mode = SI_TILE_MODE_COLOR_2D_8BPP;
1379 *tile_mode = SI_TILE_MODE_COLOR_2D_16BPP;
1382 *tile_mode = SI_TILE_MODE_COLOR_2D_32BPP;
1386 *tile_mode = SI_TILE_MODE_COLOR_2D_64BPP;
1392 /* retrieve tiling mode value */
1393 gb_tile_mode = surf_man->hw_info.tile_mode_array[*tile_mode];
1394 si_gb_tile_mode(gb_tile_mode, NULL, NULL, &surf->mtilea, &surf->bankw, &surf->bankh, &surf->tile_split);
1396 case RADEON_SURF_MODE_1D:
1397 if (surf->flags & RADEON_SURF_SBUFFER) {
1398 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1400 if (surf->flags & RADEON_SURF_ZBUFFER) {
1401 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1402 } else if (surf->flags & RADEON_SURF_SCANOUT) {
1403 *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1405 *tile_mode = SI_TILE_MODE_COLOR_1D;
1408 case RADEON_SURF_MODE_LINEAR_ALIGNED:
1410 *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
1416 static void si_surf_minify(struct radeon_surface *surf,
1417 struct radeon_surface_level *surflevel,
1418 unsigned bpe, unsigned level,
1419 uint32_t xalign, uint32_t yalign, uint32_t zalign,
1420 uint32_t slice_align, uint64_t offset)
1423 surflevel->npix_x = surf->npix_x;
1425 surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1427 surflevel->npix_y = mip_minify(surf->npix_y, level);
1428 surflevel->npix_z = mip_minify(surf->npix_z, level);
1430 if (level == 0 && surf->last_level > 0) {
1431 surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1432 surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1433 surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1435 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1436 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1437 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1440 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign);
1442 /* XXX: Texture sampling uses unexpectedly large pitches in some cases,
1443 * these are just guesses for the rules behind those
1445 if (level == 0 && surf->last_level == 0)
1446 /* Non-mipmap pitch padded to slice alignment */
1447 /* Using just bpe here breaks stencil blitting; surf->bpe works. */
1448 xalign = MAX2(xalign, slice_align / surf->bpe);
1449 else if (surflevel->mode == RADEON_SURF_MODE_LINEAR_ALIGNED)
1450 /* Small rows evenly distributed across slice */
1451 xalign = MAX2(xalign, slice_align / bpe / surflevel->nblk_y);
1453 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign);
1454 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign);
1456 surflevel->offset = offset;
1457 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
1458 surflevel->slice_size = ALIGN((uint64_t)surflevel->pitch_bytes * surflevel->nblk_y,
1459 (uint64_t)slice_align);
1461 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1464 static void si_surf_minify_2d(struct radeon_surface *surf,
1465 struct radeon_surface_level *surflevel,
1466 unsigned bpe, unsigned level, unsigned slice_pt,
1467 uint32_t xalign, uint32_t yalign, uint32_t zalign,
1468 unsigned mtileb, uint64_t offset)
1470 unsigned mtile_pr, mtile_ps;
1473 surflevel->npix_x = surf->npix_x;
1475 surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1477 surflevel->npix_y = mip_minify(surf->npix_y, level);
1478 surflevel->npix_z = mip_minify(surf->npix_z, level);
1480 if (level == 0 && surf->last_level > 0) {
1481 surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1482 surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1483 surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1485 surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1486 surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1487 surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1490 if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
1491 !(surf->flags & RADEON_SURF_FMASK)) {
1492 if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
1493 surflevel->mode = RADEON_SURF_MODE_1D;
1497 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign);
1498 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign);
1499 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign);
1501 /* macro tile per row */
1502 mtile_pr = surflevel->nblk_x / xalign;
1503 /* macro tile per slice */
1504 mtile_ps = (mtile_pr * surflevel->nblk_y) / yalign;
1505 surflevel->offset = offset;
1506 surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
1507 surflevel->slice_size = (uint64_t)mtile_ps * mtileb * slice_pt;
1509 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1512 static int si_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
1513 struct radeon_surface *surf,
1515 uint64_t offset, unsigned start_level)
1517 uint32_t xalign, yalign, zalign, slice_align;
1520 /* compute alignment */
1522 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
1524 xalign = MAX2(8, 64 / surf->bpe);
1527 slice_align = MAX2(64 * surf->bpe, surf_man->hw_info.group_bytes);
1529 /* build mipmap tree */
1530 for (i = start_level; i <= surf->last_level; i++) {
1531 surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
1532 si_surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, slice_align, offset);
1533 /* level0 and first mipmap need to have alignment */
1534 offset = surf->bo_size;
1536 offset = ALIGN(offset, surf->bo_alignment);
1538 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1539 surf->tiling_index[i] = tile_mode;
1545 static int si_surface_init_1d(struct radeon_surface_manager *surf_man,
1546 struct radeon_surface *surf,
1547 struct radeon_surface_level *level,
1548 unsigned bpe, unsigned tile_mode,
1549 uint64_t offset, unsigned start_level)
1551 uint32_t xalign, yalign, zalign, slice_align;
1552 unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
1555 /* compute alignment */
1559 slice_align = surf_man->hw_info.group_bytes;
1560 if (surf->flags & RADEON_SURF_SCANOUT) {
1561 xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
1564 if (start_level <= 1) {
1565 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1568 offset = ALIGN(offset, alignment);
1572 /* build mipmap tree */
1573 for (i = start_level; i <= surf->last_level; i++) {
1574 level[i].mode = RADEON_SURF_MODE_1D;
1575 si_surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, slice_align, offset);
1576 /* level0 and first mipmap need to have alignment */
1577 offset = surf->bo_size;
1579 offset = ALIGN(offset, alignment);
1581 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1582 if (surf->level == level) {
1583 surf->tiling_index[i] = tile_mode;
1584 /* it's ok because stencil is done after */
1585 surf->stencil_tiling_index[i] = tile_mode;
1587 surf->stencil_tiling_index[i] = tile_mode;
1594 static int si_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
1595 struct radeon_surface *surf,
1596 unsigned tile_mode, unsigned stencil_tile_mode)
1600 r = si_surface_init_1d(surf_man, surf, surf->level, surf->bpe, tile_mode, 0, 0);
1605 if (surf->flags & RADEON_SURF_SBUFFER) {
1606 r = si_surface_init_1d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode, surf->bo_size, 0);
1607 surf->stencil_offset = surf->stencil_level[0].offset;
1612 static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
1613 struct radeon_surface *surf,
1614 struct radeon_surface_level *level,
1615 unsigned bpe, unsigned tile_mode,
1616 unsigned num_pipes, unsigned num_banks,
1617 unsigned tile_split,
1619 unsigned start_level)
1621 uint64_t aligned_offset = offset;
1622 unsigned tilew, tileh, tileb;
1623 unsigned mtilew, mtileh, mtileb;
1627 /* compute tile values */
1630 tileb = tilew * tileh * bpe * surf->nsamples;
1631 /* slices per tile */
1633 if (tileb > tile_split && tile_split) {
1634 slice_pt = tileb / tile_split;
1636 tileb = tileb / slice_pt;
1638 /* macro tile width & height */
1639 mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
1640 mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
1642 /* macro tile bytes */
1643 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
1645 if (start_level <= 1) {
1646 unsigned alignment = MAX2(256, mtileb);
1647 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1649 if (aligned_offset) {
1650 aligned_offset = ALIGN(aligned_offset, alignment);
1654 /* build mipmap tree */
1655 for (i = start_level; i <= surf->last_level; i++) {
1656 level[i].mode = RADEON_SURF_MODE_2D;
1657 si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
1658 if (level[i].mode == RADEON_SURF_MODE_1D) {
1659 switch (tile_mode) {
1660 case SI_TILE_MODE_COLOR_2D_8BPP:
1661 case SI_TILE_MODE_COLOR_2D_16BPP:
1662 case SI_TILE_MODE_COLOR_2D_32BPP:
1663 case SI_TILE_MODE_COLOR_2D_64BPP:
1664 tile_mode = SI_TILE_MODE_COLOR_1D;
1666 case SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP:
1667 case SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP:
1668 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1670 case SI_TILE_MODE_DEPTH_STENCIL_2D:
1671 tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1676 return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
1678 /* level0 and first mipmap need to have alignment */
1679 aligned_offset = offset = surf->bo_size;
1681 aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
1683 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1684 if (surf->level == level) {
1685 surf->tiling_index[i] = tile_mode;
1686 /* it's ok because stencil is done after */
1687 surf->stencil_tiling_index[i] = tile_mode;
1689 surf->stencil_tiling_index[i] = tile_mode;
1696 static int si_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
1697 struct radeon_surface *surf,
1698 unsigned tile_mode, unsigned stencil_tile_mode)
1700 unsigned num_pipes, num_banks;
1701 uint32_t gb_tile_mode;
1704 /* retrieve tiling mode value */
1705 gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1706 si_gb_tile_mode(gb_tile_mode, &num_pipes, &num_banks, NULL, NULL, NULL, NULL);
1708 r = si_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode, num_pipes, num_banks, surf->tile_split, 0, 0);
1713 if (surf->flags & RADEON_SURF_SBUFFER) {
1714 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);
1715 surf->stencil_offset = surf->stencil_level[0].offset;
1720 static int si_surface_init(struct radeon_surface_manager *surf_man,
1721 struct radeon_surface *surf)
1723 unsigned mode, tile_mode, stencil_tile_mode;
1726 /* MSAA surfaces support the 2D mode only. */
1727 if (surf->nsamples > 1) {
1728 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1729 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
1733 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1735 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
1736 /* zbuffer only support 1D or 2D tiled surface */
1738 case RADEON_SURF_MODE_1D:
1739 case RADEON_SURF_MODE_2D:
1742 mode = RADEON_SURF_MODE_1D;
1743 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1744 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1749 r = si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1754 surf->stencil_offset = 0;
1755 surf->bo_alignment = 0;
1757 /* check tiling mode */
1759 case RADEON_SURF_MODE_LINEAR:
1760 r = r6_surface_init_linear(surf_man, surf, 0, 0);
1762 case RADEON_SURF_MODE_LINEAR_ALIGNED:
1763 r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
1765 case RADEON_SURF_MODE_1D:
1766 r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1768 case RADEON_SURF_MODE_2D:
1769 r = si_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1778 * depending on surface
1780 static int si_surface_best(struct radeon_surface_manager *surf_man,
1781 struct radeon_surface *surf)
1783 unsigned mode, tile_mode, stencil_tile_mode;
1786 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1788 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
1789 !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
1790 /* depth/stencil force 1d tiling for old mesa */
1791 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1792 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1795 return si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1799 /* ===========================================================================
1800 * Sea Islands family
1802 #define CIK__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f)
1803 #define CIK__PIPE_CONFIG__ADDR_SURF_P2 0
1804 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16 4
1805 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16 5
1806 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32 6
1807 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32 7
1808 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8
1809 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9
1810 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10
1811 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11
1812 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12
1813 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13
1814 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14
1815 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16 16
1816 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16 17
1817 #define CIK__GB_TILE_MODE__TILE_SPLIT(x) (((x) >> 11) & 0x7)
1818 #define CIK__TILE_SPLIT__64B 0
1819 #define CIK__TILE_SPLIT__128B 1
1820 #define CIK__TILE_SPLIT__256B 2
1821 #define CIK__TILE_SPLIT__512B 3
1822 #define CIK__TILE_SPLIT__1024B 4
1823 #define CIK__TILE_SPLIT__2048B 5
1824 #define CIK__TILE_SPLIT__4096B 6
1825 #define CIK__GB_TILE_MODE__SAMPLE_SPLIT(x) (((x) >> 25) & 0x3)
1826 #define CIK__SAMPLE_SPLIT__1 0
1827 #define CIK__SAMPLE_SPLIT__2 1
1828 #define CIK__SAMPLE_SPLIT__4 2
1829 #define CIK__SAMPLE_SPLIT__8 3
1830 #define CIK__GB_MACROTILE_MODE__BANK_WIDTH(x) ((x) & 0x3)
1831 #define CIK__BANK_WIDTH__1 0
1832 #define CIK__BANK_WIDTH__2 1
1833 #define CIK__BANK_WIDTH__4 2
1834 #define CIK__BANK_WIDTH__8 3
1835 #define CIK__GB_MACROTILE_MODE__BANK_HEIGHT(x) (((x) >> 2) & 0x3)
1836 #define CIK__BANK_HEIGHT__1 0
1837 #define CIK__BANK_HEIGHT__2 1
1838 #define CIK__BANK_HEIGHT__4 2
1839 #define CIK__BANK_HEIGHT__8 3
1840 #define CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 4) & 0x3)
1841 #define CIK__MACRO_TILE_ASPECT__1 0
1842 #define CIK__MACRO_TILE_ASPECT__2 1
1843 #define CIK__MACRO_TILE_ASPECT__4 2
1844 #define CIK__MACRO_TILE_ASPECT__8 3
1845 #define CIK__GB_MACROTILE_MODE__NUM_BANKS(x) (((x) >> 6) & 0x3)
1846 #define CIK__NUM_BANKS__2_BANK 0
1847 #define CIK__NUM_BANKS__4_BANK 1
1848 #define CIK__NUM_BANKS__8_BANK 2
1849 #define CIK__NUM_BANKS__16_BANK 3
1852 static void cik_get_2d_params(struct radeon_surface_manager *surf_man,
1853 unsigned bpe, unsigned nsamples, bool is_color,
1855 uint32_t *num_pipes,
1856 uint32_t *tile_split_ptr,
1857 uint32_t *num_banks,
1858 uint32_t *macro_tile_aspect,
1862 uint32_t gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1863 unsigned tileb_1x, tileb;
1864 unsigned gb_macrotile_mode;
1865 unsigned macrotile_index;
1866 unsigned tile_split, sample_split;
1869 switch (CIK__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1870 case CIK__PIPE_CONFIG__ADDR_SURF_P2:
1874 case CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1875 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1876 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1877 case CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1880 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1881 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1882 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1883 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1884 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1885 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1886 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1889 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16:
1890 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16:
1895 switch (CIK__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1897 case CIK__TILE_SPLIT__64B:
1900 case CIK__TILE_SPLIT__128B:
1903 case CIK__TILE_SPLIT__256B:
1906 case CIK__TILE_SPLIT__512B:
1909 case CIK__TILE_SPLIT__1024B:
1912 case CIK__TILE_SPLIT__2048B:
1915 case CIK__TILE_SPLIT__4096B:
1919 switch (CIK__GB_TILE_MODE__SAMPLE_SPLIT(gb_tile_mode)) {
1921 case CIK__SAMPLE_SPLIT__1:
1924 case CIK__SAMPLE_SPLIT__2:
1927 case CIK__SAMPLE_SPLIT__4:
1930 case CIK__SAMPLE_SPLIT__8:
1935 /* Adjust the tile split. */
1936 tileb_1x = 8 * 8 * bpe;
1938 tile_split = MAX2(256, sample_split * tileb_1x);
1940 tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
1942 /* Determine the macrotile index. */
1943 tileb = MIN2(tile_split, nsamples * tileb_1x);
1945 for (macrotile_index = 0; tileb > 64; macrotile_index++) {
1948 gb_macrotile_mode = surf_man->hw_info.macrotile_mode_array[macrotile_index];
1950 if (tile_split_ptr) {
1951 *tile_split_ptr = tile_split;
1954 switch (CIK__GB_MACROTILE_MODE__NUM_BANKS(gb_macrotile_mode)) {
1956 case CIK__NUM_BANKS__2_BANK:
1959 case CIK__NUM_BANKS__4_BANK:
1962 case CIK__NUM_BANKS__8_BANK:
1965 case CIK__NUM_BANKS__16_BANK:
1970 if (macro_tile_aspect) {
1971 switch (CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(gb_macrotile_mode)) {
1973 case CIK__MACRO_TILE_ASPECT__1:
1974 *macro_tile_aspect = 1;
1976 case CIK__MACRO_TILE_ASPECT__2:
1977 *macro_tile_aspect = 2;
1979 case CIK__MACRO_TILE_ASPECT__4:
1980 *macro_tile_aspect = 4;
1982 case CIK__MACRO_TILE_ASPECT__8:
1983 *macro_tile_aspect = 8;
1988 switch (CIK__GB_MACROTILE_MODE__BANK_WIDTH(gb_macrotile_mode)) {
1990 case CIK__BANK_WIDTH__1:
1993 case CIK__BANK_WIDTH__2:
1996 case CIK__BANK_WIDTH__4:
1999 case CIK__BANK_WIDTH__8:
2005 switch (CIK__GB_MACROTILE_MODE__BANK_HEIGHT(gb_macrotile_mode)) {
2007 case CIK__BANK_HEIGHT__1:
2010 case CIK__BANK_HEIGHT__2:
2013 case CIK__BANK_HEIGHT__4:
2016 case CIK__BANK_HEIGHT__8:
2023 static int cik_init_hw_info(struct radeon_surface_manager *surf_man)
2025 uint32_t tiling_config;
2026 drmVersionPtr version;
2029 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
2035 surf_man->hw_info.allow_2d = 0;
2036 version = drmGetVersion(surf_man->fd);
2037 if (version && version->version_minor >= 35) {
2038 if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array) &&
2039 !radeon_get_value(surf_man->fd, RADEON_INFO_CIK_MACROTILE_MODE_ARRAY, surf_man->hw_info.macrotile_mode_array)) {
2040 surf_man->hw_info.allow_2d = 1;
2043 drmFreeVersion(version);
2045 switch (tiling_config & 0xf) {
2047 surf_man->hw_info.num_pipes = 1;
2050 surf_man->hw_info.num_pipes = 2;
2053 surf_man->hw_info.num_pipes = 4;
2056 surf_man->hw_info.num_pipes = 8;
2059 surf_man->hw_info.num_pipes = 8;
2060 surf_man->hw_info.allow_2d = 0;
2064 switch ((tiling_config & 0xf0) >> 4) {
2066 surf_man->hw_info.num_banks = 4;
2069 surf_man->hw_info.num_banks = 8;
2072 surf_man->hw_info.num_banks = 16;
2075 surf_man->hw_info.num_banks = 8;
2076 surf_man->hw_info.allow_2d = 0;
2080 switch ((tiling_config & 0xf00) >> 8) {
2082 surf_man->hw_info.group_bytes = 256;
2085 surf_man->hw_info.group_bytes = 512;
2088 surf_man->hw_info.group_bytes = 256;
2089 surf_man->hw_info.allow_2d = 0;
2093 switch ((tiling_config & 0xf000) >> 12) {
2095 surf_man->hw_info.row_size = 1024;
2098 surf_man->hw_info.row_size = 2048;
2101 surf_man->hw_info.row_size = 4096;
2104 surf_man->hw_info.row_size = 4096;
2105 surf_man->hw_info.allow_2d = 0;
2111 static int cik_surface_sanity(struct radeon_surface_manager *surf_man,
2112 struct radeon_surface *surf,
2113 unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
2115 /* check surface dimension */
2116 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
2120 /* check mipmap last_level */
2121 if (surf->last_level > 15) {
2125 /* force 1d on kernel that can't do 2d */
2126 if (mode > RADEON_SURF_MODE_1D &&
2127 (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
2128 if (surf->nsamples > 1) {
2129 fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
2132 mode = RADEON_SURF_MODE_1D;
2133 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2134 surf->flags |= RADEON_SURF_SET(mode, MODE);
2137 if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
2141 if (!surf->tile_split) {
2146 surf->tile_split = 64;
2147 surf->stencil_tile_split = 64;
2151 case RADEON_SURF_MODE_2D: {
2152 if (surf->flags & RADEON_SURF_Z_OR_SBUFFER) {
2153 switch (surf->nsamples) {
2155 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64;
2159 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128;
2162 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256;
2168 if (surf->flags & RADEON_SURF_SBUFFER) {
2169 *stencil_tile_mode = *tile_mode;
2171 cik_get_2d_params(surf_man, 1, surf->nsamples, false,
2172 *stencil_tile_mode, NULL,
2173 &surf->stencil_tile_split,
2174 NULL, NULL, NULL, NULL);
2176 } else if (surf->flags & RADEON_SURF_SCANOUT) {
2177 *tile_mode = CIK_TILE_MODE_COLOR_2D_SCANOUT;
2179 *tile_mode = CIK_TILE_MODE_COLOR_2D;
2182 /* retrieve tiling mode values */
2183 cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
2184 !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), *tile_mode,
2185 NULL, &surf->tile_split, NULL, &surf->mtilea,
2186 &surf->bankw, &surf->bankh);
2189 case RADEON_SURF_MODE_1D:
2190 if (surf->flags & RADEON_SURF_SBUFFER) {
2191 *stencil_tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2193 if (surf->flags & RADEON_SURF_ZBUFFER) {
2194 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2195 } else if (surf->flags & RADEON_SURF_SCANOUT) {
2196 *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2198 *tile_mode = SI_TILE_MODE_COLOR_1D;
2201 case RADEON_SURF_MODE_LINEAR_ALIGNED:
2203 *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
2209 static int cik_surface_init_2d(struct radeon_surface_manager *surf_man,
2210 struct radeon_surface *surf,
2211 struct radeon_surface_level *level,
2212 unsigned bpe, unsigned tile_mode,
2213 unsigned tile_split,
2214 unsigned num_pipes, unsigned num_banks,
2216 unsigned start_level)
2218 uint64_t aligned_offset = offset;
2219 unsigned tilew, tileh, tileb_1x, tileb;
2220 unsigned mtilew, mtileh, mtileb;
2224 /* compute tile values */
2227 tileb_1x = tilew * tileh * bpe;
2229 tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
2231 tileb = surf->nsamples * tileb_1x;
2233 /* slices per tile */
2235 if (tileb > tile_split && tile_split) {
2236 slice_pt = tileb / tile_split;
2237 tileb = tileb / slice_pt;
2240 /* macro tile width & height */
2241 mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
2242 mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
2244 /* macro tile bytes */
2245 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
2247 if (start_level <= 1) {
2248 unsigned alignment = MAX2(256, mtileb);
2249 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
2251 if (aligned_offset) {
2252 aligned_offset = ALIGN(aligned_offset, alignment);
2256 /* build mipmap tree */
2257 for (i = start_level; i <= surf->last_level; i++) {
2258 level[i].mode = RADEON_SURF_MODE_2D;
2259 si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
2260 if (level[i].mode == RADEON_SURF_MODE_1D) {
2261 switch (tile_mode) {
2262 case CIK_TILE_MODE_COLOR_2D:
2263 tile_mode = SI_TILE_MODE_COLOR_1D;
2265 case CIK_TILE_MODE_COLOR_2D_SCANOUT:
2266 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2268 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64:
2269 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128:
2270 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256:
2271 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512:
2272 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE:
2273 tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2278 return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
2280 /* level0 and first mipmap need to have alignment */
2281 aligned_offset = offset = surf->bo_size;
2283 aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
2285 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
2286 if (surf->level == level) {
2287 surf->tiling_index[i] = tile_mode;
2288 /* it's ok because stencil is done after */
2289 surf->stencil_tiling_index[i] = tile_mode;
2291 surf->stencil_tiling_index[i] = tile_mode;
2298 static int cik_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
2299 struct radeon_surface *surf,
2300 unsigned tile_mode, unsigned stencil_tile_mode)
2303 uint32_t num_pipes, num_banks;
2305 cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
2306 !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), tile_mode,
2307 &num_pipes, NULL, &num_banks, NULL, NULL, NULL);
2309 r = cik_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode,
2310 surf->tile_split, num_pipes, num_banks, 0, 0);
2315 if (surf->flags & RADEON_SURF_SBUFFER) {
2316 r = cik_surface_init_2d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode,
2317 surf->stencil_tile_split, num_pipes, num_banks,
2319 surf->stencil_offset = surf->stencil_level[0].offset;
2324 static int cik_surface_init(struct radeon_surface_manager *surf_man,
2325 struct radeon_surface *surf)
2327 unsigned mode, tile_mode, stencil_tile_mode;
2330 /* MSAA surfaces support the 2D mode only. */
2331 if (surf->nsamples > 1) {
2332 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2333 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
2337 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2339 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
2340 /* zbuffer only support 1D or 2D tiled surface */
2342 case RADEON_SURF_MODE_1D:
2343 case RADEON_SURF_MODE_2D:
2346 mode = RADEON_SURF_MODE_1D;
2347 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2348 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2353 r = cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2358 surf->stencil_offset = 0;
2359 surf->bo_alignment = 0;
2361 /* check tiling mode */
2363 case RADEON_SURF_MODE_LINEAR:
2364 r = r6_surface_init_linear(surf_man, surf, 0, 0);
2366 case RADEON_SURF_MODE_LINEAR_ALIGNED:
2367 r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
2369 case RADEON_SURF_MODE_1D:
2370 r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2372 case RADEON_SURF_MODE_2D:
2373 r = cik_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2382 * depending on surface
2384 static int cik_surface_best(struct radeon_surface_manager *surf_man,
2385 struct radeon_surface *surf)
2387 unsigned mode, tile_mode, stencil_tile_mode;
2390 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2392 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
2393 !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
2394 /* depth/stencil force 1d tiling for old mesa */
2395 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2396 surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2399 return cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2403 /* ===========================================================================
2406 struct radeon_surface_manager *
2407 radeon_surface_manager_new(int fd)
2409 struct radeon_surface_manager *surf_man;
2411 surf_man = calloc(1, sizeof(struct radeon_surface_manager));
2412 if (surf_man == NULL) {
2416 if (radeon_get_value(fd, RADEON_INFO_DEVICE_ID, &surf_man->device_id)) {
2419 if (radeon_get_family(surf_man)) {
2423 if (surf_man->family <= CHIP_RV740) {
2424 if (r6_init_hw_info(surf_man)) {
2427 surf_man->surface_init = &r6_surface_init;
2428 surf_man->surface_best = &r6_surface_best;
2429 } else if (surf_man->family <= CHIP_ARUBA) {
2430 if (eg_init_hw_info(surf_man)) {
2433 surf_man->surface_init = &eg_surface_init;
2434 surf_man->surface_best = &eg_surface_best;
2435 } else if (surf_man->family < CHIP_BONAIRE) {
2436 if (si_init_hw_info(surf_man)) {
2439 surf_man->surface_init = &si_surface_init;
2440 surf_man->surface_best = &si_surface_best;
2442 if (cik_init_hw_info(surf_man)) {
2445 surf_man->surface_init = &cik_surface_init;
2446 surf_man->surface_best = &cik_surface_best;
2456 radeon_surface_manager_free(struct radeon_surface_manager *surf_man)
2461 static int radeon_surface_sanity(struct radeon_surface_manager *surf_man,
2462 struct radeon_surface *surf,
2466 if (surf_man == NULL || surf_man->surface_init == NULL || surf == NULL) {
2470 /* all dimension must be at least 1 ! */
2471 if (!surf->npix_x || !surf->npix_y || !surf->npix_z) {
2474 if (!surf->blk_w || !surf->blk_h || !surf->blk_d) {
2477 if (!surf->array_size) {
2480 /* array size must be a power of 2 */
2481 surf->array_size = next_power_of_two(surf->array_size);
2483 switch (surf->nsamples) {
2494 case RADEON_SURF_TYPE_1D:
2495 if (surf->npix_y > 1) {
2498 case RADEON_SURF_TYPE_2D:
2499 if (surf->npix_z > 1) {
2503 case RADEON_SURF_TYPE_CUBEMAP:
2504 if (surf->npix_z > 1) {
2507 /* deal with cubemap as they were texture array */
2508 if (surf_man->family >= CHIP_RV770) {
2509 surf->array_size = 8;
2511 surf->array_size = 6;
2514 case RADEON_SURF_TYPE_3D:
2516 case RADEON_SURF_TYPE_1D_ARRAY:
2517 if (surf->npix_y > 1) {
2520 case RADEON_SURF_TYPE_2D_ARRAY:
2529 radeon_surface_init(struct radeon_surface_manager *surf_man,
2530 struct radeon_surface *surf)
2532 unsigned mode, type;
2535 type = RADEON_SURF_GET(surf->flags, TYPE);
2536 mode = RADEON_SURF_GET(surf->flags, MODE);
2538 r = radeon_surface_sanity(surf_man, surf, type, mode);
2542 return surf_man->surface_init(surf_man, surf);
2546 radeon_surface_best(struct radeon_surface_manager *surf_man,
2547 struct radeon_surface *surf)
2549 unsigned mode, type;
2552 type = RADEON_SURF_GET(surf->flags, TYPE);
2553 mode = RADEON_SURF_GET(surf->flags, MODE);
2555 r = radeon_surface_sanity(surf_man, surf, type, mode);
2559 return surf_man->surface_best(surf_man, surf);