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