gallium/radeon: Multiply bpe by nsamples in surf_winsys_to_drm
[mesa.git] / src / gallium / winsys / radeon / drm / radeon_drm_surface.c
1 /*
2 * Copyright © 2014 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
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:
12 *
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.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 *
26 * Authors:
27 * Marek Olšák <maraeo@gmail.com>
28 */
29
30 #include "radeon_drm_winsys.h"
31 #include "util/u_format.h"
32 #include <radeon_surface.h>
33
34 static unsigned cik_get_macro_tile_index(struct radeon_surf *surf)
35 {
36 unsigned index, tileb;
37
38 tileb = 8 * 8 * surf->bpe;
39 tileb = MIN2(surf->tile_split, tileb);
40
41 for (index = 0; tileb > 64; index++)
42 tileb >>= 1;
43
44 assert(index < 16);
45 return index;
46 }
47
48 #define G_009910_MICRO_TILE_MODE(x) (((x) >> 0) & 0x03)
49 #define G_009910_MICRO_TILE_MODE_NEW(x) (((x) >> 22) & 0x07)
50
51 static void set_micro_tile_mode(struct radeon_surf *surf,
52 struct radeon_info *info)
53 {
54 uint32_t tile_mode;
55
56 if (info->chip_class < SI) {
57 surf->micro_tile_mode = 0;
58 return;
59 }
60
61 tile_mode = info->si_tile_mode_array[surf->tiling_index[0]];
62
63 if (info->chip_class >= CIK)
64 surf->micro_tile_mode = G_009910_MICRO_TILE_MODE_NEW(tile_mode);
65 else
66 surf->micro_tile_mode = G_009910_MICRO_TILE_MODE(tile_mode);
67 }
68
69 static void surf_level_winsys_to_drm(struct radeon_surface_level *level_drm,
70 const struct radeon_surf_level *level_ws,
71 unsigned bpe)
72 {
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;
79 }
80
81 static void surf_level_drm_to_winsys(struct radeon_surf_level *level_ws,
82 const struct radeon_surface_level *level_drm,
83 unsigned bpe)
84 {
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);
91 }
92
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)
98 {
99 int i;
100
101 memset(surf_drm, 0, sizeof(*surf_drm));
102
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);
108 surf_drm->blk_d = 1;
109 surf_drm->array_size = 1;
110 surf_drm->last_level = tex->last_level;
111 surf_drm->bpe = bpe;
112 surf_drm->nsamples = tex->nr_samples ? tex->nr_samples : 1;
113
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;
120
121 switch (tex->target) {
122 case PIPE_TEXTURE_1D:
123 surf_drm->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE);
124 break;
125 case PIPE_TEXTURE_RECT:
126 case PIPE_TEXTURE_2D:
127 surf_drm->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
128 break;
129 case PIPE_TEXTURE_3D:
130 surf_drm->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE);
131 break;
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;
135 break;
136 case PIPE_TEXTURE_CUBE_ARRAY: /* cube array layout like 2d array */
137 assert(tex->array_size % 6 == 0);
138 /* fall through */
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;
142 break;
143 case PIPE_TEXTURE_CUBE:
144 surf_drm->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_CUBEMAP, TYPE);
145 break;
146 case PIPE_BUFFER:
147 default:
148 assert(0);
149 }
150
151 surf_drm->bo_size = surf_ws->surf_size;
152 surf_drm->bo_alignment = surf_ws->surf_alignment;
153
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;
158
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);
162
163 surf_drm->tiling_index[i] = surf_ws->tiling_index[i];
164 }
165
166 if (flags & RADEON_SURF_SBUFFER) {
167 surf_drm->stencil_tile_split = surf_ws->stencil_tile_split;
168
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],
172 surf_drm->nsamples);
173 surf_drm->stencil_tiling_index[i] = surf_ws->stencil_tiling_index[i];
174 }
175 }
176 }
177
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)
181 {
182 int i;
183
184 memset(surf_ws, 0, sizeof(*surf_ws));
185
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;
191
192 surf_ws->surf_size = surf_drm->bo_size;
193 surf_ws->surf_alignment = surf_drm->bo_alignment;
194
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;
199
200 surf_ws->macro_tile_index = cik_get_macro_tile_index(surf_ws);
201
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];
206 }
207
208 if (surf_ws->flags & RADEON_SURF_SBUFFER) {
209 surf_ws->stencil_tile_split = surf_drm->stencil_tile_split;
210
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],
214 surf_drm->nsamples);
215 surf_ws->stencil_tiling_index[i] = surf_drm->stencil_tiling_index[i];
216 }
217 }
218
219 set_micro_tile_mode(surf_ws, &ws->info);
220 }
221
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)
227 {
228 struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
229 struct radeon_surface surf_drm;
230 int r;
231
232 surf_winsys_to_drm(&surf_drm, tex, flags, bpe, mode, surf_ws);
233
234 if (!(flags & RADEON_SURF_IMPORTED)) {
235 r = radeon_surface_best(ws->surf_man, &surf_drm);
236 if (r)
237 return r;
238 }
239
240 r = radeon_surface_init(ws->surf_man, &surf_drm);
241 if (r)
242 return r;
243
244 surf_drm_to_winsys(ws, surf_ws, &surf_drm);
245 return 0;
246 }
247
248 void radeon_surface_init_functions(struct radeon_drm_winsys *ws)
249 {
250 ws->base.surface_init = radeon_winsys_surface_init;
251 }