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