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