OSDN Git Service

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