2 * Copyright © 2014 Advanced Micro Devices, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
27 * Marek Olšák <maraeo@gmail.com>
30 #include "radeon_drm_winsys.h"
31 #include "util/u_format.h"
32 #include <radeon_surface.h>
34 static unsigned cik_get_macro_tile_index(struct radeon_surf
*surf
)
36 unsigned index
, tileb
;
38 tileb
= 8 * 8 * surf
->bpe
;
39 tileb
= MIN2(surf
->tile_split
, tileb
);
41 for (index
= 0; tileb
> 64; index
++)
48 #define G_009910_MICRO_TILE_MODE(x) (((x) >> 0) & 0x03)
49 #define G_009910_MICRO_TILE_MODE_NEW(x) (((x) >> 22) & 0x07)
51 static void set_micro_tile_mode(struct radeon_surf
*surf
,
52 struct radeon_info
*info
)
56 if (info
->chip_class
< SI
) {
57 surf
->micro_tile_mode
= 0;
61 tile_mode
= info
->si_tile_mode_array
[surf
->tiling_index
[0]];
63 if (info
->chip_class
>= CIK
)
64 surf
->micro_tile_mode
= G_009910_MICRO_TILE_MODE_NEW(tile_mode
);
66 surf
->micro_tile_mode
= G_009910_MICRO_TILE_MODE(tile_mode
);
69 static void surf_level_winsys_to_drm(struct radeon_surface_level
*level_drm
,
70 const struct radeon_surf_level
*level_ws
,
73 level_drm
->offset
= level_ws
->offset
;
74 level_drm
->slice_size
= level_ws
->slice_size
;
75 level_drm
->nblk_x
= level_ws
->nblk_x
;
76 level_drm
->nblk_y
= level_ws
->nblk_y
;
77 level_drm
->pitch_bytes
= level_ws
->nblk_x
* bpe
;
78 level_drm
->mode
= level_ws
->mode
;
81 static void surf_level_drm_to_winsys(struct radeon_surf_level
*level_ws
,
82 const struct radeon_surface_level
*level_drm
,
85 level_ws
->offset
= level_drm
->offset
;
86 level_ws
->slice_size
= level_drm
->slice_size
;
87 level_ws
->nblk_x
= level_drm
->nblk_x
;
88 level_ws
->nblk_y
= level_drm
->nblk_y
;
89 level_ws
->mode
= level_drm
->mode
;
90 assert(level_drm
->nblk_x
* bpe
== level_drm
->pitch_bytes
);
93 static void surf_winsys_to_drm(struct radeon_surface
*surf_drm
,
94 const struct pipe_resource
*tex
,
95 unsigned flags
, unsigned bpe
,
96 enum radeon_surf_mode mode
,
97 const struct radeon_surf
*surf_ws
)
101 memset(surf_drm
, 0, sizeof(*surf_drm
));
103 surf_drm
->npix_x
= tex
->width0
;
104 surf_drm
->npix_y
= tex
->height0
;
105 surf_drm
->npix_z
= tex
->depth0
;
106 surf_drm
->blk_w
= util_format_get_blockwidth(tex
->format
);
107 surf_drm
->blk_h
= util_format_get_blockheight(tex
->format
);
109 surf_drm
->array_size
= 1;
110 surf_drm
->last_level
= tex
->last_level
;
112 surf_drm
->nsamples
= tex
->nr_samples
? tex
->nr_samples
: 1;
114 surf_drm
->flags
= flags
;
115 surf_drm
->flags
= RADEON_SURF_CLR(surf_drm
->flags
, TYPE
);
116 surf_drm
->flags
= RADEON_SURF_CLR(surf_drm
->flags
, MODE
);
117 surf_drm
->flags
|= RADEON_SURF_SET(mode
, MODE
) |
118 RADEON_SURF_HAS_SBUFFER_MIPTREE
|
119 RADEON_SURF_HAS_TILE_MODE_INDEX
;
121 switch (tex
->target
) {
122 case PIPE_TEXTURE_1D
:
123 surf_drm
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_1D
, TYPE
);
125 case PIPE_TEXTURE_RECT
:
126 case PIPE_TEXTURE_2D
:
127 surf_drm
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_2D
, TYPE
);
129 case PIPE_TEXTURE_3D
:
130 surf_drm
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_3D
, TYPE
);
132 case PIPE_TEXTURE_1D_ARRAY
:
133 surf_drm
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY
, TYPE
);
134 surf_drm
->array_size
= tex
->array_size
;
136 case PIPE_TEXTURE_CUBE_ARRAY
: /* cube array layout like 2d array */
137 assert(tex
->array_size
% 6 == 0);
139 case PIPE_TEXTURE_2D_ARRAY
:
140 surf_drm
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY
, TYPE
);
141 surf_drm
->array_size
= tex
->array_size
;
143 case PIPE_TEXTURE_CUBE
:
144 surf_drm
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_CUBEMAP
, TYPE
);
151 surf_drm
->bo_size
= surf_ws
->surf_size
;
152 surf_drm
->bo_alignment
= surf_ws
->surf_alignment
;
154 surf_drm
->bankw
= surf_ws
->bankw
;
155 surf_drm
->bankh
= surf_ws
->bankh
;
156 surf_drm
->mtilea
= surf_ws
->mtilea
;
157 surf_drm
->tile_split
= surf_ws
->tile_split
;
159 for (i
= 0; i
<= surf_drm
->last_level
; i
++) {
160 surf_level_winsys_to_drm(&surf_drm
->level
[i
], &surf_ws
->level
[i
],
161 bpe
* surf_drm
->nsamples
);
163 surf_drm
->tiling_index
[i
] = surf_ws
->tiling_index
[i
];
166 if (flags
& RADEON_SURF_SBUFFER
) {
167 surf_drm
->stencil_tile_split
= surf_ws
->stencil_tile_split
;
169 for (i
= 0; i
<= surf_drm
->last_level
; i
++) {
170 surf_level_winsys_to_drm(&surf_drm
->stencil_level
[i
],
171 &surf_ws
->stencil_level
[i
],
173 surf_drm
->stencil_tiling_index
[i
] = surf_ws
->stencil_tiling_index
[i
];
178 static void surf_drm_to_winsys(struct radeon_drm_winsys
*ws
,
179 struct radeon_surf
*surf_ws
,
180 const struct radeon_surface
*surf_drm
)
184 memset(surf_ws
, 0, sizeof(*surf_ws
));
186 surf_ws
->blk_w
= surf_drm
->blk_w
;
187 surf_ws
->blk_h
= surf_drm
->blk_h
;
188 surf_ws
->bpe
= surf_drm
->bpe
;
189 surf_ws
->is_linear
= surf_drm
->level
[0].mode
<= RADEON_SURF_MODE_LINEAR_ALIGNED
;
190 surf_ws
->flags
= surf_drm
->flags
;
192 surf_ws
->surf_size
= surf_drm
->bo_size
;
193 surf_ws
->surf_alignment
= surf_drm
->bo_alignment
;
195 surf_ws
->bankw
= surf_drm
->bankw
;
196 surf_ws
->bankh
= surf_drm
->bankh
;
197 surf_ws
->mtilea
= surf_drm
->mtilea
;
198 surf_ws
->tile_split
= surf_drm
->tile_split
;
200 surf_ws
->macro_tile_index
= cik_get_macro_tile_index(surf_ws
);
202 for (i
= 0; i
<= surf_drm
->last_level
; i
++) {
203 surf_level_drm_to_winsys(&surf_ws
->level
[i
], &surf_drm
->level
[i
],
204 surf_drm
->bpe
* surf_drm
->nsamples
);
205 surf_ws
->tiling_index
[i
] = surf_drm
->tiling_index
[i
];
208 if (surf_ws
->flags
& RADEON_SURF_SBUFFER
) {
209 surf_ws
->stencil_tile_split
= surf_drm
->stencil_tile_split
;
211 for (i
= 0; i
<= surf_drm
->last_level
; i
++) {
212 surf_level_drm_to_winsys(&surf_ws
->stencil_level
[i
],
213 &surf_drm
->stencil_level
[i
],
215 surf_ws
->stencil_tiling_index
[i
] = surf_drm
->stencil_tiling_index
[i
];
219 set_micro_tile_mode(surf_ws
, &ws
->info
);
222 static int radeon_winsys_surface_init(struct radeon_winsys
*rws
,
223 const struct pipe_resource
*tex
,
224 unsigned flags
, unsigned bpe
,
225 enum radeon_surf_mode mode
,
226 struct radeon_surf
*surf_ws
)
228 struct radeon_drm_winsys
*ws
= (struct radeon_drm_winsys
*)rws
;
229 struct radeon_surface surf_drm
;
232 surf_winsys_to_drm(&surf_drm
, tex
, flags
, bpe
, mode
, surf_ws
);
234 if (!(flags
& RADEON_SURF_IMPORTED
)) {
235 r
= radeon_surface_best(ws
->surf_man
, &surf_drm
);
240 r
= radeon_surface_init(ws
->surf_man
, &surf_drm
);
244 surf_drm_to_winsys(ws
, surf_ws
, &surf_drm
);
248 void radeon_surface_init_functions(struct radeon_drm_winsys
*ws
)
250 ws
->base
.surface_init
= radeon_winsys_surface_init
;