radeon: add si tiling support v5
[platform/upstream/libdrm.git] / radeon / radeon_surface.c
1 /*
2  * Copyright © 2011 Red Hat All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
14  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15  * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
16  * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19  * USE OR OTHER DEALINGS IN THE SOFTWARE.
20  *
21  * The above copyright notice and this permission notice (including the
22  * next paragraph) shall be included in all copies or substantial portions
23  * of the Software.
24  */
25 /*
26  * Authors:
27  *      Jérôme Glisse <jglisse@redhat.com>
28  */
29 #include <errno.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <sys/mman.h>
34 #include <sys/ioctl.h>
35 #include "drm.h"
36 #include "xf86drm.h"
37 #include "radeon_drm.h"
38 #include "radeon_surface.h"
39
40 #define ALIGN(value, alignment) (((value) + alignment - 1) & ~(alignment - 1))
41 #define MAX2(A, B)              ((A) > (B) ? (A) : (B))
42 #define MIN2(A, B)              ((A) < (B) ? (A) : (B))
43
44 /* keep this private */
45 enum radeon_family {
46     CHIP_UNKNOWN,
47     CHIP_R600,
48     CHIP_RV610,
49     CHIP_RV630,
50     CHIP_RV670,
51     CHIP_RV620,
52     CHIP_RV635,
53     CHIP_RS780,
54     CHIP_RS880,
55     CHIP_RV770,
56     CHIP_RV730,
57     CHIP_RV710,
58     CHIP_RV740,
59     CHIP_CEDAR,
60     CHIP_REDWOOD,
61     CHIP_JUNIPER,
62     CHIP_CYPRESS,
63     CHIP_HEMLOCK,
64     CHIP_PALM,
65     CHIP_SUMO,
66     CHIP_SUMO2,
67     CHIP_BARTS,
68     CHIP_TURKS,
69     CHIP_CAICOS,
70     CHIP_CAYMAN,
71     CHIP_ARUBA,
72     CHIP_TAHITI,
73     CHIP_PITCAIRN,
74     CHIP_VERDE,
75     CHIP_OLAND,
76     CHIP_LAST,
77 };
78
79 typedef int (*hw_init_surface_t)(struct radeon_surface_manager *surf_man,
80                                  struct radeon_surface *surf);
81 typedef int (*hw_best_surface_t)(struct radeon_surface_manager *surf_man,
82                                  struct radeon_surface *surf);
83
84 struct radeon_hw_info {
85     /* apply to r6, eg */
86     uint32_t                        group_bytes;
87     uint32_t                        num_banks;
88     uint32_t                        num_pipes;
89     /* apply to eg */
90     uint32_t                        row_size;
91     unsigned                        allow_2d;
92     /* apply to si */
93     uint32_t                        tile_mode_array[32];
94 };
95
96 struct radeon_surface_manager {
97     int                         fd;
98     uint32_t                    device_id;
99     struct radeon_hw_info       hw_info;
100     unsigned                    family;
101     hw_init_surface_t           surface_init;
102     hw_best_surface_t           surface_best;
103 };
104
105 /* helper */
106 static int radeon_get_value(int fd, unsigned req, uint32_t *value)
107 {
108     struct drm_radeon_info info = {};
109     int r;
110
111     *value = 0;
112     info.request = req;
113     info.value = (uintptr_t)value;
114     r = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info,
115                             sizeof(struct drm_radeon_info));
116     return r;
117 }
118
119 static int radeon_get_family(struct radeon_surface_manager *surf_man)
120 {
121     switch (surf_man->device_id) {
122 #define CHIPSET(pci_id, name, fam) case pci_id: surf_man->family = CHIP_##fam; break;
123 #include "r600_pci_ids.h"
124 #undef CHIPSET
125     default:
126         return -EINVAL;
127     }
128     return 0;
129 }
130
131 static unsigned next_power_of_two(unsigned x)
132 {
133    if (x <= 1)
134        return 1;
135
136    return (1 << ((sizeof(unsigned) * 8) - __builtin_clz(x - 1)));
137 }
138
139 static unsigned mip_minify(unsigned size, unsigned level)
140 {
141     unsigned val;
142
143     val = MAX2(1, size >> level);
144     if (level > 0)
145         val = next_power_of_two(val);
146     return val;
147 }
148
149 static void surf_minify(struct radeon_surface *surf,
150                         struct radeon_surface_level *surflevel,
151                         unsigned bpe, unsigned level,
152                         uint32_t xalign, uint32_t yalign, uint32_t zalign,
153                         unsigned offset)
154 {
155     surflevel->npix_x = mip_minify(surf->npix_x, level);
156     surflevel->npix_y = mip_minify(surf->npix_y, level);
157     surflevel->npix_z = mip_minify(surf->npix_z, level);
158     surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
159     surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
160     surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
161     if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D) {
162         if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
163             surflevel->mode = RADEON_SURF_MODE_1D;
164             return;
165         }
166     }
167     surflevel->nblk_x  = ALIGN(surflevel->nblk_x, xalign);
168     surflevel->nblk_y  = ALIGN(surflevel->nblk_y, yalign);
169     surflevel->nblk_z  = ALIGN(surflevel->nblk_z, zalign);
170
171     surflevel->offset = offset;
172     surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
173     surflevel->slice_size = surflevel->pitch_bytes * surflevel->nblk_y;
174
175     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
176 }
177
178 /* ===========================================================================
179  * r600/r700 family
180  */
181 static int r6_init_hw_info(struct radeon_surface_manager *surf_man)
182 {
183     uint32_t tiling_config;
184     drmVersionPtr version;
185     int r;
186
187     r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
188                          &tiling_config);
189     if (r) {
190         return r;
191     }
192
193     surf_man->hw_info.allow_2d = 0;
194     version = drmGetVersion(surf_man->fd);
195     if (version && version->version_minor >= 14) {
196         surf_man->hw_info.allow_2d = 1;
197     }
198     drmFreeVersion(version);
199
200     switch ((tiling_config & 0xe) >> 1) {
201     case 0:
202         surf_man->hw_info.num_pipes = 1;
203         break;
204     case 1:
205         surf_man->hw_info.num_pipes = 2;
206         break;
207     case 2:
208         surf_man->hw_info.num_pipes = 4;
209         break;
210     case 3:
211         surf_man->hw_info.num_pipes = 8;
212         break;
213     default:
214         surf_man->hw_info.num_pipes = 8;
215         surf_man->hw_info.allow_2d = 0;
216         break;
217     }
218
219     switch ((tiling_config & 0x30) >> 4) {
220     case 0:
221         surf_man->hw_info.num_banks = 4;
222         break;
223     case 1:
224         surf_man->hw_info.num_banks = 8;
225         break;
226     default:
227         surf_man->hw_info.num_banks = 8;
228         surf_man->hw_info.allow_2d = 0;
229         break;
230     }
231
232     switch ((tiling_config & 0xc0) >> 6) {
233     case 0:
234         surf_man->hw_info.group_bytes = 256;
235         break;
236     case 1:
237         surf_man->hw_info.group_bytes = 512;
238         break;
239     default:
240         surf_man->hw_info.group_bytes = 256;
241         surf_man->hw_info.allow_2d = 0;
242         break;
243     }
244     return 0;
245 }
246
247 static int r6_surface_init_linear(struct radeon_surface_manager *surf_man,
248                                   struct radeon_surface *surf,
249                                   uint64_t offset, unsigned start_level)
250 {
251     uint32_t xalign, yalign, zalign;
252     unsigned i;
253
254     /* compute alignment */
255     if (!start_level) {
256         surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
257     }
258     /* the 32 alignment is for scanout, cb or db but to allow texture to be
259      * easily bound as such we force this alignment to all surface
260      */
261     xalign = MAX2(1, surf_man->hw_info.group_bytes / surf->bpe);
262     yalign = 1;
263     zalign = 1;
264     if (surf->flags & RADEON_SURF_SCANOUT) {
265         xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
266     }
267
268     /* build mipmap tree */
269     for (i = start_level; i <= surf->last_level; i++) {
270         surf->level[i].mode = RADEON_SURF_MODE_LINEAR;
271         surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
272         /* level0 and first mipmap need to have alignment */
273         offset = surf->bo_size;
274         if ((i == 0)) {
275             offset = ALIGN(offset, surf->bo_alignment);
276         }
277     }
278     return 0;
279 }
280
281 static int r6_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
282                                           struct radeon_surface *surf,
283                                           uint64_t offset, unsigned start_level)
284 {
285     uint32_t xalign, yalign, zalign;
286     unsigned i;
287
288     /* compute alignment */
289     if (!start_level) {
290         surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
291     }
292     xalign = MAX2(64, surf_man->hw_info.group_bytes / surf->bpe);
293     yalign = 1;
294     zalign = 1;
295
296     /* build mipmap tree */
297     for (i = start_level; i <= surf->last_level; i++) {
298         surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
299         surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
300         /* level0 and first mipmap need to have alignment */
301         offset = surf->bo_size;
302         if ((i == 0)) {
303             offset = ALIGN(offset, surf->bo_alignment);
304         }
305     }
306     return 0;
307 }
308
309 static int r6_surface_init_1d(struct radeon_surface_manager *surf_man,
310                               struct radeon_surface *surf,
311                               uint64_t offset, unsigned start_level)
312 {
313     uint32_t xalign, yalign, zalign, tilew;
314     unsigned i;
315
316     /* compute alignment */
317     tilew = 8;
318     xalign = surf_man->hw_info.group_bytes / (tilew * surf->bpe * surf->nsamples);
319     xalign = MAX2(tilew, xalign);
320     yalign = tilew;
321     zalign = 1;
322     if (surf->flags & RADEON_SURF_SCANOUT) {
323         xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
324     }
325     if (!start_level) {
326         surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
327     }
328
329     /* build mipmap tree */
330     for (i = start_level; i <= surf->last_level; i++) {
331         surf->level[i].mode = RADEON_SURF_MODE_1D;
332         surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
333         /* level0 and first mipmap need to have alignment */
334         offset = surf->bo_size;
335         if ((i == 0)) {
336             offset = ALIGN(offset, surf->bo_alignment);
337         }
338     }
339     return 0;
340 }
341
342 static int r6_surface_init_2d(struct radeon_surface_manager *surf_man,
343                               struct radeon_surface *surf,
344                               uint64_t offset, unsigned start_level)
345 {
346     uint32_t xalign, yalign, zalign, tilew;
347     unsigned i;
348
349     /* compute alignment */
350     tilew = 8;
351     zalign = 1;
352     xalign = (surf_man->hw_info.group_bytes * surf_man->hw_info.num_banks) /
353              (tilew * surf->bpe * surf->nsamples);
354     xalign = MAX2(tilew * surf_man->hw_info.num_banks, xalign);
355     yalign = tilew * surf_man->hw_info.num_pipes;
356     if (surf->flags & RADEON_SURF_SCANOUT) {
357         xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
358     }
359     if (!start_level) {
360         surf->bo_alignment =
361             MAX2(surf_man->hw_info.num_pipes *
362                  surf_man->hw_info.num_banks *
363                  surf->nsamples * surf->bpe * 64,
364                  xalign * yalign * surf->nsamples * surf->bpe);
365     }
366
367     /* build mipmap tree */
368     for (i = start_level; i <= surf->last_level; i++) {
369         surf->level[i].mode = RADEON_SURF_MODE_2D;
370         surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
371         if (surf->level[i].mode == RADEON_SURF_MODE_1D) {
372             return r6_surface_init_1d(surf_man, surf, offset, i);
373         }
374         /* level0 and first mipmap need to have alignment */
375         offset = surf->bo_size;
376         if ((i == 0)) {
377             offset = ALIGN(offset, surf->bo_alignment);
378         }
379     }
380     return 0;
381 }
382
383 static int r6_surface_init(struct radeon_surface_manager *surf_man,
384                            struct radeon_surface *surf)
385 {
386     unsigned mode;
387     int r;
388
389     /* MSAA surfaces support the 2D mode only. */
390     if (surf->nsamples > 1) {
391         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
392         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
393     }
394
395     /* tiling mode */
396     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
397
398     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
399         /* zbuffer only support 1D or 2D tiled surface */
400         switch (mode) {
401         case RADEON_SURF_MODE_1D:
402         case RADEON_SURF_MODE_2D:
403             break;
404         default:
405             mode = RADEON_SURF_MODE_1D;
406             surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
407             surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
408             break;
409         }
410     }
411
412     /* force 1d on kernel that can't do 2d */
413     if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) {
414         if (surf->nsamples > 1) {
415             fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__);
416             return -EFAULT;
417         }
418         mode = RADEON_SURF_MODE_1D;
419         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
420         surf->flags |= RADEON_SURF_SET(mode, MODE);
421     }
422
423     /* check surface dimension */
424     if (surf->npix_x > 8192 || surf->npix_y > 8192 || surf->npix_z > 8192) {
425         return -EINVAL;
426     }
427
428     /* check mipmap last_level */
429     if (surf->last_level > 14) {
430         return -EINVAL;
431     }
432
433     /* check tiling mode */
434     switch (mode) {
435     case RADEON_SURF_MODE_LINEAR:
436         r = r6_surface_init_linear(surf_man, surf, 0, 0);
437         break;
438     case RADEON_SURF_MODE_LINEAR_ALIGNED:
439         r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
440         break;
441     case RADEON_SURF_MODE_1D:
442         r = r6_surface_init_1d(surf_man, surf, 0, 0);
443         break;
444     case RADEON_SURF_MODE_2D:
445         r = r6_surface_init_2d(surf_man, surf, 0, 0);
446         break;
447     default:
448         return -EINVAL;
449     }
450     return r;
451 }
452
453 static int r6_surface_best(struct radeon_surface_manager *surf_man,
454                            struct radeon_surface *surf)
455 {
456     /* no value to optimize for r6xx/r7xx */
457     return 0;
458 }
459
460
461 /* ===========================================================================
462  * evergreen family
463  */
464 static int eg_init_hw_info(struct radeon_surface_manager *surf_man)
465 {
466     uint32_t tiling_config;
467     drmVersionPtr version;
468     int r;
469
470     r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
471                          &tiling_config);
472     if (r) {
473         return r;
474     }
475
476     surf_man->hw_info.allow_2d = 0;
477     version = drmGetVersion(surf_man->fd);
478     if (version && version->version_minor >= 16) {
479         surf_man->hw_info.allow_2d = 1;
480     }
481     drmFreeVersion(version);
482
483     switch (tiling_config & 0xf) {
484     case 0:
485         surf_man->hw_info.num_pipes = 1;
486         break;
487     case 1:
488         surf_man->hw_info.num_pipes = 2;
489         break;
490     case 2:
491         surf_man->hw_info.num_pipes = 4;
492         break;
493     case 3:
494         surf_man->hw_info.num_pipes = 8;
495         break;
496     default:
497         surf_man->hw_info.num_pipes = 8;
498         surf_man->hw_info.allow_2d = 0;
499         break;
500     }
501
502     switch ((tiling_config & 0xf0) >> 4) {
503     case 0:
504         surf_man->hw_info.num_banks = 4;
505         break;
506     case 1:
507         surf_man->hw_info.num_banks = 8;
508         break;
509     case 2:
510         surf_man->hw_info.num_banks = 16;
511         break;
512     default:
513         surf_man->hw_info.num_banks = 8;
514         surf_man->hw_info.allow_2d = 0;
515         break;
516     }
517
518     switch ((tiling_config & 0xf00) >> 8) {
519     case 0:
520         surf_man->hw_info.group_bytes = 256;
521         break;
522     case 1:
523         surf_man->hw_info.group_bytes = 512;
524         break;
525     default:
526         surf_man->hw_info.group_bytes = 256;
527         surf_man->hw_info.allow_2d = 0;
528         break;
529     }
530
531     switch ((tiling_config & 0xf000) >> 12) {
532     case 0:
533         surf_man->hw_info.row_size = 1024;
534         break;
535     case 1:
536         surf_man->hw_info.row_size = 2048;
537         break;
538     case 2:
539         surf_man->hw_info.row_size = 4096;
540         break;
541     default:
542         surf_man->hw_info.row_size = 4096;
543         surf_man->hw_info.allow_2d = 0;
544         break;
545     }
546     return 0;
547 }
548
549 static void eg_surf_minify(struct radeon_surface *surf,
550                            struct radeon_surface_level *surflevel,
551                            unsigned bpe,
552                            unsigned level,
553                            unsigned slice_pt,
554                            unsigned mtilew,
555                            unsigned mtileh,
556                            unsigned mtileb,
557                            unsigned offset)
558 {
559     unsigned mtile_pr, mtile_ps;
560
561     surflevel->npix_x = mip_minify(surf->npix_x, level);
562     surflevel->npix_y = mip_minify(surf->npix_y, level);
563     surflevel->npix_z = mip_minify(surf->npix_z, level);
564     surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
565     surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
566     surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
567     if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D) {
568         if (surflevel->nblk_x < mtilew || surflevel->nblk_y < mtileh) {
569             surflevel->mode = RADEON_SURF_MODE_1D;
570             return;
571         }
572     }
573     surflevel->nblk_x  = ALIGN(surflevel->nblk_x, mtilew);
574     surflevel->nblk_y  = ALIGN(surflevel->nblk_y, mtileh);
575     surflevel->nblk_z  = ALIGN(surflevel->nblk_z, 1);
576
577     /* macro tile per row */
578     mtile_pr = surflevel->nblk_x / mtilew;
579     /* macro tile per slice */
580     mtile_ps = (mtile_pr * surflevel->nblk_y) / mtileh;
581
582     surflevel->offset = offset;
583     surflevel->pitch_bytes = surflevel->nblk_x * bpe * slice_pt;
584     surflevel->slice_size = mtile_ps * mtileb * slice_pt;
585
586     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
587 }
588
589 static int eg_surface_init_1d(struct radeon_surface_manager *surf_man,
590                               struct radeon_surface *surf,
591                               struct radeon_surface_level *level,
592                               unsigned bpe,
593                               uint64_t offset, unsigned start_level)
594 {
595     uint32_t xalign, yalign, zalign, tilew;
596     unsigned i;
597
598     /* compute alignment */
599     tilew = 8;
600     xalign = surf_man->hw_info.group_bytes / (tilew * bpe * surf->nsamples);
601     xalign = MAX2(tilew, xalign);
602     yalign = tilew;
603     zalign = 1;
604     if (surf->flags & RADEON_SURF_SCANOUT) {
605         xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
606     }
607
608     if (!start_level) {
609         unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
610         surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
611
612         if (offset) {
613             offset = ALIGN(offset, alignment);
614         }
615     }
616
617     /* build mipmap tree */
618     for (i = start_level; i <= surf->last_level; i++) {
619         level[i].mode = RADEON_SURF_MODE_1D;
620         surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, offset);
621         /* level0 and first mipmap need to have alignment */
622         offset = surf->bo_size;
623         if ((i == 0)) {
624             offset = ALIGN(offset, surf->bo_alignment);
625         }
626     }
627     return 0;
628 }
629
630 static int eg_surface_init_2d(struct radeon_surface_manager *surf_man,
631                               struct radeon_surface *surf,
632                               struct radeon_surface_level *level,
633                               unsigned bpe, unsigned tile_split,
634                               uint64_t offset, unsigned start_level)
635 {
636     unsigned tilew, tileh, tileb;
637     unsigned mtilew, mtileh, mtileb;
638     unsigned slice_pt;
639     unsigned i;
640
641     /* compute tile values */
642     tilew = 8;
643     tileh = 8;
644     tileb = tilew * tileh * bpe * surf->nsamples;
645     /* slices per tile */
646     slice_pt = 1;
647     if (tileb > tile_split) {
648         slice_pt = tileb / tile_split;
649     }
650     tileb = tileb / slice_pt;
651
652     /* macro tile width & height */
653     mtilew = (tilew * surf->bankw * surf_man->hw_info.num_pipes) * surf->mtilea;
654     mtileh = (tileh * surf->bankh * surf_man->hw_info.num_banks) / surf->mtilea;
655     /* macro tile bytes */
656     mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
657
658     if (!start_level) {
659         unsigned alignment = MAX2(256, mtileb);
660         surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
661
662         if (offset) {
663             offset = ALIGN(offset, alignment);
664         }
665     }
666
667     /* build mipmap tree */
668     for (i = start_level; i <= surf->last_level; i++) {
669         level[i].mode = RADEON_SURF_MODE_2D;
670         eg_surf_minify(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, mtileb, offset);
671         if (level[i].mode == RADEON_SURF_MODE_1D) {
672             return eg_surface_init_1d(surf_man, surf, level, bpe, offset, i);
673         }
674         /* level0 and first mipmap need to have alignment */
675         offset = surf->bo_size;
676         if ((i == 0)) {
677             offset = ALIGN(offset, surf->bo_alignment);
678         }
679     }
680     return 0;
681 }
682
683 static int eg_surface_sanity(struct radeon_surface_manager *surf_man,
684                              struct radeon_surface *surf,
685                              unsigned mode)
686 {
687     unsigned tileb;
688
689     /* check surface dimension */
690     if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
691         return -EINVAL;
692     }
693
694     /* check mipmap last_level */
695     if (surf->last_level > 15) {
696         return -EINVAL;
697     }
698
699     /* force 1d on kernel that can't do 2d */
700     if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) {
701         if (surf->nsamples > 1) {
702             fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__);
703             return -EFAULT;
704         }
705         mode = RADEON_SURF_MODE_1D;
706         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
707         surf->flags |= RADEON_SURF_SET(mode, MODE);
708     }
709
710     /* check tile split */
711     if (mode == RADEON_SURF_MODE_2D) {
712         switch (surf->tile_split) {
713         case 64:
714         case 128:
715         case 256:
716         case 512:
717         case 1024:
718         case 2048:
719         case 4096:
720             break;
721         default:
722             return -EINVAL;
723         }
724         switch (surf->mtilea) {
725         case 1:
726         case 2:
727         case 4:
728         case 8:
729             break;
730         default:
731             return -EINVAL;
732         }
733         /* check aspect ratio */
734         if (surf_man->hw_info.num_banks < surf->mtilea) {
735             return -EINVAL;
736         }
737         /* check bank width */
738         switch (surf->bankw) {
739         case 1:
740         case 2:
741         case 4:
742         case 8:
743             break;
744         default:
745             return -EINVAL;
746         }
747         /* check bank height */
748         switch (surf->bankh) {
749         case 1:
750         case 2:
751         case 4:
752         case 8:
753             break;
754         default:
755             return -EINVAL;
756         }
757         tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
758         if ((tileb * surf->bankh * surf->bankw) < surf_man->hw_info.group_bytes) {
759             return -EINVAL;
760         }
761     }
762
763     return 0;
764 }
765
766 static int eg_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
767                                        struct radeon_surface *surf)
768 {
769     unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
770     int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
771     /* Old libdrm headers didn't have stencil_level in it. This prevents crashes. */
772     struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
773     struct radeon_surface_level *stencil_level =
774         (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
775
776     r = eg_surface_init_1d(surf_man, surf, surf->level, surf->bpe, 0, 0);
777     if (r)
778         return r;
779
780     if (is_depth_stencil) {
781         r = eg_surface_init_1d(surf_man, surf, stencil_level, 1,
782                                surf->bo_size, 0);
783         surf->stencil_offset = stencil_level[0].offset;
784     }
785     return r;
786 }
787
788 static int eg_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
789                                        struct radeon_surface *surf)
790 {
791     unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
792     int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
793     /* Old libdrm headers didn't have stencil_level in it. This prevents crashes. */
794     struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
795     struct radeon_surface_level *stencil_level =
796         (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
797
798     r = eg_surface_init_2d(surf_man, surf, surf->level, surf->bpe,
799                            surf->tile_split, 0, 0);
800     if (r)
801         return r;
802
803     if (is_depth_stencil) {
804         r = eg_surface_init_2d(surf_man, surf, stencil_level, 1,
805                                surf->stencil_tile_split, surf->bo_size, 0);
806         surf->stencil_offset = stencil_level[0].offset;
807     }
808     return r;
809 }
810
811 static int eg_surface_init(struct radeon_surface_manager *surf_man,
812                            struct radeon_surface *surf)
813 {
814     unsigned mode;
815     int r;
816
817     /* MSAA surfaces support the 2D mode only. */
818     if (surf->nsamples > 1) {
819         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
820         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
821     }
822
823     /* tiling mode */
824     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
825
826     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
827         /* zbuffer only support 1D or 2D tiled surface */
828         switch (mode) {
829         case RADEON_SURF_MODE_1D:
830         case RADEON_SURF_MODE_2D:
831             break;
832         default:
833             mode = RADEON_SURF_MODE_1D;
834             surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
835             surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
836             break;
837         }
838     }
839
840     r = eg_surface_sanity(surf_man, surf, mode);
841     if (r) {
842         return r;
843     }
844
845     surf->stencil_offset = 0;
846     surf->bo_alignment = 0;
847
848     /* check tiling mode */
849     switch (mode) {
850     case RADEON_SURF_MODE_LINEAR:
851         r = r6_surface_init_linear(surf_man, surf, 0, 0);
852         break;
853     case RADEON_SURF_MODE_LINEAR_ALIGNED:
854         r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
855         break;
856     case RADEON_SURF_MODE_1D:
857         r = eg_surface_init_1d_miptrees(surf_man, surf);
858         break;
859     case RADEON_SURF_MODE_2D:
860         r = eg_surface_init_2d_miptrees(surf_man, surf);
861         break;
862     default:
863         return -EINVAL;
864     }
865     return r;
866 }
867
868 static unsigned log2_int(unsigned x)
869 {
870     unsigned l;
871
872     if (x < 2) {
873         return 0;
874     }
875     for (l = 2; ; l++) {
876         if ((unsigned)(1 << l) > x) {
877             return l - 1;
878         }
879     }
880     return 0;
881 }
882
883 /* compute best tile_split, bankw, bankh, mtilea
884  * depending on surface
885  */
886 static int eg_surface_best(struct radeon_surface_manager *surf_man,
887                            struct radeon_surface *surf)
888 {
889     unsigned mode, tileb, h_over_w;
890     int r;
891
892     /* tiling mode */
893     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
894
895     /* set some default value to avoid sanity check choking on them */
896     surf->tile_split = 1024;
897     surf->bankw = 1;
898     surf->bankh = 1;
899     surf->mtilea = surf_man->hw_info.num_banks;
900     tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
901     for (; surf->bankh <= 8; surf->bankh *= 2) {
902         if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
903             break;
904         }
905     }
906     if (surf->mtilea > 8) {
907         surf->mtilea = 8;
908     }
909
910     r = eg_surface_sanity(surf_man, surf, mode);
911     if (r) {
912         return r;
913     }
914
915     if (mode != RADEON_SURF_MODE_2D) {
916         /* nothing to do for non 2D tiled surface */
917         return 0;
918     }
919
920     /* Tweak TILE_SPLIT for performance here. */
921     if (surf->nsamples > 1) {
922         if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
923             switch (surf->nsamples) {
924             case 2:
925                 surf->tile_split = 128;
926                 break;
927             case 4:
928                 surf->tile_split = 128;
929                 break;
930             case 8:
931                 surf->tile_split = 256;
932                 break;
933             case 16: /* cayman only */
934                 surf->tile_split = 512;
935                 break;
936             default:
937                 fprintf(stderr, "radeon: Wrong number of samples %i (%i)\n",
938                         surf->nsamples, __LINE__);
939                 return -EINVAL;
940             }
941             surf->stencil_tile_split = 64;
942         } else {
943             /* tile split must be >= 256 for colorbuffer surfaces */
944             surf->tile_split = MAX2(surf->nsamples * surf->bpe * 64, 256);
945             if (surf->tile_split > 4096)
946                 surf->tile_split = 4096;
947         }
948     } else {
949         /* set tile split to row size */
950         surf->tile_split = surf_man->hw_info.row_size;
951         surf->stencil_tile_split = surf_man->hw_info.row_size / 2;
952     }
953
954     /* bankw or bankh greater than 1 increase alignment requirement, not
955      * sure if it's worth using smaller bankw & bankh to stick with 2D
956      * tiling on small surface rather than falling back to 1D tiling.
957      * Use recommanded value based on tile size for now.
958      *
959      * fmask buffer has different optimal value figure them out once we
960      * use it.
961      */
962     if (surf->flags & RADEON_SURF_SBUFFER) {
963         /* assume 1 bytes for stencil, we optimize for stencil as stencil
964          * and depth shares surface values
965          */
966         tileb = MIN2(surf->tile_split, 64 * surf->nsamples);
967     } else {
968         tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
969     }
970
971     /* use bankw of 1 to minimize width alignment, might be interesting to
972      * increase it for large surface
973      */
974     surf->bankw = 1;
975     switch (tileb) {
976     case 64:
977         surf->bankh = 4;
978         break;
979     case 128:
980     case 256:
981         surf->bankh = 2;
982         break;
983     default:
984         surf->bankh = 1;
985         break;
986     }
987     /* double check the constraint */
988     for (; surf->bankh <= 8; surf->bankh *= 2) {
989         if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
990             break;
991         }
992     }
993
994     h_over_w = (((surf->bankh * surf_man->hw_info.num_banks) << 16) /
995                 (surf->bankw * surf_man->hw_info.num_pipes)) >> 16;
996     surf->mtilea = 1 << (log2_int(h_over_w) >> 1);
997
998     return 0;
999 }
1000
1001
1002 /* ===========================================================================
1003  * Southern Islands family
1004  */
1005 #define SI__GB_TILE_MODE__PIPE_CONFIG(x)        (((x) >> 6) & 0x1f)
1006 #define     SI__PIPE_CONFIG__ADDR_SURF_P2               0
1007 #define     SI__PIPE_CONFIG__ADDR_SURF_P4_8x16          4
1008 #define     SI__PIPE_CONFIG__ADDR_SURF_P4_16x16         5
1009 #define     SI__PIPE_CONFIG__ADDR_SURF_P4_16x32         6
1010 #define     SI__PIPE_CONFIG__ADDR_SURF_P4_32x32         7
1011 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16    8
1012 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16    9
1013 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16    10
1014 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16   11
1015 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16   12
1016 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32   13
1017 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32   14
1018 #define SI__GB_TILE_MODE__TILE_SPLIT(x)         (((x) >> 11) & 0x7)
1019 #define     SI__TILE_SPLIT__64B                         0
1020 #define     SI__TILE_SPLIT__128B                        1
1021 #define     SI__TILE_SPLIT__256B                        2
1022 #define     SI__TILE_SPLIT__512B                        3
1023 #define     SI__TILE_SPLIT__1024B                       4
1024 #define     SI__TILE_SPLIT__2048B                       5
1025 #define     SI__TILE_SPLIT__4096B                       6
1026 #define SI__GB_TILE_MODE__BANK_WIDTH(x)         (((x) >> 14) & 0x3)
1027 #define     SI__BANK_WIDTH__1                           0
1028 #define     SI__BANK_WIDTH__2                           1
1029 #define     SI__BANK_WIDTH__4                           2
1030 #define     SI__BANK_WIDTH__8                           3
1031 #define SI__GB_TILE_MODE__BANK_HEIGHT(x)        (((x) >> 16) & 0x3)
1032 #define     SI__BANK_HEIGHT__1                          0
1033 #define     SI__BANK_HEIGHT__2                          1
1034 #define     SI__BANK_HEIGHT__4                          2
1035 #define     SI__BANK_HEIGHT__8                          3
1036 #define SI__GB_TILE_MODE__MACRO_TILE_ASPECT(x)  (((x) >> 18) & 0x3)
1037 #define     SI__MACRO_TILE_ASPECT__1                    0
1038 #define     SI__MACRO_TILE_ASPECT__2                    1
1039 #define     SI__MACRO_TILE_ASPECT__4                    2
1040 #define     SI__MACRO_TILE_ASPECT__8                    3
1041 #define SI__GB_TILE_MODE__NUM_BANKS(x)          (((x) >> 20) & 0x3)
1042 #define     SI__NUM_BANKS__2_BANK                       0
1043 #define     SI__NUM_BANKS__4_BANK                       1
1044 #define     SI__NUM_BANKS__8_BANK                       2
1045 #define     SI__NUM_BANKS__16_BANK                      3
1046
1047
1048 static void si_gb_tile_mode(uint32_t gb_tile_mode,
1049                             unsigned *num_pipes,
1050                             unsigned *num_banks,
1051                             uint32_t *macro_tile_aspect,
1052                             uint32_t *bank_w,
1053                             uint32_t *bank_h,
1054                             uint32_t *tile_split)
1055 {
1056     if (num_pipes) {
1057         switch (SI__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1058         case SI__PIPE_CONFIG__ADDR_SURF_P2:
1059         default:
1060             *num_pipes = 2;
1061             break;
1062         case SI__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1063         case SI__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1064         case SI__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1065         case SI__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1066             *num_pipes = 4;
1067             break;
1068         case SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1069         case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1070         case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1071         case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1072         case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1073         case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1074         case SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1075             *num_pipes = 8;
1076             break;
1077         }
1078     }
1079     if (num_banks) {
1080         switch (SI__GB_TILE_MODE__NUM_BANKS(gb_tile_mode)) {
1081         default:
1082         case SI__NUM_BANKS__2_BANK:
1083             *num_banks = 2;
1084             break;
1085         case SI__NUM_BANKS__4_BANK:
1086             *num_banks = 4;
1087             break;
1088         case SI__NUM_BANKS__8_BANK:
1089             *num_banks = 8;
1090             break;
1091         case SI__NUM_BANKS__16_BANK:
1092             *num_banks = 16;
1093             break;
1094         }
1095     }
1096     if (macro_tile_aspect) {
1097         switch (SI__GB_TILE_MODE__MACRO_TILE_ASPECT(gb_tile_mode)) {
1098         default:
1099         case SI__MACRO_TILE_ASPECT__1:
1100             *macro_tile_aspect = 1;
1101             break;
1102         case SI__MACRO_TILE_ASPECT__2:
1103             *macro_tile_aspect = 2;
1104             break;
1105         case SI__MACRO_TILE_ASPECT__4:
1106             *macro_tile_aspect = 4;
1107             break;
1108         case SI__MACRO_TILE_ASPECT__8:
1109             *macro_tile_aspect = 8;
1110             break;
1111         }
1112     }
1113     if (bank_w) {
1114         switch (SI__GB_TILE_MODE__BANK_WIDTH(gb_tile_mode)) {
1115         default:
1116         case SI__BANK_WIDTH__1:
1117             *bank_w = 1;
1118             break;
1119         case SI__BANK_WIDTH__2:
1120             *bank_w = 2;
1121             break;
1122         case SI__BANK_WIDTH__4:
1123             *bank_w = 4;
1124             break;
1125         case SI__BANK_WIDTH__8:
1126             *bank_w = 8;
1127             break;
1128         }
1129     }
1130     if (bank_h) {
1131         switch (SI__GB_TILE_MODE__BANK_HEIGHT(gb_tile_mode)) {
1132         default:
1133         case SI__BANK_HEIGHT__1:
1134             *bank_h = 1;
1135             break;
1136         case SI__BANK_HEIGHT__2:
1137             *bank_h = 2;
1138             break;
1139         case SI__BANK_HEIGHT__4:
1140             *bank_h = 4;
1141             break;
1142         case SI__BANK_HEIGHT__8:
1143             *bank_h = 8;
1144             break;
1145         }
1146     }
1147     if (tile_split) {
1148         switch (SI__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1149         default:
1150         case SI__TILE_SPLIT__64B:
1151             *tile_split = 64;
1152             break;
1153         case SI__TILE_SPLIT__128B:
1154             *tile_split = 128;
1155             break;
1156         case SI__TILE_SPLIT__256B:
1157             *tile_split = 256;
1158             break;
1159         case SI__TILE_SPLIT__512B:
1160             *tile_split = 512;
1161             break;
1162         case SI__TILE_SPLIT__1024B:
1163             *tile_split = 1024;
1164             break;
1165         case SI__TILE_SPLIT__2048B:
1166             *tile_split = 2048;
1167             break;
1168         case SI__TILE_SPLIT__4096B:
1169             *tile_split = 4096;
1170             break;
1171         }
1172     }
1173 }
1174
1175 static int si_init_hw_info(struct radeon_surface_manager *surf_man)
1176 {
1177     uint32_t tiling_config;
1178     drmVersionPtr version;
1179     int r;
1180
1181     r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
1182                          &tiling_config);
1183     if (r) {
1184         return r;
1185     }
1186
1187     surf_man->hw_info.allow_2d = 0;
1188     version = drmGetVersion(surf_man->fd);
1189     if (version && version->version_minor >= 33) {
1190         if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array)) {
1191             surf_man->hw_info.allow_2d = 1;
1192         }
1193     }
1194     drmFreeVersion(version);
1195
1196     switch (tiling_config & 0xf) {
1197     case 0:
1198         surf_man->hw_info.num_pipes = 1;
1199         break;
1200     case 1:
1201         surf_man->hw_info.num_pipes = 2;
1202         break;
1203     case 2:
1204         surf_man->hw_info.num_pipes = 4;
1205         break;
1206     case 3:
1207         surf_man->hw_info.num_pipes = 8;
1208         break;
1209     default:
1210         surf_man->hw_info.num_pipes = 8;
1211         surf_man->hw_info.allow_2d = 0;
1212         break;
1213     }
1214
1215     switch ((tiling_config & 0xf0) >> 4) {
1216     case 0:
1217         surf_man->hw_info.num_banks = 4;
1218         break;
1219     case 1:
1220         surf_man->hw_info.num_banks = 8;
1221         break;
1222     case 2:
1223         surf_man->hw_info.num_banks = 16;
1224         break;
1225     default:
1226         surf_man->hw_info.num_banks = 8;
1227         surf_man->hw_info.allow_2d = 0;
1228         break;
1229     }
1230
1231     switch ((tiling_config & 0xf00) >> 8) {
1232     case 0:
1233         surf_man->hw_info.group_bytes = 256;
1234         break;
1235     case 1:
1236         surf_man->hw_info.group_bytes = 512;
1237         break;
1238     default:
1239         surf_man->hw_info.group_bytes = 256;
1240         surf_man->hw_info.allow_2d = 0;
1241         break;
1242     }
1243
1244     switch ((tiling_config & 0xf000) >> 12) {
1245     case 0:
1246         surf_man->hw_info.row_size = 1024;
1247         break;
1248     case 1:
1249         surf_man->hw_info.row_size = 2048;
1250         break;
1251     case 2:
1252         surf_man->hw_info.row_size = 4096;
1253         break;
1254     default:
1255         surf_man->hw_info.row_size = 4096;
1256         surf_man->hw_info.allow_2d = 0;
1257         break;
1258     }
1259     return 0;
1260 }
1261
1262 static int si_surface_sanity(struct radeon_surface_manager *surf_man,
1263                              struct radeon_surface *surf,
1264                              unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
1265 {
1266     uint32_t gb_tile_mode;
1267
1268     /* check surface dimension */
1269     if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
1270         return -EINVAL;
1271     }
1272
1273     /* check mipmap last_level */
1274     if (surf->last_level > 15) {
1275         return -EINVAL;
1276     }
1277
1278     /* force 1d on kernel that can't do 2d */
1279     if (mode > RADEON_SURF_MODE_1D &&
1280         (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
1281         if (surf->nsamples > 1) {
1282             fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
1283             return -EFAULT;
1284         }
1285         mode = RADEON_SURF_MODE_1D;
1286         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1287         surf->flags |= RADEON_SURF_SET(mode, MODE);
1288     }
1289
1290     if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
1291         return -EINVAL;
1292     }
1293
1294     if (!surf->tile_split) {
1295         /* default value */
1296         surf->mtilea = 1;
1297         surf->bankw = 1;
1298         surf->bankw = 1;
1299         surf->tile_split = 64;
1300         surf->stencil_tile_split = 64;
1301     }
1302
1303     switch (mode) {
1304     case RADEON_SURF_MODE_2D:
1305         if (surf->flags & RADEON_SURF_SBUFFER) {
1306             switch (surf->nsamples) {
1307             case 1:
1308                 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1309                 break;
1310             case 2:
1311                 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1312                 break;
1313             case 4:
1314                 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1315                 break;
1316             case 8:
1317                 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1318                 break;
1319             default:
1320                 return -EINVAL;
1321             }
1322             /* retrieve tiling mode value */
1323             gb_tile_mode = surf_man->hw_info.tile_mode_array[*stencil_tile_mode];
1324             si_gb_tile_mode(gb_tile_mode, NULL, NULL, NULL, NULL, NULL, &surf->stencil_tile_split);
1325         }
1326         if (surf->flags & RADEON_SURF_ZBUFFER) {
1327             switch (surf->nsamples) {
1328             case 1:
1329                 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1330                 break;
1331             case 2:
1332                 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1333                 break;
1334             case 4:
1335                 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1336                 break;
1337             case 8:
1338                 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1339                 break;
1340             default:
1341                 return -EINVAL;
1342             }
1343         } else if (surf->flags & RADEON_SURF_SCANOUT) {
1344             switch (surf->bpe) {
1345             case 2:
1346                 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
1347                 break;
1348             case 4:
1349                 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
1350                 break;
1351             default:
1352                 return -EINVAL;
1353             }
1354         } else {
1355             switch (surf->bpe) {
1356             case 1:
1357                 *tile_mode = SI_TILE_MODE_COLOR_2D_8BPP;
1358                 break;
1359             case 2:
1360                 *tile_mode = SI_TILE_MODE_COLOR_2D_16BPP;
1361                 break;
1362             case 4:
1363                 *tile_mode = SI_TILE_MODE_COLOR_2D_32BPP;
1364                 break;
1365             case 8:
1366             case 16:
1367                 *tile_mode = SI_TILE_MODE_COLOR_2D_64BPP;
1368                 break;
1369             default:
1370                 return -EINVAL;
1371             }
1372         }
1373         /* retrieve tiling mode value */
1374         gb_tile_mode = surf_man->hw_info.tile_mode_array[*tile_mode];
1375         si_gb_tile_mode(gb_tile_mode, NULL, NULL, &surf->mtilea, &surf->bankw, &surf->bankh, &surf->tile_split);
1376         break;
1377     case RADEON_SURF_MODE_1D:
1378         if (surf->flags & RADEON_SURF_SBUFFER) {
1379             *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1380         }
1381         if (surf->flags & RADEON_SURF_ZBUFFER) {
1382             *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1383         } else if (surf->flags & RADEON_SURF_SCANOUT) {
1384             *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1385         } else {
1386             *tile_mode = SI_TILE_MODE_COLOR_1D;
1387         }
1388         break;
1389     case RADEON_SURF_MODE_LINEAR_ALIGNED:
1390     default:
1391         *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
1392     }
1393
1394     return 0;
1395 }
1396
1397 static void si_surf_minify(struct radeon_surface *surf,
1398                            struct radeon_surface_level *surflevel,
1399                            unsigned bpe, unsigned level,
1400                            uint32_t xalign, uint32_t yalign, uint32_t zalign,
1401                            uint32_t slice_align, unsigned offset)
1402 {
1403     surflevel->npix_x = mip_minify(surf->npix_x, level);
1404     surflevel->npix_y = mip_minify(surf->npix_y, level);
1405     surflevel->npix_z = mip_minify(surf->npix_z, level);
1406
1407     if (level == 0 && surf->last_level > 0) {
1408         surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1409         surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1410         surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1411     } else {
1412         surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1413         surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1414         surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1415     }
1416
1417     surflevel->nblk_y  = ALIGN(surflevel->nblk_y, yalign);
1418
1419     /* XXX: Texture sampling uses unexpectedly large pitches in some cases,
1420      * these are just guesses for the rules behind those
1421      */
1422     if (level == 0 && surf->last_level == 0)
1423         /* Non-mipmap pitch padded to slice alignment */
1424         xalign = MAX2(xalign, slice_align / surf->bpe);
1425     else
1426         /* Small rows evenly distributed across slice */
1427         xalign = MAX2(xalign, slice_align / surf->bpe / surflevel->nblk_y);
1428
1429     surflevel->nblk_x  = ALIGN(surflevel->nblk_x, xalign);
1430     surflevel->nblk_z  = ALIGN(surflevel->nblk_z, zalign);
1431
1432     surflevel->offset = offset;
1433     surflevel->pitch_bytes = surflevel->nblk_x * surf->bpe * surf->nsamples;
1434     surflevel->slice_size = ALIGN(surflevel->pitch_bytes * surflevel->nblk_y, slice_align);
1435
1436     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1437 }
1438
1439 static void si_surf_minify_2d(struct radeon_surface *surf,
1440                               struct radeon_surface_level *surflevel,
1441                               unsigned bpe, unsigned level, unsigned slice_pt,
1442                               uint32_t xalign, uint32_t yalign, uint32_t zalign,
1443                               unsigned mtileb, unsigned offset)
1444 {
1445     unsigned mtile_pr, mtile_ps;
1446
1447     surflevel->npix_x = mip_minify(surf->npix_x, level);
1448     surflevel->npix_y = mip_minify(surf->npix_y, level);
1449     surflevel->npix_z = mip_minify(surf->npix_z, level);
1450
1451     if (level == 0 && surf->last_level > 0) {
1452         surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1453         surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1454         surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1455     } else {
1456         surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1457         surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1458         surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1459     }
1460
1461     if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D) {
1462         if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
1463             surflevel->mode = RADEON_SURF_MODE_1D;
1464             return;
1465         }
1466     }
1467     surflevel->nblk_x  = ALIGN(surflevel->nblk_x, xalign);
1468     surflevel->nblk_y  = ALIGN(surflevel->nblk_y, yalign);
1469     surflevel->nblk_z  = ALIGN(surflevel->nblk_z, zalign);
1470
1471     /* macro tile per row */
1472     mtile_pr = surflevel->nblk_x / xalign;
1473     /* macro tile per slice */
1474     mtile_ps = (mtile_pr * surflevel->nblk_y) / yalign;
1475     surflevel->offset = offset;
1476     surflevel->pitch_bytes = surflevel->nblk_x * bpe * slice_pt;
1477     surflevel->slice_size = mtile_ps * mtileb * slice_pt;
1478
1479     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1480 }
1481
1482 static int si_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
1483                                           struct radeon_surface *surf,
1484                                           unsigned tile_mode,
1485                                           uint64_t offset, unsigned start_level)
1486 {
1487     uint32_t xalign, yalign, zalign, slice_align;
1488     unsigned i;
1489
1490     /* compute alignment */
1491     if (!start_level) {
1492         surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
1493     }
1494     xalign = MAX2(8, 64 / surf->bpe);
1495     yalign = 1;
1496     zalign = 1;
1497     slice_align = MAX2(64 * surf->bpe, surf_man->hw_info.group_bytes);
1498
1499     /* build mipmap tree */
1500     for (i = start_level; i <= surf->last_level; i++) {
1501         surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
1502         si_surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, slice_align, offset);
1503         /* level0 and first mipmap need to have alignment */
1504         offset = surf->bo_size;
1505         if ((i == 0)) {
1506             offset = ALIGN(offset, surf->bo_alignment);
1507         }
1508         if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1509             surf->tiling_index[i] = tile_mode;
1510         }
1511     }
1512     return 0;
1513 }
1514
1515 static int si_surface_init_1d(struct radeon_surface_manager *surf_man,
1516                               struct radeon_surface *surf,
1517                               struct radeon_surface_level *level,
1518                               unsigned bpe, unsigned tile_mode,
1519                               uint64_t offset, unsigned start_level)
1520 {
1521     uint32_t xalign, yalign, zalign, slice_align;
1522     unsigned i;
1523
1524     /* compute alignment */
1525     xalign = 8;
1526     yalign = 8;
1527     zalign = 1;
1528     slice_align = surf_man->hw_info.group_bytes;
1529     if (surf->flags & RADEON_SURF_SCANOUT) {
1530         xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
1531     }
1532
1533     if (!start_level) {
1534         surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
1535
1536         if (offset) {
1537             offset = ALIGN(offset, surf->bo_alignment);
1538         }
1539     }
1540
1541     /* build mipmap tree */
1542     for (i = start_level; i <= surf->last_level; i++) {
1543         level[i].mode = RADEON_SURF_MODE_1D;
1544         si_surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, slice_align, offset);
1545         /* level0 and first mipmap need to have alignment */
1546         offset = surf->bo_size;
1547         if ((i == 0)) {
1548             offset = ALIGN(offset, surf->bo_alignment);
1549         }
1550         if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1551             if (surf->level == level) {
1552                 surf->tiling_index[i] = tile_mode;
1553                 /* it's ok because stencil is done after */
1554                 surf->stencil_tiling_index[i] = tile_mode;
1555             } else {
1556                 surf->stencil_tiling_index[i] = tile_mode;
1557             }
1558         }
1559     }
1560     return 0;
1561 }
1562
1563 static int si_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
1564                                        struct radeon_surface *surf,
1565                                        unsigned tile_mode, unsigned stencil_tile_mode)
1566 {
1567     int r;
1568
1569     r = si_surface_init_1d(surf_man, surf, surf->level, surf->bpe, tile_mode, 0, 0);
1570     if (r) {
1571         return r;
1572     }
1573
1574     if (surf->flags & RADEON_SURF_SBUFFER) {
1575         r = si_surface_init_1d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode, surf->bo_size, 0);
1576         surf->stencil_offset = surf->stencil_level[0].offset;
1577     }
1578     return r;
1579 }
1580
1581 static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
1582                               struct radeon_surface *surf,
1583                               struct radeon_surface_level *level,
1584                               unsigned bpe, unsigned tile_mode,
1585                               unsigned num_pipes, unsigned num_banks,
1586                               unsigned tile_split,
1587                               uint64_t offset,
1588                               unsigned start_level)
1589 {
1590     unsigned tilew, tileh, tileb;
1591     unsigned mtilew, mtileh, mtileb;
1592     unsigned slice_pt;
1593     unsigned i;
1594
1595     /* compute tile values */
1596     tilew = 8;
1597     tileh = 8;
1598     tileb = tilew * tileh * bpe * surf->nsamples;
1599     /* slices per tile */
1600     slice_pt = 1;
1601     if (tileb > tile_split) {
1602         slice_pt = tileb / tile_split;
1603     }
1604     tileb = tileb / slice_pt;
1605
1606     /* macro tile width & height */
1607     mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
1608     mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
1609
1610     /* macro tile bytes */
1611     mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
1612
1613     if (!start_level) {
1614         unsigned alignment = MAX2(256, mtileb);
1615         surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1616
1617         if (offset) {
1618             offset = ALIGN(offset, alignment);
1619         }
1620     }
1621
1622     /* build mipmap tree */
1623     for (i = start_level; i <= surf->last_level; i++) {
1624         level[i].mode = RADEON_SURF_MODE_2D;
1625         si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, offset);
1626         if (level[i].mode == RADEON_SURF_MODE_1D) {
1627             switch (tile_mode) {
1628             case SI_TILE_MODE_COLOR_2D_8BPP:
1629             case SI_TILE_MODE_COLOR_2D_16BPP:
1630             case SI_TILE_MODE_COLOR_2D_32BPP:
1631             case SI_TILE_MODE_COLOR_2D_64BPP:
1632                 tile_mode = SI_TILE_MODE_COLOR_1D;
1633                 break;
1634             case SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP:
1635             case SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP:
1636                 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1637                 break;
1638             case SI_TILE_MODE_DEPTH_STENCIL_2D:
1639                 tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1640                 break;
1641             default:
1642                 return -EINVAL;
1643             }
1644             return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
1645         }
1646         /* level0 and first mipmap need to have alignment */
1647         offset = surf->bo_size;
1648         if ((i == 0)) {
1649             offset = ALIGN(offset, surf->bo_alignment);
1650         }
1651         if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1652             if (surf->level == level) {
1653                 surf->tiling_index[i] = tile_mode;
1654                 /* it's ok because stencil is done after */
1655                 surf->stencil_tiling_index[i] = tile_mode;
1656             } else {
1657                 surf->stencil_tiling_index[i] = tile_mode;
1658             }
1659         }
1660     }
1661     return 0;
1662 }
1663
1664 static int si_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
1665                                        struct radeon_surface *surf,
1666                                        unsigned tile_mode, unsigned stencil_tile_mode)
1667 {
1668     unsigned num_pipes, num_banks;
1669     uint32_t gb_tile_mode;
1670     int r;
1671
1672     /* retrieve tiling mode value */
1673     gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1674     si_gb_tile_mode(gb_tile_mode, &num_pipes, &num_banks, NULL, NULL, NULL, NULL);
1675
1676     r = si_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode, num_pipes, num_banks, surf->tile_split, 0, 0);
1677     if (r) {
1678         return r;
1679     }
1680
1681     if (surf->flags & RADEON_SURF_SBUFFER) {
1682         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);
1683         surf->stencil_offset = surf->stencil_level[0].offset;
1684     }
1685     return r;
1686 }
1687
1688 static int si_surface_init(struct radeon_surface_manager *surf_man,
1689                            struct radeon_surface *surf)
1690 {
1691     unsigned mode, tile_mode, stencil_tile_mode;
1692     int r;
1693
1694     /* MSAA surfaces support the 2D mode only. */
1695     if (surf->nsamples > 1) {
1696         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1697         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
1698     }
1699
1700     /* tiling mode */
1701     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1702
1703     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
1704         /* zbuffer only support 1D or 2D tiled surface */
1705         switch (mode) {
1706         case RADEON_SURF_MODE_1D:
1707         case RADEON_SURF_MODE_2D:
1708             break;
1709         default:
1710             mode = RADEON_SURF_MODE_1D;
1711             surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1712             surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1713             break;
1714         }
1715     }
1716
1717     r = si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1718     if (r) {
1719         return r;
1720     }
1721
1722     surf->stencil_offset = 0;
1723     surf->bo_alignment = 0;
1724
1725     /* check tiling mode */
1726     switch (mode) {
1727     case RADEON_SURF_MODE_LINEAR:
1728         r = r6_surface_init_linear(surf_man, surf, 0, 0);
1729         break;
1730     case RADEON_SURF_MODE_LINEAR_ALIGNED:
1731         r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
1732         break;
1733     case RADEON_SURF_MODE_1D:
1734         r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1735         break;
1736     case RADEON_SURF_MODE_2D:
1737         r = si_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1738         break;
1739     default:
1740         return -EINVAL;
1741     }
1742     return r;
1743 }
1744
1745 /*
1746  * depending on surface
1747  */
1748 static int si_surface_best(struct radeon_surface_manager *surf_man,
1749                            struct radeon_surface *surf)
1750 {
1751     unsigned mode, tile_mode, stencil_tile_mode;
1752
1753     /* tiling mode */
1754     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1755
1756     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
1757         !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
1758         /* depth/stencil force 1d tiling for old mesa */
1759         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1760         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1761     }
1762
1763     return si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1764 }
1765
1766
1767 /* ===========================================================================
1768  * public API
1769  */
1770 struct radeon_surface_manager *radeon_surface_manager_new(int fd)
1771 {
1772     struct radeon_surface_manager *surf_man;
1773
1774     surf_man = calloc(1, sizeof(struct radeon_surface_manager));
1775     if (surf_man == NULL) {
1776         return NULL;
1777     }
1778     surf_man->fd = fd;
1779     if (radeon_get_value(fd, RADEON_INFO_DEVICE_ID, &surf_man->device_id)) {
1780         goto out_err;
1781     }
1782     if (radeon_get_family(surf_man)) {
1783         goto out_err;
1784     }
1785
1786     if (surf_man->family <= CHIP_RV740) {
1787         if (r6_init_hw_info(surf_man)) {
1788             goto out_err;
1789         }
1790         surf_man->surface_init = &r6_surface_init;
1791         surf_man->surface_best = &r6_surface_best;
1792     } else if (surf_man->family <= CHIP_ARUBA) {
1793         if (eg_init_hw_info(surf_man)) {
1794             goto out_err;
1795         }
1796         surf_man->surface_init = &eg_surface_init;
1797         surf_man->surface_best = &eg_surface_best;
1798     } else {
1799         if (si_init_hw_info(surf_man)) {
1800             goto out_err;
1801         }
1802         surf_man->surface_init = &si_surface_init;
1803         surf_man->surface_best = &si_surface_best;
1804     }
1805
1806     return surf_man;
1807 out_err:
1808     free(surf_man);
1809     return NULL;
1810 }
1811
1812 void radeon_surface_manager_free(struct radeon_surface_manager *surf_man)
1813 {
1814     free(surf_man);
1815 }
1816
1817 static int radeon_surface_sanity(struct radeon_surface_manager *surf_man,
1818                                  struct radeon_surface *surf,
1819                                  unsigned type,
1820                                  unsigned mode)
1821 {
1822     if (surf_man == NULL || surf_man->surface_init == NULL || surf == NULL) {
1823         return -EINVAL;
1824     }
1825
1826     /* all dimension must be at least 1 ! */
1827     if (!surf->npix_x || !surf->npix_y || !surf->npix_z) {
1828         return -EINVAL;
1829     }
1830     if (!surf->blk_w || !surf->blk_h || !surf->blk_d) {
1831         return -EINVAL;
1832     }
1833     if (!surf->array_size) {
1834         return -EINVAL;
1835     }
1836     /* array size must be a power of 2 */
1837     surf->array_size = next_power_of_two(surf->array_size);
1838
1839     switch (surf->nsamples) {
1840     case 1:
1841     case 2:
1842     case 4:
1843     case 8:
1844         break;
1845     default:
1846         return -EINVAL;
1847     }
1848     /* check type */
1849     switch (type) {
1850     case RADEON_SURF_TYPE_1D:
1851         if (surf->npix_y > 1) {
1852             return -EINVAL;
1853         }
1854     case RADEON_SURF_TYPE_2D:
1855         if (surf->npix_z > 1) {
1856             return -EINVAL;
1857         }
1858         break;
1859     case RADEON_SURF_TYPE_CUBEMAP:
1860         if (surf->npix_z > 1) {
1861             return -EINVAL;
1862         }
1863         /* deal with cubemap as they were texture array */
1864         if (surf_man->family >= CHIP_RV770) {
1865             surf->array_size = 8;
1866         } else {
1867             surf->array_size = 6;
1868         }
1869         break;
1870     case RADEON_SURF_TYPE_3D:
1871         break;
1872     case RADEON_SURF_TYPE_1D_ARRAY:
1873         if (surf->npix_y > 1) {
1874             return -EINVAL;
1875         }
1876     case RADEON_SURF_TYPE_2D_ARRAY:
1877         break;
1878     default:
1879         return -EINVAL;
1880     }
1881     return 0;
1882 }
1883
1884 int radeon_surface_init(struct radeon_surface_manager *surf_man,
1885                         struct radeon_surface *surf)
1886 {
1887     unsigned mode, type;
1888     int r;
1889
1890     type = RADEON_SURF_GET(surf->flags, TYPE);
1891     mode = RADEON_SURF_GET(surf->flags, MODE);
1892
1893     r = radeon_surface_sanity(surf_man, surf, type, mode);
1894     if (r) {
1895         return r;
1896     }
1897     return surf_man->surface_init(surf_man, surf);
1898 }
1899
1900 int radeon_surface_best(struct radeon_surface_manager *surf_man,
1901                         struct radeon_surface *surf)
1902 {
1903     unsigned mode, type;
1904     int r;
1905
1906     type = RADEON_SURF_GET(surf->flags, TYPE);
1907     mode = RADEON_SURF_GET(surf->flags, MODE);
1908
1909     r = radeon_surface_sanity(surf_man, surf, type, mode);
1910     if (r) {
1911         return r;
1912     }
1913     return surf_man->surface_best(surf_man, surf);
1914 }