555db8d9e6665503eef29d6f3b822b9c852aa238
[platform/upstream/libdrm.git] / radeon / radeon_surface.c
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/mman.h>
36 #include <sys/ioctl.h>
37 #include "drm.h"
38 #include "xf86drm.h"
39 #include "radeon_drm.h"
40 #include "radeon_surface.h"
41
42 #define ALIGN(value, alignment) (((value) + alignment - 1) & ~(alignment - 1))
43 #define MAX2(A, B)              ((A) > (B) ? (A) : (B))
44 #define MIN2(A, B)              ((A) < (B) ? (A) : (B))
45
46 /* keep this private */
47 enum radeon_family {
48     CHIP_UNKNOWN,
49     CHIP_R600,
50     CHIP_RV610,
51     CHIP_RV630,
52     CHIP_RV670,
53     CHIP_RV620,
54     CHIP_RV635,
55     CHIP_RS780,
56     CHIP_RS880,
57     CHIP_RV770,
58     CHIP_RV730,
59     CHIP_RV710,
60     CHIP_RV740,
61     CHIP_CEDAR,
62     CHIP_REDWOOD,
63     CHIP_JUNIPER,
64     CHIP_CYPRESS,
65     CHIP_HEMLOCK,
66     CHIP_PALM,
67     CHIP_SUMO,
68     CHIP_SUMO2,
69     CHIP_BARTS,
70     CHIP_TURKS,
71     CHIP_CAICOS,
72     CHIP_CAYMAN,
73     CHIP_ARUBA,
74     CHIP_TAHITI,
75     CHIP_PITCAIRN,
76     CHIP_VERDE,
77     CHIP_OLAND,
78     CHIP_HAINAN,
79     CHIP_BONAIRE,
80     CHIP_KAVERI,
81     CHIP_KABINI,
82     CHIP_HAWAII,
83     CHIP_LAST,
84 };
85
86 typedef int (*hw_init_surface_t)(struct radeon_surface_manager *surf_man,
87                                  struct radeon_surface *surf);
88 typedef int (*hw_best_surface_t)(struct radeon_surface_manager *surf_man,
89                                  struct radeon_surface *surf);
90
91 struct radeon_hw_info {
92     /* apply to r6, eg */
93     uint32_t                        group_bytes;
94     uint32_t                        num_banks;
95     uint32_t                        num_pipes;
96     /* apply to eg */
97     uint32_t                        row_size;
98     unsigned                        allow_2d;
99     /* apply to si */
100     uint32_t                        tile_mode_array[32];
101     /* apply to cik */
102     uint32_t                        macrotile_mode_array[16];
103 };
104
105 struct radeon_surface_manager {
106     int                         fd;
107     uint32_t                    device_id;
108     struct radeon_hw_info       hw_info;
109     unsigned                    family;
110     hw_init_surface_t           surface_init;
111     hw_best_surface_t           surface_best;
112 };
113
114 /* helper */
115 static int radeon_get_value(int fd, unsigned req, uint32_t *value)
116 {
117     struct drm_radeon_info info = {};
118     int r;
119
120     *value = 0;
121     info.request = req;
122     info.value = (uintptr_t)value;
123     r = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info,
124                             sizeof(struct drm_radeon_info));
125     return r;
126 }
127
128 static int radeon_get_family(struct radeon_surface_manager *surf_man)
129 {
130     switch (surf_man->device_id) {
131 #define CHIPSET(pci_id, name, fam) case pci_id: surf_man->family = CHIP_##fam; break;
132 #include "r600_pci_ids.h"
133 #undef CHIPSET
134     default:
135         return -EINVAL;
136     }
137     return 0;
138 }
139
140 static unsigned next_power_of_two(unsigned x)
141 {
142    if (x <= 1)
143        return 1;
144
145    return (1 << ((sizeof(unsigned) * 8) - __builtin_clz(x - 1)));
146 }
147
148 static unsigned mip_minify(unsigned size, unsigned level)
149 {
150     unsigned val;
151
152     val = MAX2(1, size >> level);
153     if (level > 0)
154         val = next_power_of_two(val);
155     return val;
156 }
157
158 static void surf_minify(struct radeon_surface *surf,
159                         struct radeon_surface_level *surflevel,
160                         unsigned bpe, unsigned level,
161                         uint32_t xalign, uint32_t yalign, uint32_t zalign,
162                         unsigned offset)
163 {
164     surflevel->npix_x = mip_minify(surf->npix_x, level);
165     surflevel->npix_y = mip_minify(surf->npix_y, level);
166     surflevel->npix_z = mip_minify(surf->npix_z, level);
167     surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
168     surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
169     surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
170     if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
171         !(surf->flags & RADEON_SURF_FMASK)) {
172         if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
173             surflevel->mode = RADEON_SURF_MODE_1D;
174             return;
175         }
176     }
177     surflevel->nblk_x  = ALIGN(surflevel->nblk_x, xalign);
178     surflevel->nblk_y  = ALIGN(surflevel->nblk_y, yalign);
179     surflevel->nblk_z  = ALIGN(surflevel->nblk_z, zalign);
180
181     surflevel->offset = offset;
182     surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
183     surflevel->slice_size = surflevel->pitch_bytes * surflevel->nblk_y;
184
185     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
186 }
187
188 /* ===========================================================================
189  * r600/r700 family
190  */
191 static int r6_init_hw_info(struct radeon_surface_manager *surf_man)
192 {
193     uint32_t tiling_config;
194     drmVersionPtr version;
195     int r;
196
197     r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
198                          &tiling_config);
199     if (r) {
200         return r;
201     }
202
203     surf_man->hw_info.allow_2d = 0;
204     version = drmGetVersion(surf_man->fd);
205     if (version && version->version_minor >= 14) {
206         surf_man->hw_info.allow_2d = 1;
207     }
208     drmFreeVersion(version);
209
210     switch ((tiling_config & 0xe) >> 1) {
211     case 0:
212         surf_man->hw_info.num_pipes = 1;
213         break;
214     case 1:
215         surf_man->hw_info.num_pipes = 2;
216         break;
217     case 2:
218         surf_man->hw_info.num_pipes = 4;
219         break;
220     case 3:
221         surf_man->hw_info.num_pipes = 8;
222         break;
223     default:
224         surf_man->hw_info.num_pipes = 8;
225         surf_man->hw_info.allow_2d = 0;
226         break;
227     }
228
229     switch ((tiling_config & 0x30) >> 4) {
230     case 0:
231         surf_man->hw_info.num_banks = 4;
232         break;
233     case 1:
234         surf_man->hw_info.num_banks = 8;
235         break;
236     default:
237         surf_man->hw_info.num_banks = 8;
238         surf_man->hw_info.allow_2d = 0;
239         break;
240     }
241
242     switch ((tiling_config & 0xc0) >> 6) {
243     case 0:
244         surf_man->hw_info.group_bytes = 256;
245         break;
246     case 1:
247         surf_man->hw_info.group_bytes = 512;
248         break;
249     default:
250         surf_man->hw_info.group_bytes = 256;
251         surf_man->hw_info.allow_2d = 0;
252         break;
253     }
254     return 0;
255 }
256
257 static int r6_surface_init_linear(struct radeon_surface_manager *surf_man,
258                                   struct radeon_surface *surf,
259                                   uint64_t offset, unsigned start_level)
260 {
261     uint32_t xalign, yalign, zalign;
262     unsigned i;
263
264     /* compute alignment */
265     if (!start_level) {
266         surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
267     }
268     /* the 32 alignment is for scanout, cb or db but to allow texture to be
269      * easily bound as such we force this alignment to all surface
270      */
271     xalign = MAX2(1, surf_man->hw_info.group_bytes / surf->bpe);
272     yalign = 1;
273     zalign = 1;
274     if (surf->flags & RADEON_SURF_SCANOUT) {
275         xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
276     }
277
278     /* build mipmap tree */
279     for (i = start_level; i <= surf->last_level; i++) {
280         surf->level[i].mode = RADEON_SURF_MODE_LINEAR;
281         surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
282         /* level0 and first mipmap need to have alignment */
283         offset = surf->bo_size;
284         if ((i == 0)) {
285             offset = ALIGN(offset, surf->bo_alignment);
286         }
287     }
288     return 0;
289 }
290
291 static int r6_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
292                                           struct radeon_surface *surf,
293                                           uint64_t offset, unsigned start_level)
294 {
295     uint32_t xalign, yalign, zalign;
296     unsigned i;
297
298     /* compute alignment */
299     if (!start_level) {
300         surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
301     }
302     xalign = MAX2(64, surf_man->hw_info.group_bytes / surf->bpe);
303     yalign = 1;
304     zalign = 1;
305
306     /* build mipmap tree */
307     for (i = start_level; i <= surf->last_level; i++) {
308         surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
309         surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
310         /* level0 and first mipmap need to have alignment */
311         offset = surf->bo_size;
312         if ((i == 0)) {
313             offset = ALIGN(offset, surf->bo_alignment);
314         }
315     }
316     return 0;
317 }
318
319 static int r6_surface_init_1d(struct radeon_surface_manager *surf_man,
320                               struct radeon_surface *surf,
321                               uint64_t offset, unsigned start_level)
322 {
323     uint32_t xalign, yalign, zalign, tilew;
324     unsigned i;
325
326     /* compute alignment */
327     tilew = 8;
328     xalign = surf_man->hw_info.group_bytes / (tilew * surf->bpe * surf->nsamples);
329     xalign = MAX2(tilew, xalign);
330     yalign = tilew;
331     zalign = 1;
332     if (surf->flags & RADEON_SURF_SCANOUT) {
333         xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
334     }
335     if (!start_level) {
336         surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
337     }
338
339     /* build mipmap tree */
340     for (i = start_level; i <= surf->last_level; i++) {
341         surf->level[i].mode = RADEON_SURF_MODE_1D;
342         surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
343         /* level0 and first mipmap need to have alignment */
344         offset = surf->bo_size;
345         if ((i == 0)) {
346             offset = ALIGN(offset, surf->bo_alignment);
347         }
348     }
349     return 0;
350 }
351
352 static int r6_surface_init_2d(struct radeon_surface_manager *surf_man,
353                               struct radeon_surface *surf,
354                               uint64_t offset, unsigned start_level)
355 {
356     uint32_t xalign, yalign, zalign, tilew;
357     unsigned i;
358
359     /* compute alignment */
360     tilew = 8;
361     zalign = 1;
362     xalign = (surf_man->hw_info.group_bytes * surf_man->hw_info.num_banks) /
363              (tilew * surf->bpe * surf->nsamples);
364     xalign = MAX2(tilew * surf_man->hw_info.num_banks, xalign);
365     yalign = tilew * surf_man->hw_info.num_pipes;
366     if (surf->flags & RADEON_SURF_SCANOUT) {
367         xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
368     }
369     if (!start_level) {
370         surf->bo_alignment =
371             MAX2(surf_man->hw_info.num_pipes *
372                  surf_man->hw_info.num_banks *
373                  surf->nsamples * surf->bpe * 64,
374                  xalign * yalign * surf->nsamples * surf->bpe);
375     }
376
377     /* build mipmap tree */
378     for (i = start_level; i <= surf->last_level; i++) {
379         surf->level[i].mode = RADEON_SURF_MODE_2D;
380         surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
381         if (surf->level[i].mode == RADEON_SURF_MODE_1D) {
382             return r6_surface_init_1d(surf_man, surf, offset, i);
383         }
384         /* level0 and first mipmap need to have alignment */
385         offset = surf->bo_size;
386         if ((i == 0)) {
387             offset = ALIGN(offset, surf->bo_alignment);
388         }
389     }
390     return 0;
391 }
392
393 static int r6_surface_init(struct radeon_surface_manager *surf_man,
394                            struct radeon_surface *surf)
395 {
396     unsigned mode;
397     int r;
398
399     /* MSAA surfaces support the 2D mode only. */
400     if (surf->nsamples > 1) {
401         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
402         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
403     }
404
405     /* tiling mode */
406     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
407
408     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
409         /* zbuffer only support 1D or 2D tiled surface */
410         switch (mode) {
411         case RADEON_SURF_MODE_1D:
412         case RADEON_SURF_MODE_2D:
413             break;
414         default:
415             mode = RADEON_SURF_MODE_1D;
416             surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
417             surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
418             break;
419         }
420     }
421
422     /* force 1d on kernel that can't do 2d */
423     if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) {
424         if (surf->nsamples > 1) {
425             fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__);
426             return -EFAULT;
427         }
428         mode = RADEON_SURF_MODE_1D;
429         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
430         surf->flags |= RADEON_SURF_SET(mode, MODE);
431     }
432
433     /* check surface dimension */
434     if (surf->npix_x > 8192 || surf->npix_y > 8192 || surf->npix_z > 8192) {
435         return -EINVAL;
436     }
437
438     /* check mipmap last_level */
439     if (surf->last_level > 14) {
440         return -EINVAL;
441     }
442
443     /* check tiling mode */
444     switch (mode) {
445     case RADEON_SURF_MODE_LINEAR:
446         r = r6_surface_init_linear(surf_man, surf, 0, 0);
447         break;
448     case RADEON_SURF_MODE_LINEAR_ALIGNED:
449         r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
450         break;
451     case RADEON_SURF_MODE_1D:
452         r = r6_surface_init_1d(surf_man, surf, 0, 0);
453         break;
454     case RADEON_SURF_MODE_2D:
455         r = r6_surface_init_2d(surf_man, surf, 0, 0);
456         break;
457     default:
458         return -EINVAL;
459     }
460     return r;
461 }
462
463 static int r6_surface_best(struct radeon_surface_manager *surf_man,
464                            struct radeon_surface *surf)
465 {
466     /* no value to optimize for r6xx/r7xx */
467     return 0;
468 }
469
470
471 /* ===========================================================================
472  * evergreen family
473  */
474 static int eg_init_hw_info(struct radeon_surface_manager *surf_man)
475 {
476     uint32_t tiling_config;
477     drmVersionPtr version;
478     int r;
479
480     r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
481                          &tiling_config);
482     if (r) {
483         return r;
484     }
485
486     surf_man->hw_info.allow_2d = 0;
487     version = drmGetVersion(surf_man->fd);
488     if (version && version->version_minor >= 16) {
489         surf_man->hw_info.allow_2d = 1;
490     }
491     drmFreeVersion(version);
492
493     switch (tiling_config & 0xf) {
494     case 0:
495         surf_man->hw_info.num_pipes = 1;
496         break;
497     case 1:
498         surf_man->hw_info.num_pipes = 2;
499         break;
500     case 2:
501         surf_man->hw_info.num_pipes = 4;
502         break;
503     case 3:
504         surf_man->hw_info.num_pipes = 8;
505         break;
506     default:
507         surf_man->hw_info.num_pipes = 8;
508         surf_man->hw_info.allow_2d = 0;
509         break;
510     }
511
512     switch ((tiling_config & 0xf0) >> 4) {
513     case 0:
514         surf_man->hw_info.num_banks = 4;
515         break;
516     case 1:
517         surf_man->hw_info.num_banks = 8;
518         break;
519     case 2:
520         surf_man->hw_info.num_banks = 16;
521         break;
522     default:
523         surf_man->hw_info.num_banks = 8;
524         surf_man->hw_info.allow_2d = 0;
525         break;
526     }
527
528     switch ((tiling_config & 0xf00) >> 8) {
529     case 0:
530         surf_man->hw_info.group_bytes = 256;
531         break;
532     case 1:
533         surf_man->hw_info.group_bytes = 512;
534         break;
535     default:
536         surf_man->hw_info.group_bytes = 256;
537         surf_man->hw_info.allow_2d = 0;
538         break;
539     }
540
541     switch ((tiling_config & 0xf000) >> 12) {
542     case 0:
543         surf_man->hw_info.row_size = 1024;
544         break;
545     case 1:
546         surf_man->hw_info.row_size = 2048;
547         break;
548     case 2:
549         surf_man->hw_info.row_size = 4096;
550         break;
551     default:
552         surf_man->hw_info.row_size = 4096;
553         surf_man->hw_info.allow_2d = 0;
554         break;
555     }
556     return 0;
557 }
558
559 static void eg_surf_minify(struct radeon_surface *surf,
560                            struct radeon_surface_level *surflevel,
561                            unsigned bpe,
562                            unsigned level,
563                            unsigned slice_pt,
564                            unsigned mtilew,
565                            unsigned mtileh,
566                            unsigned mtileb,
567                            unsigned offset)
568 {
569     unsigned mtile_pr, mtile_ps;
570
571     surflevel->npix_x = mip_minify(surf->npix_x, level);
572     surflevel->npix_y = mip_minify(surf->npix_y, level);
573     surflevel->npix_z = mip_minify(surf->npix_z, level);
574     surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
575     surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
576     surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
577     if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
578         !(surf->flags & RADEON_SURF_FMASK)) {
579         if (surflevel->nblk_x < mtilew || surflevel->nblk_y < mtileh) {
580             surflevel->mode = RADEON_SURF_MODE_1D;
581             return;
582         }
583     }
584     surflevel->nblk_x  = ALIGN(surflevel->nblk_x, mtilew);
585     surflevel->nblk_y  = ALIGN(surflevel->nblk_y, mtileh);
586     surflevel->nblk_z  = ALIGN(surflevel->nblk_z, 1);
587
588     /* macro tile per row */
589     mtile_pr = surflevel->nblk_x / mtilew;
590     /* macro tile per slice */
591     mtile_ps = (mtile_pr * surflevel->nblk_y) / mtileh;
592
593     surflevel->offset = offset;
594     surflevel->pitch_bytes = surflevel->nblk_x * bpe * slice_pt;
595     surflevel->slice_size = mtile_ps * mtileb * slice_pt;
596
597     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
598 }
599
600 static int eg_surface_init_1d(struct radeon_surface_manager *surf_man,
601                               struct radeon_surface *surf,
602                               struct radeon_surface_level *level,
603                               unsigned bpe,
604                               uint64_t offset, unsigned start_level)
605 {
606     uint32_t xalign, yalign, zalign, tilew;
607     unsigned i;
608
609     /* compute alignment */
610     tilew = 8;
611     xalign = surf_man->hw_info.group_bytes / (tilew * bpe * surf->nsamples);
612     xalign = MAX2(tilew, xalign);
613     yalign = tilew;
614     zalign = 1;
615     if (surf->flags & RADEON_SURF_SCANOUT) {
616         xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
617     }
618
619     if (!start_level) {
620         unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
621         surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
622
623         if (offset) {
624             offset = ALIGN(offset, alignment);
625         }
626     }
627
628     /* build mipmap tree */
629     for (i = start_level; i <= surf->last_level; i++) {
630         level[i].mode = RADEON_SURF_MODE_1D;
631         surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, offset);
632         /* level0 and first mipmap need to have alignment */
633         offset = surf->bo_size;
634         if ((i == 0)) {
635             offset = ALIGN(offset, surf->bo_alignment);
636         }
637     }
638     return 0;
639 }
640
641 static int eg_surface_init_2d(struct radeon_surface_manager *surf_man,
642                               struct radeon_surface *surf,
643                               struct radeon_surface_level *level,
644                               unsigned bpe, unsigned tile_split,
645                               uint64_t offset, unsigned start_level)
646 {
647     unsigned tilew, tileh, tileb;
648     unsigned mtilew, mtileh, mtileb;
649     unsigned slice_pt;
650     unsigned i;
651
652     /* compute tile values */
653     tilew = 8;
654     tileh = 8;
655     tileb = tilew * tileh * bpe * surf->nsamples;
656     /* slices per tile */
657     slice_pt = 1;
658     if (tileb > tile_split) {
659         slice_pt = tileb / tile_split;
660     }
661     tileb = tileb / slice_pt;
662
663     /* macro tile width & height */
664     mtilew = (tilew * surf->bankw * surf_man->hw_info.num_pipes) * surf->mtilea;
665     mtileh = (tileh * surf->bankh * surf_man->hw_info.num_banks) / surf->mtilea;
666     /* macro tile bytes */
667     mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
668
669     if (!start_level) {
670         unsigned alignment = MAX2(256, mtileb);
671         surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
672
673         if (offset) {
674             offset = ALIGN(offset, alignment);
675         }
676     }
677
678     /* build mipmap tree */
679     for (i = start_level; i <= surf->last_level; i++) {
680         level[i].mode = RADEON_SURF_MODE_2D;
681         eg_surf_minify(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, mtileb, offset);
682         if (level[i].mode == RADEON_SURF_MODE_1D) {
683             return eg_surface_init_1d(surf_man, surf, level, bpe, offset, i);
684         }
685         /* level0 and first mipmap need to have alignment */
686         offset = surf->bo_size;
687         if ((i == 0)) {
688             offset = ALIGN(offset, surf->bo_alignment);
689         }
690     }
691     return 0;
692 }
693
694 static int eg_surface_sanity(struct radeon_surface_manager *surf_man,
695                              struct radeon_surface *surf,
696                              unsigned mode)
697 {
698     unsigned tileb;
699
700     /* check surface dimension */
701     if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
702         return -EINVAL;
703     }
704
705     /* check mipmap last_level */
706     if (surf->last_level > 15) {
707         return -EINVAL;
708     }
709
710     /* force 1d on kernel that can't do 2d */
711     if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) {
712         if (surf->nsamples > 1) {
713             fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__);
714             return -EFAULT;
715         }
716         mode = RADEON_SURF_MODE_1D;
717         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
718         surf->flags |= RADEON_SURF_SET(mode, MODE);
719     }
720
721     /* check tile split */
722     if (mode == RADEON_SURF_MODE_2D) {
723         switch (surf->tile_split) {
724         case 64:
725         case 128:
726         case 256:
727         case 512:
728         case 1024:
729         case 2048:
730         case 4096:
731             break;
732         default:
733             return -EINVAL;
734         }
735         switch (surf->mtilea) {
736         case 1:
737         case 2:
738         case 4:
739         case 8:
740             break;
741         default:
742             return -EINVAL;
743         }
744         /* check aspect ratio */
745         if (surf_man->hw_info.num_banks < surf->mtilea) {
746             return -EINVAL;
747         }
748         /* check bank width */
749         switch (surf->bankw) {
750         case 1:
751         case 2:
752         case 4:
753         case 8:
754             break;
755         default:
756             return -EINVAL;
757         }
758         /* check bank height */
759         switch (surf->bankh) {
760         case 1:
761         case 2:
762         case 4:
763         case 8:
764             break;
765         default:
766             return -EINVAL;
767         }
768         tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
769         if ((tileb * surf->bankh * surf->bankw) < surf_man->hw_info.group_bytes) {
770             return -EINVAL;
771         }
772     }
773
774     return 0;
775 }
776
777 static int eg_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
778                                        struct radeon_surface *surf)
779 {
780     unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
781     int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
782     /* Old libdrm headers didn't have stencil_level in it. This prevents crashes. */
783     struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
784     struct radeon_surface_level *stencil_level =
785         (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
786
787     r = eg_surface_init_1d(surf_man, surf, surf->level, surf->bpe, 0, 0);
788     if (r)
789         return r;
790
791     if (is_depth_stencil) {
792         r = eg_surface_init_1d(surf_man, surf, stencil_level, 1,
793                                surf->bo_size, 0);
794         surf->stencil_offset = stencil_level[0].offset;
795     }
796     return r;
797 }
798
799 static int eg_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
800                                        struct radeon_surface *surf)
801 {
802     unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
803     int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
804     /* Old libdrm headers didn't have stencil_level in it. This prevents crashes. */
805     struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
806     struct radeon_surface_level *stencil_level =
807         (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
808
809     r = eg_surface_init_2d(surf_man, surf, surf->level, surf->bpe,
810                            surf->tile_split, 0, 0);
811     if (r)
812         return r;
813
814     if (is_depth_stencil) {
815         r = eg_surface_init_2d(surf_man, surf, stencil_level, 1,
816                                surf->stencil_tile_split, surf->bo_size, 0);
817         surf->stencil_offset = stencil_level[0].offset;
818     }
819     return r;
820 }
821
822 static int eg_surface_init(struct radeon_surface_manager *surf_man,
823                            struct radeon_surface *surf)
824 {
825     unsigned mode;
826     int r;
827
828     /* MSAA surfaces support the 2D mode only. */
829     if (surf->nsamples > 1) {
830         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
831         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
832     }
833
834     /* tiling mode */
835     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
836
837     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
838         /* zbuffer only support 1D or 2D tiled surface */
839         switch (mode) {
840         case RADEON_SURF_MODE_1D:
841         case RADEON_SURF_MODE_2D:
842             break;
843         default:
844             mode = RADEON_SURF_MODE_1D;
845             surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
846             surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
847             break;
848         }
849     }
850
851     r = eg_surface_sanity(surf_man, surf, mode);
852     if (r) {
853         return r;
854     }
855
856     surf->stencil_offset = 0;
857     surf->bo_alignment = 0;
858
859     /* check tiling mode */
860     switch (mode) {
861     case RADEON_SURF_MODE_LINEAR:
862         r = r6_surface_init_linear(surf_man, surf, 0, 0);
863         break;
864     case RADEON_SURF_MODE_LINEAR_ALIGNED:
865         r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
866         break;
867     case RADEON_SURF_MODE_1D:
868         r = eg_surface_init_1d_miptrees(surf_man, surf);
869         break;
870     case RADEON_SURF_MODE_2D:
871         r = eg_surface_init_2d_miptrees(surf_man, surf);
872         break;
873     default:
874         return -EINVAL;
875     }
876     return r;
877 }
878
879 static unsigned log2_int(unsigned x)
880 {
881     unsigned l;
882
883     if (x < 2) {
884         return 0;
885     }
886     for (l = 2; ; l++) {
887         if ((unsigned)(1 << l) > x) {
888             return l - 1;
889         }
890     }
891     return 0;
892 }
893
894 /* compute best tile_split, bankw, bankh, mtilea
895  * depending on surface
896  */
897 static int eg_surface_best(struct radeon_surface_manager *surf_man,
898                            struct radeon_surface *surf)
899 {
900     unsigned mode, tileb, h_over_w;
901     int r;
902
903     /* tiling mode */
904     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
905
906     /* set some default value to avoid sanity check choking on them */
907     surf->tile_split = 1024;
908     surf->bankw = 1;
909     surf->bankh = 1;
910     surf->mtilea = surf_man->hw_info.num_banks;
911     tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
912     for (; surf->bankh <= 8; surf->bankh *= 2) {
913         if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
914             break;
915         }
916     }
917     if (surf->mtilea > 8) {
918         surf->mtilea = 8;
919     }
920
921     r = eg_surface_sanity(surf_man, surf, mode);
922     if (r) {
923         return r;
924     }
925
926     if (mode != RADEON_SURF_MODE_2D) {
927         /* nothing to do for non 2D tiled surface */
928         return 0;
929     }
930
931     /* Tweak TILE_SPLIT for performance here. */
932     if (surf->nsamples > 1) {
933         if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
934             switch (surf->nsamples) {
935             case 2:
936                 surf->tile_split = 128;
937                 break;
938             case 4:
939                 surf->tile_split = 128;
940                 break;
941             case 8:
942                 surf->tile_split = 256;
943                 break;
944             case 16: /* cayman only */
945                 surf->tile_split = 512;
946                 break;
947             default:
948                 fprintf(stderr, "radeon: Wrong number of samples %i (%i)\n",
949                         surf->nsamples, __LINE__);
950                 return -EINVAL;
951             }
952             surf->stencil_tile_split = 64;
953         } else {
954             /* tile split must be >= 256 for colorbuffer surfaces */
955             surf->tile_split = MAX2(surf->nsamples * surf->bpe * 64, 256);
956             if (surf->tile_split > 4096)
957                 surf->tile_split = 4096;
958         }
959     } else {
960         /* set tile split to row size */
961         surf->tile_split = surf_man->hw_info.row_size;
962         surf->stencil_tile_split = surf_man->hw_info.row_size / 2;
963     }
964
965     /* bankw or bankh greater than 1 increase alignment requirement, not
966      * sure if it's worth using smaller bankw & bankh to stick with 2D
967      * tiling on small surface rather than falling back to 1D tiling.
968      * Use recommanded value based on tile size for now.
969      *
970      * fmask buffer has different optimal value figure them out once we
971      * use it.
972      */
973     if (surf->flags & RADEON_SURF_SBUFFER) {
974         /* assume 1 bytes for stencil, we optimize for stencil as stencil
975          * and depth shares surface values
976          */
977         tileb = MIN2(surf->tile_split, 64 * surf->nsamples);
978     } else {
979         tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
980     }
981
982     /* use bankw of 1 to minimize width alignment, might be interesting to
983      * increase it for large surface
984      */
985     surf->bankw = 1;
986     switch (tileb) {
987     case 64:
988         surf->bankh = 4;
989         break;
990     case 128:
991     case 256:
992         surf->bankh = 2;
993         break;
994     default:
995         surf->bankh = 1;
996         break;
997     }
998     /* double check the constraint */
999     for (; surf->bankh <= 8; surf->bankh *= 2) {
1000         if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
1001             break;
1002         }
1003     }
1004
1005     h_over_w = (((surf->bankh * surf_man->hw_info.num_banks) << 16) /
1006                 (surf->bankw * surf_man->hw_info.num_pipes)) >> 16;
1007     surf->mtilea = 1 << (log2_int(h_over_w) >> 1);
1008
1009     return 0;
1010 }
1011
1012
1013 /* ===========================================================================
1014  * Southern Islands family
1015  */
1016 #define SI__GB_TILE_MODE__PIPE_CONFIG(x)        (((x) >> 6) & 0x1f)
1017 #define     SI__PIPE_CONFIG__ADDR_SURF_P2               0
1018 #define     SI__PIPE_CONFIG__ADDR_SURF_P4_8x16          4
1019 #define     SI__PIPE_CONFIG__ADDR_SURF_P4_16x16         5
1020 #define     SI__PIPE_CONFIG__ADDR_SURF_P4_16x32         6
1021 #define     SI__PIPE_CONFIG__ADDR_SURF_P4_32x32         7
1022 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16    8
1023 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16    9
1024 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16    10
1025 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16   11
1026 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16   12
1027 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32   13
1028 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32   14
1029 #define SI__GB_TILE_MODE__TILE_SPLIT(x)         (((x) >> 11) & 0x7)
1030 #define     SI__TILE_SPLIT__64B                         0
1031 #define     SI__TILE_SPLIT__128B                        1
1032 #define     SI__TILE_SPLIT__256B                        2
1033 #define     SI__TILE_SPLIT__512B                        3
1034 #define     SI__TILE_SPLIT__1024B                       4
1035 #define     SI__TILE_SPLIT__2048B                       5
1036 #define     SI__TILE_SPLIT__4096B                       6
1037 #define SI__GB_TILE_MODE__BANK_WIDTH(x)         (((x) >> 14) & 0x3)
1038 #define     SI__BANK_WIDTH__1                           0
1039 #define     SI__BANK_WIDTH__2                           1
1040 #define     SI__BANK_WIDTH__4                           2
1041 #define     SI__BANK_WIDTH__8                           3
1042 #define SI__GB_TILE_MODE__BANK_HEIGHT(x)        (((x) >> 16) & 0x3)
1043 #define     SI__BANK_HEIGHT__1                          0
1044 #define     SI__BANK_HEIGHT__2                          1
1045 #define     SI__BANK_HEIGHT__4                          2
1046 #define     SI__BANK_HEIGHT__8                          3
1047 #define SI__GB_TILE_MODE__MACRO_TILE_ASPECT(x)  (((x) >> 18) & 0x3)
1048 #define     SI__MACRO_TILE_ASPECT__1                    0
1049 #define     SI__MACRO_TILE_ASPECT__2                    1
1050 #define     SI__MACRO_TILE_ASPECT__4                    2
1051 #define     SI__MACRO_TILE_ASPECT__8                    3
1052 #define SI__GB_TILE_MODE__NUM_BANKS(x)          (((x) >> 20) & 0x3)
1053 #define     SI__NUM_BANKS__2_BANK                       0
1054 #define     SI__NUM_BANKS__4_BANK                       1
1055 #define     SI__NUM_BANKS__8_BANK                       2
1056 #define     SI__NUM_BANKS__16_BANK                      3
1057
1058
1059 static void si_gb_tile_mode(uint32_t gb_tile_mode,
1060                             unsigned *num_pipes,
1061                             unsigned *num_banks,
1062                             uint32_t *macro_tile_aspect,
1063                             uint32_t *bank_w,
1064                             uint32_t *bank_h,
1065                             uint32_t *tile_split)
1066 {
1067     if (num_pipes) {
1068         switch (SI__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1069         case SI__PIPE_CONFIG__ADDR_SURF_P2:
1070         default:
1071             *num_pipes = 2;
1072             break;
1073         case SI__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1074         case SI__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1075         case SI__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1076         case SI__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1077             *num_pipes = 4;
1078             break;
1079         case SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1080         case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1081         case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1082         case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1083         case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1084         case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1085         case SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1086             *num_pipes = 8;
1087             break;
1088         }
1089     }
1090     if (num_banks) {
1091         switch (SI__GB_TILE_MODE__NUM_BANKS(gb_tile_mode)) {
1092         default:
1093         case SI__NUM_BANKS__2_BANK:
1094             *num_banks = 2;
1095             break;
1096         case SI__NUM_BANKS__4_BANK:
1097             *num_banks = 4;
1098             break;
1099         case SI__NUM_BANKS__8_BANK:
1100             *num_banks = 8;
1101             break;
1102         case SI__NUM_BANKS__16_BANK:
1103             *num_banks = 16;
1104             break;
1105         }
1106     }
1107     if (macro_tile_aspect) {
1108         switch (SI__GB_TILE_MODE__MACRO_TILE_ASPECT(gb_tile_mode)) {
1109         default:
1110         case SI__MACRO_TILE_ASPECT__1:
1111             *macro_tile_aspect = 1;
1112             break;
1113         case SI__MACRO_TILE_ASPECT__2:
1114             *macro_tile_aspect = 2;
1115             break;
1116         case SI__MACRO_TILE_ASPECT__4:
1117             *macro_tile_aspect = 4;
1118             break;
1119         case SI__MACRO_TILE_ASPECT__8:
1120             *macro_tile_aspect = 8;
1121             break;
1122         }
1123     }
1124     if (bank_w) {
1125         switch (SI__GB_TILE_MODE__BANK_WIDTH(gb_tile_mode)) {
1126         default:
1127         case SI__BANK_WIDTH__1:
1128             *bank_w = 1;
1129             break;
1130         case SI__BANK_WIDTH__2:
1131             *bank_w = 2;
1132             break;
1133         case SI__BANK_WIDTH__4:
1134             *bank_w = 4;
1135             break;
1136         case SI__BANK_WIDTH__8:
1137             *bank_w = 8;
1138             break;
1139         }
1140     }
1141     if (bank_h) {
1142         switch (SI__GB_TILE_MODE__BANK_HEIGHT(gb_tile_mode)) {
1143         default:
1144         case SI__BANK_HEIGHT__1:
1145             *bank_h = 1;
1146             break;
1147         case SI__BANK_HEIGHT__2:
1148             *bank_h = 2;
1149             break;
1150         case SI__BANK_HEIGHT__4:
1151             *bank_h = 4;
1152             break;
1153         case SI__BANK_HEIGHT__8:
1154             *bank_h = 8;
1155             break;
1156         }
1157     }
1158     if (tile_split) {
1159         switch (SI__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1160         default:
1161         case SI__TILE_SPLIT__64B:
1162             *tile_split = 64;
1163             break;
1164         case SI__TILE_SPLIT__128B:
1165             *tile_split = 128;
1166             break;
1167         case SI__TILE_SPLIT__256B:
1168             *tile_split = 256;
1169             break;
1170         case SI__TILE_SPLIT__512B:
1171             *tile_split = 512;
1172             break;
1173         case SI__TILE_SPLIT__1024B:
1174             *tile_split = 1024;
1175             break;
1176         case SI__TILE_SPLIT__2048B:
1177             *tile_split = 2048;
1178             break;
1179         case SI__TILE_SPLIT__4096B:
1180             *tile_split = 4096;
1181             break;
1182         }
1183     }
1184 }
1185
1186 static int si_init_hw_info(struct radeon_surface_manager *surf_man)
1187 {
1188     uint32_t tiling_config;
1189     drmVersionPtr version;
1190     int r;
1191
1192     r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
1193                          &tiling_config);
1194     if (r) {
1195         return r;
1196     }
1197
1198     surf_man->hw_info.allow_2d = 0;
1199     version = drmGetVersion(surf_man->fd);
1200     if (version && version->version_minor >= 33) {
1201         if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array)) {
1202             surf_man->hw_info.allow_2d = 1;
1203         }
1204     }
1205     drmFreeVersion(version);
1206
1207     switch (tiling_config & 0xf) {
1208     case 0:
1209         surf_man->hw_info.num_pipes = 1;
1210         break;
1211     case 1:
1212         surf_man->hw_info.num_pipes = 2;
1213         break;
1214     case 2:
1215         surf_man->hw_info.num_pipes = 4;
1216         break;
1217     case 3:
1218         surf_man->hw_info.num_pipes = 8;
1219         break;
1220     default:
1221         surf_man->hw_info.num_pipes = 8;
1222         surf_man->hw_info.allow_2d = 0;
1223         break;
1224     }
1225
1226     switch ((tiling_config & 0xf0) >> 4) {
1227     case 0:
1228         surf_man->hw_info.num_banks = 4;
1229         break;
1230     case 1:
1231         surf_man->hw_info.num_banks = 8;
1232         break;
1233     case 2:
1234         surf_man->hw_info.num_banks = 16;
1235         break;
1236     default:
1237         surf_man->hw_info.num_banks = 8;
1238         surf_man->hw_info.allow_2d = 0;
1239         break;
1240     }
1241
1242     switch ((tiling_config & 0xf00) >> 8) {
1243     case 0:
1244         surf_man->hw_info.group_bytes = 256;
1245         break;
1246     case 1:
1247         surf_man->hw_info.group_bytes = 512;
1248         break;
1249     default:
1250         surf_man->hw_info.group_bytes = 256;
1251         surf_man->hw_info.allow_2d = 0;
1252         break;
1253     }
1254
1255     switch ((tiling_config & 0xf000) >> 12) {
1256     case 0:
1257         surf_man->hw_info.row_size = 1024;
1258         break;
1259     case 1:
1260         surf_man->hw_info.row_size = 2048;
1261         break;
1262     case 2:
1263         surf_man->hw_info.row_size = 4096;
1264         break;
1265     default:
1266         surf_man->hw_info.row_size = 4096;
1267         surf_man->hw_info.allow_2d = 0;
1268         break;
1269     }
1270     return 0;
1271 }
1272
1273 static int si_surface_sanity(struct radeon_surface_manager *surf_man,
1274                              struct radeon_surface *surf,
1275                              unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
1276 {
1277     uint32_t gb_tile_mode;
1278
1279     /* check surface dimension */
1280     if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
1281         return -EINVAL;
1282     }
1283
1284     /* check mipmap last_level */
1285     if (surf->last_level > 15) {
1286         return -EINVAL;
1287     }
1288
1289     /* force 1d on kernel that can't do 2d */
1290     if (mode > RADEON_SURF_MODE_1D &&
1291         (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
1292         if (surf->nsamples > 1) {
1293             fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
1294             return -EFAULT;
1295         }
1296         mode = RADEON_SURF_MODE_1D;
1297         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1298         surf->flags |= RADEON_SURF_SET(mode, MODE);
1299     }
1300
1301     if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
1302         return -EINVAL;
1303     }
1304
1305     if (!surf->tile_split) {
1306         /* default value */
1307         surf->mtilea = 1;
1308         surf->bankw = 1;
1309         surf->bankw = 1;
1310         surf->tile_split = 64;
1311         surf->stencil_tile_split = 64;
1312     }
1313
1314     switch (mode) {
1315     case RADEON_SURF_MODE_2D:
1316         if (surf->flags & RADEON_SURF_SBUFFER) {
1317             switch (surf->nsamples) {
1318             case 1:
1319                 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1320                 break;
1321             case 2:
1322                 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1323                 break;
1324             case 4:
1325                 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1326                 break;
1327             case 8:
1328                 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1329                 break;
1330             default:
1331                 return -EINVAL;
1332             }
1333             /* retrieve tiling mode value */
1334             gb_tile_mode = surf_man->hw_info.tile_mode_array[*stencil_tile_mode];
1335             si_gb_tile_mode(gb_tile_mode, NULL, NULL, NULL, NULL, NULL, &surf->stencil_tile_split);
1336         }
1337         if (surf->flags & RADEON_SURF_ZBUFFER) {
1338             switch (surf->nsamples) {
1339             case 1:
1340                 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1341                 break;
1342             case 2:
1343                 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1344                 break;
1345             case 4:
1346                 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1347                 break;
1348             case 8:
1349                 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1350                 break;
1351             default:
1352                 return -EINVAL;
1353             }
1354         } else if (surf->flags & RADEON_SURF_SCANOUT) {
1355             switch (surf->bpe) {
1356             case 2:
1357                 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
1358                 break;
1359             case 4:
1360                 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
1361                 break;
1362             default:
1363                 return -EINVAL;
1364             }
1365         } else {
1366             switch (surf->bpe) {
1367             case 1:
1368                 *tile_mode = SI_TILE_MODE_COLOR_2D_8BPP;
1369                 break;
1370             case 2:
1371                 *tile_mode = SI_TILE_MODE_COLOR_2D_16BPP;
1372                 break;
1373             case 4:
1374                 *tile_mode = SI_TILE_MODE_COLOR_2D_32BPP;
1375                 break;
1376             case 8:
1377             case 16:
1378                 *tile_mode = SI_TILE_MODE_COLOR_2D_64BPP;
1379                 break;
1380             default:
1381                 return -EINVAL;
1382             }
1383         }
1384         /* retrieve tiling mode value */
1385         gb_tile_mode = surf_man->hw_info.tile_mode_array[*tile_mode];
1386         si_gb_tile_mode(gb_tile_mode, NULL, NULL, &surf->mtilea, &surf->bankw, &surf->bankh, &surf->tile_split);
1387         break;
1388     case RADEON_SURF_MODE_1D:
1389         if (surf->flags & RADEON_SURF_SBUFFER) {
1390             *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1391         }
1392         if (surf->flags & RADEON_SURF_ZBUFFER) {
1393             *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1394         } else if (surf->flags & RADEON_SURF_SCANOUT) {
1395             *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1396         } else {
1397             *tile_mode = SI_TILE_MODE_COLOR_1D;
1398         }
1399         break;
1400     case RADEON_SURF_MODE_LINEAR_ALIGNED:
1401     default:
1402         *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
1403     }
1404
1405     return 0;
1406 }
1407
1408 static void si_surf_minify(struct radeon_surface *surf,
1409                            struct radeon_surface_level *surflevel,
1410                            unsigned bpe, unsigned level,
1411                            uint32_t xalign, uint32_t yalign, uint32_t zalign,
1412                            uint32_t slice_align, unsigned offset)
1413 {
1414     if (level == 0) {
1415         surflevel->npix_x = surf->npix_x;
1416     } else {
1417         surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1418     }
1419     surflevel->npix_y = mip_minify(surf->npix_y, level);
1420     surflevel->npix_z = mip_minify(surf->npix_z, level);
1421
1422     if (level == 0 && surf->last_level > 0) {
1423         surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1424         surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1425         surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1426     } else {
1427         surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1428         surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1429         surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1430     }
1431
1432     surflevel->nblk_y  = ALIGN(surflevel->nblk_y, yalign);
1433
1434     /* XXX: Texture sampling uses unexpectedly large pitches in some cases,
1435      * these are just guesses for the rules behind those
1436      */
1437     if (level == 0 && surf->last_level == 0)
1438         /* Non-mipmap pitch padded to slice alignment */
1439         /* Using just bpe here breaks stencil blitting; surf->bpe works. */
1440         xalign = MAX2(xalign, slice_align / surf->bpe);
1441     else if (surflevel->mode == RADEON_SURF_MODE_LINEAR_ALIGNED)
1442         /* Small rows evenly distributed across slice */
1443         xalign = MAX2(xalign, slice_align / bpe / surflevel->nblk_y);
1444
1445     surflevel->nblk_x  = ALIGN(surflevel->nblk_x, xalign);
1446     surflevel->nblk_z  = ALIGN(surflevel->nblk_z, zalign);
1447
1448     surflevel->offset = offset;
1449     surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
1450     surflevel->slice_size = ALIGN(surflevel->pitch_bytes * surflevel->nblk_y, slice_align);
1451
1452     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1453 }
1454
1455 static void si_surf_minify_2d(struct radeon_surface *surf,
1456                               struct radeon_surface_level *surflevel,
1457                               unsigned bpe, unsigned level, unsigned slice_pt,
1458                               uint32_t xalign, uint32_t yalign, uint32_t zalign,
1459                               unsigned mtileb, unsigned offset)
1460 {
1461     unsigned mtile_pr, mtile_ps;
1462
1463     if (level == 0) {
1464         surflevel->npix_x = surf->npix_x;
1465     } else {
1466         surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1467     }
1468     surflevel->npix_y = mip_minify(surf->npix_y, level);
1469     surflevel->npix_z = mip_minify(surf->npix_z, level);
1470
1471     if (level == 0 && surf->last_level > 0) {
1472         surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1473         surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1474         surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1475     } else {
1476         surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1477         surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1478         surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1479     }
1480
1481     if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
1482         !(surf->flags & RADEON_SURF_FMASK)) {
1483         if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
1484             surflevel->mode = RADEON_SURF_MODE_1D;
1485             return;
1486         }
1487     }
1488     surflevel->nblk_x  = ALIGN(surflevel->nblk_x, xalign);
1489     surflevel->nblk_y  = ALIGN(surflevel->nblk_y, yalign);
1490     surflevel->nblk_z  = ALIGN(surflevel->nblk_z, zalign);
1491
1492     /* macro tile per row */
1493     mtile_pr = surflevel->nblk_x / xalign;
1494     /* macro tile per slice */
1495     mtile_ps = (mtile_pr * surflevel->nblk_y) / yalign;
1496     surflevel->offset = offset;
1497     surflevel->pitch_bytes = surflevel->nblk_x * bpe * slice_pt;
1498     surflevel->slice_size = mtile_ps * mtileb * slice_pt;
1499
1500     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1501 }
1502
1503 static int si_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
1504                                           struct radeon_surface *surf,
1505                                           unsigned tile_mode,
1506                                           uint64_t offset, unsigned start_level)
1507 {
1508     uint32_t xalign, yalign, zalign, slice_align;
1509     unsigned i;
1510
1511     /* compute alignment */
1512     if (!start_level) {
1513         surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
1514     }
1515     xalign = MAX2(8, 64 / surf->bpe);
1516     yalign = 1;
1517     zalign = 1;
1518     slice_align = MAX2(64 * surf->bpe, surf_man->hw_info.group_bytes);
1519
1520     /* build mipmap tree */
1521     for (i = start_level; i <= surf->last_level; i++) {
1522         surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
1523         si_surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, slice_align, offset);
1524         /* level0 and first mipmap need to have alignment */
1525         offset = surf->bo_size;
1526         if ((i == 0)) {
1527             offset = ALIGN(offset, surf->bo_alignment);
1528         }
1529         if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1530             surf->tiling_index[i] = tile_mode;
1531         }
1532     }
1533     return 0;
1534 }
1535
1536 static int si_surface_init_1d(struct radeon_surface_manager *surf_man,
1537                               struct radeon_surface *surf,
1538                               struct radeon_surface_level *level,
1539                               unsigned bpe, unsigned tile_mode,
1540                               uint64_t offset, unsigned start_level)
1541 {
1542     uint32_t xalign, yalign, zalign, slice_align;
1543     unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
1544     unsigned i;
1545
1546     /* compute alignment */
1547     xalign = 8;
1548     yalign = 8;
1549     zalign = 1;
1550     slice_align = surf_man->hw_info.group_bytes;
1551     if (surf->flags & RADEON_SURF_SCANOUT) {
1552         xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
1553     }
1554
1555     if (start_level <= 1) {
1556         surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1557
1558         if (offset) {
1559             offset = ALIGN(offset, alignment);
1560         }
1561     }
1562
1563     /* build mipmap tree */
1564     for (i = start_level; i <= surf->last_level; i++) {
1565         level[i].mode = RADEON_SURF_MODE_1D;
1566         si_surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, slice_align, offset);
1567         /* level0 and first mipmap need to have alignment */
1568         offset = surf->bo_size;
1569         if ((i == 0)) {
1570             offset = ALIGN(offset, alignment);
1571         }
1572         if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1573             if (surf->level == level) {
1574                 surf->tiling_index[i] = tile_mode;
1575                 /* it's ok because stencil is done after */
1576                 surf->stencil_tiling_index[i] = tile_mode;
1577             } else {
1578                 surf->stencil_tiling_index[i] = tile_mode;
1579             }
1580         }
1581     }
1582     return 0;
1583 }
1584
1585 static int si_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
1586                                        struct radeon_surface *surf,
1587                                        unsigned tile_mode, unsigned stencil_tile_mode)
1588 {
1589     int r;
1590
1591     r = si_surface_init_1d(surf_man, surf, surf->level, surf->bpe, tile_mode, 0, 0);
1592     if (r) {
1593         return r;
1594     }
1595
1596     if (surf->flags & RADEON_SURF_SBUFFER) {
1597         r = si_surface_init_1d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode, surf->bo_size, 0);
1598         surf->stencil_offset = surf->stencil_level[0].offset;
1599     }
1600     return r;
1601 }
1602
1603 static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
1604                               struct radeon_surface *surf,
1605                               struct radeon_surface_level *level,
1606                               unsigned bpe, unsigned tile_mode,
1607                               unsigned num_pipes, unsigned num_banks,
1608                               unsigned tile_split,
1609                               uint64_t offset,
1610                               unsigned start_level)
1611 {
1612     uint64_t aligned_offset = offset;
1613     unsigned tilew, tileh, tileb;
1614     unsigned mtilew, mtileh, mtileb;
1615     unsigned slice_pt;
1616     unsigned i;
1617
1618     /* compute tile values */
1619     tilew = 8;
1620     tileh = 8;
1621     tileb = tilew * tileh * bpe * surf->nsamples;
1622     /* slices per tile */
1623     slice_pt = 1;
1624     if (tileb > tile_split) {
1625         slice_pt = tileb / tile_split;
1626     }
1627     tileb = tileb / slice_pt;
1628
1629     /* macro tile width & height */
1630     mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
1631     mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
1632
1633     /* macro tile bytes */
1634     mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
1635
1636     if (start_level <= 1) {
1637         unsigned alignment = MAX2(256, mtileb);
1638         surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1639
1640         if (aligned_offset) {
1641             aligned_offset = ALIGN(aligned_offset, alignment);
1642         }
1643     }
1644
1645     /* build mipmap tree */
1646     for (i = start_level; i <= surf->last_level; i++) {
1647         level[i].mode = RADEON_SURF_MODE_2D;
1648         si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
1649         if (level[i].mode == RADEON_SURF_MODE_1D) {
1650             switch (tile_mode) {
1651             case SI_TILE_MODE_COLOR_2D_8BPP:
1652             case SI_TILE_MODE_COLOR_2D_16BPP:
1653             case SI_TILE_MODE_COLOR_2D_32BPP:
1654             case SI_TILE_MODE_COLOR_2D_64BPP:
1655                 tile_mode = SI_TILE_MODE_COLOR_1D;
1656                 break;
1657             case SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP:
1658             case SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP:
1659                 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1660                 break;
1661             case SI_TILE_MODE_DEPTH_STENCIL_2D:
1662                 tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1663                 break;
1664             default:
1665                 return -EINVAL;
1666             }
1667             return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
1668         }
1669         /* level0 and first mipmap need to have alignment */
1670         aligned_offset = surf->bo_size;
1671         if ((i == 0)) {
1672             aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
1673         }
1674         if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1675             if (surf->level == level) {
1676                 surf->tiling_index[i] = tile_mode;
1677                 /* it's ok because stencil is done after */
1678                 surf->stencil_tiling_index[i] = tile_mode;
1679             } else {
1680                 surf->stencil_tiling_index[i] = tile_mode;
1681             }
1682         }
1683     }
1684     return 0;
1685 }
1686
1687 static int si_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
1688                                        struct radeon_surface *surf,
1689                                        unsigned tile_mode, unsigned stencil_tile_mode)
1690 {
1691     unsigned num_pipes, num_banks;
1692     uint32_t gb_tile_mode;
1693     int r;
1694
1695     /* retrieve tiling mode value */
1696     gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1697     si_gb_tile_mode(gb_tile_mode, &num_pipes, &num_banks, NULL, NULL, NULL, NULL);
1698
1699     r = si_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode, num_pipes, num_banks, surf->tile_split, 0, 0);
1700     if (r) {
1701         return r;
1702     }
1703
1704     if (surf->flags & RADEON_SURF_SBUFFER) {
1705         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);
1706         surf->stencil_offset = surf->stencil_level[0].offset;
1707     }
1708     return r;
1709 }
1710
1711 static int si_surface_init(struct radeon_surface_manager *surf_man,
1712                            struct radeon_surface *surf)
1713 {
1714     unsigned mode, tile_mode, stencil_tile_mode;
1715     int r;
1716
1717     /* MSAA surfaces support the 2D mode only. */
1718     if (surf->nsamples > 1) {
1719         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1720         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
1721     }
1722
1723     /* tiling mode */
1724     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1725
1726     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
1727         /* zbuffer only support 1D or 2D tiled surface */
1728         switch (mode) {
1729         case RADEON_SURF_MODE_1D:
1730         case RADEON_SURF_MODE_2D:
1731             break;
1732         default:
1733             mode = RADEON_SURF_MODE_1D;
1734             surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1735             surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1736             break;
1737         }
1738     }
1739
1740     r = si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1741     if (r) {
1742         return r;
1743     }
1744
1745     surf->stencil_offset = 0;
1746     surf->bo_alignment = 0;
1747
1748     /* check tiling mode */
1749     switch (mode) {
1750     case RADEON_SURF_MODE_LINEAR:
1751         r = r6_surface_init_linear(surf_man, surf, 0, 0);
1752         break;
1753     case RADEON_SURF_MODE_LINEAR_ALIGNED:
1754         r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
1755         break;
1756     case RADEON_SURF_MODE_1D:
1757         r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1758         break;
1759     case RADEON_SURF_MODE_2D:
1760         r = si_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1761         break;
1762     default:
1763         return -EINVAL;
1764     }
1765     return r;
1766 }
1767
1768 /*
1769  * depending on surface
1770  */
1771 static int si_surface_best(struct radeon_surface_manager *surf_man,
1772                            struct radeon_surface *surf)
1773 {
1774     unsigned mode, tile_mode, stencil_tile_mode;
1775
1776     /* tiling mode */
1777     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1778
1779     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
1780         !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
1781         /* depth/stencil force 1d tiling for old mesa */
1782         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1783         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1784     }
1785
1786     return si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1787 }
1788
1789
1790 /* ===========================================================================
1791  * Sea Islands family
1792  */
1793 #define CIK__GB_TILE_MODE__PIPE_CONFIG(x)        (((x) >> 6) & 0x1f)
1794 #define     CIK__PIPE_CONFIG__ADDR_SURF_P2               0
1795 #define     CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16          4
1796 #define     CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16         5
1797 #define     CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32         6
1798 #define     CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32         7
1799 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16    8
1800 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16    9
1801 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16    10
1802 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16   11
1803 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16   12
1804 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32   13
1805 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32   14
1806 #define CIK__GB_TILE_MODE__TILE_SPLIT(x)         (((x) >> 11) & 0x7)
1807 #define     CIK__TILE_SPLIT__64B                         0
1808 #define     CIK__TILE_SPLIT__128B                        1
1809 #define     CIK__TILE_SPLIT__256B                        2
1810 #define     CIK__TILE_SPLIT__512B                        3
1811 #define     CIK__TILE_SPLIT__1024B                       4
1812 #define     CIK__TILE_SPLIT__2048B                       5
1813 #define     CIK__TILE_SPLIT__4096B                       6
1814 #define CIK__GB_TILE_MODE__SAMPLE_SPLIT(x)         (((x) >> 25) & 0x3)
1815 #define     CIK__SAMPLE_SPLIT__1                         0
1816 #define     CIK__SAMPLE_SPLIT__2                         1
1817 #define     CIK__SAMPLE_SPLIT__4                         2
1818 #define     CIK__SAMPLE_SPLIT__8                         3
1819 #define CIK__GB_MACROTILE_MODE__BANK_WIDTH(x)        ((x) & 0x3)
1820 #define     CIK__BANK_WIDTH__1                           0
1821 #define     CIK__BANK_WIDTH__2                           1
1822 #define     CIK__BANK_WIDTH__4                           2
1823 #define     CIK__BANK_WIDTH__8                           3
1824 #define CIK__GB_MACROTILE_MODE__BANK_HEIGHT(x)       (((x) >> 2) & 0x3)
1825 #define     CIK__BANK_HEIGHT__1                          0
1826 #define     CIK__BANK_HEIGHT__2                          1
1827 #define     CIK__BANK_HEIGHT__4                          2
1828 #define     CIK__BANK_HEIGHT__8                          3
1829 #define CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 4) & 0x3)
1830 #define     CIK__MACRO_TILE_ASPECT__1                    0
1831 #define     CIK__MACRO_TILE_ASPECT__2                    1
1832 #define     CIK__MACRO_TILE_ASPECT__4                    2
1833 #define     CIK__MACRO_TILE_ASPECT__8                    3
1834 #define CIK__GB_MACROTILE_MODE__NUM_BANKS(x)         (((x) >> 6) & 0x3)
1835 #define     CIK__NUM_BANKS__2_BANK                       0
1836 #define     CIK__NUM_BANKS__4_BANK                       1
1837 #define     CIK__NUM_BANKS__8_BANK                       2
1838 #define     CIK__NUM_BANKS__16_BANK                      3
1839
1840
1841 static void cik_get_2d_params(struct radeon_surface_manager *surf_man,
1842                               unsigned bpe, unsigned nsamples, bool is_color,
1843                               unsigned tile_mode,
1844                               uint32_t *num_pipes,
1845                               uint32_t *tile_split_ptr,
1846                               uint32_t *num_banks,
1847                               uint32_t *macro_tile_aspect,
1848                               uint32_t *bank_w,
1849                               uint32_t *bank_h)
1850 {
1851     uint32_t gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1852     unsigned tileb_1x, tileb;
1853     unsigned gb_macrotile_mode;
1854     unsigned macrotile_index;
1855     unsigned tile_split, sample_split;
1856
1857     if (num_pipes) {
1858         switch (CIK__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1859         case CIK__PIPE_CONFIG__ADDR_SURF_P2:
1860         default:
1861             *num_pipes = 2;
1862             break;
1863         case CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1864         case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1865         case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1866         case CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1867             *num_pipes = 4;
1868             break;
1869         case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1870         case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1871         case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1872         case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1873         case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1874         case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1875         case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1876             *num_pipes = 8;
1877             break;
1878         }
1879     }
1880     switch (CIK__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1881     default:
1882     case CIK__TILE_SPLIT__64B:
1883         tile_split = 64;
1884         break;
1885     case CIK__TILE_SPLIT__128B:
1886         tile_split = 128;
1887         break;
1888     case CIK__TILE_SPLIT__256B:
1889         tile_split = 256;
1890         break;
1891     case CIK__TILE_SPLIT__512B:
1892         tile_split = 512;
1893         break;
1894     case CIK__TILE_SPLIT__1024B:
1895         tile_split = 1024;
1896         break;
1897     case CIK__TILE_SPLIT__2048B:
1898         tile_split = 2048;
1899         break;
1900     case CIK__TILE_SPLIT__4096B:
1901         tile_split = 4096;
1902         break;
1903     }
1904     switch (CIK__GB_TILE_MODE__SAMPLE_SPLIT(gb_tile_mode)) {
1905     default:
1906     case CIK__SAMPLE_SPLIT__1:
1907         sample_split = 1;
1908         break;
1909     case CIK__SAMPLE_SPLIT__2:
1910         sample_split = 1;
1911         break;
1912     case CIK__SAMPLE_SPLIT__4:
1913         sample_split = 4;
1914         break;
1915     case CIK__SAMPLE_SPLIT__8:
1916         sample_split = 8;
1917         break;
1918     }
1919
1920     /* Adjust the tile split. */
1921     tileb_1x = 8 * 8 * bpe;
1922     if (is_color) {
1923         tile_split = MAX2(256, sample_split * tileb_1x);
1924     }
1925     tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
1926
1927     /* Determine the macrotile index. */
1928     tileb = MIN2(tile_split, nsamples * tileb_1x);
1929
1930     for (macrotile_index = 0; tileb > 64; macrotile_index++) {
1931         tileb >>= 1;
1932     }
1933     gb_macrotile_mode = surf_man->hw_info.macrotile_mode_array[macrotile_index];
1934
1935     if (tile_split_ptr) {
1936         *tile_split_ptr = tile_split;
1937     }
1938     if (num_banks) {
1939         switch (CIK__GB_MACROTILE_MODE__NUM_BANKS(gb_macrotile_mode)) {
1940         default:
1941         case CIK__NUM_BANKS__2_BANK:
1942             *num_banks = 2;
1943             break;
1944         case CIK__NUM_BANKS__4_BANK:
1945             *num_banks = 4;
1946             break;
1947         case CIK__NUM_BANKS__8_BANK:
1948             *num_banks = 8;
1949             break;
1950         case CIK__NUM_BANKS__16_BANK:
1951             *num_banks = 16;
1952             break;
1953         }
1954     }
1955     if (macro_tile_aspect) {
1956         switch (CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(gb_macrotile_mode)) {
1957         default:
1958         case CIK__MACRO_TILE_ASPECT__1:
1959             *macro_tile_aspect = 1;
1960             break;
1961         case CIK__MACRO_TILE_ASPECT__2:
1962             *macro_tile_aspect = 2;
1963             break;
1964         case CIK__MACRO_TILE_ASPECT__4:
1965             *macro_tile_aspect = 4;
1966             break;
1967         case CIK__MACRO_TILE_ASPECT__8:
1968             *macro_tile_aspect = 8;
1969             break;
1970         }
1971     }
1972     if (bank_w) {
1973         switch (CIK__GB_MACROTILE_MODE__BANK_WIDTH(gb_macrotile_mode)) {
1974         default:
1975         case CIK__BANK_WIDTH__1:
1976             *bank_w = 1;
1977             break;
1978         case CIK__BANK_WIDTH__2:
1979             *bank_w = 2;
1980             break;
1981         case CIK__BANK_WIDTH__4:
1982             *bank_w = 4;
1983             break;
1984         case CIK__BANK_WIDTH__8:
1985             *bank_w = 8;
1986             break;
1987         }
1988     }
1989     if (bank_h) {
1990         switch (CIK__GB_MACROTILE_MODE__BANK_HEIGHT(gb_macrotile_mode)) {
1991         default:
1992         case CIK__BANK_HEIGHT__1:
1993             *bank_h = 1;
1994             break;
1995         case CIK__BANK_HEIGHT__2:
1996             *bank_h = 2;
1997             break;
1998         case CIK__BANK_HEIGHT__4:
1999             *bank_h = 4;
2000             break;
2001         case CIK__BANK_HEIGHT__8:
2002             *bank_h = 8;
2003             break;
2004         }
2005     }
2006 }
2007
2008 static int cik_init_hw_info(struct radeon_surface_manager *surf_man)
2009 {
2010     uint32_t tiling_config;
2011     drmVersionPtr version;
2012     int r;
2013
2014     r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
2015                          &tiling_config);
2016     if (r) {
2017         return r;
2018     }
2019
2020     surf_man->hw_info.allow_2d = 0;
2021     version = drmGetVersion(surf_man->fd);
2022     if (version && version->version_minor >= 35) {
2023         if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array) &&
2024             !radeon_get_value(surf_man->fd, RADEON_INFO_CIK_MACROTILE_MODE_ARRAY, surf_man->hw_info.macrotile_mode_array)) {
2025             surf_man->hw_info.allow_2d = 1;
2026         }
2027     }
2028     drmFreeVersion(version);
2029
2030     switch (tiling_config & 0xf) {
2031     case 0:
2032         surf_man->hw_info.num_pipes = 1;
2033         break;
2034     case 1:
2035         surf_man->hw_info.num_pipes = 2;
2036         break;
2037     case 2:
2038         surf_man->hw_info.num_pipes = 4;
2039         break;
2040     case 3:
2041         surf_man->hw_info.num_pipes = 8;
2042         break;
2043     default:
2044         surf_man->hw_info.num_pipes = 8;
2045         surf_man->hw_info.allow_2d = 0;
2046         break;
2047     }
2048
2049     switch ((tiling_config & 0xf0) >> 4) {
2050     case 0:
2051         surf_man->hw_info.num_banks = 4;
2052         break;
2053     case 1:
2054         surf_man->hw_info.num_banks = 8;
2055         break;
2056     case 2:
2057         surf_man->hw_info.num_banks = 16;
2058         break;
2059     default:
2060         surf_man->hw_info.num_banks = 8;
2061         surf_man->hw_info.allow_2d = 0;
2062         break;
2063     }
2064
2065     switch ((tiling_config & 0xf00) >> 8) {
2066     case 0:
2067         surf_man->hw_info.group_bytes = 256;
2068         break;
2069     case 1:
2070         surf_man->hw_info.group_bytes = 512;
2071         break;
2072     default:
2073         surf_man->hw_info.group_bytes = 256;
2074         surf_man->hw_info.allow_2d = 0;
2075         break;
2076     }
2077
2078     switch ((tiling_config & 0xf000) >> 12) {
2079     case 0:
2080         surf_man->hw_info.row_size = 1024;
2081         break;
2082     case 1:
2083         surf_man->hw_info.row_size = 2048;
2084         break;
2085     case 2:
2086         surf_man->hw_info.row_size = 4096;
2087         break;
2088     default:
2089         surf_man->hw_info.row_size = 4096;
2090         surf_man->hw_info.allow_2d = 0;
2091         break;
2092     }
2093     return 0;
2094 }
2095
2096 static int cik_surface_sanity(struct radeon_surface_manager *surf_man,
2097                               struct radeon_surface *surf,
2098                               unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
2099 {
2100     /* check surface dimension */
2101     if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
2102         return -EINVAL;
2103     }
2104
2105     /* check mipmap last_level */
2106     if (surf->last_level > 15) {
2107         return -EINVAL;
2108     }
2109
2110     /* force 1d on kernel that can't do 2d */
2111     if (mode > RADEON_SURF_MODE_1D &&
2112         (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
2113         if (surf->nsamples > 1) {
2114             fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
2115             return -EFAULT;
2116         }
2117         mode = RADEON_SURF_MODE_1D;
2118         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2119         surf->flags |= RADEON_SURF_SET(mode, MODE);
2120     }
2121
2122     if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
2123         return -EINVAL;
2124     }
2125
2126     if (!surf->tile_split) {
2127         /* default value */
2128         surf->mtilea = 1;
2129         surf->bankw = 1;
2130         surf->bankw = 1;
2131         surf->tile_split = 64;
2132         surf->stencil_tile_split = 64;
2133     }
2134
2135     switch (mode) {
2136     case RADEON_SURF_MODE_2D: {
2137         if (surf->flags & RADEON_SURF_Z_OR_SBUFFER) {
2138             switch (surf->nsamples) {
2139             case 1:
2140                 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64;
2141                 break;
2142             case 2:
2143             case 4:
2144                 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128;
2145                 break;
2146             case 8:
2147                 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256;
2148                 break;
2149             default:
2150                 return -EINVAL;
2151             }
2152
2153             if (surf->flags & RADEON_SURF_SBUFFER) {
2154                 *stencil_tile_mode = *tile_mode;
2155
2156                 cik_get_2d_params(surf_man, 1, surf->nsamples, false,
2157                                   *stencil_tile_mode, NULL,
2158                                   &surf->stencil_tile_split,
2159                                   NULL, NULL, NULL, NULL);
2160             }
2161         } else if (surf->flags & RADEON_SURF_SCANOUT) {
2162             *tile_mode = CIK_TILE_MODE_COLOR_2D_SCANOUT;
2163         } else {
2164             *tile_mode = CIK_TILE_MODE_COLOR_2D;
2165         }
2166
2167         /* retrieve tiling mode values */
2168         cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
2169                           !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), *tile_mode,
2170                           NULL, &surf->tile_split, NULL, &surf->mtilea,
2171                           &surf->bankw, &surf->bankh);
2172         break;
2173     }
2174     case RADEON_SURF_MODE_1D:
2175         if (surf->flags & RADEON_SURF_SBUFFER) {
2176             *stencil_tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2177         }
2178         if (surf->flags & RADEON_SURF_ZBUFFER) {
2179             *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2180         } else if (surf->flags & RADEON_SURF_SCANOUT) {
2181             *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2182         } else {
2183             *tile_mode = SI_TILE_MODE_COLOR_1D;
2184         }
2185         break;
2186     case RADEON_SURF_MODE_LINEAR_ALIGNED:
2187     default:
2188         *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
2189     }
2190
2191     return 0;
2192 }
2193
2194 static int cik_surface_init_2d(struct radeon_surface_manager *surf_man,
2195                                struct radeon_surface *surf,
2196                                struct radeon_surface_level *level,
2197                                unsigned bpe, unsigned tile_mode,
2198                                unsigned tile_split,
2199                                unsigned num_pipes, unsigned num_banks,
2200                                uint64_t offset,
2201                                unsigned start_level)
2202 {
2203     uint64_t aligned_offset = offset;
2204     unsigned tilew, tileh, tileb_1x, tileb;
2205     unsigned mtilew, mtileh, mtileb;
2206     unsigned slice_pt;
2207     unsigned i;
2208
2209     /* compute tile values */
2210     tilew = 8;
2211     tileh = 8;
2212     tileb_1x = tilew * tileh * bpe;
2213
2214     tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
2215
2216     tileb = surf->nsamples * tileb_1x;
2217
2218     /* slices per tile */
2219     slice_pt = 1;
2220     if (tileb > tile_split) {
2221         slice_pt = tileb / tile_split;
2222         tileb = tileb / slice_pt;
2223     }
2224
2225     /* macro tile width & height */
2226     mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
2227     mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
2228
2229     /* macro tile bytes */
2230     mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
2231
2232     if (start_level <= 1) {
2233         unsigned alignment = MAX2(256, mtileb);
2234         surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
2235
2236         if (aligned_offset) {
2237             aligned_offset = ALIGN(aligned_offset, alignment);
2238         }
2239     }
2240
2241     /* build mipmap tree */
2242     for (i = start_level; i <= surf->last_level; i++) {
2243         level[i].mode = RADEON_SURF_MODE_2D;
2244         si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
2245         if (level[i].mode == RADEON_SURF_MODE_1D) {
2246             switch (tile_mode) {
2247             case CIK_TILE_MODE_COLOR_2D:
2248                 tile_mode = SI_TILE_MODE_COLOR_1D;
2249                 break;
2250             case CIK_TILE_MODE_COLOR_2D_SCANOUT:
2251                 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2252                 break;
2253             case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64:
2254             case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128:
2255             case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256:
2256             case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512:
2257             case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE:
2258                 tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2259                 break;
2260             default:
2261                 return -EINVAL;
2262             }
2263             return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
2264         }
2265         /* level0 and first mipmap need to have alignment */
2266         aligned_offset = offset = surf->bo_size;
2267         if (i == 0) {
2268             aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
2269         }
2270         if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
2271             if (surf->level == level) {
2272                 surf->tiling_index[i] = tile_mode;
2273                 /* it's ok because stencil is done after */
2274                 surf->stencil_tiling_index[i] = tile_mode;
2275             } else {
2276                 surf->stencil_tiling_index[i] = tile_mode;
2277             }
2278         }
2279     }
2280     return 0;
2281 }
2282
2283 static int cik_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
2284                                         struct radeon_surface *surf,
2285                                         unsigned tile_mode, unsigned stencil_tile_mode)
2286 {
2287     int r;
2288     uint32_t num_pipes, num_banks;
2289
2290     cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
2291                         !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), tile_mode,
2292                         &num_pipes, NULL, &num_banks, NULL, NULL, NULL);
2293
2294     r = cik_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode,
2295                             surf->tile_split, num_pipes, num_banks, 0, 0);
2296     if (r) {
2297         return r;
2298     }
2299
2300     if (surf->flags & RADEON_SURF_SBUFFER) {
2301         r = cik_surface_init_2d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode,
2302                                 surf->stencil_tile_split, num_pipes, num_banks,
2303                                 surf->bo_size, 0);
2304         surf->stencil_offset = surf->stencil_level[0].offset;
2305     }
2306     return r;
2307 }
2308
2309 static int cik_surface_init(struct radeon_surface_manager *surf_man,
2310                             struct radeon_surface *surf)
2311 {
2312     unsigned mode, tile_mode, stencil_tile_mode;
2313     int r;
2314
2315     /* MSAA surfaces support the 2D mode only. */
2316     if (surf->nsamples > 1) {
2317         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2318         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
2319     }
2320
2321     /* tiling mode */
2322     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2323
2324     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
2325         /* zbuffer only support 1D or 2D tiled surface */
2326         switch (mode) {
2327         case RADEON_SURF_MODE_1D:
2328         case RADEON_SURF_MODE_2D:
2329             break;
2330         default:
2331             mode = RADEON_SURF_MODE_1D;
2332             surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2333             surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2334             break;
2335         }
2336     }
2337
2338     r = cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2339     if (r) {
2340         return r;
2341     }
2342
2343     surf->stencil_offset = 0;
2344     surf->bo_alignment = 0;
2345
2346     /* check tiling mode */
2347     switch (mode) {
2348     case RADEON_SURF_MODE_LINEAR:
2349         r = r6_surface_init_linear(surf_man, surf, 0, 0);
2350         break;
2351     case RADEON_SURF_MODE_LINEAR_ALIGNED:
2352         r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
2353         break;
2354     case RADEON_SURF_MODE_1D:
2355         r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2356         break;
2357     case RADEON_SURF_MODE_2D:
2358         r = cik_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2359         break;
2360     default:
2361         return -EINVAL;
2362     }
2363     return r;
2364 }
2365
2366 /*
2367  * depending on surface
2368  */
2369 static int cik_surface_best(struct radeon_surface_manager *surf_man,
2370                             struct radeon_surface *surf)
2371 {
2372     unsigned mode, tile_mode, stencil_tile_mode;
2373
2374     /* tiling mode */
2375     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2376
2377     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
2378         !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
2379         /* depth/stencil force 1d tiling for old mesa */
2380         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2381         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2382     }
2383
2384     return cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2385 }
2386
2387
2388 /* ===========================================================================
2389  * public API
2390  */
2391 struct radeon_surface_manager *radeon_surface_manager_new(int fd)
2392 {
2393     struct radeon_surface_manager *surf_man;
2394
2395     surf_man = calloc(1, sizeof(struct radeon_surface_manager));
2396     if (surf_man == NULL) {
2397         return NULL;
2398     }
2399     surf_man->fd = fd;
2400     if (radeon_get_value(fd, RADEON_INFO_DEVICE_ID, &surf_man->device_id)) {
2401         goto out_err;
2402     }
2403     if (radeon_get_family(surf_man)) {
2404         goto out_err;
2405     }
2406
2407     if (surf_man->family <= CHIP_RV740) {
2408         if (r6_init_hw_info(surf_man)) {
2409             goto out_err;
2410         }
2411         surf_man->surface_init = &r6_surface_init;
2412         surf_man->surface_best = &r6_surface_best;
2413     } else if (surf_man->family <= CHIP_ARUBA) {
2414         if (eg_init_hw_info(surf_man)) {
2415             goto out_err;
2416         }
2417         surf_man->surface_init = &eg_surface_init;
2418         surf_man->surface_best = &eg_surface_best;
2419     } else if (surf_man->family < CHIP_BONAIRE) {
2420         if (si_init_hw_info(surf_man)) {
2421             goto out_err;
2422         }
2423         surf_man->surface_init = &si_surface_init;
2424         surf_man->surface_best = &si_surface_best;
2425     } else {
2426         if (cik_init_hw_info(surf_man)) {
2427             goto out_err;
2428         }
2429         surf_man->surface_init = &cik_surface_init;
2430         surf_man->surface_best = &cik_surface_best;
2431     }
2432
2433     return surf_man;
2434 out_err:
2435     free(surf_man);
2436     return NULL;
2437 }
2438
2439 void radeon_surface_manager_free(struct radeon_surface_manager *surf_man)
2440 {
2441     free(surf_man);
2442 }
2443
2444 static int radeon_surface_sanity(struct radeon_surface_manager *surf_man,
2445                                  struct radeon_surface *surf,
2446                                  unsigned type,
2447                                  unsigned mode)
2448 {
2449     if (surf_man == NULL || surf_man->surface_init == NULL || surf == NULL) {
2450         return -EINVAL;
2451     }
2452
2453     /* all dimension must be at least 1 ! */
2454     if (!surf->npix_x || !surf->npix_y || !surf->npix_z) {
2455         return -EINVAL;
2456     }
2457     if (!surf->blk_w || !surf->blk_h || !surf->blk_d) {
2458         return -EINVAL;
2459     }
2460     if (!surf->array_size) {
2461         return -EINVAL;
2462     }
2463     /* array size must be a power of 2 */
2464     surf->array_size = next_power_of_two(surf->array_size);
2465
2466     switch (surf->nsamples) {
2467     case 1:
2468     case 2:
2469     case 4:
2470     case 8:
2471         break;
2472     default:
2473         return -EINVAL;
2474     }
2475     /* check type */
2476     switch (type) {
2477     case RADEON_SURF_TYPE_1D:
2478         if (surf->npix_y > 1) {
2479             return -EINVAL;
2480         }
2481     case RADEON_SURF_TYPE_2D:
2482         if (surf->npix_z > 1) {
2483             return -EINVAL;
2484         }
2485         break;
2486     case RADEON_SURF_TYPE_CUBEMAP:
2487         if (surf->npix_z > 1) {
2488             return -EINVAL;
2489         }
2490         /* deal with cubemap as they were texture array */
2491         if (surf_man->family >= CHIP_RV770) {
2492             surf->array_size = 8;
2493         } else {
2494             surf->array_size = 6;
2495         }
2496         break;
2497     case RADEON_SURF_TYPE_3D:
2498         break;
2499     case RADEON_SURF_TYPE_1D_ARRAY:
2500         if (surf->npix_y > 1) {
2501             return -EINVAL;
2502         }
2503     case RADEON_SURF_TYPE_2D_ARRAY:
2504         break;
2505     default:
2506         return -EINVAL;
2507     }
2508     return 0;
2509 }
2510
2511 int radeon_surface_init(struct radeon_surface_manager *surf_man,
2512                         struct radeon_surface *surf)
2513 {
2514     unsigned mode, type;
2515     int r;
2516
2517     type = RADEON_SURF_GET(surf->flags, TYPE);
2518     mode = RADEON_SURF_GET(surf->flags, MODE);
2519
2520     r = radeon_surface_sanity(surf_man, surf, type, mode);
2521     if (r) {
2522         return r;
2523     }
2524     return surf_man->surface_init(surf_man, surf);
2525 }
2526
2527 int radeon_surface_best(struct radeon_surface_manager *surf_man,
2528                         struct radeon_surface *surf)
2529 {
2530     unsigned mode, type;
2531     int r;
2532
2533     type = RADEON_SURF_GET(surf->flags, TYPE);
2534     mode = RADEON_SURF_GET(surf->flags, MODE);
2535
2536     r = radeon_surface_sanity(surf_man, surf, type, mode);
2537     if (r) {
2538         return r;
2539     }
2540     return surf_man->surface_best(surf_man, surf);
2541 }