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