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