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