OSDN Git Service

drm: rename libdrm{,_macros}.h
[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                         unsigned offset)
167 {
168     surflevel->npix_x = mip_minify(surf->npix_x, level);
169     surflevel->npix_y = mip_minify(surf->npix_y, level);
170     surflevel->npix_z = mip_minify(surf->npix_z, level);
171     surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
172     surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
173     surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
174     if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
175         !(surf->flags & RADEON_SURF_FMASK)) {
176         if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
177             surflevel->mode = RADEON_SURF_MODE_1D;
178             return;
179         }
180     }
181     surflevel->nblk_x  = ALIGN(surflevel->nblk_x, xalign);
182     surflevel->nblk_y  = ALIGN(surflevel->nblk_y, yalign);
183     surflevel->nblk_z  = ALIGN(surflevel->nblk_z, zalign);
184
185     surflevel->offset = offset;
186     surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
187     surflevel->slice_size = surflevel->pitch_bytes * surflevel->nblk_y;
188
189     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
190 }
191
192 /* ===========================================================================
193  * r600/r700 family
194  */
195 static int r6_init_hw_info(struct radeon_surface_manager *surf_man)
196 {
197     uint32_t tiling_config;
198     drmVersionPtr version;
199     int r;
200
201     r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
202                          &tiling_config);
203     if (r) {
204         return r;
205     }
206
207     surf_man->hw_info.allow_2d = 0;
208     version = drmGetVersion(surf_man->fd);
209     if (version && version->version_minor >= 14) {
210         surf_man->hw_info.allow_2d = 1;
211     }
212     drmFreeVersion(version);
213
214     switch ((tiling_config & 0xe) >> 1) {
215     case 0:
216         surf_man->hw_info.num_pipes = 1;
217         break;
218     case 1:
219         surf_man->hw_info.num_pipes = 2;
220         break;
221     case 2:
222         surf_man->hw_info.num_pipes = 4;
223         break;
224     case 3:
225         surf_man->hw_info.num_pipes = 8;
226         break;
227     default:
228         surf_man->hw_info.num_pipes = 8;
229         surf_man->hw_info.allow_2d = 0;
230         break;
231     }
232
233     switch ((tiling_config & 0x30) >> 4) {
234     case 0:
235         surf_man->hw_info.num_banks = 4;
236         break;
237     case 1:
238         surf_man->hw_info.num_banks = 8;
239         break;
240     default:
241         surf_man->hw_info.num_banks = 8;
242         surf_man->hw_info.allow_2d = 0;
243         break;
244     }
245
246     switch ((tiling_config & 0xc0) >> 6) {
247     case 0:
248         surf_man->hw_info.group_bytes = 256;
249         break;
250     case 1:
251         surf_man->hw_info.group_bytes = 512;
252         break;
253     default:
254         surf_man->hw_info.group_bytes = 256;
255         surf_man->hw_info.allow_2d = 0;
256         break;
257     }
258     return 0;
259 }
260
261 static int r6_surface_init_linear(struct radeon_surface_manager *surf_man,
262                                   struct radeon_surface *surf,
263                                   uint64_t offset, unsigned start_level)
264 {
265     uint32_t xalign, yalign, zalign;
266     unsigned i;
267
268     /* compute alignment */
269     if (!start_level) {
270         surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
271     }
272     /* the 32 alignment is for scanout, cb or db but to allow texture to be
273      * easily bound as such we force this alignment to all surface
274      */
275     xalign = MAX2(1, surf_man->hw_info.group_bytes / surf->bpe);
276     yalign = 1;
277     zalign = 1;
278     if (surf->flags & RADEON_SURF_SCANOUT) {
279         xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
280     }
281
282     /* build mipmap tree */
283     for (i = start_level; i <= surf->last_level; i++) {
284         surf->level[i].mode = RADEON_SURF_MODE_LINEAR;
285         surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
286         /* level0 and first mipmap need to have alignment */
287         offset = surf->bo_size;
288         if (i == 0) {
289             offset = ALIGN(offset, surf->bo_alignment);
290         }
291     }
292     return 0;
293 }
294
295 static int r6_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
296                                           struct radeon_surface *surf,
297                                           uint64_t offset, unsigned start_level)
298 {
299     uint32_t xalign, yalign, zalign;
300     unsigned i;
301
302     /* compute alignment */
303     if (!start_level) {
304         surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
305     }
306     xalign = MAX2(64, surf_man->hw_info.group_bytes / surf->bpe);
307     yalign = 1;
308     zalign = 1;
309
310     /* build mipmap tree */
311     for (i = start_level; i <= surf->last_level; i++) {
312         surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
313         surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
314         /* level0 and first mipmap need to have alignment */
315         offset = surf->bo_size;
316         if (i == 0) {
317             offset = ALIGN(offset, surf->bo_alignment);
318         }
319     }
320     return 0;
321 }
322
323 static int r6_surface_init_1d(struct radeon_surface_manager *surf_man,
324                               struct radeon_surface *surf,
325                               uint64_t offset, unsigned start_level)
326 {
327     uint32_t xalign, yalign, zalign, tilew;
328     unsigned i;
329
330     /* compute alignment */
331     tilew = 8;
332     xalign = surf_man->hw_info.group_bytes / (tilew * surf->bpe * surf->nsamples);
333     xalign = MAX2(tilew, xalign);
334     yalign = tilew;
335     zalign = 1;
336     if (surf->flags & RADEON_SURF_SCANOUT) {
337         xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
338     }
339     if (!start_level) {
340         surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
341     }
342
343     /* build mipmap tree */
344     for (i = start_level; i <= surf->last_level; i++) {
345         surf->level[i].mode = RADEON_SURF_MODE_1D;
346         surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
347         /* level0 and first mipmap need to have alignment */
348         offset = surf->bo_size;
349         if (i == 0) {
350             offset = ALIGN(offset, surf->bo_alignment);
351         }
352     }
353     return 0;
354 }
355
356 static int r6_surface_init_2d(struct radeon_surface_manager *surf_man,
357                               struct radeon_surface *surf,
358                               uint64_t offset, unsigned start_level)
359 {
360     uint32_t xalign, yalign, zalign, tilew;
361     unsigned i;
362
363     /* compute alignment */
364     tilew = 8;
365     zalign = 1;
366     xalign = (surf_man->hw_info.group_bytes * surf_man->hw_info.num_banks) /
367              (tilew * surf->bpe * surf->nsamples);
368     xalign = MAX2(tilew * surf_man->hw_info.num_banks, xalign);
369     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                            unsigned 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 = 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             surf->tile_split = MAX2(surf->nsamples * surf->bpe * 64, 256);
962             if (surf->tile_split > 4096)
963                 surf->tile_split = 4096;
964         }
965     } else {
966         /* set tile split to row size */
967         surf->tile_split = surf_man->hw_info.row_size;
968         surf->stencil_tile_split = surf_man->hw_info.row_size / 2;
969     }
970
971     /* bankw or bankh greater than 1 increase alignment requirement, not
972      * sure if it's worth using smaller bankw & bankh to stick with 2D
973      * tiling on small surface rather than falling back to 1D tiling.
974      * Use recommanded value based on tile size for now.
975      *
976      * fmask buffer has different optimal value figure them out once we
977      * use it.
978      */
979     if (surf->flags & RADEON_SURF_SBUFFER) {
980         /* assume 1 bytes for stencil, we optimize for stencil as stencil
981          * and depth shares surface values
982          */
983         tileb = MIN2(surf->tile_split, 64 * surf->nsamples);
984     } else {
985         tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
986     }
987
988     /* use bankw of 1 to minimize width alignment, might be interesting to
989      * increase it for large surface
990      */
991     surf->bankw = 1;
992     switch (tileb) {
993     case 64:
994         surf->bankh = 4;
995         break;
996     case 128:
997     case 256:
998         surf->bankh = 2;
999         break;
1000     default:
1001         surf->bankh = 1;
1002         break;
1003     }
1004     /* double check the constraint */
1005     for (; surf->bankh <= 8; surf->bankh *= 2) {
1006         if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
1007             break;
1008         }
1009     }
1010
1011     h_over_w = (((surf->bankh * surf_man->hw_info.num_banks) << 16) /
1012                 (surf->bankw * surf_man->hw_info.num_pipes)) >> 16;
1013     surf->mtilea = 1 << (log2_int(h_over_w) >> 1);
1014
1015     return 0;
1016 }
1017
1018
1019 /* ===========================================================================
1020  * Southern Islands family
1021  */
1022 #define SI__GB_TILE_MODE__PIPE_CONFIG(x)        (((x) >> 6) & 0x1f)
1023 #define     SI__PIPE_CONFIG__ADDR_SURF_P2               0
1024 #define     SI__PIPE_CONFIG__ADDR_SURF_P4_8x16          4
1025 #define     SI__PIPE_CONFIG__ADDR_SURF_P4_16x16         5
1026 #define     SI__PIPE_CONFIG__ADDR_SURF_P4_16x32         6
1027 #define     SI__PIPE_CONFIG__ADDR_SURF_P4_32x32         7
1028 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16    8
1029 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16    9
1030 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16    10
1031 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16   11
1032 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16   12
1033 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32   13
1034 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32   14
1035 #define SI__GB_TILE_MODE__TILE_SPLIT(x)         (((x) >> 11) & 0x7)
1036 #define     SI__TILE_SPLIT__64B                         0
1037 #define     SI__TILE_SPLIT__128B                        1
1038 #define     SI__TILE_SPLIT__256B                        2
1039 #define     SI__TILE_SPLIT__512B                        3
1040 #define     SI__TILE_SPLIT__1024B                       4
1041 #define     SI__TILE_SPLIT__2048B                       5
1042 #define     SI__TILE_SPLIT__4096B                       6
1043 #define SI__GB_TILE_MODE__BANK_WIDTH(x)         (((x) >> 14) & 0x3)
1044 #define     SI__BANK_WIDTH__1                           0
1045 #define     SI__BANK_WIDTH__2                           1
1046 #define     SI__BANK_WIDTH__4                           2
1047 #define     SI__BANK_WIDTH__8                           3
1048 #define SI__GB_TILE_MODE__BANK_HEIGHT(x)        (((x) >> 16) & 0x3)
1049 #define     SI__BANK_HEIGHT__1                          0
1050 #define     SI__BANK_HEIGHT__2                          1
1051 #define     SI__BANK_HEIGHT__4                          2
1052 #define     SI__BANK_HEIGHT__8                          3
1053 #define SI__GB_TILE_MODE__MACRO_TILE_ASPECT(x)  (((x) >> 18) & 0x3)
1054 #define     SI__MACRO_TILE_ASPECT__1                    0
1055 #define     SI__MACRO_TILE_ASPECT__2                    1
1056 #define     SI__MACRO_TILE_ASPECT__4                    2
1057 #define     SI__MACRO_TILE_ASPECT__8                    3
1058 #define SI__GB_TILE_MODE__NUM_BANKS(x)          (((x) >> 20) & 0x3)
1059 #define     SI__NUM_BANKS__2_BANK                       0
1060 #define     SI__NUM_BANKS__4_BANK                       1
1061 #define     SI__NUM_BANKS__8_BANK                       2
1062 #define     SI__NUM_BANKS__16_BANK                      3
1063
1064
1065 static void si_gb_tile_mode(uint32_t gb_tile_mode,
1066                             unsigned *num_pipes,
1067                             unsigned *num_banks,
1068                             uint32_t *macro_tile_aspect,
1069                             uint32_t *bank_w,
1070                             uint32_t *bank_h,
1071                             uint32_t *tile_split)
1072 {
1073     if (num_pipes) {
1074         switch (SI__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1075         case SI__PIPE_CONFIG__ADDR_SURF_P2:
1076         default:
1077             *num_pipes = 2;
1078             break;
1079         case SI__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1080         case SI__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1081         case SI__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1082         case SI__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1083             *num_pipes = 4;
1084             break;
1085         case SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1086         case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1087         case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1088         case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1089         case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1090         case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1091         case SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1092             *num_pipes = 8;
1093             break;
1094         }
1095     }
1096     if (num_banks) {
1097         switch (SI__GB_TILE_MODE__NUM_BANKS(gb_tile_mode)) {
1098         default:
1099         case SI__NUM_BANKS__2_BANK:
1100             *num_banks = 2;
1101             break;
1102         case SI__NUM_BANKS__4_BANK:
1103             *num_banks = 4;
1104             break;
1105         case SI__NUM_BANKS__8_BANK:
1106             *num_banks = 8;
1107             break;
1108         case SI__NUM_BANKS__16_BANK:
1109             *num_banks = 16;
1110             break;
1111         }
1112     }
1113     if (macro_tile_aspect) {
1114         switch (SI__GB_TILE_MODE__MACRO_TILE_ASPECT(gb_tile_mode)) {
1115         default:
1116         case SI__MACRO_TILE_ASPECT__1:
1117             *macro_tile_aspect = 1;
1118             break;
1119         case SI__MACRO_TILE_ASPECT__2:
1120             *macro_tile_aspect = 2;
1121             break;
1122         case SI__MACRO_TILE_ASPECT__4:
1123             *macro_tile_aspect = 4;
1124             break;
1125         case SI__MACRO_TILE_ASPECT__8:
1126             *macro_tile_aspect = 8;
1127             break;
1128         }
1129     }
1130     if (bank_w) {
1131         switch (SI__GB_TILE_MODE__BANK_WIDTH(gb_tile_mode)) {
1132         default:
1133         case SI__BANK_WIDTH__1:
1134             *bank_w = 1;
1135             break;
1136         case SI__BANK_WIDTH__2:
1137             *bank_w = 2;
1138             break;
1139         case SI__BANK_WIDTH__4:
1140             *bank_w = 4;
1141             break;
1142         case SI__BANK_WIDTH__8:
1143             *bank_w = 8;
1144             break;
1145         }
1146     }
1147     if (bank_h) {
1148         switch (SI__GB_TILE_MODE__BANK_HEIGHT(gb_tile_mode)) {
1149         default:
1150         case SI__BANK_HEIGHT__1:
1151             *bank_h = 1;
1152             break;
1153         case SI__BANK_HEIGHT__2:
1154             *bank_h = 2;
1155             break;
1156         case SI__BANK_HEIGHT__4:
1157             *bank_h = 4;
1158             break;
1159         case SI__BANK_HEIGHT__8:
1160             *bank_h = 8;
1161             break;
1162         }
1163     }
1164     if (tile_split) {
1165         switch (SI__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1166         default:
1167         case SI__TILE_SPLIT__64B:
1168             *tile_split = 64;
1169             break;
1170         case SI__TILE_SPLIT__128B:
1171             *tile_split = 128;
1172             break;
1173         case SI__TILE_SPLIT__256B:
1174             *tile_split = 256;
1175             break;
1176         case SI__TILE_SPLIT__512B:
1177             *tile_split = 512;
1178             break;
1179         case SI__TILE_SPLIT__1024B:
1180             *tile_split = 1024;
1181             break;
1182         case SI__TILE_SPLIT__2048B:
1183             *tile_split = 2048;
1184             break;
1185         case SI__TILE_SPLIT__4096B:
1186             *tile_split = 4096;
1187             break;
1188         }
1189     }
1190 }
1191
1192 static int si_init_hw_info(struct radeon_surface_manager *surf_man)
1193 {
1194     uint32_t tiling_config;
1195     drmVersionPtr version;
1196     int r;
1197
1198     r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
1199                          &tiling_config);
1200     if (r) {
1201         return r;
1202     }
1203
1204     surf_man->hw_info.allow_2d = 0;
1205     version = drmGetVersion(surf_man->fd);
1206     if (version && version->version_minor >= 33) {
1207         if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array)) {
1208             surf_man->hw_info.allow_2d = 1;
1209         }
1210     }
1211     drmFreeVersion(version);
1212
1213     switch (tiling_config & 0xf) {
1214     case 0:
1215         surf_man->hw_info.num_pipes = 1;
1216         break;
1217     case 1:
1218         surf_man->hw_info.num_pipes = 2;
1219         break;
1220     case 2:
1221         surf_man->hw_info.num_pipes = 4;
1222         break;
1223     case 3:
1224         surf_man->hw_info.num_pipes = 8;
1225         break;
1226     default:
1227         surf_man->hw_info.num_pipes = 8;
1228         surf_man->hw_info.allow_2d = 0;
1229         break;
1230     }
1231
1232     switch ((tiling_config & 0xf0) >> 4) {
1233     case 0:
1234         surf_man->hw_info.num_banks = 4;
1235         break;
1236     case 1:
1237         surf_man->hw_info.num_banks = 8;
1238         break;
1239     case 2:
1240         surf_man->hw_info.num_banks = 16;
1241         break;
1242     default:
1243         surf_man->hw_info.num_banks = 8;
1244         surf_man->hw_info.allow_2d = 0;
1245         break;
1246     }
1247
1248     switch ((tiling_config & 0xf00) >> 8) {
1249     case 0:
1250         surf_man->hw_info.group_bytes = 256;
1251         break;
1252     case 1:
1253         surf_man->hw_info.group_bytes = 512;
1254         break;
1255     default:
1256         surf_man->hw_info.group_bytes = 256;
1257         surf_man->hw_info.allow_2d = 0;
1258         break;
1259     }
1260
1261     switch ((tiling_config & 0xf000) >> 12) {
1262     case 0:
1263         surf_man->hw_info.row_size = 1024;
1264         break;
1265     case 1:
1266         surf_man->hw_info.row_size = 2048;
1267         break;
1268     case 2:
1269         surf_man->hw_info.row_size = 4096;
1270         break;
1271     default:
1272         surf_man->hw_info.row_size = 4096;
1273         surf_man->hw_info.allow_2d = 0;
1274         break;
1275     }
1276     return 0;
1277 }
1278
1279 static int si_surface_sanity(struct radeon_surface_manager *surf_man,
1280                              struct radeon_surface *surf,
1281                              unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
1282 {
1283     uint32_t gb_tile_mode;
1284
1285     /* check surface dimension */
1286     if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
1287         return -EINVAL;
1288     }
1289
1290     /* check mipmap last_level */
1291     if (surf->last_level > 15) {
1292         return -EINVAL;
1293     }
1294
1295     /* force 1d on kernel that can't do 2d */
1296     if (mode > RADEON_SURF_MODE_1D &&
1297         (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
1298         if (surf->nsamples > 1) {
1299             fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
1300             return -EFAULT;
1301         }
1302         mode = RADEON_SURF_MODE_1D;
1303         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1304         surf->flags |= RADEON_SURF_SET(mode, MODE);
1305     }
1306
1307     if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
1308         return -EINVAL;
1309     }
1310
1311     if (!surf->tile_split) {
1312         /* default value */
1313         surf->mtilea = 1;
1314         surf->bankw = 1;
1315         surf->bankh = 1;
1316         surf->tile_split = 64;
1317         surf->stencil_tile_split = 64;
1318     }
1319
1320     switch (mode) {
1321     case RADEON_SURF_MODE_2D:
1322         if (surf->flags & RADEON_SURF_SBUFFER) {
1323             switch (surf->nsamples) {
1324             case 1:
1325                 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1326                 break;
1327             case 2:
1328                 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1329                 break;
1330             case 4:
1331                 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1332                 break;
1333             case 8:
1334                 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1335                 break;
1336             default:
1337                 return -EINVAL;
1338             }
1339             /* retrieve tiling mode value */
1340             gb_tile_mode = surf_man->hw_info.tile_mode_array[*stencil_tile_mode];
1341             si_gb_tile_mode(gb_tile_mode, NULL, NULL, NULL, NULL, NULL, &surf->stencil_tile_split);
1342         }
1343         if (surf->flags & RADEON_SURF_ZBUFFER) {
1344             switch (surf->nsamples) {
1345             case 1:
1346                 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1347                 break;
1348             case 2:
1349                 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1350                 break;
1351             case 4:
1352                 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1353                 break;
1354             case 8:
1355                 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1356                 break;
1357             default:
1358                 return -EINVAL;
1359             }
1360         } else if (surf->flags & RADEON_SURF_SCANOUT) {
1361             switch (surf->bpe) {
1362             case 2:
1363                 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
1364                 break;
1365             case 4:
1366                 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
1367                 break;
1368             default:
1369                 return -EINVAL;
1370             }
1371         } else {
1372             switch (surf->bpe) {
1373             case 1:
1374                 *tile_mode = SI_TILE_MODE_COLOR_2D_8BPP;
1375                 break;
1376             case 2:
1377                 *tile_mode = SI_TILE_MODE_COLOR_2D_16BPP;
1378                 break;
1379             case 4:
1380                 *tile_mode = SI_TILE_MODE_COLOR_2D_32BPP;
1381                 break;
1382             case 8:
1383             case 16:
1384                 *tile_mode = SI_TILE_MODE_COLOR_2D_64BPP;
1385                 break;
1386             default:
1387                 return -EINVAL;
1388             }
1389         }
1390         /* retrieve tiling mode value */
1391         gb_tile_mode = surf_man->hw_info.tile_mode_array[*tile_mode];
1392         si_gb_tile_mode(gb_tile_mode, NULL, NULL, &surf->mtilea, &surf->bankw, &surf->bankh, &surf->tile_split);
1393         break;
1394     case RADEON_SURF_MODE_1D:
1395         if (surf->flags & RADEON_SURF_SBUFFER) {
1396             *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1397         }
1398         if (surf->flags & RADEON_SURF_ZBUFFER) {
1399             *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1400         } else if (surf->flags & RADEON_SURF_SCANOUT) {
1401             *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1402         } else {
1403             *tile_mode = SI_TILE_MODE_COLOR_1D;
1404         }
1405         break;
1406     case RADEON_SURF_MODE_LINEAR_ALIGNED:
1407     default:
1408         *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
1409     }
1410
1411     return 0;
1412 }
1413
1414 static void si_surf_minify(struct radeon_surface *surf,
1415                            struct radeon_surface_level *surflevel,
1416                            unsigned bpe, unsigned level,
1417                            uint32_t xalign, uint32_t yalign, uint32_t zalign,
1418                            uint32_t slice_align, unsigned offset)
1419 {
1420     if (level == 0) {
1421         surflevel->npix_x = surf->npix_x;
1422     } else {
1423         surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1424     }
1425     surflevel->npix_y = mip_minify(surf->npix_y, level);
1426     surflevel->npix_z = mip_minify(surf->npix_z, level);
1427
1428     if (level == 0 && surf->last_level > 0) {
1429         surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1430         surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1431         surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1432     } else {
1433         surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1434         surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1435         surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1436     }
1437
1438     surflevel->nblk_y  = ALIGN(surflevel->nblk_y, yalign);
1439
1440     /* XXX: Texture sampling uses unexpectedly large pitches in some cases,
1441      * these are just guesses for the rules behind those
1442      */
1443     if (level == 0 && surf->last_level == 0)
1444         /* Non-mipmap pitch padded to slice alignment */
1445         /* Using just bpe here breaks stencil blitting; surf->bpe works. */
1446         xalign = MAX2(xalign, slice_align / surf->bpe);
1447     else if (surflevel->mode == RADEON_SURF_MODE_LINEAR_ALIGNED)
1448         /* Small rows evenly distributed across slice */
1449         xalign = MAX2(xalign, slice_align / bpe / surflevel->nblk_y);
1450
1451     surflevel->nblk_x  = ALIGN(surflevel->nblk_x, xalign);
1452     surflevel->nblk_z  = ALIGN(surflevel->nblk_z, zalign);
1453
1454     surflevel->offset = offset;
1455     surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
1456     surflevel->slice_size = ALIGN(surflevel->pitch_bytes * surflevel->nblk_y, slice_align);
1457
1458     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1459 }
1460
1461 static void si_surf_minify_2d(struct radeon_surface *surf,
1462                               struct radeon_surface_level *surflevel,
1463                               unsigned bpe, unsigned level, unsigned slice_pt,
1464                               uint32_t xalign, uint32_t yalign, uint32_t zalign,
1465                               unsigned mtileb, unsigned offset)
1466 {
1467     unsigned mtile_pr, mtile_ps;
1468
1469     if (level == 0) {
1470         surflevel->npix_x = surf->npix_x;
1471     } else {
1472         surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1473     }
1474     surflevel->npix_y = mip_minify(surf->npix_y, level);
1475     surflevel->npix_z = mip_minify(surf->npix_z, level);
1476
1477     if (level == 0 && surf->last_level > 0) {
1478         surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1479         surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1480         surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1481     } else {
1482         surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1483         surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1484         surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1485     }
1486
1487     if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
1488         !(surf->flags & RADEON_SURF_FMASK)) {
1489         if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
1490             surflevel->mode = RADEON_SURF_MODE_1D;
1491             return;
1492         }
1493     }
1494     surflevel->nblk_x  = ALIGN(surflevel->nblk_x, xalign);
1495     surflevel->nblk_y  = ALIGN(surflevel->nblk_y, yalign);
1496     surflevel->nblk_z  = ALIGN(surflevel->nblk_z, zalign);
1497
1498     /* macro tile per row */
1499     mtile_pr = surflevel->nblk_x / xalign;
1500     /* macro tile per slice */
1501     mtile_ps = (mtile_pr * surflevel->nblk_y) / yalign;
1502     surflevel->offset = offset;
1503     surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
1504     surflevel->slice_size = mtile_ps * mtileb * slice_pt;
1505
1506     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1507 }
1508
1509 static int si_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
1510                                           struct radeon_surface *surf,
1511                                           unsigned tile_mode,
1512                                           uint64_t offset, unsigned start_level)
1513 {
1514     uint32_t xalign, yalign, zalign, slice_align;
1515     unsigned i;
1516
1517     /* compute alignment */
1518     if (!start_level) {
1519         surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
1520     }
1521     xalign = MAX2(8, 64 / surf->bpe);
1522     yalign = 1;
1523     zalign = 1;
1524     slice_align = MAX2(64 * surf->bpe, surf_man->hw_info.group_bytes);
1525
1526     /* build mipmap tree */
1527     for (i = start_level; i <= surf->last_level; i++) {
1528         surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
1529         si_surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, slice_align, offset);
1530         /* level0 and first mipmap need to have alignment */
1531         offset = surf->bo_size;
1532         if (i == 0) {
1533             offset = ALIGN(offset, surf->bo_alignment);
1534         }
1535         if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1536             surf->tiling_index[i] = tile_mode;
1537         }
1538     }
1539     return 0;
1540 }
1541
1542 static int si_surface_init_1d(struct radeon_surface_manager *surf_man,
1543                               struct radeon_surface *surf,
1544                               struct radeon_surface_level *level,
1545                               unsigned bpe, unsigned tile_mode,
1546                               uint64_t offset, unsigned start_level)
1547 {
1548     uint32_t xalign, yalign, zalign, slice_align;
1549     unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
1550     unsigned i;
1551
1552     /* compute alignment */
1553     xalign = 8;
1554     yalign = 8;
1555     zalign = 1;
1556     slice_align = surf_man->hw_info.group_bytes;
1557     if (surf->flags & RADEON_SURF_SCANOUT) {
1558         xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
1559     }
1560
1561     if (start_level <= 1) {
1562         surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1563
1564         if (offset) {
1565             offset = ALIGN(offset, alignment);
1566         }
1567     }
1568
1569     /* build mipmap tree */
1570     for (i = start_level; i <= surf->last_level; i++) {
1571         level[i].mode = RADEON_SURF_MODE_1D;
1572         si_surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, slice_align, offset);
1573         /* level0 and first mipmap need to have alignment */
1574         offset = surf->bo_size;
1575         if (i == 0) {
1576             offset = ALIGN(offset, alignment);
1577         }
1578         if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1579             if (surf->level == level) {
1580                 surf->tiling_index[i] = tile_mode;
1581                 /* it's ok because stencil is done after */
1582                 surf->stencil_tiling_index[i] = tile_mode;
1583             } else {
1584                 surf->stencil_tiling_index[i] = tile_mode;
1585             }
1586         }
1587     }
1588     return 0;
1589 }
1590
1591 static int si_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
1592                                        struct radeon_surface *surf,
1593                                        unsigned tile_mode, unsigned stencil_tile_mode)
1594 {
1595     int r;
1596
1597     r = si_surface_init_1d(surf_man, surf, surf->level, surf->bpe, tile_mode, 0, 0);
1598     if (r) {
1599         return r;
1600     }
1601
1602     if (surf->flags & RADEON_SURF_SBUFFER) {
1603         r = si_surface_init_1d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode, surf->bo_size, 0);
1604         surf->stencil_offset = surf->stencil_level[0].offset;
1605     }
1606     return r;
1607 }
1608
1609 static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
1610                               struct radeon_surface *surf,
1611                               struct radeon_surface_level *level,
1612                               unsigned bpe, unsigned tile_mode,
1613                               unsigned num_pipes, unsigned num_banks,
1614                               unsigned tile_split,
1615                               uint64_t offset,
1616                               unsigned start_level)
1617 {
1618     uint64_t aligned_offset = offset;
1619     unsigned tilew, tileh, tileb;
1620     unsigned mtilew, mtileh, mtileb;
1621     unsigned slice_pt;
1622     unsigned i;
1623
1624     /* compute tile values */
1625     tilew = 8;
1626     tileh = 8;
1627     tileb = tilew * tileh * bpe * surf->nsamples;
1628     /* slices per tile */
1629     slice_pt = 1;
1630     if (tileb > tile_split && tile_split) {
1631         slice_pt = tileb / tile_split;
1632     }
1633     tileb = tileb / slice_pt;
1634
1635     /* macro tile width & height */
1636     mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
1637     mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
1638
1639     /* macro tile bytes */
1640     mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
1641
1642     if (start_level <= 1) {
1643         unsigned alignment = MAX2(256, mtileb);
1644         surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1645
1646         if (aligned_offset) {
1647             aligned_offset = ALIGN(aligned_offset, alignment);
1648         }
1649     }
1650
1651     /* build mipmap tree */
1652     for (i = start_level; i <= surf->last_level; i++) {
1653         level[i].mode = RADEON_SURF_MODE_2D;
1654         si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
1655         if (level[i].mode == RADEON_SURF_MODE_1D) {
1656             switch (tile_mode) {
1657             case SI_TILE_MODE_COLOR_2D_8BPP:
1658             case SI_TILE_MODE_COLOR_2D_16BPP:
1659             case SI_TILE_MODE_COLOR_2D_32BPP:
1660             case SI_TILE_MODE_COLOR_2D_64BPP:
1661                 tile_mode = SI_TILE_MODE_COLOR_1D;
1662                 break;
1663             case SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP:
1664             case SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP:
1665                 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1666                 break;
1667             case SI_TILE_MODE_DEPTH_STENCIL_2D:
1668                 tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1669                 break;
1670             default:
1671                 return -EINVAL;
1672             }
1673             return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
1674         }
1675         /* level0 and first mipmap need to have alignment */
1676         aligned_offset = offset = surf->bo_size;
1677         if (i == 0) {
1678             aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
1679         }
1680         if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1681             if (surf->level == level) {
1682                 surf->tiling_index[i] = tile_mode;
1683                 /* it's ok because stencil is done after */
1684                 surf->stencil_tiling_index[i] = tile_mode;
1685             } else {
1686                 surf->stencil_tiling_index[i] = tile_mode;
1687             }
1688         }
1689     }
1690     return 0;
1691 }
1692
1693 static int si_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
1694                                        struct radeon_surface *surf,
1695                                        unsigned tile_mode, unsigned stencil_tile_mode)
1696 {
1697     unsigned num_pipes, num_banks;
1698     uint32_t gb_tile_mode;
1699     int r;
1700
1701     /* retrieve tiling mode value */
1702     gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1703     si_gb_tile_mode(gb_tile_mode, &num_pipes, &num_banks, NULL, NULL, NULL, NULL);
1704
1705     r = si_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode, num_pipes, num_banks, surf->tile_split, 0, 0);
1706     if (r) {
1707         return r;
1708     }
1709
1710     if (surf->flags & RADEON_SURF_SBUFFER) {
1711         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);
1712         surf->stencil_offset = surf->stencil_level[0].offset;
1713     }
1714     return r;
1715 }
1716
1717 static int si_surface_init(struct radeon_surface_manager *surf_man,
1718                            struct radeon_surface *surf)
1719 {
1720     unsigned mode, tile_mode, stencil_tile_mode;
1721     int r;
1722
1723     /* MSAA surfaces support the 2D mode only. */
1724     if (surf->nsamples > 1) {
1725         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1726         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
1727     }
1728
1729     /* tiling mode */
1730     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1731
1732     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
1733         /* zbuffer only support 1D or 2D tiled surface */
1734         switch (mode) {
1735         case RADEON_SURF_MODE_1D:
1736         case RADEON_SURF_MODE_2D:
1737             break;
1738         default:
1739             mode = RADEON_SURF_MODE_1D;
1740             surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1741             surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1742             break;
1743         }
1744     }
1745
1746     r = si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1747     if (r) {
1748         return r;
1749     }
1750
1751     surf->stencil_offset = 0;
1752     surf->bo_alignment = 0;
1753
1754     /* check tiling mode */
1755     switch (mode) {
1756     case RADEON_SURF_MODE_LINEAR:
1757         r = r6_surface_init_linear(surf_man, surf, 0, 0);
1758         break;
1759     case RADEON_SURF_MODE_LINEAR_ALIGNED:
1760         r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
1761         break;
1762     case RADEON_SURF_MODE_1D:
1763         r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1764         break;
1765     case RADEON_SURF_MODE_2D:
1766         r = si_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1767         break;
1768     default:
1769         return -EINVAL;
1770     }
1771     return r;
1772 }
1773
1774 /*
1775  * depending on surface
1776  */
1777 static int si_surface_best(struct radeon_surface_manager *surf_man,
1778                            struct radeon_surface *surf)
1779 {
1780     unsigned mode, tile_mode, stencil_tile_mode;
1781
1782     /* tiling mode */
1783     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1784
1785     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
1786         !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
1787         /* depth/stencil force 1d tiling for old mesa */
1788         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1789         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1790     }
1791
1792     return si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1793 }
1794
1795
1796 /* ===========================================================================
1797  * Sea Islands family
1798  */
1799 #define CIK__GB_TILE_MODE__PIPE_CONFIG(x)        (((x) >> 6) & 0x1f)
1800 #define     CIK__PIPE_CONFIG__ADDR_SURF_P2               0
1801 #define     CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16          4
1802 #define     CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16         5
1803 #define     CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32         6
1804 #define     CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32         7
1805 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16    8
1806 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16    9
1807 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16    10
1808 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16   11
1809 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16   12
1810 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32   13
1811 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32   14
1812 #define     CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16   16
1813 #define     CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16  17
1814 #define CIK__GB_TILE_MODE__TILE_SPLIT(x)         (((x) >> 11) & 0x7)
1815 #define     CIK__TILE_SPLIT__64B                         0
1816 #define     CIK__TILE_SPLIT__128B                        1
1817 #define     CIK__TILE_SPLIT__256B                        2
1818 #define     CIK__TILE_SPLIT__512B                        3
1819 #define     CIK__TILE_SPLIT__1024B                       4
1820 #define     CIK__TILE_SPLIT__2048B                       5
1821 #define     CIK__TILE_SPLIT__4096B                       6
1822 #define CIK__GB_TILE_MODE__SAMPLE_SPLIT(x)         (((x) >> 25) & 0x3)
1823 #define     CIK__SAMPLE_SPLIT__1                         0
1824 #define     CIK__SAMPLE_SPLIT__2                         1
1825 #define     CIK__SAMPLE_SPLIT__4                         2
1826 #define     CIK__SAMPLE_SPLIT__8                         3
1827 #define CIK__GB_MACROTILE_MODE__BANK_WIDTH(x)        ((x) & 0x3)
1828 #define     CIK__BANK_WIDTH__1                           0
1829 #define     CIK__BANK_WIDTH__2                           1
1830 #define     CIK__BANK_WIDTH__4                           2
1831 #define     CIK__BANK_WIDTH__8                           3
1832 #define CIK__GB_MACROTILE_MODE__BANK_HEIGHT(x)       (((x) >> 2) & 0x3)
1833 #define     CIK__BANK_HEIGHT__1                          0
1834 #define     CIK__BANK_HEIGHT__2                          1
1835 #define     CIK__BANK_HEIGHT__4                          2
1836 #define     CIK__BANK_HEIGHT__8                          3
1837 #define CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 4) & 0x3)
1838 #define     CIK__MACRO_TILE_ASPECT__1                    0
1839 #define     CIK__MACRO_TILE_ASPECT__2                    1
1840 #define     CIK__MACRO_TILE_ASPECT__4                    2
1841 #define     CIK__MACRO_TILE_ASPECT__8                    3
1842 #define CIK__GB_MACROTILE_MODE__NUM_BANKS(x)         (((x) >> 6) & 0x3)
1843 #define     CIK__NUM_BANKS__2_BANK                       0
1844 #define     CIK__NUM_BANKS__4_BANK                       1
1845 #define     CIK__NUM_BANKS__8_BANK                       2
1846 #define     CIK__NUM_BANKS__16_BANK                      3
1847
1848
1849 static void cik_get_2d_params(struct radeon_surface_manager *surf_man,
1850                               unsigned bpe, unsigned nsamples, bool is_color,
1851                               unsigned tile_mode,
1852                               uint32_t *num_pipes,
1853                               uint32_t *tile_split_ptr,
1854                               uint32_t *num_banks,
1855                               uint32_t *macro_tile_aspect,
1856                               uint32_t *bank_w,
1857                               uint32_t *bank_h)
1858 {
1859     uint32_t gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1860     unsigned tileb_1x, tileb;
1861     unsigned gb_macrotile_mode;
1862     unsigned macrotile_index;
1863     unsigned tile_split, sample_split;
1864
1865     if (num_pipes) {
1866         switch (CIK__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1867         case CIK__PIPE_CONFIG__ADDR_SURF_P2:
1868         default:
1869             *num_pipes = 2;
1870             break;
1871         case CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1872         case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1873         case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1874         case CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1875             *num_pipes = 4;
1876             break;
1877         case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1878         case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1879         case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1880         case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1881         case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1882         case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1883         case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1884             *num_pipes = 8;
1885             break;
1886         case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16:
1887         case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16:
1888             *num_pipes = 16;
1889             break;
1890         }
1891     }
1892     switch (CIK__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1893     default:
1894     case CIK__TILE_SPLIT__64B:
1895         tile_split = 64;
1896         break;
1897     case CIK__TILE_SPLIT__128B:
1898         tile_split = 128;
1899         break;
1900     case CIK__TILE_SPLIT__256B:
1901         tile_split = 256;
1902         break;
1903     case CIK__TILE_SPLIT__512B:
1904         tile_split = 512;
1905         break;
1906     case CIK__TILE_SPLIT__1024B:
1907         tile_split = 1024;
1908         break;
1909     case CIK__TILE_SPLIT__2048B:
1910         tile_split = 2048;
1911         break;
1912     case CIK__TILE_SPLIT__4096B:
1913         tile_split = 4096;
1914         break;
1915     }
1916     switch (CIK__GB_TILE_MODE__SAMPLE_SPLIT(gb_tile_mode)) {
1917     default:
1918     case CIK__SAMPLE_SPLIT__1:
1919         sample_split = 1;
1920         break;
1921     case CIK__SAMPLE_SPLIT__2:
1922         sample_split = 2;
1923         break;
1924     case CIK__SAMPLE_SPLIT__4:
1925         sample_split = 4;
1926         break;
1927     case CIK__SAMPLE_SPLIT__8:
1928         sample_split = 8;
1929         break;
1930     }
1931
1932     /* Adjust the tile split. */
1933     tileb_1x = 8 * 8 * bpe;
1934     if (is_color) {
1935         tile_split = MAX2(256, sample_split * tileb_1x);
1936     }
1937     tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
1938
1939     /* Determine the macrotile index. */
1940     tileb = MIN2(tile_split, nsamples * tileb_1x);
1941
1942     for (macrotile_index = 0; tileb > 64; macrotile_index++) {
1943         tileb >>= 1;
1944     }
1945     gb_macrotile_mode = surf_man->hw_info.macrotile_mode_array[macrotile_index];
1946
1947     if (tile_split_ptr) {
1948         *tile_split_ptr = tile_split;
1949     }
1950     if (num_banks) {
1951         switch (CIK__GB_MACROTILE_MODE__NUM_BANKS(gb_macrotile_mode)) {
1952         default:
1953         case CIK__NUM_BANKS__2_BANK:
1954             *num_banks = 2;
1955             break;
1956         case CIK__NUM_BANKS__4_BANK:
1957             *num_banks = 4;
1958             break;
1959         case CIK__NUM_BANKS__8_BANK:
1960             *num_banks = 8;
1961             break;
1962         case CIK__NUM_BANKS__16_BANK:
1963             *num_banks = 16;
1964             break;
1965         }
1966     }
1967     if (macro_tile_aspect) {
1968         switch (CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(gb_macrotile_mode)) {
1969         default:
1970         case CIK__MACRO_TILE_ASPECT__1:
1971             *macro_tile_aspect = 1;
1972             break;
1973         case CIK__MACRO_TILE_ASPECT__2:
1974             *macro_tile_aspect = 2;
1975             break;
1976         case CIK__MACRO_TILE_ASPECT__4:
1977             *macro_tile_aspect = 4;
1978             break;
1979         case CIK__MACRO_TILE_ASPECT__8:
1980             *macro_tile_aspect = 8;
1981             break;
1982         }
1983     }
1984     if (bank_w) {
1985         switch (CIK__GB_MACROTILE_MODE__BANK_WIDTH(gb_macrotile_mode)) {
1986         default:
1987         case CIK__BANK_WIDTH__1:
1988             *bank_w = 1;
1989             break;
1990         case CIK__BANK_WIDTH__2:
1991             *bank_w = 2;
1992             break;
1993         case CIK__BANK_WIDTH__4:
1994             *bank_w = 4;
1995             break;
1996         case CIK__BANK_WIDTH__8:
1997             *bank_w = 8;
1998             break;
1999         }
2000     }
2001     if (bank_h) {
2002         switch (CIK__GB_MACROTILE_MODE__BANK_HEIGHT(gb_macrotile_mode)) {
2003         default:
2004         case CIK__BANK_HEIGHT__1:
2005             *bank_h = 1;
2006             break;
2007         case CIK__BANK_HEIGHT__2:
2008             *bank_h = 2;
2009             break;
2010         case CIK__BANK_HEIGHT__4:
2011             *bank_h = 4;
2012             break;
2013         case CIK__BANK_HEIGHT__8:
2014             *bank_h = 8;
2015             break;
2016         }
2017     }
2018 }
2019
2020 static int cik_init_hw_info(struct radeon_surface_manager *surf_man)
2021 {
2022     uint32_t tiling_config;
2023     drmVersionPtr version;
2024     int r;
2025
2026     r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
2027                          &tiling_config);
2028     if (r) {
2029         return r;
2030     }
2031
2032     surf_man->hw_info.allow_2d = 0;
2033     version = drmGetVersion(surf_man->fd);
2034     if (version && version->version_minor >= 35) {
2035         if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array) &&
2036             !radeon_get_value(surf_man->fd, RADEON_INFO_CIK_MACROTILE_MODE_ARRAY, surf_man->hw_info.macrotile_mode_array)) {
2037             surf_man->hw_info.allow_2d = 1;
2038         }
2039     }
2040     drmFreeVersion(version);
2041
2042     switch (tiling_config & 0xf) {
2043     case 0:
2044         surf_man->hw_info.num_pipes = 1;
2045         break;
2046     case 1:
2047         surf_man->hw_info.num_pipes = 2;
2048         break;
2049     case 2:
2050         surf_man->hw_info.num_pipes = 4;
2051         break;
2052     case 3:
2053         surf_man->hw_info.num_pipes = 8;
2054         break;
2055     default:
2056         surf_man->hw_info.num_pipes = 8;
2057         surf_man->hw_info.allow_2d = 0;
2058         break;
2059     }
2060
2061     switch ((tiling_config & 0xf0) >> 4) {
2062     case 0:
2063         surf_man->hw_info.num_banks = 4;
2064         break;
2065     case 1:
2066         surf_man->hw_info.num_banks = 8;
2067         break;
2068     case 2:
2069         surf_man->hw_info.num_banks = 16;
2070         break;
2071     default:
2072         surf_man->hw_info.num_banks = 8;
2073         surf_man->hw_info.allow_2d = 0;
2074         break;
2075     }
2076
2077     switch ((tiling_config & 0xf00) >> 8) {
2078     case 0:
2079         surf_man->hw_info.group_bytes = 256;
2080         break;
2081     case 1:
2082         surf_man->hw_info.group_bytes = 512;
2083         break;
2084     default:
2085         surf_man->hw_info.group_bytes = 256;
2086         surf_man->hw_info.allow_2d = 0;
2087         break;
2088     }
2089
2090     switch ((tiling_config & 0xf000) >> 12) {
2091     case 0:
2092         surf_man->hw_info.row_size = 1024;
2093         break;
2094     case 1:
2095         surf_man->hw_info.row_size = 2048;
2096         break;
2097     case 2:
2098         surf_man->hw_info.row_size = 4096;
2099         break;
2100     default:
2101         surf_man->hw_info.row_size = 4096;
2102         surf_man->hw_info.allow_2d = 0;
2103         break;
2104     }
2105     return 0;
2106 }
2107
2108 static int cik_surface_sanity(struct radeon_surface_manager *surf_man,
2109                               struct radeon_surface *surf,
2110                               unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
2111 {
2112     /* check surface dimension */
2113     if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
2114         return -EINVAL;
2115     }
2116
2117     /* check mipmap last_level */
2118     if (surf->last_level > 15) {
2119         return -EINVAL;
2120     }
2121
2122     /* force 1d on kernel that can't do 2d */
2123     if (mode > RADEON_SURF_MODE_1D &&
2124         (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
2125         if (surf->nsamples > 1) {
2126             fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
2127             return -EFAULT;
2128         }
2129         mode = RADEON_SURF_MODE_1D;
2130         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2131         surf->flags |= RADEON_SURF_SET(mode, MODE);
2132     }
2133
2134     if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
2135         return -EINVAL;
2136     }
2137
2138     if (!surf->tile_split) {
2139         /* default value */
2140         surf->mtilea = 1;
2141         surf->bankw = 1;
2142         surf->bankh = 1;
2143         surf->tile_split = 64;
2144         surf->stencil_tile_split = 64;
2145     }
2146
2147     switch (mode) {
2148     case RADEON_SURF_MODE_2D: {
2149         if (surf->flags & RADEON_SURF_Z_OR_SBUFFER) {
2150             switch (surf->nsamples) {
2151             case 1:
2152                 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64;
2153                 break;
2154             case 2:
2155             case 4:
2156                 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128;
2157                 break;
2158             case 8:
2159                 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256;
2160                 break;
2161             default:
2162                 return -EINVAL;
2163             }
2164
2165             if (surf->flags & RADEON_SURF_SBUFFER) {
2166                 *stencil_tile_mode = *tile_mode;
2167
2168                 cik_get_2d_params(surf_man, 1, surf->nsamples, false,
2169                                   *stencil_tile_mode, NULL,
2170                                   &surf->stencil_tile_split,
2171                                   NULL, NULL, NULL, NULL);
2172             }
2173         } else if (surf->flags & RADEON_SURF_SCANOUT) {
2174             *tile_mode = CIK_TILE_MODE_COLOR_2D_SCANOUT;
2175         } else {
2176             *tile_mode = CIK_TILE_MODE_COLOR_2D;
2177         }
2178
2179         /* retrieve tiling mode values */
2180         cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
2181                           !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), *tile_mode,
2182                           NULL, &surf->tile_split, NULL, &surf->mtilea,
2183                           &surf->bankw, &surf->bankh);
2184         break;
2185     }
2186     case RADEON_SURF_MODE_1D:
2187         if (surf->flags & RADEON_SURF_SBUFFER) {
2188             *stencil_tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2189         }
2190         if (surf->flags & RADEON_SURF_ZBUFFER) {
2191             *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2192         } else if (surf->flags & RADEON_SURF_SCANOUT) {
2193             *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2194         } else {
2195             *tile_mode = SI_TILE_MODE_COLOR_1D;
2196         }
2197         break;
2198     case RADEON_SURF_MODE_LINEAR_ALIGNED:
2199     default:
2200         *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
2201     }
2202
2203     return 0;
2204 }
2205
2206 static int cik_surface_init_2d(struct radeon_surface_manager *surf_man,
2207                                struct radeon_surface *surf,
2208                                struct radeon_surface_level *level,
2209                                unsigned bpe, unsigned tile_mode,
2210                                unsigned tile_split,
2211                                unsigned num_pipes, unsigned num_banks,
2212                                uint64_t offset,
2213                                unsigned start_level)
2214 {
2215     uint64_t aligned_offset = offset;
2216     unsigned tilew, tileh, tileb_1x, tileb;
2217     unsigned mtilew, mtileh, mtileb;
2218     unsigned slice_pt;
2219     unsigned i;
2220
2221     /* compute tile values */
2222     tilew = 8;
2223     tileh = 8;
2224     tileb_1x = tilew * tileh * bpe;
2225
2226     tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
2227
2228     tileb = surf->nsamples * tileb_1x;
2229
2230     /* slices per tile */
2231     slice_pt = 1;
2232     if (tileb > tile_split && tile_split) {
2233         slice_pt = tileb / tile_split;
2234         tileb = tileb / slice_pt;
2235     }
2236
2237     /* macro tile width & height */
2238     mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
2239     mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
2240
2241     /* macro tile bytes */
2242     mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
2243
2244     if (start_level <= 1) {
2245         unsigned alignment = MAX2(256, mtileb);
2246         surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
2247
2248         if (aligned_offset) {
2249             aligned_offset = ALIGN(aligned_offset, alignment);
2250         }
2251     }
2252
2253     /* build mipmap tree */
2254     for (i = start_level; i <= surf->last_level; i++) {
2255         level[i].mode = RADEON_SURF_MODE_2D;
2256         si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
2257         if (level[i].mode == RADEON_SURF_MODE_1D) {
2258             switch (tile_mode) {
2259             case CIK_TILE_MODE_COLOR_2D:
2260                 tile_mode = SI_TILE_MODE_COLOR_1D;
2261                 break;
2262             case CIK_TILE_MODE_COLOR_2D_SCANOUT:
2263                 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2264                 break;
2265             case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64:
2266             case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128:
2267             case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256:
2268             case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512:
2269             case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE:
2270                 tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2271                 break;
2272             default:
2273                 return -EINVAL;
2274             }
2275             return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
2276         }
2277         /* level0 and first mipmap need to have alignment */
2278         aligned_offset = offset = surf->bo_size;
2279         if (i == 0) {
2280             aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
2281         }
2282         if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
2283             if (surf->level == level) {
2284                 surf->tiling_index[i] = tile_mode;
2285                 /* it's ok because stencil is done after */
2286                 surf->stencil_tiling_index[i] = tile_mode;
2287             } else {
2288                 surf->stencil_tiling_index[i] = tile_mode;
2289             }
2290         }
2291     }
2292     return 0;
2293 }
2294
2295 static int cik_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
2296                                         struct radeon_surface *surf,
2297                                         unsigned tile_mode, unsigned stencil_tile_mode)
2298 {
2299     int r;
2300     uint32_t num_pipes, num_banks;
2301
2302     cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
2303                         !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), tile_mode,
2304                         &num_pipes, NULL, &num_banks, NULL, NULL, NULL);
2305
2306     r = cik_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode,
2307                             surf->tile_split, num_pipes, num_banks, 0, 0);
2308     if (r) {
2309         return r;
2310     }
2311
2312     if (surf->flags & RADEON_SURF_SBUFFER) {
2313         r = cik_surface_init_2d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode,
2314                                 surf->stencil_tile_split, num_pipes, num_banks,
2315                                 surf->bo_size, 0);
2316         surf->stencil_offset = surf->stencil_level[0].offset;
2317     }
2318     return r;
2319 }
2320
2321 static int cik_surface_init(struct radeon_surface_manager *surf_man,
2322                             struct radeon_surface *surf)
2323 {
2324     unsigned mode, tile_mode, stencil_tile_mode;
2325     int r;
2326
2327     /* MSAA surfaces support the 2D mode only. */
2328     if (surf->nsamples > 1) {
2329         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2330         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
2331     }
2332
2333     /* tiling mode */
2334     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2335
2336     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
2337         /* zbuffer only support 1D or 2D tiled surface */
2338         switch (mode) {
2339         case RADEON_SURF_MODE_1D:
2340         case RADEON_SURF_MODE_2D:
2341             break;
2342         default:
2343             mode = RADEON_SURF_MODE_1D;
2344             surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2345             surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2346             break;
2347         }
2348     }
2349
2350     r = cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2351     if (r) {
2352         return r;
2353     }
2354
2355     surf->stencil_offset = 0;
2356     surf->bo_alignment = 0;
2357
2358     /* check tiling mode */
2359     switch (mode) {
2360     case RADEON_SURF_MODE_LINEAR:
2361         r = r6_surface_init_linear(surf_man, surf, 0, 0);
2362         break;
2363     case RADEON_SURF_MODE_LINEAR_ALIGNED:
2364         r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
2365         break;
2366     case RADEON_SURF_MODE_1D:
2367         r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2368         break;
2369     case RADEON_SURF_MODE_2D:
2370         r = cik_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2371         break;
2372     default:
2373         return -EINVAL;
2374     }
2375     return r;
2376 }
2377
2378 /*
2379  * depending on surface
2380  */
2381 static int cik_surface_best(struct radeon_surface_manager *surf_man,
2382                             struct radeon_surface *surf)
2383 {
2384     unsigned mode, tile_mode, stencil_tile_mode;
2385
2386     /* tiling mode */
2387     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2388
2389     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
2390         !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
2391         /* depth/stencil force 1d tiling for old mesa */
2392         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2393         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2394     }
2395
2396     return cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2397 }
2398
2399
2400 /* ===========================================================================
2401  * public API
2402  */
2403 drm_public struct radeon_surface_manager *
2404 radeon_surface_manager_new(int fd)
2405 {
2406     struct radeon_surface_manager *surf_man;
2407
2408     surf_man = calloc(1, sizeof(struct radeon_surface_manager));
2409     if (surf_man == NULL) {
2410         return NULL;
2411     }
2412     surf_man->fd = fd;
2413     if (radeon_get_value(fd, RADEON_INFO_DEVICE_ID, &surf_man->device_id)) {
2414         goto out_err;
2415     }
2416     if (radeon_get_family(surf_man)) {
2417         goto out_err;
2418     }
2419
2420     if (surf_man->family <= CHIP_RV740) {
2421         if (r6_init_hw_info(surf_man)) {
2422             goto out_err;
2423         }
2424         surf_man->surface_init = &r6_surface_init;
2425         surf_man->surface_best = &r6_surface_best;
2426     } else if (surf_man->family <= CHIP_ARUBA) {
2427         if (eg_init_hw_info(surf_man)) {
2428             goto out_err;
2429         }
2430         surf_man->surface_init = &eg_surface_init;
2431         surf_man->surface_best = &eg_surface_best;
2432     } else if (surf_man->family < CHIP_BONAIRE) {
2433         if (si_init_hw_info(surf_man)) {
2434             goto out_err;
2435         }
2436         surf_man->surface_init = &si_surface_init;
2437         surf_man->surface_best = &si_surface_best;
2438     } else {
2439         if (cik_init_hw_info(surf_man)) {
2440             goto out_err;
2441         }
2442         surf_man->surface_init = &cik_surface_init;
2443         surf_man->surface_best = &cik_surface_best;
2444     }
2445
2446     return surf_man;
2447 out_err:
2448     free(surf_man);
2449     return NULL;
2450 }
2451
2452 drm_public void
2453 radeon_surface_manager_free(struct radeon_surface_manager *surf_man)
2454 {
2455     free(surf_man);
2456 }
2457
2458 static int radeon_surface_sanity(struct radeon_surface_manager *surf_man,
2459                                  struct radeon_surface *surf,
2460                                  unsigned type,
2461                                  unsigned mode)
2462 {
2463     if (surf_man == NULL || surf_man->surface_init == NULL || surf == NULL) {
2464         return -EINVAL;
2465     }
2466
2467     /* all dimension must be at least 1 ! */
2468     if (!surf->npix_x || !surf->npix_y || !surf->npix_z) {
2469         return -EINVAL;
2470     }
2471     if (!surf->blk_w || !surf->blk_h || !surf->blk_d) {
2472         return -EINVAL;
2473     }
2474     if (!surf->array_size) {
2475         return -EINVAL;
2476     }
2477     /* array size must be a power of 2 */
2478     surf->array_size = next_power_of_two(surf->array_size);
2479
2480     switch (surf->nsamples) {
2481     case 1:
2482     case 2:
2483     case 4:
2484     case 8:
2485         break;
2486     default:
2487         return -EINVAL;
2488     }
2489     /* check type */
2490     switch (type) {
2491     case RADEON_SURF_TYPE_1D:
2492         if (surf->npix_y > 1) {
2493             return -EINVAL;
2494         }
2495     case RADEON_SURF_TYPE_2D:
2496         if (surf->npix_z > 1) {
2497             return -EINVAL;
2498         }
2499         break;
2500     case RADEON_SURF_TYPE_CUBEMAP:
2501         if (surf->npix_z > 1) {
2502             return -EINVAL;
2503         }
2504         /* deal with cubemap as they were texture array */
2505         if (surf_man->family >= CHIP_RV770) {
2506             surf->array_size = 8;
2507         } else {
2508             surf->array_size = 6;
2509         }
2510         break;
2511     case RADEON_SURF_TYPE_3D:
2512         break;
2513     case RADEON_SURF_TYPE_1D_ARRAY:
2514         if (surf->npix_y > 1) {
2515             return -EINVAL;
2516         }
2517     case RADEON_SURF_TYPE_2D_ARRAY:
2518         break;
2519     default:
2520         return -EINVAL;
2521     }
2522     return 0;
2523 }
2524
2525 drm_public int
2526 radeon_surface_init(struct radeon_surface_manager *surf_man,
2527                     struct radeon_surface *surf)
2528 {
2529     unsigned mode, type;
2530     int r;
2531
2532     type = RADEON_SURF_GET(surf->flags, TYPE);
2533     mode = RADEON_SURF_GET(surf->flags, MODE);
2534
2535     r = radeon_surface_sanity(surf_man, surf, type, mode);
2536     if (r) {
2537         return r;
2538     }
2539     return surf_man->surface_init(surf_man, surf);
2540 }
2541
2542 drm_public int
2543 radeon_surface_best(struct radeon_surface_manager *surf_man,
2544                     struct radeon_surface *surf)
2545 {
2546     unsigned mode, type;
2547     int r;
2548
2549     type = RADEON_SURF_GET(surf->flags, TYPE);
2550     mode = RADEON_SURF_GET(surf->flags, MODE);
2551
2552     r = radeon_surface_sanity(surf_man, surf, type, mode);
2553     if (r) {
2554         return r;
2555     }
2556     return surf_man->surface_best(surf_man, surf);
2557 }