OSDN Git Service

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