1 /*
2 * Copyright © 2011 Red Hat All Rights Reserved.
3 *
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:
11 *
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.
20 *
21 * The above copyright notice and this permission notice (including the
22 * next paragraph) shall be included in all copies or substantial portions
23 * of the Software.
24 */
25 /*
26 * Authors:
27 * Jérôme Glisse <jglisse@redhat.com>
28 */
29 #include <stdbool.h>
30 #include <assert.h>
31 #include <errno.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <sys/ioctl.h>
36 #include "drm.h"
37 #include "libdrm_macros.h"
38 #include "xf86drm.h"
39 #include "radeon_drm.h"
40 #include "radeon_surface.h"
41
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
49
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))
53
54 /* keep this private */
55 enum radeon_family {
56 CHIP_UNKNOWN,
57 CHIP_R600,
58 CHIP_RV610,
59 CHIP_RV630,
60 CHIP_RV670,
61 CHIP_RV620,
62 CHIP_RV635,
63 CHIP_RS780,
64 CHIP_RS880,
65 CHIP_RV770,
66 CHIP_RV730,
67 CHIP_RV710,
68 CHIP_RV740,
69 CHIP_CEDAR,
70 CHIP_REDWOOD,
71 CHIP_JUNIPER,
72 CHIP_CYPRESS,
73 CHIP_HEMLOCK,
74 CHIP_PALM,
75 CHIP_SUMO,
76 CHIP_SUMO2,
77 CHIP_BARTS,
78 CHIP_TURKS,
79 CHIP_CAICOS,
80 CHIP_CAYMAN,
81 CHIP_ARUBA,
82 CHIP_TAHITI,
83 CHIP_PITCAIRN,
84 CHIP_VERDE,
85 CHIP_OLAND,
86 CHIP_HAINAN,
87 CHIP_BONAIRE,
88 CHIP_KAVERI,
89 CHIP_KABINI,
90 CHIP_HAWAII,
91 CHIP_MULLINS,
92 CHIP_LAST,
93 };
94
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);
99
100 struct radeon_hw_info {
101 /* apply to r6, eg */
102 uint32_t group_bytes;
103 uint32_t num_banks;
104 uint32_t num_pipes;
105 /* apply to eg */
106 uint32_t row_size;
107 unsigned allow_2d;
108 /* apply to si */
109 uint32_t tile_mode_array[32];
110 /* apply to cik */
111 uint32_t macrotile_mode_array[16];
112 };
113
114 struct radeon_surface_manager {
115 int fd;
116 uint32_t device_id;
117 struct radeon_hw_info hw_info;
118 unsigned family;
119 hw_init_surface_t surface_init;
120 hw_best_surface_t surface_best;
121 };
122
123 /* helper */
radeon_get_value(int fd,unsigned req,uint32_t * value)124 static int radeon_get_value(int fd, unsigned req, uint32_t *value)
125 {
126 struct drm_radeon_info info = {};
127 int r;
128
129 *value = 0;
130 info.request = req;
131 info.value = (uintptr_t)value;
132 r = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info,
133 sizeof(struct drm_radeon_info));
134 return r;
135 }
136
radeon_get_family(struct radeon_surface_manager * surf_man)137 static int radeon_get_family(struct radeon_surface_manager *surf_man)
138 {
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"
142 #undef CHIPSET
143 default:
144 return -EINVAL;
145 }
146 return 0;
147 }
148
next_power_of_two(unsigned x)149 static unsigned next_power_of_two(unsigned x)
150 {
151 if (x <= 1)
152 return 1;
153
154 return (1 << ((sizeof(unsigned) * 8) - __builtin_clz(x - 1)));
155 }
156
mip_minify(unsigned size,unsigned level)157 static unsigned mip_minify(unsigned size, unsigned level)
158 {
159 unsigned val;
160
161 val = MAX2(1, size >> level);
162 if (level > 0)
163 val = next_power_of_two(val);
164 return val;
165 }
166
surf_minify(struct radeon_surface * surf,struct radeon_surface_level * surflevel,unsigned bpe,unsigned level,uint32_t xalign,uint32_t yalign,uint32_t zalign,uint64_t offset)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,
171 uint64_t offset)
172 {
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;
183 return;
184 }
185 }
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);
189
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;
193
194 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
195 }
196
197 /* ===========================================================================
198 * r600/r700 family
199 */
r6_init_hw_info(struct radeon_surface_manager * surf_man)200 static int r6_init_hw_info(struct radeon_surface_manager *surf_man)
201 {
202 uint32_t tiling_config;
203 drmVersionPtr version;
204 int r;
205
206 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
207 &tiling_config);
208 if (r) {
209 return r;
210 }
211
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;
216 }
217 drmFreeVersion(version);
218
219 switch ((tiling_config & 0xe) >> 1) {
220 case 0:
221 surf_man->hw_info.num_pipes = 1;
222 break;
223 case 1:
224 surf_man->hw_info.num_pipes = 2;
225 break;
226 case 2:
227 surf_man->hw_info.num_pipes = 4;
228 break;
229 case 3:
230 surf_man->hw_info.num_pipes = 8;
231 break;
232 default:
233 surf_man->hw_info.num_pipes = 8;
234 surf_man->hw_info.allow_2d = 0;
235 break;
236 }
237
238 switch ((tiling_config & 0x30) >> 4) {
239 case 0:
240 surf_man->hw_info.num_banks = 4;
241 break;
242 case 1:
243 surf_man->hw_info.num_banks = 8;
244 break;
245 default:
246 surf_man->hw_info.num_banks = 8;
247 surf_man->hw_info.allow_2d = 0;
248 break;
249 }
250
251 switch ((tiling_config & 0xc0) >> 6) {
252 case 0:
253 surf_man->hw_info.group_bytes = 256;
254 break;
255 case 1:
256 surf_man->hw_info.group_bytes = 512;
257 break;
258 default:
259 surf_man->hw_info.group_bytes = 256;
260 surf_man->hw_info.allow_2d = 0;
261 break;
262 }
263 return 0;
264 }
265
r6_surface_init_linear(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,uint64_t offset,unsigned start_level)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)
269 {
270 uint32_t xalign, yalign, zalign;
271 unsigned i;
272
273 /* compute alignment */
274 if (!start_level) {
275 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
276 }
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
279 */
280 xalign = MAX2(1, surf_man->hw_info.group_bytes / surf->bpe);
281 yalign = 1;
282 zalign = 1;
283 if (surf->flags & RADEON_SURF_SCANOUT) {
284 xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
285 }
286
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;
293 if (i == 0) {
294 offset = ALIGN(offset, surf->bo_alignment);
295 }
296 }
297 return 0;
298 }
299
r6_surface_init_linear_aligned(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,uint64_t offset,unsigned start_level)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)
303 {
304 uint32_t xalign, yalign, zalign;
305 unsigned i;
306
307 /* compute alignment */
308 if (!start_level) {
309 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
310 }
311 xalign = MAX2(64, surf_man->hw_info.group_bytes / surf->bpe);
312 yalign = 1;
313 zalign = 1;
314
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;
321 if (i == 0) {
322 offset = ALIGN(offset, surf->bo_alignment);
323 }
324 }
325 return 0;
326 }
327
r6_surface_init_1d(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,uint64_t offset,unsigned start_level)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)
331 {
332 uint32_t xalign, yalign, zalign, tilew;
333 unsigned i;
334
335 /* compute alignment */
336 tilew = 8;
337 xalign = surf_man->hw_info.group_bytes / (tilew * surf->bpe * surf->nsamples);
338 xalign = MAX2(tilew, xalign);
339 yalign = tilew;
340 zalign = 1;
341 if (surf->flags & RADEON_SURF_SCANOUT) {
342 xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
343 }
344 if (!start_level) {
345 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
346 }
347
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;
354 if (i == 0) {
355 offset = ALIGN(offset, surf->bo_alignment);
356 }
357 }
358 return 0;
359 }
360
r6_surface_init_2d(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,uint64_t offset,unsigned start_level)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)
364 {
365 uint32_t xalign, yalign, zalign, tilew;
366 unsigned i;
367
368 /* compute alignment */
369 tilew = 8;
370 zalign = 1;
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);
379 }
380 if (!start_level) {
381 surf->bo_alignment =
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);
386 }
387
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);
394 }
395 /* level0 and first mipmap need to have alignment */
396 offset = surf->bo_size;
397 if (i == 0) {
398 offset = ALIGN(offset, surf->bo_alignment);
399 }
400 }
401 return 0;
402 }
403
r6_surface_init(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)404 static int r6_surface_init(struct radeon_surface_manager *surf_man,
405 struct radeon_surface *surf)
406 {
407 unsigned mode;
408 int r;
409
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);
414 }
415
416 /* tiling mode */
417 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
418
419 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
420 /* zbuffer only support 1D or 2D tiled surface */
421 switch (mode) {
422 case RADEON_SURF_MODE_1D:
423 case RADEON_SURF_MODE_2D:
424 break;
425 default:
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);
429 break;
430 }
431 }
432
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__);
437 return -EFAULT;
438 }
439 mode = RADEON_SURF_MODE_1D;
440 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
441 surf->flags |= RADEON_SURF_SET(mode, MODE);
442 }
443
444 /* check surface dimension */
445 if (surf->npix_x > 8192 || surf->npix_y > 8192 || surf->npix_z > 8192) {
446 return -EINVAL;
447 }
448
449 /* check mipmap last_level */
450 if (surf->last_level > 14) {
451 return -EINVAL;
452 }
453
454 /* check tiling mode */
455 switch (mode) {
456 case RADEON_SURF_MODE_LINEAR:
457 r = r6_surface_init_linear(surf_man, surf, 0, 0);
458 break;
459 case RADEON_SURF_MODE_LINEAR_ALIGNED:
460 r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
461 break;
462 case RADEON_SURF_MODE_1D:
463 r = r6_surface_init_1d(surf_man, surf, 0, 0);
464 break;
465 case RADEON_SURF_MODE_2D:
466 r = r6_surface_init_2d(surf_man, surf, 0, 0);
467 break;
468 default:
469 return -EINVAL;
470 }
471 return r;
472 }
473
r6_surface_best(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)474 static int r6_surface_best(struct radeon_surface_manager *surf_man,
475 struct radeon_surface *surf)
476 {
477 /* no value to optimize for r6xx/r7xx */
478 return 0;
479 }
480
481
482 /* ===========================================================================
483 * evergreen family
484 */
eg_init_hw_info(struct radeon_surface_manager * surf_man)485 static int eg_init_hw_info(struct radeon_surface_manager *surf_man)
486 {
487 uint32_t tiling_config;
488 drmVersionPtr version;
489 int r;
490
491 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
492 &tiling_config);
493 if (r) {
494 return r;
495 }
496
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;
501 }
502 drmFreeVersion(version);
503
504 switch (tiling_config & 0xf) {
505 case 0:
506 surf_man->hw_info.num_pipes = 1;
507 break;
508 case 1:
509 surf_man->hw_info.num_pipes = 2;
510 break;
511 case 2:
512 surf_man->hw_info.num_pipes = 4;
513 break;
514 case 3:
515 surf_man->hw_info.num_pipes = 8;
516 break;
517 default:
518 surf_man->hw_info.num_pipes = 8;
519 surf_man->hw_info.allow_2d = 0;
520 break;
521 }
522
523 switch ((tiling_config & 0xf0) >> 4) {
524 case 0:
525 surf_man->hw_info.num_banks = 4;
526 break;
527 case 1:
528 surf_man->hw_info.num_banks = 8;
529 break;
530 case 2:
531 surf_man->hw_info.num_banks = 16;
532 break;
533 default:
534 surf_man->hw_info.num_banks = 8;
535 surf_man->hw_info.allow_2d = 0;
536 break;
537 }
538
539 switch ((tiling_config & 0xf00) >> 8) {
540 case 0:
541 surf_man->hw_info.group_bytes = 256;
542 break;
543 case 1:
544 surf_man->hw_info.group_bytes = 512;
545 break;
546 default:
547 surf_man->hw_info.group_bytes = 256;
548 surf_man->hw_info.allow_2d = 0;
549 break;
550 }
551
552 switch ((tiling_config & 0xf000) >> 12) {
553 case 0:
554 surf_man->hw_info.row_size = 1024;
555 break;
556 case 1:
557 surf_man->hw_info.row_size = 2048;
558 break;
559 case 2:
560 surf_man->hw_info.row_size = 4096;
561 break;
562 default:
563 surf_man->hw_info.row_size = 4096;
564 surf_man->hw_info.allow_2d = 0;
565 break;
566 }
567 return 0;
568 }
569
eg_surf_minify(struct radeon_surface * surf,struct radeon_surface_level * surflevel,unsigned bpe,unsigned level,unsigned slice_pt,unsigned mtilew,unsigned mtileh,unsigned mtileb,uint64_t offset)570 static void eg_surf_minify(struct radeon_surface *surf,
571 struct radeon_surface_level *surflevel,
572 unsigned bpe,
573 unsigned level,
574 unsigned slice_pt,
575 unsigned mtilew,
576 unsigned mtileh,
577 unsigned mtileb,
578 uint64_t offset)
579 {
580 unsigned mtile_pr, mtile_ps;
581
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;
592 return;
593 }
594 }
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);
598
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;
603
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;
607
608 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
609 }
610
eg_surface_init_1d(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,struct radeon_surface_level * level,unsigned bpe,uint64_t offset,unsigned start_level)611 static int eg_surface_init_1d(struct radeon_surface_manager *surf_man,
612 struct radeon_surface *surf,
613 struct radeon_surface_level *level,
614 unsigned bpe,
615 uint64_t offset, unsigned start_level)
616 {
617 uint32_t xalign, yalign, zalign, tilew;
618 unsigned i;
619
620 /* compute alignment */
621 tilew = 8;
622 xalign = surf_man->hw_info.group_bytes / (tilew * bpe * surf->nsamples);
623 xalign = MAX2(tilew, xalign);
624 yalign = tilew;
625 zalign = 1;
626 if (surf->flags & RADEON_SURF_SCANOUT) {
627 xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
628 }
629
630 if (!start_level) {
631 unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
632 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
633
634 if (offset) {
635 offset = ALIGN(offset, alignment);
636 }
637 }
638
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;
645 if (i == 0) {
646 offset = ALIGN(offset, surf->bo_alignment);
647 }
648 }
649 return 0;
650 }
651
eg_surface_init_2d(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,struct radeon_surface_level * level,unsigned bpe,unsigned tile_split,uint64_t offset,unsigned start_level)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)
657 {
658 unsigned tilew, tileh, tileb;
659 unsigned mtilew, mtileh, mtileb;
660 unsigned slice_pt;
661 unsigned i;
662
663 /* compute tile values */
664 tilew = 8;
665 tileh = 8;
666 tileb = tilew * tileh * bpe * surf->nsamples;
667 /* slices per tile */
668 slice_pt = 1;
669 if (tileb > tile_split && tile_split) {
670 slice_pt = tileb / tile_split;
671 }
672 tileb = tileb / slice_pt;
673
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;
679
680 if (!start_level) {
681 unsigned alignment = MAX2(256, mtileb);
682 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
683
684 if (offset) {
685 offset = ALIGN(offset, alignment);
686 }
687 }
688
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);
695 }
696 /* level0 and first mipmap need to have alignment */
697 offset = surf->bo_size;
698 if (i == 0) {
699 offset = ALIGN(offset, surf->bo_alignment);
700 }
701 }
702 return 0;
703 }
704
eg_surface_sanity(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,unsigned mode)705 static int eg_surface_sanity(struct radeon_surface_manager *surf_man,
706 struct radeon_surface *surf,
707 unsigned mode)
708 {
709 unsigned tileb;
710
711 /* check surface dimension */
712 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
713 return -EINVAL;
714 }
715
716 /* check mipmap last_level */
717 if (surf->last_level > 15) {
718 return -EINVAL;
719 }
720
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__);
725 return -EFAULT;
726 }
727 mode = RADEON_SURF_MODE_1D;
728 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
729 surf->flags |= RADEON_SURF_SET(mode, MODE);
730 }
731
732 /* check tile split */
733 if (mode == RADEON_SURF_MODE_2D) {
734 switch (surf->tile_split) {
735 case 64:
736 case 128:
737 case 256:
738 case 512:
739 case 1024:
740 case 2048:
741 case 4096:
742 break;
743 default:
744 return -EINVAL;
745 }
746 switch (surf->mtilea) {
747 case 1:
748 case 2:
749 case 4:
750 case 8:
751 break;
752 default:
753 return -EINVAL;
754 }
755 /* check aspect ratio */
756 if (surf_man->hw_info.num_banks < surf->mtilea) {
757 return -EINVAL;
758 }
759 /* check bank width */
760 switch (surf->bankw) {
761 case 1:
762 case 2:
763 case 4:
764 case 8:
765 break;
766 default:
767 return -EINVAL;
768 }
769 /* check bank height */
770 switch (surf->bankh) {
771 case 1:
772 case 2:
773 case 4:
774 case 8:
775 break;
776 default:
777 return -EINVAL;
778 }
779 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
780 if ((tileb * surf->bankh * surf->bankw) < surf_man->hw_info.group_bytes) {
781 return -EINVAL;
782 }
783 }
784
785 return 0;
786 }
787
eg_surface_init_1d_miptrees(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)788 static int eg_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
789 struct radeon_surface *surf)
790 {
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;
797
798 r = eg_surface_init_1d(surf_man, surf, surf->level, surf->bpe, 0, 0);
799 if (r)
800 return r;
801
802 if (is_depth_stencil) {
803 r = eg_surface_init_1d(surf_man, surf, stencil_level, 1,
804 surf->bo_size, 0);
805 surf->stencil_offset = stencil_level[0].offset;
806 }
807 return r;
808 }
809
eg_surface_init_2d_miptrees(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)810 static int eg_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
811 struct radeon_surface *surf)
812 {
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;
819
820 r = eg_surface_init_2d(surf_man, surf, surf->level, surf->bpe,
821 surf->tile_split, 0, 0);
822 if (r)
823 return r;
824
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;
829 }
830 return r;
831 }
832
eg_surface_init(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)833 static int eg_surface_init(struct radeon_surface_manager *surf_man,
834 struct radeon_surface *surf)
835 {
836 unsigned mode;
837 int r;
838
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);
843 }
844
845 /* tiling mode */
846 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
847
848 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
849 /* zbuffer only support 1D or 2D tiled surface */
850 switch (mode) {
851 case RADEON_SURF_MODE_1D:
852 case RADEON_SURF_MODE_2D:
853 break;
854 default:
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);
858 break;
859 }
860 }
861
862 r = eg_surface_sanity(surf_man, surf, mode);
863 if (r) {
864 return r;
865 }
866
867 surf->stencil_offset = 0;
868 surf->bo_alignment = 0;
869
870 /* check tiling mode */
871 switch (mode) {
872 case RADEON_SURF_MODE_LINEAR:
873 r = r6_surface_init_linear(surf_man, surf, 0, 0);
874 break;
875 case RADEON_SURF_MODE_LINEAR_ALIGNED:
876 r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
877 break;
878 case RADEON_SURF_MODE_1D:
879 r = eg_surface_init_1d_miptrees(surf_man, surf);
880 break;
881 case RADEON_SURF_MODE_2D:
882 r = eg_surface_init_2d_miptrees(surf_man, surf);
883 break;
884 default:
885 return -EINVAL;
886 }
887 return r;
888 }
889
log2_int(unsigned x)890 static unsigned log2_int(unsigned x)
891 {
892 unsigned l;
893
894 if (x < 2) {
895 return 0;
896 }
897 for (l = 2; ; l++) {
898 if ((unsigned)(1 << l) > x) {
899 return l - 1;
900 }
901 }
902 return 0;
903 }
904
905 /* compute best tile_split, bankw, bankh, mtilea
906 * depending on surface
907 */
eg_surface_best(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)908 static int eg_surface_best(struct radeon_surface_manager *surf_man,
909 struct radeon_surface *surf)
910 {
911 unsigned mode, tileb, h_over_w;
912 int r;
913
914 /* tiling mode */
915 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
916
917 /* set some default value to avoid sanity check choking on them */
918 surf->tile_split = 1024;
919 surf->bankw = 1;
920 surf->bankh = 1;
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) {
925 break;
926 }
927 }
928 if (surf->mtilea > 8) {
929 surf->mtilea = 8;
930 }
931
932 r = eg_surface_sanity(surf_man, surf, mode);
933 if (r) {
934 return r;
935 }
936
937 if (mode != RADEON_SURF_MODE_2D) {
938 /* nothing to do for non 2D tiled surface */
939 return 0;
940 }
941
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) {
946 case 2:
947 surf->tile_split = 128;
948 break;
949 case 4:
950 surf->tile_split = 128;
951 break;
952 case 8:
953 surf->tile_split = 256;
954 break;
955 case 16: /* cayman only */
956 surf->tile_split = 512;
957 break;
958 default:
959 fprintf(stderr, "radeon: Wrong number of samples %i (%i)\n",
960 surf->nsamples, __LINE__);
961 return -EINVAL;
962 }
963 surf->stencil_tile_split = 64;
964 } else {
965 /* tile split must be >= 256 for colorbuffer surfaces,
966 * SAMPLE_SPLIT = tile_split / (bpe * 64), the optimal value is 2
967 */
968 surf->tile_split = MAX2(2 * surf->bpe * 64, 256);
969 if (surf->tile_split > 4096)
970 surf->tile_split = 4096;
971 }
972 } else {
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;
976 }
977
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.
982 *
983 * fmask buffer has different optimal value figure them out once we
984 * use it.
985 */
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
989 */
990 tileb = MIN2(surf->tile_split, 64 * surf->nsamples);
991 } else {
992 tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
993 }
994
995 /* use bankw of 1 to minimize width alignment, might be interesting to
996 * increase it for large surface
997 */
998 surf->bankw = 1;
999 switch (tileb) {
1000 case 64:
1001 surf->bankh = 4;
1002 break;
1003 case 128:
1004 case 256:
1005 surf->bankh = 2;
1006 break;
1007 default:
1008 surf->bankh = 1;
1009 break;
1010 }
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) {
1014 break;
1015 }
1016 }
1017
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);
1021
1022 return 0;
1023 }
1024
1025
1026 /* ===========================================================================
1027 * Southern Islands family
1028 */
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
1070
1071
si_gb_tile_mode(uint32_t gb_tile_mode,unsigned * num_pipes,unsigned * num_banks,uint32_t * macro_tile_aspect,uint32_t * bank_w,uint32_t * bank_h,uint32_t * tile_split)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,
1076 uint32_t *bank_w,
1077 uint32_t *bank_h,
1078 uint32_t *tile_split)
1079 {
1080 if (num_pipes) {
1081 switch (SI__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1082 case SI__PIPE_CONFIG__ADDR_SURF_P2:
1083 default:
1084 *num_pipes = 2;
1085 break;
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:
1090 *num_pipes = 4;
1091 break;
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:
1099 *num_pipes = 8;
1100 break;
1101 }
1102 }
1103 if (num_banks) {
1104 switch (SI__GB_TILE_MODE__NUM_BANKS(gb_tile_mode)) {
1105 default:
1106 case SI__NUM_BANKS__2_BANK:
1107 *num_banks = 2;
1108 break;
1109 case SI__NUM_BANKS__4_BANK:
1110 *num_banks = 4;
1111 break;
1112 case SI__NUM_BANKS__8_BANK:
1113 *num_banks = 8;
1114 break;
1115 case SI__NUM_BANKS__16_BANK:
1116 *num_banks = 16;
1117 break;
1118 }
1119 }
1120 if (macro_tile_aspect) {
1121 switch (SI__GB_TILE_MODE__MACRO_TILE_ASPECT(gb_tile_mode)) {
1122 default:
1123 case SI__MACRO_TILE_ASPECT__1:
1124 *macro_tile_aspect = 1;
1125 break;
1126 case SI__MACRO_TILE_ASPECT__2:
1127 *macro_tile_aspect = 2;
1128 break;
1129 case SI__MACRO_TILE_ASPECT__4:
1130 *macro_tile_aspect = 4;
1131 break;
1132 case SI__MACRO_TILE_ASPECT__8:
1133 *macro_tile_aspect = 8;
1134 break;
1135 }
1136 }
1137 if (bank_w) {
1138 switch (SI__GB_TILE_MODE__BANK_WIDTH(gb_tile_mode)) {
1139 default:
1140 case SI__BANK_WIDTH__1:
1141 *bank_w = 1;
1142 break;
1143 case SI__BANK_WIDTH__2:
1144 *bank_w = 2;
1145 break;
1146 case SI__BANK_WIDTH__4:
1147 *bank_w = 4;
1148 break;
1149 case SI__BANK_WIDTH__8:
1150 *bank_w = 8;
1151 break;
1152 }
1153 }
1154 if (bank_h) {
1155 switch (SI__GB_TILE_MODE__BANK_HEIGHT(gb_tile_mode)) {
1156 default:
1157 case SI__BANK_HEIGHT__1:
1158 *bank_h = 1;
1159 break;
1160 case SI__BANK_HEIGHT__2:
1161 *bank_h = 2;
1162 break;
1163 case SI__BANK_HEIGHT__4:
1164 *bank_h = 4;
1165 break;
1166 case SI__BANK_HEIGHT__8:
1167 *bank_h = 8;
1168 break;
1169 }
1170 }
1171 if (tile_split) {
1172 switch (SI__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1173 default:
1174 case SI__TILE_SPLIT__64B:
1175 *tile_split = 64;
1176 break;
1177 case SI__TILE_SPLIT__128B:
1178 *tile_split = 128;
1179 break;
1180 case SI__TILE_SPLIT__256B:
1181 *tile_split = 256;
1182 break;
1183 case SI__TILE_SPLIT__512B:
1184 *tile_split = 512;
1185 break;
1186 case SI__TILE_SPLIT__1024B:
1187 *tile_split = 1024;
1188 break;
1189 case SI__TILE_SPLIT__2048B:
1190 *tile_split = 2048;
1191 break;
1192 case SI__TILE_SPLIT__4096B:
1193 *tile_split = 4096;
1194 break;
1195 }
1196 }
1197 }
1198
si_init_hw_info(struct radeon_surface_manager * surf_man)1199 static int si_init_hw_info(struct radeon_surface_manager *surf_man)
1200 {
1201 uint32_t tiling_config;
1202 drmVersionPtr version;
1203 int r;
1204
1205 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
1206 &tiling_config);
1207 if (r) {
1208 return r;
1209 }
1210
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;
1216 }
1217 }
1218 drmFreeVersion(version);
1219
1220 switch (tiling_config & 0xf) {
1221 case 0:
1222 surf_man->hw_info.num_pipes = 1;
1223 break;
1224 case 1:
1225 surf_man->hw_info.num_pipes = 2;
1226 break;
1227 case 2:
1228 surf_man->hw_info.num_pipes = 4;
1229 break;
1230 case 3:
1231 surf_man->hw_info.num_pipes = 8;
1232 break;
1233 default:
1234 surf_man->hw_info.num_pipes = 8;
1235 surf_man->hw_info.allow_2d = 0;
1236 break;
1237 }
1238
1239 switch ((tiling_config & 0xf0) >> 4) {
1240 case 0:
1241 surf_man->hw_info.num_banks = 4;
1242 break;
1243 case 1:
1244 surf_man->hw_info.num_banks = 8;
1245 break;
1246 case 2:
1247 surf_man->hw_info.num_banks = 16;
1248 break;
1249 default:
1250 surf_man->hw_info.num_banks = 8;
1251 surf_man->hw_info.allow_2d = 0;
1252 break;
1253 }
1254
1255 switch ((tiling_config & 0xf00) >> 8) {
1256 case 0:
1257 surf_man->hw_info.group_bytes = 256;
1258 break;
1259 case 1:
1260 surf_man->hw_info.group_bytes = 512;
1261 break;
1262 default:
1263 surf_man->hw_info.group_bytes = 256;
1264 surf_man->hw_info.allow_2d = 0;
1265 break;
1266 }
1267
1268 switch ((tiling_config & 0xf000) >> 12) {
1269 case 0:
1270 surf_man->hw_info.row_size = 1024;
1271 break;
1272 case 1:
1273 surf_man->hw_info.row_size = 2048;
1274 break;
1275 case 2:
1276 surf_man->hw_info.row_size = 4096;
1277 break;
1278 default:
1279 surf_man->hw_info.row_size = 4096;
1280 surf_man->hw_info.allow_2d = 0;
1281 break;
1282 }
1283 return 0;
1284 }
1285
si_surface_sanity(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,unsigned mode,unsigned * tile_mode,unsigned * stencil_tile_mode)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)
1289 {
1290 uint32_t gb_tile_mode;
1291
1292 /* check surface dimension */
1293 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
1294 return -EINVAL;
1295 }
1296
1297 /* check mipmap last_level */
1298 if (surf->last_level > 15) {
1299 return -EINVAL;
1300 }
1301
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__);
1307 return -EFAULT;
1308 }
1309 mode = RADEON_SURF_MODE_1D;
1310 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1311 surf->flags |= RADEON_SURF_SET(mode, MODE);
1312 }
1313
1314 if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
1315 return -EINVAL;
1316 }
1317
1318 if (!surf->tile_split) {
1319 /* default value */
1320 surf->mtilea = 1;
1321 surf->bankw = 1;
1322 surf->bankh = 1;
1323 surf->tile_split = 64;
1324 surf->stencil_tile_split = 64;
1325 }
1326
1327 switch (mode) {
1328 case RADEON_SURF_MODE_2D:
1329 if (surf->flags & RADEON_SURF_SBUFFER) {
1330 switch (surf->nsamples) {
1331 case 1:
1332 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1333 break;
1334 case 2:
1335 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1336 break;
1337 case 4:
1338 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1339 break;
1340 case 8:
1341 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1342 break;
1343 default:
1344 return -EINVAL;
1345 }
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);
1349 }
1350 if (surf->flags & RADEON_SURF_ZBUFFER) {
1351 switch (surf->nsamples) {
1352 case 1:
1353 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1354 break;
1355 case 2:
1356 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1357 break;
1358 case 4:
1359 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1360 break;
1361 case 8:
1362 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1363 break;
1364 default:
1365 return -EINVAL;
1366 }
1367 } else if (surf->flags & RADEON_SURF_SCANOUT) {
1368 switch (surf->bpe) {
1369 case 2:
1370 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
1371 break;
1372 case 4:
1373 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
1374 break;
1375 default:
1376 return -EINVAL;
1377 }
1378 } else {
1379 switch (surf->bpe) {
1380 case 1:
1381 *tile_mode = SI_TILE_MODE_COLOR_2D_8BPP;
1382 break;
1383 case 2:
1384 *tile_mode = SI_TILE_MODE_COLOR_2D_16BPP;
1385 break;
1386 case 4:
1387 *tile_mode = SI_TILE_MODE_COLOR_2D_32BPP;
1388 break;
1389 case 8:
1390 case 16:
1391 *tile_mode = SI_TILE_MODE_COLOR_2D_64BPP;
1392 break;
1393 default:
1394 return -EINVAL;
1395 }
1396 }
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);
1400 break;
1401 case RADEON_SURF_MODE_1D:
1402 if (surf->flags & RADEON_SURF_SBUFFER) {
1403 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1404 }
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;
1409 } else {
1410 *tile_mode = SI_TILE_MODE_COLOR_1D;
1411 }
1412 break;
1413 case RADEON_SURF_MODE_LINEAR_ALIGNED:
1414 default:
1415 *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
1416 }
1417
1418 return 0;
1419 }
1420
si_surf_minify(struct radeon_surface * surf,struct radeon_surface_level * surflevel,unsigned bpe,unsigned level,uint32_t xalign,uint32_t yalign,uint32_t zalign,uint32_t slice_align,uint64_t offset)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)
1426 {
1427 if (level == 0) {
1428 surflevel->npix_x = surf->npix_x;
1429 } else {
1430 surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1431 }
1432 surflevel->npix_y = mip_minify(surf->npix_y, level);
1433 surflevel->npix_z = mip_minify(surf->npix_z, level);
1434
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;
1439 } else {
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;
1443 }
1444
1445 surflevel->nblk_y = ALIGN(surflevel->nblk_y, yalign);
1446
1447 /* XXX: Texture sampling uses unexpectedly large pitches in some cases,
1448 * these are just guesses for the rules behind those
1449 */
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);
1457
1458 surflevel->nblk_x = ALIGN(surflevel->nblk_x, xalign);
1459 surflevel->nblk_z = ALIGN(surflevel->nblk_z, zalign);
1460
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);
1465
1466 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1467 }
1468
si_surf_minify_2d(struct radeon_surface * surf,struct radeon_surface_level * surflevel,unsigned bpe,unsigned level,unsigned slice_pt,uint32_t xalign,uint32_t yalign,uint32_t zalign,unsigned mtileb,uint64_t offset)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)
1474 {
1475 unsigned mtile_pr, mtile_ps;
1476
1477 if (level == 0) {
1478 surflevel->npix_x = surf->npix_x;
1479 } else {
1480 surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1481 }
1482 surflevel->npix_y = mip_minify(surf->npix_y, level);
1483 surflevel->npix_z = mip_minify(surf->npix_z, level);
1484
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;
1489 } else {
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;
1493 }
1494
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;
1499 return;
1500 }
1501 }
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);
1505
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;
1513
1514 surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1515 }
1516
si_surface_init_linear_aligned(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,unsigned tile_mode,uint64_t offset,unsigned start_level)1517 static int si_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
1518 struct radeon_surface *surf,
1519 unsigned tile_mode,
1520 uint64_t offset, unsigned start_level)
1521 {
1522 uint32_t xalign, yalign, zalign, slice_align;
1523 unsigned i;
1524
1525 /* compute alignment */
1526 if (!start_level) {
1527 surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
1528 }
1529 xalign = MAX2(8, 64 / surf->bpe);
1530 yalign = 1;
1531 zalign = 1;
1532 slice_align = MAX2(64 * surf->bpe, surf_man->hw_info.group_bytes);
1533
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;
1540 if (i == 0) {
1541 offset = ALIGN(offset, surf->bo_alignment);
1542 }
1543 if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1544 surf->tiling_index[i] = tile_mode;
1545 }
1546 }
1547 return 0;
1548 }
1549
si_surface_init_1d(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,struct radeon_surface_level * level,unsigned bpe,unsigned tile_mode,uint64_t offset,unsigned start_level)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)
1555 {
1556 uint32_t xalign, yalign, zalign, slice_align;
1557 unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
1558 unsigned i;
1559
1560 /* compute alignment */
1561 xalign = 8;
1562 yalign = 8;
1563 zalign = 1;
1564 slice_align = surf_man->hw_info.group_bytes;
1565 if (surf->flags & RADEON_SURF_SCANOUT) {
1566 xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
1567 }
1568
1569 if (start_level <= 1) {
1570 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1571
1572 if (offset) {
1573 offset = ALIGN(offset, alignment);
1574 }
1575 }
1576
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;
1583 if (i == 0) {
1584 offset = ALIGN(offset, alignment);
1585 }
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;
1591 } else {
1592 surf->stencil_tiling_index[i] = tile_mode;
1593 }
1594 }
1595 }
1596 return 0;
1597 }
1598
si_surface_init_1d_miptrees(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,unsigned tile_mode,unsigned stencil_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)
1602 {
1603 int r;
1604
1605 r = si_surface_init_1d(surf_man, surf, surf->level, surf->bpe, tile_mode, 0, 0);
1606 if (r) {
1607 return r;
1608 }
1609
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;
1613 }
1614 return r;
1615 }
1616
si_surface_init_2d(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,struct radeon_surface_level * level,unsigned bpe,unsigned tile_mode,unsigned num_pipes,unsigned num_banks,unsigned tile_split,uint64_t offset,unsigned start_level)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,
1623 uint64_t offset,
1624 unsigned start_level)
1625 {
1626 uint64_t aligned_offset = offset;
1627 unsigned tilew, tileh, tileb;
1628 unsigned mtilew, mtileh, mtileb;
1629 unsigned slice_pt;
1630 unsigned i;
1631
1632 /* compute tile values */
1633 tilew = 8;
1634 tileh = 8;
1635 tileb = tilew * tileh * bpe * surf->nsamples;
1636 /* slices per tile */
1637 slice_pt = 1;
1638 if (tileb > tile_split && tile_split) {
1639 slice_pt = tileb / tile_split;
1640 }
1641 tileb = tileb / slice_pt;
1642
1643 /* macro tile width & height */
1644 mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
1645 mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
1646
1647 /* macro tile bytes */
1648 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
1649
1650 if (start_level <= 1) {
1651 unsigned alignment = MAX2(256, mtileb);
1652 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1653
1654 if (aligned_offset) {
1655 aligned_offset = ALIGN(aligned_offset, alignment);
1656 }
1657 }
1658
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;
1670 break;
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;
1674 break;
1675 case SI_TILE_MODE_DEPTH_STENCIL_2D:
1676 tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1677 break;
1678 default:
1679 return -EINVAL;
1680 }
1681 return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
1682 }
1683 /* level0 and first mipmap need to have alignment */
1684 aligned_offset = offset = surf->bo_size;
1685 if (i == 0) {
1686 aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
1687 }
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;
1693 } else {
1694 surf->stencil_tiling_index[i] = tile_mode;
1695 }
1696 }
1697 }
1698 return 0;
1699 }
1700
si_surface_init_2d_miptrees(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,unsigned tile_mode,unsigned stencil_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)
1704 {
1705 unsigned num_pipes, num_banks;
1706 uint32_t gb_tile_mode;
1707 int r;
1708
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);
1712
1713 r = si_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode, num_pipes, num_banks, surf->tile_split, 0, 0);
1714 if (r) {
1715 return r;
1716 }
1717
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;
1721 }
1722 return r;
1723 }
1724
si_surface_init(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)1725 static int si_surface_init(struct radeon_surface_manager *surf_man,
1726 struct radeon_surface *surf)
1727 {
1728 unsigned mode, tile_mode, stencil_tile_mode;
1729 int r;
1730
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);
1735 }
1736
1737 /* tiling mode */
1738 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1739
1740 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
1741 /* zbuffer only support 1D or 2D tiled surface */
1742 switch (mode) {
1743 case RADEON_SURF_MODE_1D:
1744 case RADEON_SURF_MODE_2D:
1745 break;
1746 default:
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);
1750 break;
1751 }
1752 }
1753
1754 r = si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1755 if (r) {
1756 return r;
1757 }
1758
1759 surf->stencil_offset = 0;
1760 surf->bo_alignment = 0;
1761
1762 /* check tiling mode */
1763 switch (mode) {
1764 case RADEON_SURF_MODE_LINEAR:
1765 r = r6_surface_init_linear(surf_man, surf, 0, 0);
1766 break;
1767 case RADEON_SURF_MODE_LINEAR_ALIGNED:
1768 r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
1769 break;
1770 case RADEON_SURF_MODE_1D:
1771 r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1772 break;
1773 case RADEON_SURF_MODE_2D:
1774 r = si_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1775 break;
1776 default:
1777 return -EINVAL;
1778 }
1779 return r;
1780 }
1781
1782 /*
1783 * depending on surface
1784 */
si_surface_best(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)1785 static int si_surface_best(struct radeon_surface_manager *surf_man,
1786 struct radeon_surface *surf)
1787 {
1788 unsigned mode, tile_mode, stencil_tile_mode;
1789
1790 /* tiling mode */
1791 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1792
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);
1798 }
1799
1800 return si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1801 }
1802
1803
1804 /* ===========================================================================
1805 * Sea Islands family
1806 */
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
1855
1856
cik_get_2d_params(struct radeon_surface_manager * surf_man,unsigned bpe,unsigned nsamples,bool is_color,unsigned tile_mode,uint32_t * num_pipes,uint32_t * tile_split_ptr,uint32_t * num_banks,uint32_t * macro_tile_aspect,uint32_t * bank_w,uint32_t * bank_h)1857 static void cik_get_2d_params(struct radeon_surface_manager *surf_man,
1858 unsigned bpe, unsigned nsamples, bool is_color,
1859 unsigned tile_mode,
1860 uint32_t *num_pipes,
1861 uint32_t *tile_split_ptr,
1862 uint32_t *num_banks,
1863 uint32_t *macro_tile_aspect,
1864 uint32_t *bank_w,
1865 uint32_t *bank_h)
1866 {
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;
1872
1873 if (num_pipes) {
1874 switch (CIK__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1875 case CIK__PIPE_CONFIG__ADDR_SURF_P2:
1876 default:
1877 *num_pipes = 2;
1878 break;
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:
1883 *num_pipes = 4;
1884 break;
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:
1892 *num_pipes = 8;
1893 break;
1894 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16:
1895 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16:
1896 *num_pipes = 16;
1897 break;
1898 }
1899 }
1900 switch (CIK__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1901 default:
1902 case CIK__TILE_SPLIT__64B:
1903 tile_split = 64;
1904 break;
1905 case CIK__TILE_SPLIT__128B:
1906 tile_split = 128;
1907 break;
1908 case CIK__TILE_SPLIT__256B:
1909 tile_split = 256;
1910 break;
1911 case CIK__TILE_SPLIT__512B:
1912 tile_split = 512;
1913 break;
1914 case CIK__TILE_SPLIT__1024B:
1915 tile_split = 1024;
1916 break;
1917 case CIK__TILE_SPLIT__2048B:
1918 tile_split = 2048;
1919 break;
1920 case CIK__TILE_SPLIT__4096B:
1921 tile_split = 4096;
1922 break;
1923 }
1924 switch (CIK__GB_TILE_MODE__SAMPLE_SPLIT(gb_tile_mode)) {
1925 default:
1926 case CIK__SAMPLE_SPLIT__1:
1927 sample_split = 1;
1928 break;
1929 case CIK__SAMPLE_SPLIT__2:
1930 sample_split = 2;
1931 break;
1932 case CIK__SAMPLE_SPLIT__4:
1933 sample_split = 4;
1934 break;
1935 case CIK__SAMPLE_SPLIT__8:
1936 sample_split = 8;
1937 break;
1938 }
1939
1940 /* Adjust the tile split. */
1941 tileb_1x = 8 * 8 * bpe;
1942 if (is_color) {
1943 tile_split = MAX2(256, sample_split * tileb_1x);
1944 }
1945 tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
1946
1947 /* Determine the macrotile index. */
1948 tileb = MIN2(tile_split, nsamples * tileb_1x);
1949
1950 for (macrotile_index = 0; tileb > 64; macrotile_index++) {
1951 tileb >>= 1;
1952 }
1953 gb_macrotile_mode = surf_man->hw_info.macrotile_mode_array[macrotile_index];
1954
1955 if (tile_split_ptr) {
1956 *tile_split_ptr = tile_split;
1957 }
1958 if (num_banks) {
1959 switch (CIK__GB_MACROTILE_MODE__NUM_BANKS(gb_macrotile_mode)) {
1960 default:
1961 case CIK__NUM_BANKS__2_BANK:
1962 *num_banks = 2;
1963 break;
1964 case CIK__NUM_BANKS__4_BANK:
1965 *num_banks = 4;
1966 break;
1967 case CIK__NUM_BANKS__8_BANK:
1968 *num_banks = 8;
1969 break;
1970 case CIK__NUM_BANKS__16_BANK:
1971 *num_banks = 16;
1972 break;
1973 }
1974 }
1975 if (macro_tile_aspect) {
1976 switch (CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(gb_macrotile_mode)) {
1977 default:
1978 case CIK__MACRO_TILE_ASPECT__1:
1979 *macro_tile_aspect = 1;
1980 break;
1981 case CIK__MACRO_TILE_ASPECT__2:
1982 *macro_tile_aspect = 2;
1983 break;
1984 case CIK__MACRO_TILE_ASPECT__4:
1985 *macro_tile_aspect = 4;
1986 break;
1987 case CIK__MACRO_TILE_ASPECT__8:
1988 *macro_tile_aspect = 8;
1989 break;
1990 }
1991 }
1992 if (bank_w) {
1993 switch (CIK__GB_MACROTILE_MODE__BANK_WIDTH(gb_macrotile_mode)) {
1994 default:
1995 case CIK__BANK_WIDTH__1:
1996 *bank_w = 1;
1997 break;
1998 case CIK__BANK_WIDTH__2:
1999 *bank_w = 2;
2000 break;
2001 case CIK__BANK_WIDTH__4:
2002 *bank_w = 4;
2003 break;
2004 case CIK__BANK_WIDTH__8:
2005 *bank_w = 8;
2006 break;
2007 }
2008 }
2009 if (bank_h) {
2010 switch (CIK__GB_MACROTILE_MODE__BANK_HEIGHT(gb_macrotile_mode)) {
2011 default:
2012 case CIK__BANK_HEIGHT__1:
2013 *bank_h = 1;
2014 break;
2015 case CIK__BANK_HEIGHT__2:
2016 *bank_h = 2;
2017 break;
2018 case CIK__BANK_HEIGHT__4:
2019 *bank_h = 4;
2020 break;
2021 case CIK__BANK_HEIGHT__8:
2022 *bank_h = 8;
2023 break;
2024 }
2025 }
2026 }
2027
cik_init_hw_info(struct radeon_surface_manager * surf_man)2028 static int cik_init_hw_info(struct radeon_surface_manager *surf_man)
2029 {
2030 uint32_t tiling_config;
2031 drmVersionPtr version;
2032 int r;
2033
2034 r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
2035 &tiling_config);
2036 if (r) {
2037 return r;
2038 }
2039
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;
2046 }
2047 }
2048 drmFreeVersion(version);
2049
2050 switch (tiling_config & 0xf) {
2051 case 0:
2052 surf_man->hw_info.num_pipes = 1;
2053 break;
2054 case 1:
2055 surf_man->hw_info.num_pipes = 2;
2056 break;
2057 case 2:
2058 surf_man->hw_info.num_pipes = 4;
2059 break;
2060 case 3:
2061 surf_man->hw_info.num_pipes = 8;
2062 break;
2063 default:
2064 surf_man->hw_info.num_pipes = 8;
2065 surf_man->hw_info.allow_2d = 0;
2066 break;
2067 }
2068
2069 switch ((tiling_config & 0xf0) >> 4) {
2070 case 0:
2071 surf_man->hw_info.num_banks = 4;
2072 break;
2073 case 1:
2074 surf_man->hw_info.num_banks = 8;
2075 break;
2076 case 2:
2077 surf_man->hw_info.num_banks = 16;
2078 break;
2079 default:
2080 surf_man->hw_info.num_banks = 8;
2081 surf_man->hw_info.allow_2d = 0;
2082 break;
2083 }
2084
2085 switch ((tiling_config & 0xf00) >> 8) {
2086 case 0:
2087 surf_man->hw_info.group_bytes = 256;
2088 break;
2089 case 1:
2090 surf_man->hw_info.group_bytes = 512;
2091 break;
2092 default:
2093 surf_man->hw_info.group_bytes = 256;
2094 surf_man->hw_info.allow_2d = 0;
2095 break;
2096 }
2097
2098 switch ((tiling_config & 0xf000) >> 12) {
2099 case 0:
2100 surf_man->hw_info.row_size = 1024;
2101 break;
2102 case 1:
2103 surf_man->hw_info.row_size = 2048;
2104 break;
2105 case 2:
2106 surf_man->hw_info.row_size = 4096;
2107 break;
2108 default:
2109 surf_man->hw_info.row_size = 4096;
2110 surf_man->hw_info.allow_2d = 0;
2111 break;
2112 }
2113 return 0;
2114 }
2115
cik_surface_sanity(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,unsigned mode,unsigned * tile_mode,unsigned * stencil_tile_mode)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)
2119 {
2120 /* check surface dimension */
2121 if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
2122 return -EINVAL;
2123 }
2124
2125 /* check mipmap last_level */
2126 if (surf->last_level > 15) {
2127 return -EINVAL;
2128 }
2129
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__);
2135 return -EFAULT;
2136 }
2137 mode = RADEON_SURF_MODE_1D;
2138 surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2139 surf->flags |= RADEON_SURF_SET(mode, MODE);
2140 }
2141
2142 if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
2143 return -EINVAL;
2144 }
2145
2146 if (!surf->tile_split) {
2147 /* default value */
2148 surf->mtilea = 1;
2149 surf->bankw = 1;
2150 surf->bankh = 1;
2151 surf->tile_split = 64;
2152 surf->stencil_tile_split = 64;
2153 }
2154
2155 switch (mode) {
2156 case RADEON_SURF_MODE_2D: {
2157 if (surf->flags & RADEON_SURF_Z_OR_SBUFFER) {
2158 switch (surf->nsamples) {
2159 case 1:
2160 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64;
2161 break;
2162 case 2:
2163 case 4:
2164 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128;
2165 break;
2166 case 8:
2167 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256;
2168 break;
2169 default:
2170 return -EINVAL;
2171 }
2172
2173 if (surf->flags & RADEON_SURF_SBUFFER) {
2174 *stencil_tile_mode = *tile_mode;
2175
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);
2180 }
2181 } else if (surf->flags & RADEON_SURF_SCANOUT) {
2182 *tile_mode = CIK_TILE_MODE_COLOR_2D_SCANOUT;
2183 } else {
2184 *tile_mode = CIK_TILE_MODE_COLOR_2D;
2185 }
2186
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);
2192 break;
2193 }
2194 case RADEON_SURF_MODE_1D:
2195 if (surf->flags & RADEON_SURF_SBUFFER) {
2196 *stencil_tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2197 }
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;
2202 } else {
2203 *tile_mode = SI_TILE_MODE_COLOR_1D;
2204 }
2205 break;
2206 case RADEON_SURF_MODE_LINEAR_ALIGNED:
2207 default:
2208 *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
2209 }
2210
2211 return 0;
2212 }
2213
cik_surface_init_2d(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,struct radeon_surface_level * level,unsigned bpe,unsigned tile_mode,unsigned tile_split,unsigned num_pipes,unsigned num_banks,uint64_t offset,unsigned start_level)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,
2220 uint64_t offset,
2221 unsigned start_level)
2222 {
2223 uint64_t aligned_offset = offset;
2224 unsigned tilew, tileh, tileb_1x, tileb;
2225 unsigned mtilew, mtileh, mtileb;
2226 unsigned slice_pt;
2227 unsigned i;
2228
2229 /* compute tile values */
2230 tilew = 8;
2231 tileh = 8;
2232 tileb_1x = tilew * tileh * bpe;
2233
2234 tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
2235
2236 tileb = surf->nsamples * tileb_1x;
2237
2238 /* slices per tile */
2239 slice_pt = 1;
2240 if (tileb > tile_split && tile_split) {
2241 slice_pt = tileb / tile_split;
2242 tileb = tileb / slice_pt;
2243 }
2244
2245 /* macro tile width & height */
2246 mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
2247 mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
2248
2249 /* macro tile bytes */
2250 mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
2251
2252 if (start_level <= 1) {
2253 unsigned alignment = MAX2(256, mtileb);
2254 surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
2255
2256 if (aligned_offset) {
2257 aligned_offset = ALIGN(aligned_offset, alignment);
2258 }
2259 }
2260
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;
2269 break;
2270 case CIK_TILE_MODE_COLOR_2D_SCANOUT:
2271 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2272 break;
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;
2279 break;
2280 default:
2281 return -EINVAL;
2282 }
2283 return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
2284 }
2285 /* level0 and first mipmap need to have alignment */
2286 aligned_offset = offset = surf->bo_size;
2287 if (i == 0) {
2288 aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
2289 }
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;
2295 } else {
2296 surf->stencil_tiling_index[i] = tile_mode;
2297 }
2298 }
2299 }
2300 return 0;
2301 }
2302
cik_surface_init_2d_miptrees(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,unsigned tile_mode,unsigned stencil_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)
2306 {
2307 int r;
2308 uint32_t num_pipes, num_banks;
2309
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);
2313
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);
2316 if (r) {
2317 return r;
2318 }
2319
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,
2323 surf->bo_size, 0);
2324 surf->stencil_offset = surf->stencil_level[0].offset;
2325 }
2326 return r;
2327 }
2328
cik_surface_init(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)2329 static int cik_surface_init(struct radeon_surface_manager *surf_man,
2330 struct radeon_surface *surf)
2331 {
2332 unsigned mode, tile_mode, stencil_tile_mode;
2333 int r;
2334
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);
2339 }
2340
2341 /* tiling mode */
2342 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2343
2344 if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
2345 /* zbuffer only support 1D or 2D tiled surface */
2346 switch (mode) {
2347 case RADEON_SURF_MODE_1D:
2348 case RADEON_SURF_MODE_2D:
2349 break;
2350 default:
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);
2354 break;
2355 }
2356 }
2357
2358 r = cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2359 if (r) {
2360 return r;
2361 }
2362
2363 surf->stencil_offset = 0;
2364 surf->bo_alignment = 0;
2365
2366 /* check tiling mode */
2367 switch (mode) {
2368 case RADEON_SURF_MODE_LINEAR:
2369 r = r6_surface_init_linear(surf_man, surf, 0, 0);
2370 break;
2371 case RADEON_SURF_MODE_LINEAR_ALIGNED:
2372 r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
2373 break;
2374 case RADEON_SURF_MODE_1D:
2375 r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2376 break;
2377 case RADEON_SURF_MODE_2D:
2378 r = cik_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2379 break;
2380 default:
2381 return -EINVAL;
2382 }
2383 return r;
2384 }
2385
2386 /*
2387 * depending on surface
2388 */
cik_surface_best(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)2389 static int cik_surface_best(struct radeon_surface_manager *surf_man,
2390 struct radeon_surface *surf)
2391 {
2392 unsigned mode, tile_mode, stencil_tile_mode;
2393
2394 /* tiling mode */
2395 mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2396
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);
2402 }
2403
2404 return cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2405 }
2406
2407
2408 /* ===========================================================================
2409 * public API
2410 */
2411 drm_public struct radeon_surface_manager *
radeon_surface_manager_new(int fd)2412 radeon_surface_manager_new(int fd)
2413 {
2414 struct radeon_surface_manager *surf_man;
2415
2416 surf_man = calloc(1, sizeof(struct radeon_surface_manager));
2417 if (surf_man == NULL) {
2418 return NULL;
2419 }
2420 surf_man->fd = fd;
2421 if (radeon_get_value(fd, RADEON_INFO_DEVICE_ID, &surf_man->device_id)) {
2422 goto out_err;
2423 }
2424 if (radeon_get_family(surf_man)) {
2425 goto out_err;
2426 }
2427
2428 if (surf_man->family <= CHIP_RV740) {
2429 if (r6_init_hw_info(surf_man)) {
2430 goto out_err;
2431 }
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)) {
2436 goto out_err;
2437 }
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)) {
2442 goto out_err;
2443 }
2444 surf_man->surface_init = &si_surface_init;
2445 surf_man->surface_best = &si_surface_best;
2446 } else {
2447 if (cik_init_hw_info(surf_man)) {
2448 goto out_err;
2449 }
2450 surf_man->surface_init = &cik_surface_init;
2451 surf_man->surface_best = &cik_surface_best;
2452 }
2453
2454 return surf_man;
2455 out_err:
2456 free(surf_man);
2457 return NULL;
2458 }
2459
2460 drm_public void
radeon_surface_manager_free(struct radeon_surface_manager * surf_man)2461 radeon_surface_manager_free(struct radeon_surface_manager *surf_man)
2462 {
2463 free(surf_man);
2464 }
2465
radeon_surface_sanity(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,unsigned type,unsigned mode)2466 static int radeon_surface_sanity(struct radeon_surface_manager *surf_man,
2467 struct radeon_surface *surf,
2468 unsigned type,
2469 unsigned mode)
2470 {
2471 if (surf_man == NULL || surf_man->surface_init == NULL || surf == NULL) {
2472 return -EINVAL;
2473 }
2474
2475 /* all dimension must be at least 1 ! */
2476 if (!surf->npix_x || !surf->npix_y || !surf->npix_z) {
2477 return -EINVAL;
2478 }
2479 if (!surf->blk_w || !surf->blk_h || !surf->blk_d) {
2480 return -EINVAL;
2481 }
2482 if (!surf->array_size) {
2483 return -EINVAL;
2484 }
2485 /* array size must be a power of 2 */
2486 surf->array_size = next_power_of_two(surf->array_size);
2487
2488 switch (surf->nsamples) {
2489 case 1:
2490 case 2:
2491 case 4:
2492 case 8:
2493 break;
2494 default:
2495 return -EINVAL;
2496 }
2497 /* check type */
2498 switch (type) {
2499 case RADEON_SURF_TYPE_1D:
2500 if (surf->npix_y > 1) {
2501 return -EINVAL;
2502 }
2503 /* fallthrough */
2504 case RADEON_SURF_TYPE_2D:
2505 if (surf->npix_z > 1) {
2506 return -EINVAL;
2507 }
2508 break;
2509 case RADEON_SURF_TYPE_CUBEMAP:
2510 if (surf->npix_z > 1) {
2511 return -EINVAL;
2512 }
2513 /* deal with cubemap as they were texture array */
2514 if (surf_man->family >= CHIP_RV770) {
2515 surf->array_size = 8;
2516 } else {
2517 surf->array_size = 6;
2518 }
2519 break;
2520 case RADEON_SURF_TYPE_3D:
2521 break;
2522 case RADEON_SURF_TYPE_1D_ARRAY:
2523 if (surf->npix_y > 1) {
2524 return -EINVAL;
2525 }
2526 case RADEON_SURF_TYPE_2D_ARRAY:
2527 break;
2528 default:
2529 return -EINVAL;
2530 }
2531 return 0;
2532 }
2533
2534 drm_public int
radeon_surface_init(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)2535 radeon_surface_init(struct radeon_surface_manager *surf_man,
2536 struct radeon_surface *surf)
2537 {
2538 unsigned mode, type;
2539 int r;
2540
2541 type = RADEON_SURF_GET(surf->flags, TYPE);
2542 mode = RADEON_SURF_GET(surf->flags, MODE);
2543
2544 r = radeon_surface_sanity(surf_man, surf, type, mode);
2545 if (r) {
2546 return r;
2547 }
2548 return surf_man->surface_init(surf_man, surf);
2549 }
2550
2551 drm_public int
radeon_surface_best(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)2552 radeon_surface_best(struct radeon_surface_manager *surf_man,
2553 struct radeon_surface *surf)
2554 {
2555 unsigned mode, type;
2556 int r;
2557
2558 type = RADEON_SURF_GET(surf->flags, TYPE);
2559 mode = RADEON_SURF_GET(surf->flags, MODE);
2560
2561 r = radeon_surface_sanity(surf_man, surf, type, mode);
2562 if (r) {
2563 return r;
2564 }
2565 return surf_man->surface_best(surf_man, surf);
2566 }
2567