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>
35 #include <sys/ioctl.h>
37 #include "libdrm_macros.h"
39 #include "radeon_drm.h"
40 #include "radeon_surface.h"
42 #define CIK_TILE_MODE_COLOR_2D 14
43 #define CIK_TILE_MODE_COLOR_2D_SCANOUT 10
44 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64 0
45 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128 1
46 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256 2
47 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512 3
48 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE 4
50 #define ALIGN(value, alignment) (((value) + alignment - 1) & ~(alignment - 1))
51 #define MAX2(A, B) ((A) > (B) ? (A) : (B))
52 #define MIN2(A, B) ((A) < (B) ? (A) : (B))
54 /* keep this private */
95 typedef int (*hw_init_surface_t
)(struct radeon_surface_manager
*surf_man
,
96 struct radeon_surface
*surf
);
97 typedef int (*hw_best_surface_t
)(struct radeon_surface_manager
*surf_man
,
98 struct radeon_surface
*surf
);
100 struct radeon_hw_info
{
101 /* apply to r6, eg */
102 uint32_t group_bytes
;
109 uint32_t tile_mode_array
[32];
111 uint32_t macrotile_mode_array
[16];
114 struct radeon_surface_manager
{
117 struct radeon_hw_info hw_info
;
119 hw_init_surface_t surface_init
;
120 hw_best_surface_t surface_best
;
124 static int radeon_get_value(int fd
, unsigned req
, uint32_t *value
)
126 struct drm_radeon_info info
= {};
131 info
.value
= (uintptr_t)value
;
132 r
= drmCommandWriteRead(fd
, DRM_RADEON_INFO
, &info
,
133 sizeof(struct drm_radeon_info
));
137 static int radeon_get_family(struct radeon_surface_manager
*surf_man
)
139 switch (surf_man
->device_id
) {
140 #define CHIPSET(pci_id, name, fam) case pci_id: surf_man->family = CHIP_##fam; break;
141 #include "r600_pci_ids.h"
149 static unsigned next_power_of_two(unsigned x
)
154 return (1 << ((sizeof(unsigned) * 8) - __builtin_clz(x
- 1)));
157 static unsigned mip_minify(unsigned size
, unsigned level
)
161 val
= MAX2(1, size
>> level
);
163 val
= next_power_of_two(val
);
167 static void surf_minify(struct radeon_surface
*surf
,
168 struct radeon_surface_level
*surflevel
,
169 unsigned bpe
, unsigned level
,
170 uint32_t xalign
, uint32_t yalign
, uint32_t zalign
,
173 surflevel
->npix_x
= mip_minify(surf
->npix_x
, level
);
174 surflevel
->npix_y
= mip_minify(surf
->npix_y
, level
);
175 surflevel
->npix_z
= mip_minify(surf
->npix_z
, level
);
176 surflevel
->nblk_x
= (surflevel
->npix_x
+ surf
->blk_w
- 1) / surf
->blk_w
;
177 surflevel
->nblk_y
= (surflevel
->npix_y
+ surf
->blk_h
- 1) / surf
->blk_h
;
178 surflevel
->nblk_z
= (surflevel
->npix_z
+ surf
->blk_d
- 1) / surf
->blk_d
;
179 if (surf
->nsamples
== 1 && surflevel
->mode
== RADEON_SURF_MODE_2D
&&
180 !(surf
->flags
& RADEON_SURF_FMASK
)) {
181 if (surflevel
->nblk_x
< xalign
|| surflevel
->nblk_y
< yalign
) {
182 surflevel
->mode
= RADEON_SURF_MODE_1D
;
186 surflevel
->nblk_x
= ALIGN(surflevel
->nblk_x
, xalign
);
187 surflevel
->nblk_y
= ALIGN(surflevel
->nblk_y
, yalign
);
188 surflevel
->nblk_z
= ALIGN(surflevel
->nblk_z
, zalign
);
190 surflevel
->offset
= offset
;
191 surflevel
->pitch_bytes
= surflevel
->nblk_x
* bpe
* surf
->nsamples
;
192 surflevel
->slice_size
= (uint64_t)surflevel
->pitch_bytes
* surflevel
->nblk_y
;
194 surf
->bo_size
= offset
+ surflevel
->slice_size
* surflevel
->nblk_z
* surf
->array_size
;
197 /* ===========================================================================
200 static int r6_init_hw_info(struct radeon_surface_manager
*surf_man
)
202 uint32_t tiling_config
;
203 drmVersionPtr version
;
206 r
= radeon_get_value(surf_man
->fd
, RADEON_INFO_TILING_CONFIG
,
212 surf_man
->hw_info
.allow_2d
= 0;
213 version
= drmGetVersion(surf_man
->fd
);
214 if (version
&& version
->version_minor
>= 14) {
215 surf_man
->hw_info
.allow_2d
= 1;
217 drmFreeVersion(version
);
219 switch ((tiling_config
& 0xe) >> 1) {
221 surf_man
->hw_info
.num_pipes
= 1;
224 surf_man
->hw_info
.num_pipes
= 2;
227 surf_man
->hw_info
.num_pipes
= 4;
230 surf_man
->hw_info
.num_pipes
= 8;
233 surf_man
->hw_info
.num_pipes
= 8;
234 surf_man
->hw_info
.allow_2d
= 0;
238 switch ((tiling_config
& 0x30) >> 4) {
240 surf_man
->hw_info
.num_banks
= 4;
243 surf_man
->hw_info
.num_banks
= 8;
246 surf_man
->hw_info
.num_banks
= 8;
247 surf_man
->hw_info
.allow_2d
= 0;
251 switch ((tiling_config
& 0xc0) >> 6) {
253 surf_man
->hw_info
.group_bytes
= 256;
256 surf_man
->hw_info
.group_bytes
= 512;
259 surf_man
->hw_info
.group_bytes
= 256;
260 surf_man
->hw_info
.allow_2d
= 0;
266 static int r6_surface_init_linear(struct radeon_surface_manager
*surf_man
,
267 struct radeon_surface
*surf
,
268 uint64_t offset
, unsigned start_level
)
270 uint32_t xalign
, yalign
, zalign
;
273 /* compute alignment */
275 surf
->bo_alignment
= MAX2(256, surf_man
->hw_info
.group_bytes
);
277 /* the 32 alignment is for scanout, cb or db but to allow texture to be
278 * easily bound as such we force this alignment to all surface
280 xalign
= MAX2(1, surf_man
->hw_info
.group_bytes
/ surf
->bpe
);
283 if (surf
->flags
& RADEON_SURF_SCANOUT
) {
284 xalign
= MAX2((surf
->bpe
== 1) ? 64 : 32, xalign
);
287 /* build mipmap tree */
288 for (i
= start_level
; i
<= surf
->last_level
; i
++) {
289 surf
->level
[i
].mode
= RADEON_SURF_MODE_LINEAR
;
290 surf_minify(surf
, surf
->level
+i
, surf
->bpe
, i
, xalign
, yalign
, zalign
, offset
);
291 /* level0 and first mipmap need to have alignment */
292 offset
= surf
->bo_size
;
294 offset
= ALIGN(offset
, surf
->bo_alignment
);
300 static int r6_surface_init_linear_aligned(struct radeon_surface_manager
*surf_man
,
301 struct radeon_surface
*surf
,
302 uint64_t offset
, unsigned start_level
)
304 uint32_t xalign
, yalign
, zalign
;
307 /* compute alignment */
309 surf
->bo_alignment
= MAX2(256, surf_man
->hw_info
.group_bytes
);
311 xalign
= MAX2(64, surf_man
->hw_info
.group_bytes
/ surf
->bpe
);
315 /* build mipmap tree */
316 for (i
= start_level
; i
<= surf
->last_level
; i
++) {
317 surf
->level
[i
].mode
= RADEON_SURF_MODE_LINEAR_ALIGNED
;
318 surf_minify(surf
, surf
->level
+i
, surf
->bpe
, i
, xalign
, yalign
, zalign
, offset
);
319 /* level0 and first mipmap need to have alignment */
320 offset
= surf
->bo_size
;
322 offset
= ALIGN(offset
, surf
->bo_alignment
);
328 static int r6_surface_init_1d(struct radeon_surface_manager
*surf_man
,
329 struct radeon_surface
*surf
,
330 uint64_t offset
, unsigned start_level
)
332 uint32_t xalign
, yalign
, zalign
, tilew
;
335 /* compute alignment */
337 xalign
= surf_man
->hw_info
.group_bytes
/ (tilew
* surf
->bpe
* surf
->nsamples
);
338 xalign
= MAX2(tilew
, xalign
);
341 if (surf
->flags
& RADEON_SURF_SCANOUT
) {
342 xalign
= MAX2((surf
->bpe
== 1) ? 64 : 32, xalign
);
345 surf
->bo_alignment
= MAX2(256, surf_man
->hw_info
.group_bytes
);
348 /* build mipmap tree */
349 for (i
= start_level
; i
<= surf
->last_level
; i
++) {
350 surf
->level
[i
].mode
= RADEON_SURF_MODE_1D
;
351 surf_minify(surf
, surf
->level
+i
, surf
->bpe
, i
, xalign
, yalign
, zalign
, offset
);
352 /* level0 and first mipmap need to have alignment */
353 offset
= surf
->bo_size
;
355 offset
= ALIGN(offset
, surf
->bo_alignment
);
361 static int r6_surface_init_2d(struct radeon_surface_manager
*surf_man
,
362 struct radeon_surface
*surf
,
363 uint64_t offset
, unsigned start_level
)
365 uint32_t xalign
, yalign
, zalign
, tilew
;
368 /* compute alignment */
371 xalign
= (surf_man
->hw_info
.group_bytes
* surf_man
->hw_info
.num_banks
) /
372 (tilew
* surf
->bpe
* surf
->nsamples
);
373 xalign
= MAX2(tilew
* surf_man
->hw_info
.num_banks
, xalign
);
374 if (surf
->flags
& RADEON_SURF_FMASK
)
375 xalign
= MAX2(128, xalign
);
376 yalign
= tilew
* surf_man
->hw_info
.num_pipes
;
377 if (surf
->flags
& RADEON_SURF_SCANOUT
) {
378 xalign
= MAX2((surf
->bpe
== 1) ? 64 : 32, xalign
);
382 MAX2(surf_man
->hw_info
.num_pipes
*
383 surf_man
->hw_info
.num_banks
*
384 surf
->nsamples
* surf
->bpe
* 64,
385 xalign
* yalign
* surf
->nsamples
* surf
->bpe
);
388 /* build mipmap tree */
389 for (i
= start_level
; i
<= surf
->last_level
; i
++) {
390 surf
->level
[i
].mode
= RADEON_SURF_MODE_2D
;
391 surf_minify(surf
, surf
->level
+i
, surf
->bpe
, i
, xalign
, yalign
, zalign
, offset
);
392 if (surf
->level
[i
].mode
== RADEON_SURF_MODE_1D
) {
393 return r6_surface_init_1d(surf_man
, surf
, offset
, i
);
395 /* level0 and first mipmap need to have alignment */
396 offset
= surf
->bo_size
;
398 offset
= ALIGN(offset
, surf
->bo_alignment
);
404 static int r6_surface_init(struct radeon_surface_manager
*surf_man
,
405 struct radeon_surface
*surf
)
410 /* MSAA surfaces support the 2D mode only. */
411 if (surf
->nsamples
> 1) {
412 surf
->flags
= RADEON_SURF_CLR(surf
->flags
, MODE
);
413 surf
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_2D
, MODE
);
417 mode
= (surf
->flags
>> RADEON_SURF_MODE_SHIFT
) & RADEON_SURF_MODE_MASK
;
419 if (surf
->flags
& (RADEON_SURF_ZBUFFER
| RADEON_SURF_SBUFFER
)) {
420 /* zbuffer only support 1D or 2D tiled surface */
422 case RADEON_SURF_MODE_1D
:
423 case RADEON_SURF_MODE_2D
:
426 mode
= RADEON_SURF_MODE_1D
;
427 surf
->flags
= RADEON_SURF_CLR(surf
->flags
, MODE
);
428 surf
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_1D
, MODE
);
433 /* force 1d on kernel that can't do 2d */
434 if (!surf_man
->hw_info
.allow_2d
&& mode
> RADEON_SURF_MODE_1D
) {
435 if (surf
->nsamples
> 1) {
436 fprintf(stderr
, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__
);
439 mode
= RADEON_SURF_MODE_1D
;
440 surf
->flags
= RADEON_SURF_CLR(surf
->flags
, MODE
);
441 surf
->flags
|= RADEON_SURF_SET(mode
, MODE
);
444 /* check surface dimension */
445 if (surf
->npix_x
> 8192 || surf
->npix_y
> 8192 || surf
->npix_z
> 8192) {
449 /* check mipmap last_level */
450 if (surf
->last_level
> 14) {
454 /* check tiling mode */
456 case RADEON_SURF_MODE_LINEAR
:
457 r
= r6_surface_init_linear(surf_man
, surf
, 0, 0);
459 case RADEON_SURF_MODE_LINEAR_ALIGNED
:
460 r
= r6_surface_init_linear_aligned(surf_man
, surf
, 0, 0);
462 case RADEON_SURF_MODE_1D
:
463 r
= r6_surface_init_1d(surf_man
, surf
, 0, 0);
465 case RADEON_SURF_MODE_2D
:
466 r
= r6_surface_init_2d(surf_man
, surf
, 0, 0);
474 static int r6_surface_best(struct radeon_surface_manager
*surf_man
,
475 struct radeon_surface
*surf
)
477 /* no value to optimize for r6xx/r7xx */
482 /* ===========================================================================
485 static int eg_init_hw_info(struct radeon_surface_manager
*surf_man
)
487 uint32_t tiling_config
;
488 drmVersionPtr version
;
491 r
= radeon_get_value(surf_man
->fd
, RADEON_INFO_TILING_CONFIG
,
497 surf_man
->hw_info
.allow_2d
= 0;
498 version
= drmGetVersion(surf_man
->fd
);
499 if (version
&& version
->version_minor
>= 16) {
500 surf_man
->hw_info
.allow_2d
= 1;
502 drmFreeVersion(version
);
504 switch (tiling_config
& 0xf) {
506 surf_man
->hw_info
.num_pipes
= 1;
509 surf_man
->hw_info
.num_pipes
= 2;
512 surf_man
->hw_info
.num_pipes
= 4;
515 surf_man
->hw_info
.num_pipes
= 8;
518 surf_man
->hw_info
.num_pipes
= 8;
519 surf_man
->hw_info
.allow_2d
= 0;
523 switch ((tiling_config
& 0xf0) >> 4) {
525 surf_man
->hw_info
.num_banks
= 4;
528 surf_man
->hw_info
.num_banks
= 8;
531 surf_man
->hw_info
.num_banks
= 16;
534 surf_man
->hw_info
.num_banks
= 8;
535 surf_man
->hw_info
.allow_2d
= 0;
539 switch ((tiling_config
& 0xf00) >> 8) {
541 surf_man
->hw_info
.group_bytes
= 256;
544 surf_man
->hw_info
.group_bytes
= 512;
547 surf_man
->hw_info
.group_bytes
= 256;
548 surf_man
->hw_info
.allow_2d
= 0;
552 switch ((tiling_config
& 0xf000) >> 12) {
554 surf_man
->hw_info
.row_size
= 1024;
557 surf_man
->hw_info
.row_size
= 2048;
560 surf_man
->hw_info
.row_size
= 4096;
563 surf_man
->hw_info
.row_size
= 4096;
564 surf_man
->hw_info
.allow_2d
= 0;
570 static void eg_surf_minify(struct radeon_surface
*surf
,
571 struct radeon_surface_level
*surflevel
,
580 unsigned mtile_pr
, mtile_ps
;
582 surflevel
->npix_x
= mip_minify(surf
->npix_x
, level
);
583 surflevel
->npix_y
= mip_minify(surf
->npix_y
, level
);
584 surflevel
->npix_z
= mip_minify(surf
->npix_z
, level
);
585 surflevel
->nblk_x
= (surflevel
->npix_x
+ surf
->blk_w
- 1) / surf
->blk_w
;
586 surflevel
->nblk_y
= (surflevel
->npix_y
+ surf
->blk_h
- 1) / surf
->blk_h
;
587 surflevel
->nblk_z
= (surflevel
->npix_z
+ surf
->blk_d
- 1) / surf
->blk_d
;
588 if (surf
->nsamples
== 1 && surflevel
->mode
== RADEON_SURF_MODE_2D
&&
589 !(surf
->flags
& RADEON_SURF_FMASK
)) {
590 if (surflevel
->nblk_x
< mtilew
|| surflevel
->nblk_y
< mtileh
) {
591 surflevel
->mode
= RADEON_SURF_MODE_1D
;
595 surflevel
->nblk_x
= ALIGN(surflevel
->nblk_x
, mtilew
);
596 surflevel
->nblk_y
= ALIGN(surflevel
->nblk_y
, mtileh
);
597 surflevel
->nblk_z
= ALIGN(surflevel
->nblk_z
, 1);
599 /* macro tile per row */
600 mtile_pr
= surflevel
->nblk_x
/ mtilew
;
601 /* macro tile per slice */
602 mtile_ps
= (mtile_pr
* surflevel
->nblk_y
) / mtileh
;
604 surflevel
->offset
= offset
;
605 surflevel
->pitch_bytes
= surflevel
->nblk_x
* bpe
* surf
->nsamples
;
606 surflevel
->slice_size
= (uint64_t)mtile_ps
* mtileb
* slice_pt
;
608 surf
->bo_size
= offset
+ surflevel
->slice_size
* surflevel
->nblk_z
* surf
->array_size
;
611 static int eg_surface_init_1d(struct radeon_surface_manager
*surf_man
,
612 struct radeon_surface
*surf
,
613 struct radeon_surface_level
*level
,
615 uint64_t offset
, unsigned start_level
)
617 uint32_t xalign
, yalign
, zalign
, tilew
;
620 /* compute alignment */
622 xalign
= surf_man
->hw_info
.group_bytes
/ (tilew
* bpe
* surf
->nsamples
);
623 xalign
= MAX2(tilew
, xalign
);
626 if (surf
->flags
& RADEON_SURF_SCANOUT
) {
627 xalign
= MAX2((bpe
== 1) ? 64 : 32, xalign
);
631 unsigned alignment
= MAX2(256, surf_man
->hw_info
.group_bytes
);
632 surf
->bo_alignment
= MAX2(surf
->bo_alignment
, alignment
);
635 offset
= ALIGN(offset
, alignment
);
639 /* build mipmap tree */
640 for (i
= start_level
; i
<= surf
->last_level
; i
++) {
641 level
[i
].mode
= RADEON_SURF_MODE_1D
;
642 surf_minify(surf
, level
+i
, bpe
, i
, xalign
, yalign
, zalign
, offset
);
643 /* level0 and first mipmap need to have alignment */
644 offset
= surf
->bo_size
;
646 offset
= ALIGN(offset
, surf
->bo_alignment
);
652 static int eg_surface_init_2d(struct radeon_surface_manager
*surf_man
,
653 struct radeon_surface
*surf
,
654 struct radeon_surface_level
*level
,
655 unsigned bpe
, unsigned tile_split
,
656 uint64_t offset
, unsigned start_level
)
658 unsigned tilew
, tileh
, tileb
;
659 unsigned mtilew
, mtileh
, mtileb
;
663 /* compute tile values */
666 tileb
= tilew
* tileh
* bpe
* surf
->nsamples
;
667 /* slices per tile */
669 if (tileb
> tile_split
&& tile_split
) {
670 slice_pt
= tileb
/ tile_split
;
672 tileb
= tileb
/ slice_pt
;
674 /* macro tile width & height */
675 mtilew
= (tilew
* surf
->bankw
* surf_man
->hw_info
.num_pipes
) * surf
->mtilea
;
676 mtileh
= (tileh
* surf
->bankh
* surf_man
->hw_info
.num_banks
) / surf
->mtilea
;
677 /* macro tile bytes */
678 mtileb
= (mtilew
/ tilew
) * (mtileh
/ tileh
) * tileb
;
681 unsigned alignment
= MAX2(256, mtileb
);
682 surf
->bo_alignment
= MAX2(surf
->bo_alignment
, alignment
);
685 offset
= ALIGN(offset
, alignment
);
689 /* build mipmap tree */
690 for (i
= start_level
; i
<= surf
->last_level
; i
++) {
691 level
[i
].mode
= RADEON_SURF_MODE_2D
;
692 eg_surf_minify(surf
, level
+i
, bpe
, i
, slice_pt
, mtilew
, mtileh
, mtileb
, offset
);
693 if (level
[i
].mode
== RADEON_SURF_MODE_1D
) {
694 return eg_surface_init_1d(surf_man
, surf
, level
, bpe
, offset
, i
);
696 /* level0 and first mipmap need to have alignment */
697 offset
= surf
->bo_size
;
699 offset
= ALIGN(offset
, surf
->bo_alignment
);
705 static int eg_surface_sanity(struct radeon_surface_manager
*surf_man
,
706 struct radeon_surface
*surf
,
711 /* check surface dimension */
712 if (surf
->npix_x
> 16384 || surf
->npix_y
> 16384 || surf
->npix_z
> 16384) {
716 /* check mipmap last_level */
717 if (surf
->last_level
> 15) {
721 /* force 1d on kernel that can't do 2d */
722 if (!surf_man
->hw_info
.allow_2d
&& mode
> RADEON_SURF_MODE_1D
) {
723 if (surf
->nsamples
> 1) {
724 fprintf(stderr
, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__
);
727 mode
= RADEON_SURF_MODE_1D
;
728 surf
->flags
= RADEON_SURF_CLR(surf
->flags
, MODE
);
729 surf
->flags
|= RADEON_SURF_SET(mode
, MODE
);
732 /* check tile split */
733 if (mode
== RADEON_SURF_MODE_2D
) {
734 switch (surf
->tile_split
) {
746 switch (surf
->mtilea
) {
755 /* check aspect ratio */
756 if (surf_man
->hw_info
.num_banks
< surf
->mtilea
) {
759 /* check bank width */
760 switch (surf
->bankw
) {
769 /* check bank height */
770 switch (surf
->bankh
) {
779 tileb
= MIN2(surf
->tile_split
, 64 * surf
->bpe
* surf
->nsamples
);
780 if ((tileb
* surf
->bankh
* surf
->bankw
) < surf_man
->hw_info
.group_bytes
) {
788 static int eg_surface_init_1d_miptrees(struct radeon_surface_manager
*surf_man
,
789 struct radeon_surface
*surf
)
791 unsigned zs_flags
= RADEON_SURF_ZBUFFER
| RADEON_SURF_SBUFFER
;
792 int r
, is_depth_stencil
= (surf
->flags
& zs_flags
) == zs_flags
;
793 /* Old libdrm_macros.headers didn't have stencil_level in it. This prevents crashes. */
794 struct radeon_surface_level tmp
[RADEON_SURF_MAX_LEVEL
];
795 struct radeon_surface_level
*stencil_level
=
796 (surf
->flags
& RADEON_SURF_HAS_SBUFFER_MIPTREE
) ? surf
->stencil_level
: tmp
;
798 r
= eg_surface_init_1d(surf_man
, surf
, surf
->level
, surf
->bpe
, 0, 0);
802 if (is_depth_stencil
) {
803 r
= eg_surface_init_1d(surf_man
, surf
, stencil_level
, 1,
805 surf
->stencil_offset
= stencil_level
[0].offset
;
810 static int eg_surface_init_2d_miptrees(struct radeon_surface_manager
*surf_man
,
811 struct radeon_surface
*surf
)
813 unsigned zs_flags
= RADEON_SURF_ZBUFFER
| RADEON_SURF_SBUFFER
;
814 int r
, is_depth_stencil
= (surf
->flags
& zs_flags
) == zs_flags
;
815 /* Old libdrm_macros.headers didn't have stencil_level in it. This prevents crashes. */
816 struct radeon_surface_level tmp
[RADEON_SURF_MAX_LEVEL
];
817 struct radeon_surface_level
*stencil_level
=
818 (surf
->flags
& RADEON_SURF_HAS_SBUFFER_MIPTREE
) ? surf
->stencil_level
: tmp
;
820 r
= eg_surface_init_2d(surf_man
, surf
, surf
->level
, surf
->bpe
,
821 surf
->tile_split
, 0, 0);
825 if (is_depth_stencil
) {
826 r
= eg_surface_init_2d(surf_man
, surf
, stencil_level
, 1,
827 surf
->stencil_tile_split
, surf
->bo_size
, 0);
828 surf
->stencil_offset
= stencil_level
[0].offset
;
833 static int eg_surface_init(struct radeon_surface_manager
*surf_man
,
834 struct radeon_surface
*surf
)
839 /* MSAA surfaces support the 2D mode only. */
840 if (surf
->nsamples
> 1) {
841 surf
->flags
= RADEON_SURF_CLR(surf
->flags
, MODE
);
842 surf
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_2D
, MODE
);
846 mode
= (surf
->flags
>> RADEON_SURF_MODE_SHIFT
) & RADEON_SURF_MODE_MASK
;
848 if (surf
->flags
& (RADEON_SURF_ZBUFFER
| RADEON_SURF_SBUFFER
)) {
849 /* zbuffer only support 1D or 2D tiled surface */
851 case RADEON_SURF_MODE_1D
:
852 case RADEON_SURF_MODE_2D
:
855 mode
= RADEON_SURF_MODE_1D
;
856 surf
->flags
= RADEON_SURF_CLR(surf
->flags
, MODE
);
857 surf
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_1D
, MODE
);
862 r
= eg_surface_sanity(surf_man
, surf
, mode
);
867 surf
->stencil_offset
= 0;
868 surf
->bo_alignment
= 0;
870 /* check tiling mode */
872 case RADEON_SURF_MODE_LINEAR
:
873 r
= r6_surface_init_linear(surf_man
, surf
, 0, 0);
875 case RADEON_SURF_MODE_LINEAR_ALIGNED
:
876 r
= r6_surface_init_linear_aligned(surf_man
, surf
, 0, 0);
878 case RADEON_SURF_MODE_1D
:
879 r
= eg_surface_init_1d_miptrees(surf_man
, surf
);
881 case RADEON_SURF_MODE_2D
:
882 r
= eg_surface_init_2d_miptrees(surf_man
, surf
);
890 static unsigned log2_int(unsigned x
)
898 if ((unsigned)(1 << l
) > x
) {
905 /* compute best tile_split, bankw, bankh, mtilea
906 * depending on surface
908 static int eg_surface_best(struct radeon_surface_manager
*surf_man
,
909 struct radeon_surface
*surf
)
911 unsigned mode
, tileb
, h_over_w
;
915 mode
= (surf
->flags
>> RADEON_SURF_MODE_SHIFT
) & RADEON_SURF_MODE_MASK
;
917 /* set some default value to avoid sanity check choking on them */
918 surf
->tile_split
= 1024;
921 surf
->mtilea
= surf_man
->hw_info
.num_banks
;
922 tileb
= MIN2(surf
->tile_split
, 64 * surf
->bpe
* surf
->nsamples
);
923 for (; surf
->bankh
<= 8; surf
->bankh
*= 2) {
924 if ((tileb
* surf
->bankh
* surf
->bankw
) >= surf_man
->hw_info
.group_bytes
) {
928 if (surf
->mtilea
> 8) {
932 r
= eg_surface_sanity(surf_man
, surf
, mode
);
937 if (mode
!= RADEON_SURF_MODE_2D
) {
938 /* nothing to do for non 2D tiled surface */
942 /* Tweak TILE_SPLIT for performance here. */
943 if (surf
->nsamples
> 1) {
944 if (surf
->flags
& (RADEON_SURF_ZBUFFER
| RADEON_SURF_SBUFFER
)) {
945 switch (surf
->nsamples
) {
947 surf
->tile_split
= 128;
950 surf
->tile_split
= 128;
953 surf
->tile_split
= 256;
955 case 16: /* cayman only */
956 surf
->tile_split
= 512;
959 fprintf(stderr
, "radeon: Wrong number of samples %i (%i)\n",
960 surf
->nsamples
, __LINE__
);
963 surf
->stencil_tile_split
= 64;
965 /* tile split must be >= 256 for colorbuffer surfaces,
966 * SAMPLE_SPLIT = tile_split / (bpe * 64), the optimal value is 2
968 surf
->tile_split
= MAX2(2 * surf
->bpe
* 64, 256);
969 if (surf
->tile_split
> 4096)
970 surf
->tile_split
= 4096;
973 /* set tile split to row size */
974 surf
->tile_split
= surf_man
->hw_info
.row_size
;
975 surf
->stencil_tile_split
= surf_man
->hw_info
.row_size
/ 2;
978 /* bankw or bankh greater than 1 increase alignment requirement, not
979 * sure if it's worth using smaller bankw & bankh to stick with 2D
980 * tiling on small surface rather than falling back to 1D tiling.
981 * Use recommended value based on tile size for now.
983 * fmask buffer has different optimal value figure them out once we
986 if (surf
->flags
& RADEON_SURF_SBUFFER
) {
987 /* assume 1 bytes for stencil, we optimize for stencil as stencil
988 * and depth shares surface values
990 tileb
= MIN2(surf
->tile_split
, 64 * surf
->nsamples
);
992 tileb
= MIN2(surf
->tile_split
, 64 * surf
->bpe
* surf
->nsamples
);
995 /* use bankw of 1 to minimize width alignment, might be interesting to
996 * increase it for large surface
1011 /* double check the constraint */
1012 for (; surf
->bankh
<= 8; surf
->bankh
*= 2) {
1013 if ((tileb
* surf
->bankh
* surf
->bankw
) >= surf_man
->hw_info
.group_bytes
) {
1018 h_over_w
= (((surf
->bankh
* surf_man
->hw_info
.num_banks
) << 16) /
1019 (surf
->bankw
* surf_man
->hw_info
.num_pipes
)) >> 16;
1020 surf
->mtilea
= 1 << (log2_int(h_over_w
) >> 1);
1026 /* ===========================================================================
1027 * Southern Islands family
1029 #define SI__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f)
1030 #define SI__PIPE_CONFIG__ADDR_SURF_P2 0
1031 #define SI__PIPE_CONFIG__ADDR_SURF_P4_8x16 4
1032 #define SI__PIPE_CONFIG__ADDR_SURF_P4_16x16 5
1033 #define SI__PIPE_CONFIG__ADDR_SURF_P4_16x32 6
1034 #define SI__PIPE_CONFIG__ADDR_SURF_P4_32x32 7
1035 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8
1036 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9
1037 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10
1038 #define SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11
1039 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12
1040 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13
1041 #define SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14
1042 #define SI__GB_TILE_MODE__TILE_SPLIT(x) (((x) >> 11) & 0x7)
1043 #define SI__TILE_SPLIT__64B 0
1044 #define SI__TILE_SPLIT__128B 1
1045 #define SI__TILE_SPLIT__256B 2
1046 #define SI__TILE_SPLIT__512B 3
1047 #define SI__TILE_SPLIT__1024B 4
1048 #define SI__TILE_SPLIT__2048B 5
1049 #define SI__TILE_SPLIT__4096B 6
1050 #define SI__GB_TILE_MODE__BANK_WIDTH(x) (((x) >> 14) & 0x3)
1051 #define SI__BANK_WIDTH__1 0
1052 #define SI__BANK_WIDTH__2 1
1053 #define SI__BANK_WIDTH__4 2
1054 #define SI__BANK_WIDTH__8 3
1055 #define SI__GB_TILE_MODE__BANK_HEIGHT(x) (((x) >> 16) & 0x3)
1056 #define SI__BANK_HEIGHT__1 0
1057 #define SI__BANK_HEIGHT__2 1
1058 #define SI__BANK_HEIGHT__4 2
1059 #define SI__BANK_HEIGHT__8 3
1060 #define SI__GB_TILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 18) & 0x3)
1061 #define SI__MACRO_TILE_ASPECT__1 0
1062 #define SI__MACRO_TILE_ASPECT__2 1
1063 #define SI__MACRO_TILE_ASPECT__4 2
1064 #define SI__MACRO_TILE_ASPECT__8 3
1065 #define SI__GB_TILE_MODE__NUM_BANKS(x) (((x) >> 20) & 0x3)
1066 #define SI__NUM_BANKS__2_BANK 0
1067 #define SI__NUM_BANKS__4_BANK 1
1068 #define SI__NUM_BANKS__8_BANK 2
1069 #define SI__NUM_BANKS__16_BANK 3
1072 static void si_gb_tile_mode(uint32_t gb_tile_mode
,
1073 unsigned *num_pipes
,
1074 unsigned *num_banks
,
1075 uint32_t *macro_tile_aspect
,
1078 uint32_t *tile_split
)
1081 switch (SI__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode
)) {
1082 case SI__PIPE_CONFIG__ADDR_SURF_P2
:
1086 case SI__PIPE_CONFIG__ADDR_SURF_P4_8x16
:
1087 case SI__PIPE_CONFIG__ADDR_SURF_P4_16x16
:
1088 case SI__PIPE_CONFIG__ADDR_SURF_P4_16x32
:
1089 case SI__PIPE_CONFIG__ADDR_SURF_P4_32x32
:
1092 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16
:
1093 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16
:
1094 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16
:
1095 case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16
:
1096 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16
:
1097 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32
:
1098 case SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32
:
1104 switch (SI__GB_TILE_MODE__NUM_BANKS(gb_tile_mode
)) {
1106 case SI__NUM_BANKS__2_BANK
:
1109 case SI__NUM_BANKS__4_BANK
:
1112 case SI__NUM_BANKS__8_BANK
:
1115 case SI__NUM_BANKS__16_BANK
:
1120 if (macro_tile_aspect
) {
1121 switch (SI__GB_TILE_MODE__MACRO_TILE_ASPECT(gb_tile_mode
)) {
1123 case SI__MACRO_TILE_ASPECT__1
:
1124 *macro_tile_aspect
= 1;
1126 case SI__MACRO_TILE_ASPECT__2
:
1127 *macro_tile_aspect
= 2;
1129 case SI__MACRO_TILE_ASPECT__4
:
1130 *macro_tile_aspect
= 4;
1132 case SI__MACRO_TILE_ASPECT__8
:
1133 *macro_tile_aspect
= 8;
1138 switch (SI__GB_TILE_MODE__BANK_WIDTH(gb_tile_mode
)) {
1140 case SI__BANK_WIDTH__1
:
1143 case SI__BANK_WIDTH__2
:
1146 case SI__BANK_WIDTH__4
:
1149 case SI__BANK_WIDTH__8
:
1155 switch (SI__GB_TILE_MODE__BANK_HEIGHT(gb_tile_mode
)) {
1157 case SI__BANK_HEIGHT__1
:
1160 case SI__BANK_HEIGHT__2
:
1163 case SI__BANK_HEIGHT__4
:
1166 case SI__BANK_HEIGHT__8
:
1172 switch (SI__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode
)) {
1174 case SI__TILE_SPLIT__64B
:
1177 case SI__TILE_SPLIT__128B
:
1180 case SI__TILE_SPLIT__256B
:
1183 case SI__TILE_SPLIT__512B
:
1186 case SI__TILE_SPLIT__1024B
:
1189 case SI__TILE_SPLIT__2048B
:
1192 case SI__TILE_SPLIT__4096B
:
1199 static int si_init_hw_info(struct radeon_surface_manager
*surf_man
)
1201 uint32_t tiling_config
;
1202 drmVersionPtr version
;
1205 r
= radeon_get_value(surf_man
->fd
, RADEON_INFO_TILING_CONFIG
,
1211 surf_man
->hw_info
.allow_2d
= 0;
1212 version
= drmGetVersion(surf_man
->fd
);
1213 if (version
&& version
->version_minor
>= 33) {
1214 if (!radeon_get_value(surf_man
->fd
, RADEON_INFO_SI_TILE_MODE_ARRAY
, surf_man
->hw_info
.tile_mode_array
)) {
1215 surf_man
->hw_info
.allow_2d
= 1;
1218 drmFreeVersion(version
);
1220 switch (tiling_config
& 0xf) {
1222 surf_man
->hw_info
.num_pipes
= 1;
1225 surf_man
->hw_info
.num_pipes
= 2;
1228 surf_man
->hw_info
.num_pipes
= 4;
1231 surf_man
->hw_info
.num_pipes
= 8;
1234 surf_man
->hw_info
.num_pipes
= 8;
1235 surf_man
->hw_info
.allow_2d
= 0;
1239 switch ((tiling_config
& 0xf0) >> 4) {
1241 surf_man
->hw_info
.num_banks
= 4;
1244 surf_man
->hw_info
.num_banks
= 8;
1247 surf_man
->hw_info
.num_banks
= 16;
1250 surf_man
->hw_info
.num_banks
= 8;
1251 surf_man
->hw_info
.allow_2d
= 0;
1255 switch ((tiling_config
& 0xf00) >> 8) {
1257 surf_man
->hw_info
.group_bytes
= 256;
1260 surf_man
->hw_info
.group_bytes
= 512;
1263 surf_man
->hw_info
.group_bytes
= 256;
1264 surf_man
->hw_info
.allow_2d
= 0;
1268 switch ((tiling_config
& 0xf000) >> 12) {
1270 surf_man
->hw_info
.row_size
= 1024;
1273 surf_man
->hw_info
.row_size
= 2048;
1276 surf_man
->hw_info
.row_size
= 4096;
1279 surf_man
->hw_info
.row_size
= 4096;
1280 surf_man
->hw_info
.allow_2d
= 0;
1286 static int si_surface_sanity(struct radeon_surface_manager
*surf_man
,
1287 struct radeon_surface
*surf
,
1288 unsigned mode
, unsigned *tile_mode
, unsigned *stencil_tile_mode
)
1290 uint32_t gb_tile_mode
;
1292 /* check surface dimension */
1293 if (surf
->npix_x
> 16384 || surf
->npix_y
> 16384 || surf
->npix_z
> 16384) {
1297 /* check mipmap last_level */
1298 if (surf
->last_level
> 15) {
1302 /* force 1d on kernel that can't do 2d */
1303 if (mode
> RADEON_SURF_MODE_1D
&&
1304 (!surf_man
->hw_info
.allow_2d
|| !(surf
->flags
& RADEON_SURF_HAS_TILE_MODE_INDEX
))) {
1305 if (surf
->nsamples
> 1) {
1306 fprintf(stderr
, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__
);
1309 mode
= RADEON_SURF_MODE_1D
;
1310 surf
->flags
= RADEON_SURF_CLR(surf
->flags
, MODE
);
1311 surf
->flags
|= RADEON_SURF_SET(mode
, MODE
);
1314 if (surf
->nsamples
> 1 && mode
!= RADEON_SURF_MODE_2D
) {
1318 if (!surf
->tile_split
) {
1323 surf
->tile_split
= 64;
1324 surf
->stencil_tile_split
= 64;
1328 case RADEON_SURF_MODE_2D
:
1329 if (surf
->flags
& RADEON_SURF_SBUFFER
) {
1330 switch (surf
->nsamples
) {
1332 *stencil_tile_mode
= SI_TILE_MODE_DEPTH_STENCIL_2D
;
1335 *stencil_tile_mode
= SI_TILE_MODE_DEPTH_STENCIL_2D_2AA
;
1338 *stencil_tile_mode
= SI_TILE_MODE_DEPTH_STENCIL_2D_4AA
;
1341 *stencil_tile_mode
= SI_TILE_MODE_DEPTH_STENCIL_2D_8AA
;
1346 /* retrieve tiling mode value */
1347 gb_tile_mode
= surf_man
->hw_info
.tile_mode_array
[*stencil_tile_mode
];
1348 si_gb_tile_mode(gb_tile_mode
, NULL
, NULL
, NULL
, NULL
, NULL
, &surf
->stencil_tile_split
);
1350 if (surf
->flags
& RADEON_SURF_ZBUFFER
) {
1351 switch (surf
->nsamples
) {
1353 *tile_mode
= SI_TILE_MODE_DEPTH_STENCIL_2D
;
1356 *tile_mode
= SI_TILE_MODE_DEPTH_STENCIL_2D_2AA
;
1359 *tile_mode
= SI_TILE_MODE_DEPTH_STENCIL_2D_4AA
;
1362 *tile_mode
= SI_TILE_MODE_DEPTH_STENCIL_2D_8AA
;
1367 } else if (surf
->flags
& RADEON_SURF_SCANOUT
) {
1368 switch (surf
->bpe
) {
1370 *tile_mode
= SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP
;
1373 *tile_mode
= SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP
;
1379 switch (surf
->bpe
) {
1381 *tile_mode
= SI_TILE_MODE_COLOR_2D_8BPP
;
1384 *tile_mode
= SI_TILE_MODE_COLOR_2D_16BPP
;
1387 *tile_mode
= SI_TILE_MODE_COLOR_2D_32BPP
;
1391 *tile_mode
= SI_TILE_MODE_COLOR_2D_64BPP
;
1397 /* retrieve tiling mode value */
1398 gb_tile_mode
= surf_man
->hw_info
.tile_mode_array
[*tile_mode
];
1399 si_gb_tile_mode(gb_tile_mode
, NULL
, NULL
, &surf
->mtilea
, &surf
->bankw
, &surf
->bankh
, &surf
->tile_split
);
1401 case RADEON_SURF_MODE_1D
:
1402 if (surf
->flags
& RADEON_SURF_SBUFFER
) {
1403 *stencil_tile_mode
= SI_TILE_MODE_DEPTH_STENCIL_1D
;
1405 if (surf
->flags
& RADEON_SURF_ZBUFFER
) {
1406 *tile_mode
= SI_TILE_MODE_DEPTH_STENCIL_1D
;
1407 } else if (surf
->flags
& RADEON_SURF_SCANOUT
) {
1408 *tile_mode
= SI_TILE_MODE_COLOR_1D_SCANOUT
;
1410 *tile_mode
= SI_TILE_MODE_COLOR_1D
;
1413 case RADEON_SURF_MODE_LINEAR_ALIGNED
:
1415 *tile_mode
= SI_TILE_MODE_COLOR_LINEAR_ALIGNED
;
1421 static void si_surf_minify(struct radeon_surface
*surf
,
1422 struct radeon_surface_level
*surflevel
,
1423 unsigned bpe
, unsigned level
,
1424 uint32_t xalign
, uint32_t yalign
, uint32_t zalign
,
1425 uint32_t slice_align
, uint64_t offset
)
1428 surflevel
->npix_x
= surf
->npix_x
;
1430 surflevel
->npix_x
= mip_minify(next_power_of_two(surf
->npix_x
), level
);
1432 surflevel
->npix_y
= mip_minify(surf
->npix_y
, level
);
1433 surflevel
->npix_z
= mip_minify(surf
->npix_z
, level
);
1435 if (level
== 0 && surf
->last_level
> 0) {
1436 surflevel
->nblk_x
= (next_power_of_two(surflevel
->npix_x
) + surf
->blk_w
- 1) / surf
->blk_w
;
1437 surflevel
->nblk_y
= (next_power_of_two(surflevel
->npix_y
) + surf
->blk_h
- 1) / surf
->blk_h
;
1438 surflevel
->nblk_z
= (next_power_of_two(surflevel
->npix_z
) + surf
->blk_d
- 1) / surf
->blk_d
;
1440 surflevel
->nblk_x
= (surflevel
->npix_x
+ surf
->blk_w
- 1) / surf
->blk_w
;
1441 surflevel
->nblk_y
= (surflevel
->npix_y
+ surf
->blk_h
- 1) / surf
->blk_h
;
1442 surflevel
->nblk_z
= (surflevel
->npix_z
+ surf
->blk_d
- 1) / surf
->blk_d
;
1445 surflevel
->nblk_y
= ALIGN(surflevel
->nblk_y
, yalign
);
1447 /* XXX: Texture sampling uses unexpectedly large pitches in some cases,
1448 * these are just guesses for the rules behind those
1450 if (level
== 0 && surf
->last_level
== 0)
1451 /* Non-mipmap pitch padded to slice alignment */
1452 /* Using just bpe here breaks stencil blitting; surf->bpe works. */
1453 xalign
= MAX2(xalign
, slice_align
/ surf
->bpe
);
1454 else if (surflevel
->mode
== RADEON_SURF_MODE_LINEAR_ALIGNED
)
1455 /* Small rows evenly distributed across slice */
1456 xalign
= MAX2(xalign
, slice_align
/ bpe
/ surflevel
->nblk_y
);
1458 surflevel
->nblk_x
= ALIGN(surflevel
->nblk_x
, xalign
);
1459 surflevel
->nblk_z
= ALIGN(surflevel
->nblk_z
, zalign
);
1461 surflevel
->offset
= offset
;
1462 surflevel
->pitch_bytes
= surflevel
->nblk_x
* bpe
* surf
->nsamples
;
1463 surflevel
->slice_size
= ALIGN((uint64_t)surflevel
->pitch_bytes
* surflevel
->nblk_y
,
1464 (uint64_t)slice_align
);
1466 surf
->bo_size
= offset
+ surflevel
->slice_size
* surflevel
->nblk_z
* surf
->array_size
;
1469 static void si_surf_minify_2d(struct radeon_surface
*surf
,
1470 struct radeon_surface_level
*surflevel
,
1471 unsigned bpe
, unsigned level
, unsigned slice_pt
,
1472 uint32_t xalign
, uint32_t yalign
, uint32_t zalign
,
1473 unsigned mtileb
, uint64_t offset
)
1475 unsigned mtile_pr
, mtile_ps
;
1478 surflevel
->npix_x
= surf
->npix_x
;
1480 surflevel
->npix_x
= mip_minify(next_power_of_two(surf
->npix_x
), level
);
1482 surflevel
->npix_y
= mip_minify(surf
->npix_y
, level
);
1483 surflevel
->npix_z
= mip_minify(surf
->npix_z
, level
);
1485 if (level
== 0 && surf
->last_level
> 0) {
1486 surflevel
->nblk_x
= (next_power_of_two(surflevel
->npix_x
) + surf
->blk_w
- 1) / surf
->blk_w
;
1487 surflevel
->nblk_y
= (next_power_of_two(surflevel
->npix_y
) + surf
->blk_h
- 1) / surf
->blk_h
;
1488 surflevel
->nblk_z
= (next_power_of_two(surflevel
->npix_z
) + surf
->blk_d
- 1) / surf
->blk_d
;
1490 surflevel
->nblk_x
= (surflevel
->npix_x
+ surf
->blk_w
- 1) / surf
->blk_w
;
1491 surflevel
->nblk_y
= (surflevel
->npix_y
+ surf
->blk_h
- 1) / surf
->blk_h
;
1492 surflevel
->nblk_z
= (surflevel
->npix_z
+ surf
->blk_d
- 1) / surf
->blk_d
;
1495 if (surf
->nsamples
== 1 && surflevel
->mode
== RADEON_SURF_MODE_2D
&&
1496 !(surf
->flags
& RADEON_SURF_FMASK
)) {
1497 if (surflevel
->nblk_x
< xalign
|| surflevel
->nblk_y
< yalign
) {
1498 surflevel
->mode
= RADEON_SURF_MODE_1D
;
1502 surflevel
->nblk_x
= ALIGN(surflevel
->nblk_x
, xalign
);
1503 surflevel
->nblk_y
= ALIGN(surflevel
->nblk_y
, yalign
);
1504 surflevel
->nblk_z
= ALIGN(surflevel
->nblk_z
, zalign
);
1506 /* macro tile per row */
1507 mtile_pr
= surflevel
->nblk_x
/ xalign
;
1508 /* macro tile per slice */
1509 mtile_ps
= (mtile_pr
* surflevel
->nblk_y
) / yalign
;
1510 surflevel
->offset
= offset
;
1511 surflevel
->pitch_bytes
= surflevel
->nblk_x
* bpe
* surf
->nsamples
;
1512 surflevel
->slice_size
= (uint64_t)mtile_ps
* mtileb
* slice_pt
;
1514 surf
->bo_size
= offset
+ surflevel
->slice_size
* surflevel
->nblk_z
* surf
->array_size
;
1517 static int si_surface_init_linear_aligned(struct radeon_surface_manager
*surf_man
,
1518 struct radeon_surface
*surf
,
1520 uint64_t offset
, unsigned start_level
)
1522 uint32_t xalign
, yalign
, zalign
, slice_align
;
1525 /* compute alignment */
1527 surf
->bo_alignment
= MAX2(256, surf_man
->hw_info
.group_bytes
);
1529 xalign
= MAX2(8, 64 / surf
->bpe
);
1532 slice_align
= MAX2(64 * surf
->bpe
, surf_man
->hw_info
.group_bytes
);
1534 /* build mipmap tree */
1535 for (i
= start_level
; i
<= surf
->last_level
; i
++) {
1536 surf
->level
[i
].mode
= RADEON_SURF_MODE_LINEAR_ALIGNED
;
1537 si_surf_minify(surf
, surf
->level
+i
, surf
->bpe
, i
, xalign
, yalign
, zalign
, slice_align
, offset
);
1538 /* level0 and first mipmap need to have alignment */
1539 offset
= surf
->bo_size
;
1541 offset
= ALIGN(offset
, surf
->bo_alignment
);
1543 if (surf
->flags
& RADEON_SURF_HAS_TILE_MODE_INDEX
) {
1544 surf
->tiling_index
[i
] = tile_mode
;
1550 static int si_surface_init_1d(struct radeon_surface_manager
*surf_man
,
1551 struct radeon_surface
*surf
,
1552 struct radeon_surface_level
*level
,
1553 unsigned bpe
, unsigned tile_mode
,
1554 uint64_t offset
, unsigned start_level
)
1556 uint32_t xalign
, yalign
, zalign
, slice_align
;
1557 unsigned alignment
= MAX2(256, surf_man
->hw_info
.group_bytes
);
1560 /* compute alignment */
1564 slice_align
= surf_man
->hw_info
.group_bytes
;
1565 if (surf
->flags
& RADEON_SURF_SCANOUT
) {
1566 xalign
= MAX2((bpe
== 1) ? 64 : 32, xalign
);
1569 if (start_level
<= 1) {
1570 surf
->bo_alignment
= MAX2(surf
->bo_alignment
, alignment
);
1573 offset
= ALIGN(offset
, alignment
);
1577 /* build mipmap tree */
1578 for (i
= start_level
; i
<= surf
->last_level
; i
++) {
1579 level
[i
].mode
= RADEON_SURF_MODE_1D
;
1580 si_surf_minify(surf
, level
+i
, bpe
, i
, xalign
, yalign
, zalign
, slice_align
, offset
);
1581 /* level0 and first mipmap need to have alignment */
1582 offset
= surf
->bo_size
;
1584 offset
= ALIGN(offset
, alignment
);
1586 if (surf
->flags
& RADEON_SURF_HAS_TILE_MODE_INDEX
) {
1587 if (surf
->level
== level
) {
1588 surf
->tiling_index
[i
] = tile_mode
;
1589 /* it's ok because stencil is done after */
1590 surf
->stencil_tiling_index
[i
] = tile_mode
;
1592 surf
->stencil_tiling_index
[i
] = tile_mode
;
1599 static int si_surface_init_1d_miptrees(struct radeon_surface_manager
*surf_man
,
1600 struct radeon_surface
*surf
,
1601 unsigned tile_mode
, unsigned stencil_tile_mode
)
1605 r
= si_surface_init_1d(surf_man
, surf
, surf
->level
, surf
->bpe
, tile_mode
, 0, 0);
1610 if (surf
->flags
& RADEON_SURF_SBUFFER
) {
1611 r
= si_surface_init_1d(surf_man
, surf
, surf
->stencil_level
, 1, stencil_tile_mode
, surf
->bo_size
, 0);
1612 surf
->stencil_offset
= surf
->stencil_level
[0].offset
;
1617 static int si_surface_init_2d(struct radeon_surface_manager
*surf_man
,
1618 struct radeon_surface
*surf
,
1619 struct radeon_surface_level
*level
,
1620 unsigned bpe
, unsigned tile_mode
,
1621 unsigned num_pipes
, unsigned num_banks
,
1622 unsigned tile_split
,
1624 unsigned start_level
)
1626 uint64_t aligned_offset
= offset
;
1627 unsigned tilew
, tileh
, tileb
;
1628 unsigned mtilew
, mtileh
, mtileb
;
1632 /* compute tile values */
1635 tileb
= tilew
* tileh
* bpe
* surf
->nsamples
;
1636 /* slices per tile */
1638 if (tileb
> tile_split
&& tile_split
) {
1639 slice_pt
= tileb
/ tile_split
;
1641 tileb
= tileb
/ slice_pt
;
1643 /* macro tile width & height */
1644 mtilew
= (tilew
* surf
->bankw
* num_pipes
) * surf
->mtilea
;
1645 mtileh
= (tileh
* surf
->bankh
* num_banks
) / surf
->mtilea
;
1647 /* macro tile bytes */
1648 mtileb
= (mtilew
/ tilew
) * (mtileh
/ tileh
) * tileb
;
1650 if (start_level
<= 1) {
1651 unsigned alignment
= MAX2(256, mtileb
);
1652 surf
->bo_alignment
= MAX2(surf
->bo_alignment
, alignment
);
1654 if (aligned_offset
) {
1655 aligned_offset
= ALIGN(aligned_offset
, alignment
);
1659 /* build mipmap tree */
1660 for (i
= start_level
; i
<= surf
->last_level
; i
++) {
1661 level
[i
].mode
= RADEON_SURF_MODE_2D
;
1662 si_surf_minify_2d(surf
, level
+i
, bpe
, i
, slice_pt
, mtilew
, mtileh
, 1, mtileb
, aligned_offset
);
1663 if (level
[i
].mode
== RADEON_SURF_MODE_1D
) {
1664 switch (tile_mode
) {
1665 case SI_TILE_MODE_COLOR_2D_8BPP
:
1666 case SI_TILE_MODE_COLOR_2D_16BPP
:
1667 case SI_TILE_MODE_COLOR_2D_32BPP
:
1668 case SI_TILE_MODE_COLOR_2D_64BPP
:
1669 tile_mode
= SI_TILE_MODE_COLOR_1D
;
1671 case SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP
:
1672 case SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP
:
1673 tile_mode
= SI_TILE_MODE_COLOR_1D_SCANOUT
;
1675 case SI_TILE_MODE_DEPTH_STENCIL_2D
:
1676 tile_mode
= SI_TILE_MODE_DEPTH_STENCIL_1D
;
1681 return si_surface_init_1d(surf_man
, surf
, level
, bpe
, tile_mode
, offset
, i
);
1683 /* level0 and first mipmap need to have alignment */
1684 aligned_offset
= offset
= surf
->bo_size
;
1686 aligned_offset
= ALIGN(aligned_offset
, surf
->bo_alignment
);
1688 if (surf
->flags
& RADEON_SURF_HAS_TILE_MODE_INDEX
) {
1689 if (surf
->level
== level
) {
1690 surf
->tiling_index
[i
] = tile_mode
;
1691 /* it's ok because stencil is done after */
1692 surf
->stencil_tiling_index
[i
] = tile_mode
;
1694 surf
->stencil_tiling_index
[i
] = tile_mode
;
1701 static int si_surface_init_2d_miptrees(struct radeon_surface_manager
*surf_man
,
1702 struct radeon_surface
*surf
,
1703 unsigned tile_mode
, unsigned stencil_tile_mode
)
1705 unsigned num_pipes
, num_banks
;
1706 uint32_t gb_tile_mode
;
1709 /* retrieve tiling mode value */
1710 gb_tile_mode
= surf_man
->hw_info
.tile_mode_array
[tile_mode
];
1711 si_gb_tile_mode(gb_tile_mode
, &num_pipes
, &num_banks
, NULL
, NULL
, NULL
, NULL
);
1713 r
= si_surface_init_2d(surf_man
, surf
, surf
->level
, surf
->bpe
, tile_mode
, num_pipes
, num_banks
, surf
->tile_split
, 0, 0);
1718 if (surf
->flags
& RADEON_SURF_SBUFFER
) {
1719 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);
1720 surf
->stencil_offset
= surf
->stencil_level
[0].offset
;
1725 static int si_surface_init(struct radeon_surface_manager
*surf_man
,
1726 struct radeon_surface
*surf
)
1728 unsigned mode
, tile_mode
, stencil_tile_mode
;
1731 /* MSAA surfaces support the 2D mode only. */
1732 if (surf
->nsamples
> 1) {
1733 surf
->flags
= RADEON_SURF_CLR(surf
->flags
, MODE
);
1734 surf
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_2D
, MODE
);
1738 mode
= (surf
->flags
>> RADEON_SURF_MODE_SHIFT
) & RADEON_SURF_MODE_MASK
;
1740 if (surf
->flags
& (RADEON_SURF_ZBUFFER
| RADEON_SURF_SBUFFER
)) {
1741 /* zbuffer only support 1D or 2D tiled surface */
1743 case RADEON_SURF_MODE_1D
:
1744 case RADEON_SURF_MODE_2D
:
1747 mode
= RADEON_SURF_MODE_1D
;
1748 surf
->flags
= RADEON_SURF_CLR(surf
->flags
, MODE
);
1749 surf
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_1D
, MODE
);
1754 r
= si_surface_sanity(surf_man
, surf
, mode
, &tile_mode
, &stencil_tile_mode
);
1759 surf
->stencil_offset
= 0;
1760 surf
->bo_alignment
= 0;
1762 /* check tiling mode */
1764 case RADEON_SURF_MODE_LINEAR
:
1765 r
= r6_surface_init_linear(surf_man
, surf
, 0, 0);
1767 case RADEON_SURF_MODE_LINEAR_ALIGNED
:
1768 r
= si_surface_init_linear_aligned(surf_man
, surf
, tile_mode
, 0, 0);
1770 case RADEON_SURF_MODE_1D
:
1771 r
= si_surface_init_1d_miptrees(surf_man
, surf
, tile_mode
, stencil_tile_mode
);
1773 case RADEON_SURF_MODE_2D
:
1774 r
= si_surface_init_2d_miptrees(surf_man
, surf
, tile_mode
, stencil_tile_mode
);
1783 * depending on surface
1785 static int si_surface_best(struct radeon_surface_manager
*surf_man
,
1786 struct radeon_surface
*surf
)
1788 unsigned mode
, tile_mode
, stencil_tile_mode
;
1791 mode
= (surf
->flags
>> RADEON_SURF_MODE_SHIFT
) & RADEON_SURF_MODE_MASK
;
1793 if (surf
->flags
& (RADEON_SURF_ZBUFFER
| RADEON_SURF_SBUFFER
) &&
1794 !(surf
->flags
& RADEON_SURF_HAS_TILE_MODE_INDEX
)) {
1795 /* depth/stencil force 1d tiling for old mesa */
1796 surf
->flags
= RADEON_SURF_CLR(surf
->flags
, MODE
);
1797 surf
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_1D
, MODE
);
1800 return si_surface_sanity(surf_man
, surf
, mode
, &tile_mode
, &stencil_tile_mode
);
1804 /* ===========================================================================
1805 * Sea Islands family
1807 #define CIK__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f)
1808 #define CIK__PIPE_CONFIG__ADDR_SURF_P2 0
1809 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16 4
1810 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16 5
1811 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32 6
1812 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32 7
1813 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8
1814 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9
1815 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10
1816 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11
1817 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12
1818 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13
1819 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14
1820 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16 16
1821 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16 17
1822 #define CIK__GB_TILE_MODE__TILE_SPLIT(x) (((x) >> 11) & 0x7)
1823 #define CIK__TILE_SPLIT__64B 0
1824 #define CIK__TILE_SPLIT__128B 1
1825 #define CIK__TILE_SPLIT__256B 2
1826 #define CIK__TILE_SPLIT__512B 3
1827 #define CIK__TILE_SPLIT__1024B 4
1828 #define CIK__TILE_SPLIT__2048B 5
1829 #define CIK__TILE_SPLIT__4096B 6
1830 #define CIK__GB_TILE_MODE__SAMPLE_SPLIT(x) (((x) >> 25) & 0x3)
1831 #define CIK__SAMPLE_SPLIT__1 0
1832 #define CIK__SAMPLE_SPLIT__2 1
1833 #define CIK__SAMPLE_SPLIT__4 2
1834 #define CIK__SAMPLE_SPLIT__8 3
1835 #define CIK__GB_MACROTILE_MODE__BANK_WIDTH(x) ((x) & 0x3)
1836 #define CIK__BANK_WIDTH__1 0
1837 #define CIK__BANK_WIDTH__2 1
1838 #define CIK__BANK_WIDTH__4 2
1839 #define CIK__BANK_WIDTH__8 3
1840 #define CIK__GB_MACROTILE_MODE__BANK_HEIGHT(x) (((x) >> 2) & 0x3)
1841 #define CIK__BANK_HEIGHT__1 0
1842 #define CIK__BANK_HEIGHT__2 1
1843 #define CIK__BANK_HEIGHT__4 2
1844 #define CIK__BANK_HEIGHT__8 3
1845 #define CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 4) & 0x3)
1846 #define CIK__MACRO_TILE_ASPECT__1 0
1847 #define CIK__MACRO_TILE_ASPECT__2 1
1848 #define CIK__MACRO_TILE_ASPECT__4 2
1849 #define CIK__MACRO_TILE_ASPECT__8 3
1850 #define CIK__GB_MACROTILE_MODE__NUM_BANKS(x) (((x) >> 6) & 0x3)
1851 #define CIK__NUM_BANKS__2_BANK 0
1852 #define CIK__NUM_BANKS__4_BANK 1
1853 #define CIK__NUM_BANKS__8_BANK 2
1854 #define CIK__NUM_BANKS__16_BANK 3
1857 static void cik_get_2d_params(struct radeon_surface_manager
*surf_man
,
1858 unsigned bpe
, unsigned nsamples
, bool is_color
,
1860 uint32_t *num_pipes
,
1861 uint32_t *tile_split_ptr
,
1862 uint32_t *num_banks
,
1863 uint32_t *macro_tile_aspect
,
1867 uint32_t gb_tile_mode
= surf_man
->hw_info
.tile_mode_array
[tile_mode
];
1868 unsigned tileb_1x
, tileb
;
1869 unsigned gb_macrotile_mode
;
1870 unsigned macrotile_index
;
1871 unsigned tile_split
, sample_split
;
1874 switch (CIK__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode
)) {
1875 case CIK__PIPE_CONFIG__ADDR_SURF_P2
:
1879 case CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16
:
1880 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16
:
1881 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32
:
1882 case CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32
:
1885 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16
:
1886 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16
:
1887 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16
:
1888 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16
:
1889 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16
:
1890 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32
:
1891 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32
:
1894 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16
:
1895 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16
:
1900 switch (CIK__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode
)) {
1902 case CIK__TILE_SPLIT__64B
:
1905 case CIK__TILE_SPLIT__128B
:
1908 case CIK__TILE_SPLIT__256B
:
1911 case CIK__TILE_SPLIT__512B
:
1914 case CIK__TILE_SPLIT__1024B
:
1917 case CIK__TILE_SPLIT__2048B
:
1920 case CIK__TILE_SPLIT__4096B
:
1924 switch (CIK__GB_TILE_MODE__SAMPLE_SPLIT(gb_tile_mode
)) {
1926 case CIK__SAMPLE_SPLIT__1
:
1929 case CIK__SAMPLE_SPLIT__2
:
1932 case CIK__SAMPLE_SPLIT__4
:
1935 case CIK__SAMPLE_SPLIT__8
:
1940 /* Adjust the tile split. */
1941 tileb_1x
= 8 * 8 * bpe
;
1943 tile_split
= MAX2(256, sample_split
* tileb_1x
);
1945 tile_split
= MIN2(surf_man
->hw_info
.row_size
, tile_split
);
1947 /* Determine the macrotile index. */
1948 tileb
= MIN2(tile_split
, nsamples
* tileb_1x
);
1950 for (macrotile_index
= 0; tileb
> 64; macrotile_index
++) {
1953 gb_macrotile_mode
= surf_man
->hw_info
.macrotile_mode_array
[macrotile_index
];
1955 if (tile_split_ptr
) {
1956 *tile_split_ptr
= tile_split
;
1959 switch (CIK__GB_MACROTILE_MODE__NUM_BANKS(gb_macrotile_mode
)) {
1961 case CIK__NUM_BANKS__2_BANK
:
1964 case CIK__NUM_BANKS__4_BANK
:
1967 case CIK__NUM_BANKS__8_BANK
:
1970 case CIK__NUM_BANKS__16_BANK
:
1975 if (macro_tile_aspect
) {
1976 switch (CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(gb_macrotile_mode
)) {
1978 case CIK__MACRO_TILE_ASPECT__1
:
1979 *macro_tile_aspect
= 1;
1981 case CIK__MACRO_TILE_ASPECT__2
:
1982 *macro_tile_aspect
= 2;
1984 case CIK__MACRO_TILE_ASPECT__4
:
1985 *macro_tile_aspect
= 4;
1987 case CIK__MACRO_TILE_ASPECT__8
:
1988 *macro_tile_aspect
= 8;
1993 switch (CIK__GB_MACROTILE_MODE__BANK_WIDTH(gb_macrotile_mode
)) {
1995 case CIK__BANK_WIDTH__1
:
1998 case CIK__BANK_WIDTH__2
:
2001 case CIK__BANK_WIDTH__4
:
2004 case CIK__BANK_WIDTH__8
:
2010 switch (CIK__GB_MACROTILE_MODE__BANK_HEIGHT(gb_macrotile_mode
)) {
2012 case CIK__BANK_HEIGHT__1
:
2015 case CIK__BANK_HEIGHT__2
:
2018 case CIK__BANK_HEIGHT__4
:
2021 case CIK__BANK_HEIGHT__8
:
2028 static int cik_init_hw_info(struct radeon_surface_manager
*surf_man
)
2030 uint32_t tiling_config
;
2031 drmVersionPtr version
;
2034 r
= radeon_get_value(surf_man
->fd
, RADEON_INFO_TILING_CONFIG
,
2040 surf_man
->hw_info
.allow_2d
= 0;
2041 version
= drmGetVersion(surf_man
->fd
);
2042 if (version
&& version
->version_minor
>= 35) {
2043 if (!radeon_get_value(surf_man
->fd
, RADEON_INFO_SI_TILE_MODE_ARRAY
, surf_man
->hw_info
.tile_mode_array
) &&
2044 !radeon_get_value(surf_man
->fd
, RADEON_INFO_CIK_MACROTILE_MODE_ARRAY
, surf_man
->hw_info
.macrotile_mode_array
)) {
2045 surf_man
->hw_info
.allow_2d
= 1;
2048 drmFreeVersion(version
);
2050 switch (tiling_config
& 0xf) {
2052 surf_man
->hw_info
.num_pipes
= 1;
2055 surf_man
->hw_info
.num_pipes
= 2;
2058 surf_man
->hw_info
.num_pipes
= 4;
2061 surf_man
->hw_info
.num_pipes
= 8;
2064 surf_man
->hw_info
.num_pipes
= 8;
2065 surf_man
->hw_info
.allow_2d
= 0;
2069 switch ((tiling_config
& 0xf0) >> 4) {
2071 surf_man
->hw_info
.num_banks
= 4;
2074 surf_man
->hw_info
.num_banks
= 8;
2077 surf_man
->hw_info
.num_banks
= 16;
2080 surf_man
->hw_info
.num_banks
= 8;
2081 surf_man
->hw_info
.allow_2d
= 0;
2085 switch ((tiling_config
& 0xf00) >> 8) {
2087 surf_man
->hw_info
.group_bytes
= 256;
2090 surf_man
->hw_info
.group_bytes
= 512;
2093 surf_man
->hw_info
.group_bytes
= 256;
2094 surf_man
->hw_info
.allow_2d
= 0;
2098 switch ((tiling_config
& 0xf000) >> 12) {
2100 surf_man
->hw_info
.row_size
= 1024;
2103 surf_man
->hw_info
.row_size
= 2048;
2106 surf_man
->hw_info
.row_size
= 4096;
2109 surf_man
->hw_info
.row_size
= 4096;
2110 surf_man
->hw_info
.allow_2d
= 0;
2116 static int cik_surface_sanity(struct radeon_surface_manager
*surf_man
,
2117 struct radeon_surface
*surf
,
2118 unsigned mode
, unsigned *tile_mode
, unsigned *stencil_tile_mode
)
2120 /* check surface dimension */
2121 if (surf
->npix_x
> 16384 || surf
->npix_y
> 16384 || surf
->npix_z
> 16384) {
2125 /* check mipmap last_level */
2126 if (surf
->last_level
> 15) {
2130 /* force 1d on kernel that can't do 2d */
2131 if (mode
> RADEON_SURF_MODE_1D
&&
2132 (!surf_man
->hw_info
.allow_2d
|| !(surf
->flags
& RADEON_SURF_HAS_TILE_MODE_INDEX
))) {
2133 if (surf
->nsamples
> 1) {
2134 fprintf(stderr
, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__
);
2137 mode
= RADEON_SURF_MODE_1D
;
2138 surf
->flags
= RADEON_SURF_CLR(surf
->flags
, MODE
);
2139 surf
->flags
|= RADEON_SURF_SET(mode
, MODE
);
2142 if (surf
->nsamples
> 1 && mode
!= RADEON_SURF_MODE_2D
) {
2146 if (!surf
->tile_split
) {
2151 surf
->tile_split
= 64;
2152 surf
->stencil_tile_split
= 64;
2156 case RADEON_SURF_MODE_2D
: {
2157 if (surf
->flags
& RADEON_SURF_Z_OR_SBUFFER
) {
2158 switch (surf
->nsamples
) {
2160 *tile_mode
= CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64
;
2164 *tile_mode
= CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128
;
2167 *tile_mode
= CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256
;
2173 if (surf
->flags
& RADEON_SURF_SBUFFER
) {
2174 *stencil_tile_mode
= *tile_mode
;
2176 cik_get_2d_params(surf_man
, 1, surf
->nsamples
, false,
2177 *stencil_tile_mode
, NULL
,
2178 &surf
->stencil_tile_split
,
2179 NULL
, NULL
, NULL
, NULL
);
2181 } else if (surf
->flags
& RADEON_SURF_SCANOUT
) {
2182 *tile_mode
= CIK_TILE_MODE_COLOR_2D_SCANOUT
;
2184 *tile_mode
= CIK_TILE_MODE_COLOR_2D
;
2187 /* retrieve tiling mode values */
2188 cik_get_2d_params(surf_man
, surf
->bpe
, surf
->nsamples
,
2189 !(surf
->flags
& RADEON_SURF_Z_OR_SBUFFER
), *tile_mode
,
2190 NULL
, &surf
->tile_split
, NULL
, &surf
->mtilea
,
2191 &surf
->bankw
, &surf
->bankh
);
2194 case RADEON_SURF_MODE_1D
:
2195 if (surf
->flags
& RADEON_SURF_SBUFFER
) {
2196 *stencil_tile_mode
= CIK_TILE_MODE_DEPTH_STENCIL_1D
;
2198 if (surf
->flags
& RADEON_SURF_ZBUFFER
) {
2199 *tile_mode
= CIK_TILE_MODE_DEPTH_STENCIL_1D
;
2200 } else if (surf
->flags
& RADEON_SURF_SCANOUT
) {
2201 *tile_mode
= SI_TILE_MODE_COLOR_1D_SCANOUT
;
2203 *tile_mode
= SI_TILE_MODE_COLOR_1D
;
2206 case RADEON_SURF_MODE_LINEAR_ALIGNED
:
2208 *tile_mode
= SI_TILE_MODE_COLOR_LINEAR_ALIGNED
;
2214 static int cik_surface_init_2d(struct radeon_surface_manager
*surf_man
,
2215 struct radeon_surface
*surf
,
2216 struct radeon_surface_level
*level
,
2217 unsigned bpe
, unsigned tile_mode
,
2218 unsigned tile_split
,
2219 unsigned num_pipes
, unsigned num_banks
,
2221 unsigned start_level
)
2223 uint64_t aligned_offset
= offset
;
2224 unsigned tilew
, tileh
, tileb_1x
, tileb
;
2225 unsigned mtilew
, mtileh
, mtileb
;
2229 /* compute tile values */
2232 tileb_1x
= tilew
* tileh
* bpe
;
2234 tile_split
= MIN2(surf_man
->hw_info
.row_size
, tile_split
);
2236 tileb
= surf
->nsamples
* tileb_1x
;
2238 /* slices per tile */
2240 if (tileb
> tile_split
&& tile_split
) {
2241 slice_pt
= tileb
/ tile_split
;
2242 tileb
= tileb
/ slice_pt
;
2245 /* macro tile width & height */
2246 mtilew
= (tilew
* surf
->bankw
* num_pipes
) * surf
->mtilea
;
2247 mtileh
= (tileh
* surf
->bankh
* num_banks
) / surf
->mtilea
;
2249 /* macro tile bytes */
2250 mtileb
= (mtilew
/ tilew
) * (mtileh
/ tileh
) * tileb
;
2252 if (start_level
<= 1) {
2253 unsigned alignment
= MAX2(256, mtileb
);
2254 surf
->bo_alignment
= MAX2(surf
->bo_alignment
, alignment
);
2256 if (aligned_offset
) {
2257 aligned_offset
= ALIGN(aligned_offset
, alignment
);
2261 /* build mipmap tree */
2262 for (i
= start_level
; i
<= surf
->last_level
; i
++) {
2263 level
[i
].mode
= RADEON_SURF_MODE_2D
;
2264 si_surf_minify_2d(surf
, level
+i
, bpe
, i
, slice_pt
, mtilew
, mtileh
, 1, mtileb
, aligned_offset
);
2265 if (level
[i
].mode
== RADEON_SURF_MODE_1D
) {
2266 switch (tile_mode
) {
2267 case CIK_TILE_MODE_COLOR_2D
:
2268 tile_mode
= SI_TILE_MODE_COLOR_1D
;
2270 case CIK_TILE_MODE_COLOR_2D_SCANOUT
:
2271 tile_mode
= SI_TILE_MODE_COLOR_1D_SCANOUT
;
2273 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64
:
2274 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128
:
2275 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256
:
2276 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512
:
2277 case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE
:
2278 tile_mode
= CIK_TILE_MODE_DEPTH_STENCIL_1D
;
2283 return si_surface_init_1d(surf_man
, surf
, level
, bpe
, tile_mode
, offset
, i
);
2285 /* level0 and first mipmap need to have alignment */
2286 aligned_offset
= offset
= surf
->bo_size
;
2288 aligned_offset
= ALIGN(aligned_offset
, surf
->bo_alignment
);
2290 if (surf
->flags
& RADEON_SURF_HAS_TILE_MODE_INDEX
) {
2291 if (surf
->level
== level
) {
2292 surf
->tiling_index
[i
] = tile_mode
;
2293 /* it's ok because stencil is done after */
2294 surf
->stencil_tiling_index
[i
] = tile_mode
;
2296 surf
->stencil_tiling_index
[i
] = tile_mode
;
2303 static int cik_surface_init_2d_miptrees(struct radeon_surface_manager
*surf_man
,
2304 struct radeon_surface
*surf
,
2305 unsigned tile_mode
, unsigned stencil_tile_mode
)
2308 uint32_t num_pipes
, num_banks
;
2310 cik_get_2d_params(surf_man
, surf
->bpe
, surf
->nsamples
,
2311 !(surf
->flags
& RADEON_SURF_Z_OR_SBUFFER
), tile_mode
,
2312 &num_pipes
, NULL
, &num_banks
, NULL
, NULL
, NULL
);
2314 r
= cik_surface_init_2d(surf_man
, surf
, surf
->level
, surf
->bpe
, tile_mode
,
2315 surf
->tile_split
, num_pipes
, num_banks
, 0, 0);
2320 if (surf
->flags
& RADEON_SURF_SBUFFER
) {
2321 r
= cik_surface_init_2d(surf_man
, surf
, surf
->stencil_level
, 1, stencil_tile_mode
,
2322 surf
->stencil_tile_split
, num_pipes
, num_banks
,
2324 surf
->stencil_offset
= surf
->stencil_level
[0].offset
;
2329 static int cik_surface_init(struct radeon_surface_manager
*surf_man
,
2330 struct radeon_surface
*surf
)
2332 unsigned mode
, tile_mode
, stencil_tile_mode
;
2335 /* MSAA surfaces support the 2D mode only. */
2336 if (surf
->nsamples
> 1) {
2337 surf
->flags
= RADEON_SURF_CLR(surf
->flags
, MODE
);
2338 surf
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_2D
, MODE
);
2342 mode
= (surf
->flags
>> RADEON_SURF_MODE_SHIFT
) & RADEON_SURF_MODE_MASK
;
2344 if (surf
->flags
& (RADEON_SURF_ZBUFFER
| RADEON_SURF_SBUFFER
)) {
2345 /* zbuffer only support 1D or 2D tiled surface */
2347 case RADEON_SURF_MODE_1D
:
2348 case RADEON_SURF_MODE_2D
:
2351 mode
= RADEON_SURF_MODE_1D
;
2352 surf
->flags
= RADEON_SURF_CLR(surf
->flags
, MODE
);
2353 surf
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_1D
, MODE
);
2358 r
= cik_surface_sanity(surf_man
, surf
, mode
, &tile_mode
, &stencil_tile_mode
);
2363 surf
->stencil_offset
= 0;
2364 surf
->bo_alignment
= 0;
2366 /* check tiling mode */
2368 case RADEON_SURF_MODE_LINEAR
:
2369 r
= r6_surface_init_linear(surf_man
, surf
, 0, 0);
2371 case RADEON_SURF_MODE_LINEAR_ALIGNED
:
2372 r
= si_surface_init_linear_aligned(surf_man
, surf
, tile_mode
, 0, 0);
2374 case RADEON_SURF_MODE_1D
:
2375 r
= si_surface_init_1d_miptrees(surf_man
, surf
, tile_mode
, stencil_tile_mode
);
2377 case RADEON_SURF_MODE_2D
:
2378 r
= cik_surface_init_2d_miptrees(surf_man
, surf
, tile_mode
, stencil_tile_mode
);
2387 * depending on surface
2389 static int cik_surface_best(struct radeon_surface_manager
*surf_man
,
2390 struct radeon_surface
*surf
)
2392 unsigned mode
, tile_mode
, stencil_tile_mode
;
2395 mode
= (surf
->flags
>> RADEON_SURF_MODE_SHIFT
) & RADEON_SURF_MODE_MASK
;
2397 if (surf
->flags
& (RADEON_SURF_ZBUFFER
| RADEON_SURF_SBUFFER
) &&
2398 !(surf
->flags
& RADEON_SURF_HAS_TILE_MODE_INDEX
)) {
2399 /* depth/stencil force 1d tiling for old mesa */
2400 surf
->flags
= RADEON_SURF_CLR(surf
->flags
, MODE
);
2401 surf
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_1D
, MODE
);
2404 return cik_surface_sanity(surf_man
, surf
, mode
, &tile_mode
, &stencil_tile_mode
);
2408 /* ===========================================================================
2411 drm_public
struct radeon_surface_manager
*
2412 radeon_surface_manager_new(int fd
)
2414 struct radeon_surface_manager
*surf_man
;
2416 surf_man
= calloc(1, sizeof(struct radeon_surface_manager
));
2417 if (surf_man
== NULL
) {
2421 if (radeon_get_value(fd
, RADEON_INFO_DEVICE_ID
, &surf_man
->device_id
)) {
2424 if (radeon_get_family(surf_man
)) {
2428 if (surf_man
->family
<= CHIP_RV740
) {
2429 if (r6_init_hw_info(surf_man
)) {
2432 surf_man
->surface_init
= &r6_surface_init
;
2433 surf_man
->surface_best
= &r6_surface_best
;
2434 } else if (surf_man
->family
<= CHIP_ARUBA
) {
2435 if (eg_init_hw_info(surf_man
)) {
2438 surf_man
->surface_init
= &eg_surface_init
;
2439 surf_man
->surface_best
= &eg_surface_best
;
2440 } else if (surf_man
->family
< CHIP_BONAIRE
) {
2441 if (si_init_hw_info(surf_man
)) {
2444 surf_man
->surface_init
= &si_surface_init
;
2445 surf_man
->surface_best
= &si_surface_best
;
2447 if (cik_init_hw_info(surf_man
)) {
2450 surf_man
->surface_init
= &cik_surface_init
;
2451 surf_man
->surface_best
= &cik_surface_best
;
2461 radeon_surface_manager_free(struct radeon_surface_manager
*surf_man
)
2466 static int radeon_surface_sanity(struct radeon_surface_manager
*surf_man
,
2467 struct radeon_surface
*surf
,
2471 if (surf_man
== NULL
|| surf_man
->surface_init
== NULL
|| surf
== NULL
) {
2475 /* all dimension must be at least 1 ! */
2476 if (!surf
->npix_x
|| !surf
->npix_y
|| !surf
->npix_z
) {
2479 if (!surf
->blk_w
|| !surf
->blk_h
|| !surf
->blk_d
) {
2482 if (!surf
->array_size
) {
2485 /* array size must be a power of 2 */
2486 surf
->array_size
= next_power_of_two(surf
->array_size
);
2488 switch (surf
->nsamples
) {
2499 case RADEON_SURF_TYPE_1D
:
2500 if (surf
->npix_y
> 1) {
2504 case RADEON_SURF_TYPE_2D
:
2505 if (surf
->npix_z
> 1) {
2509 case RADEON_SURF_TYPE_CUBEMAP
:
2510 if (surf
->npix_z
> 1) {
2513 /* deal with cubemap as they were texture array */
2514 if (surf_man
->family
>= CHIP_RV770
) {
2515 surf
->array_size
= 8;
2517 surf
->array_size
= 6;
2520 case RADEON_SURF_TYPE_3D
:
2522 case RADEON_SURF_TYPE_1D_ARRAY
:
2523 if (surf
->npix_y
> 1) {
2526 case RADEON_SURF_TYPE_2D_ARRAY
:
2535 radeon_surface_init(struct radeon_surface_manager
*surf_man
,
2536 struct radeon_surface
*surf
)
2538 unsigned mode
, type
;
2541 type
= RADEON_SURF_GET(surf
->flags
, TYPE
);
2542 mode
= RADEON_SURF_GET(surf
->flags
, MODE
);
2544 r
= radeon_surface_sanity(surf_man
, surf
, type
, mode
);
2548 return surf_man
->surface_init(surf_man
, surf
);
2552 radeon_surface_best(struct radeon_surface_manager
*surf_man
,
2553 struct radeon_surface
*surf
)
2555 unsigned mode
, type
;
2558 type
= RADEON_SURF_GET(surf
->flags
, TYPE
);
2559 mode
= RADEON_SURF_GET(surf
->flags
, MODE
);
2561 r
= radeon_surface_sanity(surf_man
, surf
, type
, mode
);
2565 return surf_man
->surface_best(surf_man
, surf
);