1c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse/*
2c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * Copyright © 2011 Red Hat All Rights Reserved.
3c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse *
4c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * Permission is hereby granted, free of charge, to any person obtaining
5c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * a copy of this software and associated documentation files (the
6c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * "Software"), to deal in the Software without restriction, including
7c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * without limitation the rights to use, copy, modify, merge, publish,
8c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * distribute, sub license, and/or sell copies of the Software, and to
9c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * permit persons to whom the Software is furnished to do so, subject to
10c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * the following conditions:
11c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse *
12c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
14c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
16c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * USE OR OTHER DEALINGS IN THE SOFTWARE.
20c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse *
21c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * The above copyright notice and this permission notice (including the
22c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * next paragraph) shall be included in all copies or substantial portions
23c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * of the Software.
24c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse */
25c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse/*
26c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * Authors:
27c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse *      Jérôme Glisse <jglisse@redhat.com>
28c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse */
2958ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorst#ifdef HAVE_CONFIG_H
3058ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorst#include <config.h>
3158ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorst#endif
3267d92404d62044972599dcef3011d17fca46eed5Marek Olšák#include <stdbool.h>
3367d92404d62044972599dcef3011d17fca46eed5Marek Olšák#include <assert.h>
34c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse#include <errno.h>
35c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse#include <stdio.h>
36c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse#include <stdlib.h>
37c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse#include <string.h>
38c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse#include <sys/ioctl.h>
39c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse#include "drm.h"
4042465feb9759ef5a6d79d7e628510cd0a081f913Emil Velikov#include "libdrm_macros.h"
41c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse#include "xf86drm.h"
42c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse#include "radeon_drm.h"
43c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse#include "radeon_surface.h"
44c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
4539fff5996227692cf8b6a75771a28a8d624f16efMarek Olšák#define CIK_TILE_MODE_COLOR_2D			14
4639fff5996227692cf8b6a75771a28a8d624f16efMarek Olšák#define CIK_TILE_MODE_COLOR_2D_SCANOUT		10
4739fff5996227692cf8b6a75771a28a8d624f16efMarek Olšák#define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64       0
4839fff5996227692cf8b6a75771a28a8d624f16efMarek Olšák#define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128      1
4939fff5996227692cf8b6a75771a28a8d624f16efMarek Olšák#define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256      2
5039fff5996227692cf8b6a75771a28a8d624f16efMarek Olšák#define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512      3
5139fff5996227692cf8b6a75771a28a8d624f16efMarek Olšák#define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE 4
5239fff5996227692cf8b6a75771a28a8d624f16efMarek Olšák
53c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse#define ALIGN(value, alignment) (((value) + alignment - 1) & ~(alignment - 1))
54c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse#define MAX2(A, B)              ((A) > (B) ? (A) : (B))
55c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse#define MIN2(A, B)              ((A) < (B) ? (A) : (B))
56c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
57c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse/* keep this private */
58c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisseenum radeon_family {
59c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_UNKNOWN,
60c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_R600,
61c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_RV610,
62c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_RV630,
63c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_RV670,
64c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_RV620,
65c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_RV635,
66c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_RS780,
67c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_RS880,
68c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_RV770,
69c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_RV730,
70c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_RV710,
71c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_RV740,
72c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_CEDAR,
73c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_REDWOOD,
74c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_JUNIPER,
75c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_CYPRESS,
76c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_HEMLOCK,
77c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_PALM,
78c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_SUMO,
79c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_SUMO2,
80c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_BARTS,
81c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_TURKS,
82c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_CAICOS,
83c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_CAYMAN,
84c50cc24690938db53cd91ae9ff2fa0958693f80dAlex Deucher    CHIP_ARUBA,
85481234f2909c0506962a2f42da862da6a9b13fd8Michel Dänzer    CHIP_TAHITI,
86481234f2909c0506962a2f42da862da6a9b13fd8Michel Dänzer    CHIP_PITCAIRN,
87481234f2909c0506962a2f42da862da6a9b13fd8Michel Dänzer    CHIP_VERDE,
8876ae1f4837ceb2c15ccf847e4abe2b5c4f66df85Alex Deucher    CHIP_OLAND,
89c56729cc1564bb4204ca30a18499a78a39f48892Alex Deucher    CHIP_HAINAN,
900ff7f2760d052503d5cf65ded34a66fe20ccec28Alex Deucher    CHIP_BONAIRE,
910ff7f2760d052503d5cf65ded34a66fe20ccec28Alex Deucher    CHIP_KAVERI,
920ff7f2760d052503d5cf65ded34a66fe20ccec28Alex Deucher    CHIP_KABINI,
93efcc456030334a692e2fce7bbd279df3aee13a6dAlex Deucher    CHIP_HAWAII,
94c2bc8ad438693262480ce1426bcf5c1d8ec4e808Samuel Li    CHIP_MULLINS,
95c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    CHIP_LAST,
96c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse};
97c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
98c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissetypedef int (*hw_init_surface_t)(struct radeon_surface_manager *surf_man,
99c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                                 struct radeon_surface *surf);
100c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissetypedef int (*hw_best_surface_t)(struct radeon_surface_manager *surf_man,
101c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                                 struct radeon_surface *surf);
102c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
103c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestruct radeon_hw_info {
104c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* apply to r6, eg */
105a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    uint32_t                        group_bytes;
106a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    uint32_t                        num_banks;
107a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    uint32_t                        num_pipes;
108c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* apply to eg */
109a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    uint32_t                        row_size;
110a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    unsigned                        allow_2d;
111a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    /* apply to si */
112a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    uint32_t                        tile_mode_array[32];
11367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    /* apply to cik */
11467d92404d62044972599dcef3011d17fca46eed5Marek Olšák    uint32_t                        macrotile_mode_array[16];
115c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse};
116c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
117c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestruct radeon_surface_manager {
118c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    int                         fd;
119c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    uint32_t                    device_id;
120c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    struct radeon_hw_info       hw_info;
121c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned                    family;
122c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    hw_init_surface_t           surface_init;
123c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    hw_best_surface_t           surface_best;
124c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse};
125c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
126c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse/* helper */
127c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic int radeon_get_value(int fd, unsigned req, uint32_t *value)
128c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
129c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    struct drm_radeon_info info = {};
130c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    int r;
131c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
132c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    *value = 0;
133c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    info.request = req;
134c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    info.value = (uintptr_t)value;
135c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    r = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info,
136c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                            sizeof(struct drm_radeon_info));
137c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return r;
138c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
139c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
140c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic int radeon_get_family(struct radeon_surface_manager *surf_man)
141c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
142c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    switch (surf_man->device_id) {
143c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse#define CHIPSET(pci_id, name, fam) case pci_id: surf_man->family = CHIP_##fam; break;
144c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse#include "r600_pci_ids.h"
145c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse#undef CHIPSET
146c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    default:
147c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return -EINVAL;
148c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
149c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return 0;
150c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
151c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
152c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic unsigned next_power_of_two(unsigned x)
153c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
154c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse   if (x <= 1)
155c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse       return 1;
156c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
157c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse   return (1 << ((sizeof(unsigned) * 8) - __builtin_clz(x - 1)));
158c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
159c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
160c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic unsigned mip_minify(unsigned size, unsigned level)
161c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
162c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned val;
163c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
164c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    val = MAX2(1, size >> level);
165c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (level > 0)
166c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        val = next_power_of_two(val);
167c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return val;
168c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
169c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
170c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic void surf_minify(struct radeon_surface *surf,
1711aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák                        struct radeon_surface_level *surflevel,
1721aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák                        unsigned bpe, unsigned level,
173c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                        uint32_t xalign, uint32_t yalign, uint32_t zalign,
174c3deddd9c2bf54fa6bec3dbd9ec7eae5fa22e220Michel Dänzer                        uint64_t offset)
175c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
1761aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->npix_x = mip_minify(surf->npix_x, level);
1771aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->npix_y = mip_minify(surf->npix_y, level);
1781aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->npix_z = mip_minify(surf->npix_z, level);
1791aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1801aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1811aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
182e5e51c2110ebf6e1edaa14b7567c5d6a79008a90Marek Olšák    if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
183e5e51c2110ebf6e1edaa14b7567c5d6a79008a90Marek Olšák        !(surf->flags & RADEON_SURF_FMASK)) {
1841aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
1851aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák            surflevel->mode = RADEON_SURF_MODE_1D;
186c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            return;
187c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
188c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
1891aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->nblk_x  = ALIGN(surflevel->nblk_x, xalign);
1901aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->nblk_y  = ALIGN(surflevel->nblk_y, yalign);
1911aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->nblk_z  = ALIGN(surflevel->nblk_z, zalign);
192c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
1931aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->offset = offset;
1941aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
195c3deddd9c2bf54fa6bec3dbd9ec7eae5fa22e220Michel Dänzer    surflevel->slice_size = (uint64_t)surflevel->pitch_bytes * surflevel->nblk_y;
196c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
1971aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
198c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
199c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
200c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse/* ===========================================================================
201c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * r600/r700 family
202c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse */
203c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic int r6_init_hw_info(struct radeon_surface_manager *surf_man)
204c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
205c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    uint32_t tiling_config;
2066a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse    drmVersionPtr version;
207c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    int r;
208c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
209c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
210c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                         &tiling_config);
211c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (r) {
212c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return r;
213c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
214c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
2156a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse    surf_man->hw_info.allow_2d = 0;
2166a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse    version = drmGetVersion(surf_man->fd);
2176a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse    if (version && version->version_minor >= 14) {
2186a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        surf_man->hw_info.allow_2d = 1;
2196a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse    }
220a1d462d2a6f720538eaf1199a94dd27cd04e8a54Dave Airlie    drmFreeVersion(version);
2216a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse
222c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    switch ((tiling_config & 0xe) >> 1) {
223c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 0:
224c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.num_pipes = 1;
225c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
226c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 1:
227c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.num_pipes = 2;
228c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
229c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 2:
230c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.num_pipes = 4;
231c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
232c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 3:
233c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.num_pipes = 8;
234c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
235c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    default:
236c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        surf_man->hw_info.num_pipes = 8;
237c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        surf_man->hw_info.allow_2d = 0;
238c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        break;
239c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
240c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
241c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    switch ((tiling_config & 0x30) >> 4) {
242c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 0:
243c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.num_banks = 4;
244c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
245c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 1:
246c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.num_banks = 8;
247c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
248c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    default:
249c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        surf_man->hw_info.num_banks = 8;
250c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        surf_man->hw_info.allow_2d = 0;
251c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        break;
252c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
253c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
254c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    switch ((tiling_config & 0xc0) >> 6) {
255c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 0:
256c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.group_bytes = 256;
257c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
258c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 1:
259c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.group_bytes = 512;
260c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
261c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    default:
262c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        surf_man->hw_info.group_bytes = 256;
263c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        surf_man->hw_info.allow_2d = 0;
264c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        break;
265c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
266c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return 0;
267c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
268c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
269c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic int r6_surface_init_linear(struct radeon_surface_manager *surf_man,
270c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                                  struct radeon_surface *surf,
271c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                                  uint64_t offset, unsigned start_level)
272c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
273c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    uint32_t xalign, yalign, zalign;
274c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned i;
275c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
276c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* compute alignment */
277c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (!start_level) {
278c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
279c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
280c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* the 32 alignment is for scanout, cb or db but to allow texture to be
281c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse     * easily bound as such we force this alignment to all surface
282c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse     */
2839b3ad51ae5fd9654df8ef75de845a519015150bbJerome Glisse    xalign = MAX2(1, surf_man->hw_info.group_bytes / surf->bpe);
284c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    yalign = 1;
285c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    zalign = 1;
2869b3ad51ae5fd9654df8ef75de845a519015150bbJerome Glisse    if (surf->flags & RADEON_SURF_SCANOUT) {
2879b3ad51ae5fd9654df8ef75de845a519015150bbJerome Glisse        xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
2889b3ad51ae5fd9654df8ef75de845a519015150bbJerome Glisse    }
289c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
290c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* build mipmap tree */
291c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    for (i = start_level; i <= surf->last_level; i++) {
292c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf->level[i].mode = RADEON_SURF_MODE_LINEAR;
2931aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
294c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        /* level0 and first mipmap need to have alignment */
295c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        offset = surf->bo_size;
29672f84b85afbe762b86ea8c095fee01e7d406b131Thomas Klausner        if (i == 0) {
297c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            offset = ALIGN(offset, surf->bo_alignment);
298c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
299c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
300c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return 0;
301c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
302c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
303c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic int r6_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
304c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                                          struct radeon_surface *surf,
305c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                                          uint64_t offset, unsigned start_level)
306c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
307c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    uint32_t xalign, yalign, zalign;
308c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned i;
309c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
310c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* compute alignment */
311c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (!start_level) {
312c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
313c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
314c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    xalign = MAX2(64, surf_man->hw_info.group_bytes / surf->bpe);
315c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    yalign = 1;
316c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    zalign = 1;
317c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
318c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* build mipmap tree */
319c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    for (i = start_level; i <= surf->last_level; i++) {
320c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
3211aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
322c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        /* level0 and first mipmap need to have alignment */
323c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        offset = surf->bo_size;
32472f84b85afbe762b86ea8c095fee01e7d406b131Thomas Klausner        if (i == 0) {
325c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            offset = ALIGN(offset, surf->bo_alignment);
326c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
327c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
328c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return 0;
329c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
330c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
331c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic int r6_surface_init_1d(struct radeon_surface_manager *surf_man,
332c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                              struct radeon_surface *surf,
333c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                              uint64_t offset, unsigned start_level)
334c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
335c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    uint32_t xalign, yalign, zalign, tilew;
336c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned i;
337c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
338c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* compute alignment */
339c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    tilew = 8;
340c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    xalign = surf_man->hw_info.group_bytes / (tilew * surf->bpe * surf->nsamples);
341c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    xalign = MAX2(tilew, xalign);
342c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    yalign = tilew;
343c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    zalign = 1;
3449b3ad51ae5fd9654df8ef75de845a519015150bbJerome Glisse    if (surf->flags & RADEON_SURF_SCANOUT) {
3459b3ad51ae5fd9654df8ef75de845a519015150bbJerome Glisse        xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
3469b3ad51ae5fd9654df8ef75de845a519015150bbJerome Glisse    }
347c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (!start_level) {
348c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
349c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
350c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
351c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* build mipmap tree */
352c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    for (i = start_level; i <= surf->last_level; i++) {
353c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf->level[i].mode = RADEON_SURF_MODE_1D;
3541aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
355c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        /* level0 and first mipmap need to have alignment */
356c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        offset = surf->bo_size;
35772f84b85afbe762b86ea8c095fee01e7d406b131Thomas Klausner        if (i == 0) {
358c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            offset = ALIGN(offset, surf->bo_alignment);
359c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
360c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
361c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return 0;
362c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
363c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
364c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic int r6_surface_init_2d(struct radeon_surface_manager *surf_man,
365c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                              struct radeon_surface *surf,
366c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                              uint64_t offset, unsigned start_level)
367c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
368c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    uint32_t xalign, yalign, zalign, tilew;
369c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned i;
370c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
371c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* compute alignment */
372c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    tilew = 8;
373c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    zalign = 1;
374c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    xalign = (surf_man->hw_info.group_bytes * surf_man->hw_info.num_banks) /
375c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse             (tilew * surf->bpe * surf->nsamples);
376c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    xalign = MAX2(tilew * surf_man->hw_info.num_banks, xalign);
377eca91cf163d50090db36d0b2abbffcff813a2adfDave Airlie    if (surf->flags & RADEON_SURF_FMASK)
378eca91cf163d50090db36d0b2abbffcff813a2adfDave Airlie	xalign = MAX2(128, xalign);
379c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    yalign = tilew * surf_man->hw_info.num_pipes;
3809b3ad51ae5fd9654df8ef75de845a519015150bbJerome Glisse    if (surf->flags & RADEON_SURF_SCANOUT) {
3819b3ad51ae5fd9654df8ef75de845a519015150bbJerome Glisse        xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
3829b3ad51ae5fd9654df8ef75de845a519015150bbJerome Glisse    }
383c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (!start_level) {
384c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf->bo_alignment =
385c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            MAX2(surf_man->hw_info.num_pipes *
386c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                 surf_man->hw_info.num_banks *
387853429b939c792c4bc0bc91fdef696e3251b88d9Marek Olšák                 surf->nsamples * surf->bpe * 64,
388c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                 xalign * yalign * surf->nsamples * surf->bpe);
389c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
390c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
391c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* build mipmap tree */
392c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    for (i = start_level; i <= surf->last_level; i++) {
393c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf->level[i].mode = RADEON_SURF_MODE_2D;
3941aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
395c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        if (surf->level[i].mode == RADEON_SURF_MODE_1D) {
396c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            return r6_surface_init_1d(surf_man, surf, offset, i);
397c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
398c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        /* level0 and first mipmap need to have alignment */
399c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        offset = surf->bo_size;
40072f84b85afbe762b86ea8c095fee01e7d406b131Thomas Klausner        if (i == 0) {
401c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            offset = ALIGN(offset, surf->bo_alignment);
402c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
403c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
404c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return 0;
405c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
406c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
407c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic int r6_surface_init(struct radeon_surface_manager *surf_man,
408c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                           struct radeon_surface *surf)
409c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
410c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned mode;
411c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    int r;
412c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
413e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák    /* MSAA surfaces support the 2D mode only. */
414e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák    if (surf->nsamples > 1) {
415e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák        surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
416e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák        surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
417e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák    }
418e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák
419c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* tiling mode */
420c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
421c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
422ad66c17209811acdae21e44290a449523882a734Marek Olšák    if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
423d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse        /* zbuffer only support 1D or 2D tiled surface */
424d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse        switch (mode) {
425d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse        case RADEON_SURF_MODE_1D:
426d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse        case RADEON_SURF_MODE_2D:
427d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse            break;
428d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse        default:
429d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse            mode = RADEON_SURF_MODE_1D;
430d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse            surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
431d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse            surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
432d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse            break;
433d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse        }
434d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse    }
435d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse
4366a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse    /* force 1d on kernel that can't do 2d */
4376a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse    if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) {
438e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák        if (surf->nsamples > 1) {
439e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák            fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__);
440e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák            return -EFAULT;
441e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák        }
4426a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        mode = RADEON_SURF_MODE_1D;
4436a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
4446a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        surf->flags |= RADEON_SURF_SET(mode, MODE);
4456a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse    }
4466a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse
447c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* check surface dimension */
448c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (surf->npix_x > 8192 || surf->npix_y > 8192 || surf->npix_z > 8192) {
449c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return -EINVAL;
450c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
451c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
452c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* check mipmap last_level */
453c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (surf->last_level > 14) {
454c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return -EINVAL;
455c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
456c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
457c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* check tiling mode */
458c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    switch (mode) {
459c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case RADEON_SURF_MODE_LINEAR:
460c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        r = r6_surface_init_linear(surf_man, surf, 0, 0);
461c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
462c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case RADEON_SURF_MODE_LINEAR_ALIGNED:
463c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
464c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
465c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case RADEON_SURF_MODE_1D:
466c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        r = r6_surface_init_1d(surf_man, surf, 0, 0);
467c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
468c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case RADEON_SURF_MODE_2D:
469c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        r = r6_surface_init_2d(surf_man, surf, 0, 0);
470c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
471c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    default:
472c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return -EINVAL;
473c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
474c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return r;
475c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
476c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
477c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic int r6_surface_best(struct radeon_surface_manager *surf_man,
478c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                           struct radeon_surface *surf)
479c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
480c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* no value to optimize for r6xx/r7xx */
481c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return 0;
482c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
483c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
484c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
485c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse/* ===========================================================================
486c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * evergreen family
487c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse */
488c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic int eg_init_hw_info(struct radeon_surface_manager *surf_man)
489c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
490c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    uint32_t tiling_config;
491c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    drmVersionPtr version;
492c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    int r;
493c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
494c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
495c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                         &tiling_config);
496c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (r) {
497c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return r;
498c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
499c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
500c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    surf_man->hw_info.allow_2d = 0;
501c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    version = drmGetVersion(surf_man->fd);
5022f56002cc0b5424902dfe2bd4024f7b825ecde67Jerome Glisse    if (version && version->version_minor >= 16) {
503c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.allow_2d = 1;
504c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
505a1d462d2a6f720538eaf1199a94dd27cd04e8a54Dave Airlie    drmFreeVersion(version);
506c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
507c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    switch (tiling_config & 0xf) {
508c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 0:
509c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.num_pipes = 1;
510c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
511c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 1:
512c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.num_pipes = 2;
513c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
514c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 2:
515c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.num_pipes = 4;
516c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
517c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 3:
518c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.num_pipes = 8;
519c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
520c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    default:
521c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        surf_man->hw_info.num_pipes = 8;
522c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        surf_man->hw_info.allow_2d = 0;
523c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        break;
524c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
525c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
526c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    switch ((tiling_config & 0xf0) >> 4) {
527c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 0:
528c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.num_banks = 4;
529c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
530c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 1:
531c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.num_banks = 8;
532c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
533c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 2:
534c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.num_banks = 16;
535c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
536c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    default:
537c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        surf_man->hw_info.num_banks = 8;
538c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        surf_man->hw_info.allow_2d = 0;
539c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        break;
540c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
541c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
542c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    switch ((tiling_config & 0xf00) >> 8) {
543c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 0:
544c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.group_bytes = 256;
545c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
546c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 1:
547c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.group_bytes = 512;
548c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
549c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    default:
550c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        surf_man->hw_info.group_bytes = 256;
551c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        surf_man->hw_info.allow_2d = 0;
552c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        break;
553c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
554c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
555c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    switch ((tiling_config & 0xf000) >> 12) {
556c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 0:
557c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.row_size = 1024;
558c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
559c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 1:
560c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.row_size = 2048;
561c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
562c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 2:
563c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->hw_info.row_size = 4096;
564c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
565c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    default:
566c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        surf_man->hw_info.row_size = 4096;
567c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        surf_man->hw_info.allow_2d = 0;
568c2b77a02d4e188cfa6d1b73a721946fd9b1d3577Alex Deucher        break;
569c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
570c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return 0;
571c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
572c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
573c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic void eg_surf_minify(struct radeon_surface *surf,
5741aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák                           struct radeon_surface_level *surflevel,
5751aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák                           unsigned bpe,
576c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                           unsigned level,
577c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                           unsigned slice_pt,
578c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                           unsigned mtilew,
579c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                           unsigned mtileh,
580c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                           unsigned mtileb,
581c3deddd9c2bf54fa6bec3dbd9ec7eae5fa22e220Michel Dänzer                           uint64_t offset)
582c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
583c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned mtile_pr, mtile_ps;
584c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
5851aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->npix_x = mip_minify(surf->npix_x, level);
5861aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->npix_y = mip_minify(surf->npix_y, level);
5871aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->npix_z = mip_minify(surf->npix_z, level);
5881aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
5891aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
5901aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
591e5e51c2110ebf6e1edaa14b7567c5d6a79008a90Marek Olšák    if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
592e5e51c2110ebf6e1edaa14b7567c5d6a79008a90Marek Olšák        !(surf->flags & RADEON_SURF_FMASK)) {
5931aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        if (surflevel->nblk_x < mtilew || surflevel->nblk_y < mtileh) {
5941aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák            surflevel->mode = RADEON_SURF_MODE_1D;
595c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            return;
596c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
597c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
5981aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->nblk_x  = ALIGN(surflevel->nblk_x, mtilew);
5991aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->nblk_y  = ALIGN(surflevel->nblk_y, mtileh);
6001aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->nblk_z  = ALIGN(surflevel->nblk_z, 1);
601c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
602c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* macro tile per row */
6031aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    mtile_pr = surflevel->nblk_x / mtilew;
604c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* macro tile per slice */
6051aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    mtile_ps = (mtile_pr * surflevel->nblk_y) / mtileh;
606c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
6071aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surflevel->offset = offset;
608c866dc7c00e7f5f219901a9a81bf456a24d29cd1Michel Dänzer    surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
609c3deddd9c2bf54fa6bec3dbd9ec7eae5fa22e220Michel Dänzer    surflevel->slice_size = (uint64_t)mtile_ps * mtileb * slice_pt;
610c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
6111aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
612c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
613c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
614c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic int eg_surface_init_1d(struct radeon_surface_manager *surf_man,
615c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                              struct radeon_surface *surf,
6161aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák                              struct radeon_surface_level *level,
6171aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák                              unsigned bpe,
618c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                              uint64_t offset, unsigned start_level)
619c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
620c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    uint32_t xalign, yalign, zalign, tilew;
621c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned i;
622c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
623c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* compute alignment */
624c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    tilew = 8;
6251aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    xalign = surf_man->hw_info.group_bytes / (tilew * bpe * surf->nsamples);
626c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    xalign = MAX2(tilew, xalign);
627c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    yalign = tilew;
628c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    zalign = 1;
6299b3ad51ae5fd9654df8ef75de845a519015150bbJerome Glisse    if (surf->flags & RADEON_SURF_SCANOUT) {
6301aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
6319b3ad51ae5fd9654df8ef75de845a519015150bbJerome Glisse    }
6321aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák
633c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (!start_level) {
6341aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
6351aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
6361aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák
6371aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        if (offset) {
6381aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák            offset = ALIGN(offset, alignment);
6391aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        }
640c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
641c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
642c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* build mipmap tree */
643c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    for (i = start_level; i <= surf->last_level; i++) {
6441aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        level[i].mode = RADEON_SURF_MODE_1D;
6451aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, offset);
646c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        /* level0 and first mipmap need to have alignment */
647c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        offset = surf->bo_size;
64872f84b85afbe762b86ea8c095fee01e7d406b131Thomas Klausner        if (i == 0) {
649c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            offset = ALIGN(offset, surf->bo_alignment);
650c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
651c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
652c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return 0;
653c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
654c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
655c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic int eg_surface_init_2d(struct radeon_surface_manager *surf_man,
656c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                              struct radeon_surface *surf,
6571aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák                              struct radeon_surface_level *level,
6581aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák                              unsigned bpe, unsigned tile_split,
659c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                              uint64_t offset, unsigned start_level)
660c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
661c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned tilew, tileh, tileb;
662c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned mtilew, mtileh, mtileb;
663c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned slice_pt;
664c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned i;
665c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
666c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* compute tile values */
667c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    tilew = 8;
668c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    tileh = 8;
6691aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    tileb = tilew * tileh * bpe * surf->nsamples;
670c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* slices per tile */
671c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    slice_pt = 1;
6721543c96e154d6801cf725c3b511d61604a378e03Alex Deucher    if (tileb > tile_split && tile_split) {
6731aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        slice_pt = tileb / tile_split;
674c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
675c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    tileb = tileb / slice_pt;
676c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
677c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* macro tile width & height */
678c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    mtilew = (tilew * surf->bankw * surf_man->hw_info.num_pipes) * surf->mtilea;
679c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    mtileh = (tileh * surf->bankh * surf_man->hw_info.num_banks) / surf->mtilea;
680c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* macro tile bytes */
681c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
682c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
683c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (!start_level) {
6841aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        unsigned alignment = MAX2(256, mtileb);
6851aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
6861aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák
6871aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        if (offset) {
6881aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák            offset = ALIGN(offset, alignment);
6891aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        }
690c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
691c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
692c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* build mipmap tree */
693c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    for (i = start_level; i <= surf->last_level; i++) {
6941aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        level[i].mode = RADEON_SURF_MODE_2D;
6951aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        eg_surf_minify(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, mtileb, offset);
6961aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        if (level[i].mode == RADEON_SURF_MODE_1D) {
6971aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák            return eg_surface_init_1d(surf_man, surf, level, bpe, offset, i);
698c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
699c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        /* level0 and first mipmap need to have alignment */
700c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        offset = surf->bo_size;
70172f84b85afbe762b86ea8c095fee01e7d406b131Thomas Klausner        if (i == 0) {
702c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            offset = ALIGN(offset, surf->bo_alignment);
703c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
704c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
705c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return 0;
706c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
707c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
708c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic int eg_surface_sanity(struct radeon_surface_manager *surf_man,
709c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                             struct radeon_surface *surf,
710c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                             unsigned mode)
711c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
712c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned tileb;
713c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
714c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* check surface dimension */
715c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
716c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return -EINVAL;
717c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
718c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
719c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* check mipmap last_level */
720c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (surf->last_level > 15) {
721c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return -EINVAL;
722c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
723c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
7246a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse    /* force 1d on kernel that can't do 2d */
7256a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse    if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) {
726e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák        if (surf->nsamples > 1) {
727e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák            fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__);
728e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák            return -EFAULT;
729e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák        }
7306a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        mode = RADEON_SURF_MODE_1D;
7316a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
7326a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        surf->flags |= RADEON_SURF_SET(mode, MODE);
7336a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse    }
7346a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse
735c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* check tile split */
7366a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse    if (mode == RADEON_SURF_MODE_2D) {
7376a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        switch (surf->tile_split) {
7386a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 64:
7396a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 128:
7406a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 256:
7416a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 512:
7426a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 1024:
7436a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 2048:
7446a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 4096:
7456a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse            break;
7466a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        default:
747c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            return -EINVAL;
748c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
7496a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        switch (surf->mtilea) {
7506a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 1:
7516a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 2:
7526a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 4:
7536a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 8:
7546a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse            break;
7556a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        default:
7566a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse            return -EINVAL;
7576a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        }
7586a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        /* check aspect ratio */
7596a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        if (surf_man->hw_info.num_banks < surf->mtilea) {
7606a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse            return -EINVAL;
7616a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        }
7626a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        /* check bank width */
7636a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        switch (surf->bankw) {
7646a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 1:
7656a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 2:
7666a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 4:
7676a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 8:
7686a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse            break;
7696a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        default:
7706a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse            return -EINVAL;
7716a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        }
7726a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        /* check bank height */
7736a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        switch (surf->bankh) {
7746a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 1:
7756a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 2:
7766a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 4:
7776a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        case 8:
7786a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse            break;
7796a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        default:
7806a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse            return -EINVAL;
7816a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        }
7826a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
7836a720cb8660975acea1100e61a88a92a7cb3856eJerome Glisse        if ((tileb * surf->bankh * surf->bankw) < surf_man->hw_info.group_bytes) {
784c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            return -EINVAL;
785c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
786c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
787c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
788c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return 0;
789c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
790c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
7911aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšákstatic int eg_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
7921aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák                                       struct radeon_surface *surf)
7931aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák{
7941aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
7951aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
79642465feb9759ef5a6d79d7e628510cd0a081f913Emil Velikov    /* Old libdrm_macros.headers didn't have stencil_level in it. This prevents crashes. */
7971aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
7981aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    struct radeon_surface_level *stencil_level =
7991aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
8001aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák
8011aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    r = eg_surface_init_1d(surf_man, surf, surf->level, surf->bpe, 0, 0);
8021aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    if (r)
8031aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        return r;
8041aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák
8051aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    if (is_depth_stencil) {
8061aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        r = eg_surface_init_1d(surf_man, surf, stencil_level, 1,
8071aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák                               surf->bo_size, 0);
8081aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        surf->stencil_offset = stencil_level[0].offset;
8091aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    }
8101aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    return r;
8111aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák}
8121aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák
8131aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšákstatic int eg_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
8141aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák                                       struct radeon_surface *surf)
8151aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák{
8161aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
8171aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
81842465feb9759ef5a6d79d7e628510cd0a081f913Emil Velikov    /* Old libdrm_macros.headers didn't have stencil_level in it. This prevents crashes. */
8191aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
8201aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    struct radeon_surface_level *stencil_level =
8211aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
8221aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák
8231aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    r = eg_surface_init_2d(surf_man, surf, surf->level, surf->bpe,
8241aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák                           surf->tile_split, 0, 0);
8251aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    if (r)
8261aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        return r;
8271aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák
8281aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    if (is_depth_stencil) {
8291aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        r = eg_surface_init_2d(surf_man, surf, stencil_level, 1,
8301aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák                               surf->stencil_tile_split, surf->bo_size, 0);
8311aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        surf->stencil_offset = stencil_level[0].offset;
8321aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    }
8331aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    return r;
8341aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák}
8351aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák
836c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic int eg_surface_init(struct radeon_surface_manager *surf_man,
837c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                           struct radeon_surface *surf)
838c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
839c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned mode;
840c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    int r;
841c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
842e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák    /* MSAA surfaces support the 2D mode only. */
843e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák    if (surf->nsamples > 1) {
844e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák        surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
845e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák        surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
846e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák    }
847e14aedce64e365ef1a8726ed8c1ebed881d7a398Marek Olšák
848c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* tiling mode */
849c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
850c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
85123372955730048bbcddafc74365d911f9a74fb13Marek Olšák    if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
852d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse        /* zbuffer only support 1D or 2D tiled surface */
853d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse        switch (mode) {
854d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse        case RADEON_SURF_MODE_1D:
855d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse        case RADEON_SURF_MODE_2D:
856d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse            break;
857d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse        default:
858d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse            mode = RADEON_SURF_MODE_1D;
859d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse            surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
860d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse            surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
861d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse            break;
862d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse        }
863d1fcfb17b9642ae351b03056a27b328f314ca80aJerome Glisse    }
864c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
865c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    r = eg_surface_sanity(surf_man, surf, mode);
866c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (r) {
867c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return r;
868c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
869c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
870325e2e52a96ede6a19e891f769c803cb9ba85e10Jerome Glisse    surf->stencil_offset = 0;
8711aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surf->bo_alignment = 0;
872325e2e52a96ede6a19e891f769c803cb9ba85e10Jerome Glisse
873c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* check tiling mode */
874c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    switch (mode) {
875c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case RADEON_SURF_MODE_LINEAR:
876c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        r = r6_surface_init_linear(surf_man, surf, 0, 0);
877c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
878c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case RADEON_SURF_MODE_LINEAR_ALIGNED:
879c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
880c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
881c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case RADEON_SURF_MODE_1D:
8821aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        r = eg_surface_init_1d_miptrees(surf_man, surf);
883c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
884c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case RADEON_SURF_MODE_2D:
8851aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák        r = eg_surface_init_2d_miptrees(surf_man, surf);
886c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
887c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    default:
888c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return -EINVAL;
889c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
890c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return r;
891c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
892c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
893c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic unsigned log2_int(unsigned x)
894c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
895c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned l;
896c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
897c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (x < 2) {
898c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return 0;
899c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
900c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    for (l = 2; ; l++) {
901c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        if ((unsigned)(1 << l) > x) {
902c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            return l - 1;
903c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
904c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
905c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return 0;
906c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
907c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
908c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse/* compute best tile_split, bankw, bankh, mtilea
909c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * depending on surface
910c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse */
911c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic int eg_surface_best(struct radeon_surface_manager *surf_man,
912c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                           struct radeon_surface *surf)
913c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
914c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned mode, tileb, h_over_w;
915c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    int r;
916c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
917c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* tiling mode */
918c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
919c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
920c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* set some default value to avoid sanity check choking on them */
921c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    surf->tile_split = 1024;
922c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    surf->bankw = 1;
923c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    surf->bankh = 1;
924c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    surf->mtilea = surf_man->hw_info.num_banks;
925c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
926c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    for (; surf->bankh <= 8; surf->bankh *= 2) {
927c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
928c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            break;
929c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
930c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
931c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (surf->mtilea > 8) {
932c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf->mtilea = 8;
933c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
934c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
935c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    r = eg_surface_sanity(surf_man, surf, mode);
936c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (r) {
937c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return r;
938c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
939c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
940c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (mode != RADEON_SURF_MODE_2D) {
941c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        /* nothing to do for non 2D tiled surface */
942c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return 0;
943c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
944c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
945128803a107fde8ce36036e59437a536fc4d46553Marek Olšák    /* Tweak TILE_SPLIT for performance here. */
946128803a107fde8ce36036e59437a536fc4d46553Marek Olšák    if (surf->nsamples > 1) {
947128803a107fde8ce36036e59437a536fc4d46553Marek Olšák        if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
948128803a107fde8ce36036e59437a536fc4d46553Marek Olšák            switch (surf->nsamples) {
949128803a107fde8ce36036e59437a536fc4d46553Marek Olšák            case 2:
950128803a107fde8ce36036e59437a536fc4d46553Marek Olšák                surf->tile_split = 128;
951128803a107fde8ce36036e59437a536fc4d46553Marek Olšák                break;
952128803a107fde8ce36036e59437a536fc4d46553Marek Olšák            case 4:
953128803a107fde8ce36036e59437a536fc4d46553Marek Olšák                surf->tile_split = 128;
954128803a107fde8ce36036e59437a536fc4d46553Marek Olšák                break;
955128803a107fde8ce36036e59437a536fc4d46553Marek Olšák            case 8:
956128803a107fde8ce36036e59437a536fc4d46553Marek Olšák                surf->tile_split = 256;
957128803a107fde8ce36036e59437a536fc4d46553Marek Olšák                break;
958128803a107fde8ce36036e59437a536fc4d46553Marek Olšák            case 16: /* cayman only */
959128803a107fde8ce36036e59437a536fc4d46553Marek Olšák                surf->tile_split = 512;
960128803a107fde8ce36036e59437a536fc4d46553Marek Olšák                break;
961128803a107fde8ce36036e59437a536fc4d46553Marek Olšák            default:
962128803a107fde8ce36036e59437a536fc4d46553Marek Olšák                fprintf(stderr, "radeon: Wrong number of samples %i (%i)\n",
963128803a107fde8ce36036e59437a536fc4d46553Marek Olšák                        surf->nsamples, __LINE__);
964128803a107fde8ce36036e59437a536fc4d46553Marek Olšák                return -EINVAL;
965128803a107fde8ce36036e59437a536fc4d46553Marek Olšák            }
966128803a107fde8ce36036e59437a536fc4d46553Marek Olšák            surf->stencil_tile_split = 64;
967128803a107fde8ce36036e59437a536fc4d46553Marek Olšák        } else {
968625d1810ad1f61dd4f4b2b2ee7e5cc67e1fdc2f1Marek Olšák            /* tile split must be >= 256 for colorbuffer surfaces,
969625d1810ad1f61dd4f4b2b2ee7e5cc67e1fdc2f1Marek Olšák             * SAMPLE_SPLIT = tile_split / (bpe * 64), the optimal value is 2
970625d1810ad1f61dd4f4b2b2ee7e5cc67e1fdc2f1Marek Olšák             */
971625d1810ad1f61dd4f4b2b2ee7e5cc67e1fdc2f1Marek Olšák            surf->tile_split = MAX2(2 * surf->bpe * 64, 256);
972e32fff8e9ea8d522679eaab21a9555cab134fb36Marek Olšák            if (surf->tile_split > 4096)
973e32fff8e9ea8d522679eaab21a9555cab134fb36Marek Olšák                surf->tile_split = 4096;
974128803a107fde8ce36036e59437a536fc4d46553Marek Olšák        }
975128803a107fde8ce36036e59437a536fc4d46553Marek Olšák    } else {
976128803a107fde8ce36036e59437a536fc4d46553Marek Olšák        /* set tile split to row size */
977128803a107fde8ce36036e59437a536fc4d46553Marek Olšák        surf->tile_split = surf_man->hw_info.row_size;
978128803a107fde8ce36036e59437a536fc4d46553Marek Olšák        surf->stencil_tile_split = surf_man->hw_info.row_size / 2;
979128803a107fde8ce36036e59437a536fc4d46553Marek Olšák    }
980c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
981c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* bankw or bankh greater than 1 increase alignment requirement, not
982c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse     * sure if it's worth using smaller bankw & bankh to stick with 2D
983c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse     * tiling on small surface rather than falling back to 1D tiling.
9841924b6704aa34bb3dd044b8e1e29558c521c6902Grazvydas Ignotas     * Use recommended value based on tile size for now.
985c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse     *
986c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse     * fmask buffer has different optimal value figure them out once we
987c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse     * use it.
988c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse     */
989b3d90bbc1d43bb11d8de25109f403b1b30533c34Marek Olšák    if (surf->flags & RADEON_SURF_SBUFFER) {
990c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        /* assume 1 bytes for stencil, we optimize for stencil as stencil
991c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse         * and depth shares surface values
992c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse         */
993c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        tileb = MIN2(surf->tile_split, 64 * surf->nsamples);
994c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    } else {
995c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
996c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
997c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
998c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* use bankw of 1 to minimize width alignment, might be interesting to
999c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse     * increase it for large surface
1000c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse     */
1001c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    surf->bankw = 1;
1002c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    switch (tileb) {
1003c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 64:
1004c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf->bankh = 4;
1005c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
1006c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 128:
1007c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 256:
1008c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf->bankh = 2;
1009c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
1010c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    default:
1011c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf->bankh = 1;
1012c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
1013c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
1014c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* double check the constraint */
1015c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    for (; surf->bankh <= 8; surf->bankh *= 2) {
1016c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
1017c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            break;
1018c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
1019c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
1020c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
1021c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    h_over_w = (((surf->bankh * surf_man->hw_info.num_banks) << 16) /
1022c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                (surf->bankw * surf_man->hw_info.num_pipes)) >> 16;
1023c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    surf->mtilea = 1 << (log2_int(h_over_w) >> 1);
1024c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
1025c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return 0;
1026c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
1027c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
1028c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
1029c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse/* ===========================================================================
10308572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer * Southern Islands family
10318572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer */
1032a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define SI__GB_TILE_MODE__PIPE_CONFIG(x)        (((x) >> 6) & 0x1f)
1033a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__PIPE_CONFIG__ADDR_SURF_P2               0
1034a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__PIPE_CONFIG__ADDR_SURF_P4_8x16          4
1035a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__PIPE_CONFIG__ADDR_SURF_P4_16x16         5
1036a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__PIPE_CONFIG__ADDR_SURF_P4_16x32         6
1037a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__PIPE_CONFIG__ADDR_SURF_P4_32x32         7
1038a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16    8
1039a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16    9
1040a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16    10
1041a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16   11
1042a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16   12
1043a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32   13
1044a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32   14
1045a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define SI__GB_TILE_MODE__TILE_SPLIT(x)         (((x) >> 11) & 0x7)
1046a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__TILE_SPLIT__64B                         0
1047a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__TILE_SPLIT__128B                        1
1048a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__TILE_SPLIT__256B                        2
1049a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__TILE_SPLIT__512B                        3
1050a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__TILE_SPLIT__1024B                       4
1051a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__TILE_SPLIT__2048B                       5
1052a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__TILE_SPLIT__4096B                       6
1053a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define SI__GB_TILE_MODE__BANK_WIDTH(x)         (((x) >> 14) & 0x3)
1054a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__BANK_WIDTH__1                           0
1055a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__BANK_WIDTH__2                           1
1056a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__BANK_WIDTH__4                           2
1057a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__BANK_WIDTH__8                           3
1058a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define SI__GB_TILE_MODE__BANK_HEIGHT(x)        (((x) >> 16) & 0x3)
1059a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__BANK_HEIGHT__1                          0
1060a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__BANK_HEIGHT__2                          1
1061a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__BANK_HEIGHT__4                          2
1062a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__BANK_HEIGHT__8                          3
1063a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define SI__GB_TILE_MODE__MACRO_TILE_ASPECT(x)  (((x) >> 18) & 0x3)
1064a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__MACRO_TILE_ASPECT__1                    0
1065a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__MACRO_TILE_ASPECT__2                    1
1066a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__MACRO_TILE_ASPECT__4                    2
1067a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__MACRO_TILE_ASPECT__8                    3
1068a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define SI__GB_TILE_MODE__NUM_BANKS(x)          (((x) >> 20) & 0x3)
1069a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__NUM_BANKS__2_BANK                       0
1070a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__NUM_BANKS__4_BANK                       1
1071a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__NUM_BANKS__8_BANK                       2
1072a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse#define     SI__NUM_BANKS__16_BANK                      3
1073a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1074a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1075a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glissestatic void si_gb_tile_mode(uint32_t gb_tile_mode,
1076a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                            unsigned *num_pipes,
1077a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                            unsigned *num_banks,
1078a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                            uint32_t *macro_tile_aspect,
1079a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                            uint32_t *bank_w,
1080a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                            uint32_t *bank_h,
1081a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                            uint32_t *tile_split)
1082a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse{
1083a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (num_pipes) {
1084a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        switch (SI__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1085a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__PIPE_CONFIG__ADDR_SURF_P2:
1086a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        default:
1087a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *num_pipes = 2;
1088a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1089a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1090a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1091a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1092a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1093a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *num_pipes = 4;
1094a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1095a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1096a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1097a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1098a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1099a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1100a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1101a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1102a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *num_pipes = 8;
1103a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1104a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
1105a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1106a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (num_banks) {
1107a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        switch (SI__GB_TILE_MODE__NUM_BANKS(gb_tile_mode)) {
1108a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        default:
1109a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__NUM_BANKS__2_BANK:
1110a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *num_banks = 2;
1111a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1112a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__NUM_BANKS__4_BANK:
1113a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *num_banks = 4;
1114a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1115a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__NUM_BANKS__8_BANK:
1116a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *num_banks = 8;
1117a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1118a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__NUM_BANKS__16_BANK:
1119a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *num_banks = 16;
1120a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1121a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
1122a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1123a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (macro_tile_aspect) {
1124a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        switch (SI__GB_TILE_MODE__MACRO_TILE_ASPECT(gb_tile_mode)) {
1125a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        default:
1126a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__MACRO_TILE_ASPECT__1:
1127a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *macro_tile_aspect = 1;
1128a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1129a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__MACRO_TILE_ASPECT__2:
1130a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *macro_tile_aspect = 2;
1131a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1132a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__MACRO_TILE_ASPECT__4:
1133a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *macro_tile_aspect = 4;
1134a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1135a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__MACRO_TILE_ASPECT__8:
1136a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *macro_tile_aspect = 8;
1137a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1138a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
1139a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1140a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (bank_w) {
1141a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        switch (SI__GB_TILE_MODE__BANK_WIDTH(gb_tile_mode)) {
1142a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        default:
1143a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__BANK_WIDTH__1:
1144a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *bank_w = 1;
1145a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1146a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__BANK_WIDTH__2:
1147a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *bank_w = 2;
1148a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1149a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__BANK_WIDTH__4:
1150a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *bank_w = 4;
1151a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1152a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__BANK_WIDTH__8:
1153a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *bank_w = 8;
1154a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1155a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
1156a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1157a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (bank_h) {
1158a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        switch (SI__GB_TILE_MODE__BANK_HEIGHT(gb_tile_mode)) {
1159a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        default:
1160a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__BANK_HEIGHT__1:
1161a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *bank_h = 1;
1162a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1163a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__BANK_HEIGHT__2:
1164a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *bank_h = 2;
1165a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1166a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__BANK_HEIGHT__4:
1167a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *bank_h = 4;
1168a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1169a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__BANK_HEIGHT__8:
1170a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *bank_h = 8;
1171a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1172a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
1173a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1174a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (tile_split) {
1175a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        switch (SI__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1176a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        default:
1177a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__TILE_SPLIT__64B:
1178a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *tile_split = 64;
1179a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1180a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__TILE_SPLIT__128B:
1181a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *tile_split = 128;
1182a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1183a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__TILE_SPLIT__256B:
1184a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *tile_split = 256;
1185a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1186a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__TILE_SPLIT__512B:
1187a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *tile_split = 512;
1188a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1189a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__TILE_SPLIT__1024B:
1190a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *tile_split = 1024;
1191a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1192a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__TILE_SPLIT__2048B:
1193a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *tile_split = 2048;
1194a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1195a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        case SI__TILE_SPLIT__4096B:
1196a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *tile_split = 4096;
1197a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            break;
1198a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
1199a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1200a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse}
1201a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1202a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glissestatic int si_init_hw_info(struct radeon_surface_manager *surf_man)
1203a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse{
1204a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    uint32_t tiling_config;
1205a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    drmVersionPtr version;
1206a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    int r;
1207a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1208a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
1209a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                         &tiling_config);
1210a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (r) {
1211a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        return r;
1212a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1213a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1214a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    surf_man->hw_info.allow_2d = 0;
1215a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    version = drmGetVersion(surf_man->fd);
1216a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (version && version->version_minor >= 33) {
1217a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array)) {
1218a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            surf_man->hw_info.allow_2d = 1;
1219a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
1220a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1221a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    drmFreeVersion(version);
1222a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1223a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    switch (tiling_config & 0xf) {
1224a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    case 0:
1225a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.num_pipes = 1;
1226a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        break;
1227a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    case 1:
1228a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.num_pipes = 2;
1229a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        break;
1230a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    case 2:
1231a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.num_pipes = 4;
1232a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        break;
1233a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    case 3:
1234a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.num_pipes = 8;
1235a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        break;
1236a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    default:
1237a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.num_pipes = 8;
1238a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.allow_2d = 0;
1239a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        break;
1240a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1241a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1242a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    switch ((tiling_config & 0xf0) >> 4) {
1243a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    case 0:
1244a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.num_banks = 4;
1245a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        break;
1246a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    case 1:
1247a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.num_banks = 8;
1248a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        break;
1249a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    case 2:
1250a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.num_banks = 16;
1251a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        break;
1252a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    default:
1253a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.num_banks = 8;
1254a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.allow_2d = 0;
1255a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        break;
1256a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1257a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1258a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    switch ((tiling_config & 0xf00) >> 8) {
1259a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    case 0:
1260a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.group_bytes = 256;
1261a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        break;
1262a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    case 1:
1263a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.group_bytes = 512;
1264a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        break;
1265a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    default:
1266a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.group_bytes = 256;
1267a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.allow_2d = 0;
1268a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        break;
1269a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1270a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1271a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    switch ((tiling_config & 0xf000) >> 12) {
1272a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    case 0:
1273a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.row_size = 1024;
1274a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        break;
1275a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    case 1:
1276a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.row_size = 2048;
1277a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        break;
1278a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    case 2:
1279a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.row_size = 4096;
1280a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        break;
1281a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    default:
1282a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.row_size = 4096;
1283a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->hw_info.allow_2d = 0;
1284a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        break;
1285a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1286a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    return 0;
1287a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse}
1288a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1289a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glissestatic int si_surface_sanity(struct radeon_surface_manager *surf_man,
1290a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                             struct radeon_surface *surf,
1291a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                             unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
1292a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse{
1293a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    uint32_t gb_tile_mode;
1294a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1295a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    /* check surface dimension */
1296a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
1297a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        return -EINVAL;
1298a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1299a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1300a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    /* check mipmap last_level */
1301a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (surf->last_level > 15) {
1302a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        return -EINVAL;
1303a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1304a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1305a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    /* force 1d on kernel that can't do 2d */
1306a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (mode > RADEON_SURF_MODE_1D &&
1307a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
1308a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        if (surf->nsamples > 1) {
1309a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
1310a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            return -EFAULT;
1311a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
1312a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        mode = RADEON_SURF_MODE_1D;
1313a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1314a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf->flags |= RADEON_SURF_SET(mode, MODE);
1315a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1316a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1317a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
1318a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        return -EINVAL;
1319a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1320a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1321a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (!surf->tile_split) {
1322a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        /* default value */
1323a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf->mtilea = 1;
1324a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf->bankw = 1;
1325391bba9c4cd2825eadaa648df10e3d1c99c66e80Maks Naumov        surf->bankh = 1;
1326a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf->tile_split = 64;
1327a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf->stencil_tile_split = 64;
1328a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1329a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1330a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    switch (mode) {
1331a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    case RADEON_SURF_MODE_2D:
1332a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        if (surf->flags & RADEON_SURF_SBUFFER) {
1333a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            switch (surf->nsamples) {
1334a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case 1:
1335a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1336a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                break;
1337a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case 2:
1338a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1339a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                break;
1340a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case 4:
1341a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1342a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                break;
1343a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case 8:
1344a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1345a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                break;
1346a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            default:
1347a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                return -EINVAL;
1348a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            }
1349a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            /* retrieve tiling mode value */
1350a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            gb_tile_mode = surf_man->hw_info.tile_mode_array[*stencil_tile_mode];
1351a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            si_gb_tile_mode(gb_tile_mode, NULL, NULL, NULL, NULL, NULL, &surf->stencil_tile_split);
1352a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
1353a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        if (surf->flags & RADEON_SURF_ZBUFFER) {
1354a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            switch (surf->nsamples) {
1355a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case 1:
1356a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1357a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                break;
1358a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case 2:
1359a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1360a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                break;
1361a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case 4:
1362a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1363a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                break;
1364a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case 8:
1365a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1366a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                break;
1367a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            default:
1368a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                return -EINVAL;
1369a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            }
1370a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        } else if (surf->flags & RADEON_SURF_SCANOUT) {
1371a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            switch (surf->bpe) {
1372a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case 2:
1373a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
1374a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                break;
1375a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case 4:
1376a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
1377a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                break;
1378a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            default:
1379a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                return -EINVAL;
1380a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            }
1381a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        } else {
1382a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            switch (surf->bpe) {
1383a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case 1:
1384a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                *tile_mode = SI_TILE_MODE_COLOR_2D_8BPP;
1385a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                break;
1386a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case 2:
1387a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                *tile_mode = SI_TILE_MODE_COLOR_2D_16BPP;
1388a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                break;
1389a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case 4:
1390a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                *tile_mode = SI_TILE_MODE_COLOR_2D_32BPP;
1391a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                break;
1392a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case 8:
1393a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case 16:
1394a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                *tile_mode = SI_TILE_MODE_COLOR_2D_64BPP;
1395a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                break;
1396a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            default:
1397a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                return -EINVAL;
1398a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            }
1399a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
1400a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        /* retrieve tiling mode value */
1401a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        gb_tile_mode = surf_man->hw_info.tile_mode_array[*tile_mode];
1402a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        si_gb_tile_mode(gb_tile_mode, NULL, NULL, &surf->mtilea, &surf->bankw, &surf->bankh, &surf->tile_split);
1403a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        break;
1404a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    case RADEON_SURF_MODE_1D:
1405a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        if (surf->flags & RADEON_SURF_SBUFFER) {
140667d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1407a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
1408a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        if (surf->flags & RADEON_SURF_ZBUFFER) {
140967d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1410a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        } else if (surf->flags & RADEON_SURF_SCANOUT) {
1411a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1412a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        } else {
1413a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            *tile_mode = SI_TILE_MODE_COLOR_1D;
1414a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
1415a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        break;
1416a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    case RADEON_SURF_MODE_LINEAR_ALIGNED:
1417a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    default:
1418a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
1419a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1420a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1421a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    return 0;
1422a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse}
14238572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer
1424303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzerstatic void si_surf_minify(struct radeon_surface *surf,
1425a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                           struct radeon_surface_level *surflevel,
1426a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                           unsigned bpe, unsigned level,
1427a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                           uint32_t xalign, uint32_t yalign, uint32_t zalign,
1428c3deddd9c2bf54fa6bec3dbd9ec7eae5fa22e220Michel Dänzer                           uint32_t slice_align, uint64_t offset)
14298572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer{
143075f747b919e1b1cd852eeaa8e662e72273189fb2Marek Olšák    if (level == 0) {
143175f747b919e1b1cd852eeaa8e662e72273189fb2Marek Olšák        surflevel->npix_x = surf->npix_x;
143275f747b919e1b1cd852eeaa8e662e72273189fb2Marek Olšák    } else {
143375f747b919e1b1cd852eeaa8e662e72273189fb2Marek Olšák        surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
143475f747b919e1b1cd852eeaa8e662e72273189fb2Marek Olšák    }
1435303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    surflevel->npix_y = mip_minify(surf->npix_y, level);
1436303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    surflevel->npix_z = mip_minify(surf->npix_z, level);
143745083e6d36125c64267c917da3d81e1e144ed33dMichel Dänzer
143845083e6d36125c64267c917da3d81e1e144ed33dMichel Dänzer    if (level == 0 && surf->last_level > 0) {
1439303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer        surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1440303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer        surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1441303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer        surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
144245083e6d36125c64267c917da3d81e1e144ed33dMichel Dänzer    } else {
1443303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer        surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1444303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer        surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1445303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer        surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
144645083e6d36125c64267c917da3d81e1e144ed33dMichel Dänzer    }
14478572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer
1448303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    surflevel->nblk_y  = ALIGN(surflevel->nblk_y, yalign);
1449303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer
1450b925022a3e4616665b388a78abab4e3270b4b4ecMichel Dänzer    /* XXX: Texture sampling uses unexpectedly large pitches in some cases,
1451b925022a3e4616665b388a78abab4e3270b4b4ecMichel Dänzer     * these are just guesses for the rules behind those
14528572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer     */
1453b925022a3e4616665b388a78abab4e3270b4b4ecMichel Dänzer    if (level == 0 && surf->last_level == 0)
1454b925022a3e4616665b388a78abab4e3270b4b4ecMichel Dänzer        /* Non-mipmap pitch padded to slice alignment */
1455f0e399d8f0c3c006687e0fc8e68268087607d5f5Michel Dänzer        /* Using just bpe here breaks stencil blitting; surf->bpe works. */
1456b925022a3e4616665b388a78abab4e3270b4b4ecMichel Dänzer        xalign = MAX2(xalign, slice_align / surf->bpe);
145775f747b919e1b1cd852eeaa8e662e72273189fb2Marek Olšák    else if (surflevel->mode == RADEON_SURF_MODE_LINEAR_ALIGNED)
1458b925022a3e4616665b388a78abab4e3270b4b4ecMichel Dänzer        /* Small rows evenly distributed across slice */
1459f0e399d8f0c3c006687e0fc8e68268087607d5f5Michel Dänzer        xalign = MAX2(xalign, slice_align / bpe / surflevel->nblk_y);
14608572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer
1461303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    surflevel->nblk_x  = ALIGN(surflevel->nblk_x, xalign);
1462303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    surflevel->nblk_z  = ALIGN(surflevel->nblk_z, zalign);
14638572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer
1464303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    surflevel->offset = offset;
1465f0e399d8f0c3c006687e0fc8e68268087607d5f5Michel Dänzer    surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
1466c3deddd9c2bf54fa6bec3dbd9ec7eae5fa22e220Michel Dänzer    surflevel->slice_size = ALIGN((uint64_t)surflevel->pitch_bytes * surflevel->nblk_y,
1467c3deddd9c2bf54fa6bec3dbd9ec7eae5fa22e220Michel Dänzer				  (uint64_t)slice_align);
14688572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer
1469303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
14708572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer}
14718572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer
1472a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glissestatic void si_surf_minify_2d(struct radeon_surface *surf,
1473a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                              struct radeon_surface_level *surflevel,
1474a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                              unsigned bpe, unsigned level, unsigned slice_pt,
1475a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                              uint32_t xalign, uint32_t yalign, uint32_t zalign,
1476c3deddd9c2bf54fa6bec3dbd9ec7eae5fa22e220Michel Dänzer                              unsigned mtileb, uint64_t offset)
1477a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse{
1478a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    unsigned mtile_pr, mtile_ps;
1479a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
148075f747b919e1b1cd852eeaa8e662e72273189fb2Marek Olšák    if (level == 0) {
148175f747b919e1b1cd852eeaa8e662e72273189fb2Marek Olšák        surflevel->npix_x = surf->npix_x;
148275f747b919e1b1cd852eeaa8e662e72273189fb2Marek Olšák    } else {
148375f747b919e1b1cd852eeaa8e662e72273189fb2Marek Olšák        surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
148475f747b919e1b1cd852eeaa8e662e72273189fb2Marek Olšák    }
1485a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    surflevel->npix_y = mip_minify(surf->npix_y, level);
1486a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    surflevel->npix_z = mip_minify(surf->npix_z, level);
1487a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1488a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (level == 0 && surf->last_level > 0) {
1489a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1490a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1491a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1492a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    } else {
1493a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1494a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1495a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1496a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1497a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1498e5e51c2110ebf6e1edaa14b7567c5d6a79008a90Marek Olšák    if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
1499e5e51c2110ebf6e1edaa14b7567c5d6a79008a90Marek Olšák        !(surf->flags & RADEON_SURF_FMASK)) {
1500a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
1501a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            surflevel->mode = RADEON_SURF_MODE_1D;
1502a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            return;
1503a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
1504a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1505a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    surflevel->nblk_x  = ALIGN(surflevel->nblk_x, xalign);
1506a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    surflevel->nblk_y  = ALIGN(surflevel->nblk_y, yalign);
1507a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    surflevel->nblk_z  = ALIGN(surflevel->nblk_z, zalign);
1508a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1509a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    /* macro tile per row */
1510a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    mtile_pr = surflevel->nblk_x / xalign;
1511a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    /* macro tile per slice */
1512a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    mtile_ps = (mtile_pr * surflevel->nblk_y) / yalign;
1513a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    surflevel->offset = offset;
1514c866dc7c00e7f5f219901a9a81bf456a24d29cd1Michel Dänzer    surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
1515c3deddd9c2bf54fa6bec3dbd9ec7eae5fa22e220Michel Dänzer    surflevel->slice_size = (uint64_t)mtile_ps * mtileb * slice_pt;
1516a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1517a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1518a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse}
1519a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
15208572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzerstatic int si_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
15218572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer                                          struct radeon_surface *surf,
1522a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                                          unsigned tile_mode,
15238572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer                                          uint64_t offset, unsigned start_level)
15248572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer{
15258572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    uint32_t xalign, yalign, zalign, slice_align;
15268572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    unsigned i;
15278572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer
15288572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    /* compute alignment */
15298572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    if (!start_level) {
15308572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
15318572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    }
15328572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    xalign = MAX2(8, 64 / surf->bpe);
15338572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    yalign = 1;
15348572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    zalign = 1;
15358572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    slice_align = MAX2(64 * surf->bpe, surf_man->hw_info.group_bytes);
15368572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer
15378572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    /* build mipmap tree */
15388572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    for (i = start_level; i <= surf->last_level; i++) {
15398572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
1540a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        si_surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, slice_align, offset);
1541303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer        /* level0 and first mipmap need to have alignment */
1542303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer        offset = surf->bo_size;
154372f84b85afbe762b86ea8c095fee01e7d406b131Thomas Klausner        if (i == 0) {
1544303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer            offset = ALIGN(offset, surf->bo_alignment);
1545303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer        }
1546a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1547a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            surf->tiling_index[i] = tile_mode;
1548a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
1549303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    }
1550303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    return 0;
1551303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer}
1552303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer
1553303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzerstatic int si_surface_init_1d(struct radeon_surface_manager *surf_man,
1554303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer                              struct radeon_surface *surf,
1555303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer                              struct radeon_surface_level *level,
1556a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                              unsigned bpe, unsigned tile_mode,
1557303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer                              uint64_t offset, unsigned start_level)
1558303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer{
1559303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    uint32_t xalign, yalign, zalign, slice_align;
1560ce8af454259279c14c44bcd32c429640ca5e1691Michel Dänzer    unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
1561303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    unsigned i;
1562303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer
1563303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    /* compute alignment */
1564303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    xalign = 8;
1565303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    yalign = 8;
1566303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    zalign = 1;
1567303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    slice_align = surf_man->hw_info.group_bytes;
1568303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    if (surf->flags & RADEON_SURF_SCANOUT) {
1569303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer        xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
1570303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    }
1571303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer
1572ce8af454259279c14c44bcd32c429640ca5e1691Michel Dänzer    if (start_level <= 1) {
1573ce8af454259279c14c44bcd32c429640ca5e1691Michel Dänzer        surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1574303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer
1575303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer        if (offset) {
1576ce8af454259279c14c44bcd32c429640ca5e1691Michel Dänzer            offset = ALIGN(offset, alignment);
1577303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer        }
1578303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    }
1579303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer
1580303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    /* build mipmap tree */
1581303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    for (i = start_level; i <= surf->last_level; i++) {
1582303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer        level[i].mode = RADEON_SURF_MODE_1D;
1583303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer        si_surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, slice_align, offset);
15848572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        /* level0 and first mipmap need to have alignment */
15858572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        offset = surf->bo_size;
158672f84b85afbe762b86ea8c095fee01e7d406b131Thomas Klausner        if (i == 0) {
1587ce8af454259279c14c44bcd32c429640ca5e1691Michel Dänzer            offset = ALIGN(offset, alignment);
15888572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        }
1589a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1590a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            if (surf->level == level) {
1591a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                surf->tiling_index[i] = tile_mode;
1592a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                /* it's ok because stencil is done after */
1593a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                surf->stencil_tiling_index[i] = tile_mode;
1594a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            } else {
1595a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                surf->stencil_tiling_index[i] = tile_mode;
1596a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            }
1597a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
15988572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    }
15998572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    return 0;
16008572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer}
16018572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer
1602303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzerstatic int si_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
1603a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                                       struct radeon_surface *surf,
1604a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                                       unsigned tile_mode, unsigned stencil_tile_mode)
1605303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer{
1606a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    int r;
1607303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer
1608a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    r = si_surface_init_1d(surf_man, surf, surf->level, surf->bpe, tile_mode, 0, 0);
1609a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (r) {
1610303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer        return r;
1611a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1612303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer
1613a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (surf->flags & RADEON_SURF_SBUFFER) {
1614a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        r = si_surface_init_1d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode, surf->bo_size, 0);
1615a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf->stencil_offset = surf->stencil_level[0].offset;
1616a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1617a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    return r;
1618a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse}
1619a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1620a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glissestatic int si_surface_init_2d(struct radeon_surface_manager *surf_man,
1621a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                              struct radeon_surface *surf,
1622a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                              struct radeon_surface_level *level,
1623a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                              unsigned bpe, unsigned tile_mode,
1624a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                              unsigned num_pipes, unsigned num_banks,
1625a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                              unsigned tile_split,
1626a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                              uint64_t offset,
1627a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                              unsigned start_level)
1628a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse{
1629ce8af454259279c14c44bcd32c429640ca5e1691Michel Dänzer    uint64_t aligned_offset = offset;
1630a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    unsigned tilew, tileh, tileb;
1631a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    unsigned mtilew, mtileh, mtileb;
1632a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    unsigned slice_pt;
1633a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    unsigned i;
1634a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1635a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    /* compute tile values */
1636a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    tilew = 8;
1637a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    tileh = 8;
1638a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    tileb = tilew * tileh * bpe * surf->nsamples;
1639a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    /* slices per tile */
1640a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    slice_pt = 1;
16411543c96e154d6801cf725c3b511d61604a378e03Alex Deucher    if (tileb > tile_split && tile_split) {
1642a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        slice_pt = tileb / tile_split;
1643a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1644a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    tileb = tileb / slice_pt;
1645a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1646a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    /* macro tile width & height */
1647a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
1648a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
1649a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1650a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    /* macro tile bytes */
1651a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
1652a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1653ce8af454259279c14c44bcd32c429640ca5e1691Michel Dänzer    if (start_level <= 1) {
1654a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        unsigned alignment = MAX2(256, mtileb);
1655a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1656a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1657ce8af454259279c14c44bcd32c429640ca5e1691Michel Dänzer        if (aligned_offset) {
1658ce8af454259279c14c44bcd32c429640ca5e1691Michel Dänzer            aligned_offset = ALIGN(aligned_offset, alignment);
1659a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
1660a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1661a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1662a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    /* build mipmap tree */
1663a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    for (i = start_level; i <= surf->last_level; i++) {
1664a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        level[i].mode = RADEON_SURF_MODE_2D;
1665ce8af454259279c14c44bcd32c429640ca5e1691Michel Dänzer        si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
1666a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        if (level[i].mode == RADEON_SURF_MODE_1D) {
1667a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            switch (tile_mode) {
1668a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case SI_TILE_MODE_COLOR_2D_8BPP:
1669a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case SI_TILE_MODE_COLOR_2D_16BPP:
1670a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case SI_TILE_MODE_COLOR_2D_32BPP:
1671a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case SI_TILE_MODE_COLOR_2D_64BPP:
1672a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                tile_mode = SI_TILE_MODE_COLOR_1D;
1673a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                break;
1674a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP:
1675a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP:
1676a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1677a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                break;
1678a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            case SI_TILE_MODE_DEPTH_STENCIL_2D:
167967d92404d62044972599dcef3011d17fca46eed5Marek Olšák                tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1680a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                break;
1681a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            default:
1682a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                return -EINVAL;
1683a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            }
1684a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
1685a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
1686a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        /* level0 and first mipmap need to have alignment */
1687c8a437f4c76527b3c8385699ccee07f35fe3f166Michel Dänzer        aligned_offset = offset = surf->bo_size;
168872f84b85afbe762b86ea8c095fee01e7d406b131Thomas Klausner        if (i == 0) {
1689ce8af454259279c14c44bcd32c429640ca5e1691Michel Dänzer            aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
1690a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
1691a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1692a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            if (surf->level == level) {
1693a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                surf->tiling_index[i] = tile_mode;
1694a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                /* it's ok because stencil is done after */
1695a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                surf->stencil_tiling_index[i] = tile_mode;
1696a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            } else {
1697a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                surf->stencil_tiling_index[i] = tile_mode;
1698a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            }
1699a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
1700a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1701a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    return 0;
1702a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse}
1703a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1704a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glissestatic int si_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
1705a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                                       struct radeon_surface *surf,
1706a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                                       unsigned tile_mode, unsigned stencil_tile_mode)
1707a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse{
1708a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    unsigned num_pipes, num_banks;
1709a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    uint32_t gb_tile_mode;
1710a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    int r;
1711a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1712a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    /* retrieve tiling mode value */
1713a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1714a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    si_gb_tile_mode(gb_tile_mode, &num_pipes, &num_banks, NULL, NULL, NULL, NULL);
1715a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1716a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    r = si_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode, num_pipes, num_banks, surf->tile_split, 0, 0);
1717a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (r) {
1718a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        return r;
1719a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1720a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1721a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (surf->flags & RADEON_SURF_SBUFFER) {
1722a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        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);
1723a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf->stencil_offset = surf->stencil_level[0].offset;
1724303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    }
1725303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer    return r;
1726303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer}
1727303ca37e722e68900cb7eb43ddbef8069b0c711bMichel Dänzer
17288572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzerstatic int si_surface_init(struct radeon_surface_manager *surf_man,
17298572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer                           struct radeon_surface *surf)
17308572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer{
1731a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    unsigned mode, tile_mode, stencil_tile_mode;
17328572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    int r;
17338572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer
17348572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    /* MSAA surfaces support the 2D mode only. */
17358572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    if (surf->nsamples > 1) {
17368572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
17378572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
17388572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    }
17398572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer
17408572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    /* tiling mode */
17418572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
17428572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer
17438572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
17448572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        /* zbuffer only support 1D or 2D tiled surface */
17458572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        switch (mode) {
17468572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        case RADEON_SURF_MODE_1D:
17478572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        case RADEON_SURF_MODE_2D:
17488572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer            break;
17498572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        default:
17508572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer            mode = RADEON_SURF_MODE_1D;
17518572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer            surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
17528572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer            surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
17538572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer            break;
17548572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        }
17558572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    }
17568572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer
1757a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    r = si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
17588572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    if (r) {
17598572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        return r;
17608572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    }
17618572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer
17628572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    surf->stencil_offset = 0;
17631aebfdc1121ccb6babb3a63dc0b99d68b4860b04Marek Olšák    surf->bo_alignment = 0;
17648572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer
17658572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    /* check tiling mode */
17668572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    switch (mode) {
17678572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    case RADEON_SURF_MODE_LINEAR:
17688572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        r = r6_surface_init_linear(surf_man, surf, 0, 0);
17698572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        break;
17708572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    case RADEON_SURF_MODE_LINEAR_ALIGNED:
1771a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
17728572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        break;
17738572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    case RADEON_SURF_MODE_1D:
1774a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
17758572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        break;
17768572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    case RADEON_SURF_MODE_2D:
1777a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        r = si_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
17788572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        break;
17798572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    default:
17808572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer        return -EINVAL;
17818572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    }
17828572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer    return r;
17838572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer}
17848572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer
1785a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse/*
1786a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse * depending on surface
1787a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse */
1788a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glissestatic int si_surface_best(struct radeon_surface_manager *surf_man,
1789a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse                           struct radeon_surface *surf)
1790a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse{
1791a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    unsigned mode, tile_mode, stencil_tile_mode;
1792a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1793a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    /* tiling mode */
1794a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1795a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1796a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
1797a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
1798a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        /* depth/stencil force 1d tiling for old mesa */
1799a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1800a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1801a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    }
1802a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1803a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    return si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1804a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse}
1805a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
1806a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse
18078572444fd0cda3e7b9557c09d2d0f7a9e049a2e7Michel Dänzer/* ===========================================================================
180867d92404d62044972599dcef3011d17fca46eed5Marek Olšák * Sea Islands family
180967d92404d62044972599dcef3011d17fca46eed5Marek Olšák */
181067d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define CIK__GB_TILE_MODE__PIPE_CONFIG(x)        (((x) >> 6) & 0x1f)
181167d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__PIPE_CONFIG__ADDR_SURF_P2               0
181267d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16          4
181367d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16         5
181467d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32         6
181567d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32         7
181667d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16    8
181767d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16    9
181867d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16    10
181967d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16   11
182067d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16   12
182167d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32   13
182267d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32   14
18233f4648902296efa3a8cc0abc941d978637f0ee28Marek Olšák#define     CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16   16
18243f4648902296efa3a8cc0abc941d978637f0ee28Marek Olšák#define     CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16  17
182567d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define CIK__GB_TILE_MODE__TILE_SPLIT(x)         (((x) >> 11) & 0x7)
182667d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__TILE_SPLIT__64B                         0
182767d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__TILE_SPLIT__128B                        1
182867d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__TILE_SPLIT__256B                        2
182967d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__TILE_SPLIT__512B                        3
183067d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__TILE_SPLIT__1024B                       4
183167d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__TILE_SPLIT__2048B                       5
183267d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__TILE_SPLIT__4096B                       6
183367d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define CIK__GB_TILE_MODE__SAMPLE_SPLIT(x)         (((x) >> 25) & 0x3)
183467d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__SAMPLE_SPLIT__1                         0
183567d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__SAMPLE_SPLIT__2                         1
183667d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__SAMPLE_SPLIT__4                         2
183767d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__SAMPLE_SPLIT__8                         3
183867d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define CIK__GB_MACROTILE_MODE__BANK_WIDTH(x)        ((x) & 0x3)
183967d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__BANK_WIDTH__1                           0
184067d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__BANK_WIDTH__2                           1
184167d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__BANK_WIDTH__4                           2
184267d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__BANK_WIDTH__8                           3
184367d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define CIK__GB_MACROTILE_MODE__BANK_HEIGHT(x)       (((x) >> 2) & 0x3)
184467d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__BANK_HEIGHT__1                          0
184567d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__BANK_HEIGHT__2                          1
184667d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__BANK_HEIGHT__4                          2
184767d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__BANK_HEIGHT__8                          3
184867d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 4) & 0x3)
184967d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__MACRO_TILE_ASPECT__1                    0
185067d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__MACRO_TILE_ASPECT__2                    1
185167d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__MACRO_TILE_ASPECT__4                    2
185267d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__MACRO_TILE_ASPECT__8                    3
185367d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define CIK__GB_MACROTILE_MODE__NUM_BANKS(x)         (((x) >> 6) & 0x3)
185467d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__NUM_BANKS__2_BANK                       0
185567d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__NUM_BANKS__4_BANK                       1
185667d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__NUM_BANKS__8_BANK                       2
185767d92404d62044972599dcef3011d17fca46eed5Marek Olšák#define     CIK__NUM_BANKS__16_BANK                      3
185867d92404d62044972599dcef3011d17fca46eed5Marek Olšák
185967d92404d62044972599dcef3011d17fca46eed5Marek Olšák
186067d92404d62044972599dcef3011d17fca46eed5Marek Olšákstatic void cik_get_2d_params(struct radeon_surface_manager *surf_man,
186167d92404d62044972599dcef3011d17fca46eed5Marek Olšák                              unsigned bpe, unsigned nsamples, bool is_color,
186267d92404d62044972599dcef3011d17fca46eed5Marek Olšák                              unsigned tile_mode,
186367d92404d62044972599dcef3011d17fca46eed5Marek Olšák                              uint32_t *num_pipes,
186467d92404d62044972599dcef3011d17fca46eed5Marek Olšák                              uint32_t *tile_split_ptr,
186567d92404d62044972599dcef3011d17fca46eed5Marek Olšák                              uint32_t *num_banks,
186667d92404d62044972599dcef3011d17fca46eed5Marek Olšák                              uint32_t *macro_tile_aspect,
186767d92404d62044972599dcef3011d17fca46eed5Marek Olšák                              uint32_t *bank_w,
186867d92404d62044972599dcef3011d17fca46eed5Marek Olšák                              uint32_t *bank_h)
186967d92404d62044972599dcef3011d17fca46eed5Marek Olšák{
187067d92404d62044972599dcef3011d17fca46eed5Marek Olšák    uint32_t gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
187167d92404d62044972599dcef3011d17fca46eed5Marek Olšák    unsigned tileb_1x, tileb;
187267d92404d62044972599dcef3011d17fca46eed5Marek Olšák    unsigned gb_macrotile_mode;
187367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    unsigned macrotile_index;
187467d92404d62044972599dcef3011d17fca46eed5Marek Olšák    unsigned tile_split, sample_split;
187567d92404d62044972599dcef3011d17fca46eed5Marek Olšák
187667d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (num_pipes) {
187767d92404d62044972599dcef3011d17fca46eed5Marek Olšák        switch (CIK__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
187867d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__PIPE_CONFIG__ADDR_SURF_P2:
187967d92404d62044972599dcef3011d17fca46eed5Marek Olšák        default:
188067d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *num_pipes = 2;
188167d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
188267d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16:
188367d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16:
188467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32:
188567d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32:
188667d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *num_pipes = 4;
188767d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
188867d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
188967d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
189067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
189167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
189267d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
189367d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
189467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
189567d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *num_pipes = 8;
189667d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
18973f4648902296efa3a8cc0abc941d978637f0ee28Marek Olšák        case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16:
18983f4648902296efa3a8cc0abc941d978637f0ee28Marek Olšák        case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16:
18993f4648902296efa3a8cc0abc941d978637f0ee28Marek Olšák            *num_pipes = 16;
19003f4648902296efa3a8cc0abc941d978637f0ee28Marek Olšák            break;
190167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        }
190267d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
190367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    switch (CIK__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
190467d92404d62044972599dcef3011d17fca46eed5Marek Olšák    default:
190567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case CIK__TILE_SPLIT__64B:
190667d92404d62044972599dcef3011d17fca46eed5Marek Olšák        tile_split = 64;
190767d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
190867d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case CIK__TILE_SPLIT__128B:
190967d92404d62044972599dcef3011d17fca46eed5Marek Olšák        tile_split = 128;
191067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
191167d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case CIK__TILE_SPLIT__256B:
191267d92404d62044972599dcef3011d17fca46eed5Marek Olšák        tile_split = 256;
191367d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
191467d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case CIK__TILE_SPLIT__512B:
191567d92404d62044972599dcef3011d17fca46eed5Marek Olšák        tile_split = 512;
191667d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
191767d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case CIK__TILE_SPLIT__1024B:
191867d92404d62044972599dcef3011d17fca46eed5Marek Olšák        tile_split = 1024;
191967d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
192067d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case CIK__TILE_SPLIT__2048B:
192167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        tile_split = 2048;
192267d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
192367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case CIK__TILE_SPLIT__4096B:
192467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        tile_split = 4096;
192567d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
192667d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
192767d92404d62044972599dcef3011d17fca46eed5Marek Olšák    switch (CIK__GB_TILE_MODE__SAMPLE_SPLIT(gb_tile_mode)) {
192867d92404d62044972599dcef3011d17fca46eed5Marek Olšák    default:
192967d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case CIK__SAMPLE_SPLIT__1:
193067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        sample_split = 1;
193167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
193267d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case CIK__SAMPLE_SPLIT__2:
19332169dce96c5503ef8f6e4bb008e989d0ef02ec8eMarek Olšák        sample_split = 2;
193467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
193567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case CIK__SAMPLE_SPLIT__4:
193667d92404d62044972599dcef3011d17fca46eed5Marek Olšák        sample_split = 4;
193767d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
193867d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case CIK__SAMPLE_SPLIT__8:
193967d92404d62044972599dcef3011d17fca46eed5Marek Olšák        sample_split = 8;
194067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
194167d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
194267d92404d62044972599dcef3011d17fca46eed5Marek Olšák
194367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    /* Adjust the tile split. */
194467d92404d62044972599dcef3011d17fca46eed5Marek Olšák    tileb_1x = 8 * 8 * bpe;
194567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (is_color) {
194667d92404d62044972599dcef3011d17fca46eed5Marek Olšák        tile_split = MAX2(256, sample_split * tileb_1x);
194767d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
194867d92404d62044972599dcef3011d17fca46eed5Marek Olšák    tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
194967d92404d62044972599dcef3011d17fca46eed5Marek Olšák
195067d92404d62044972599dcef3011d17fca46eed5Marek Olšák    /* Determine the macrotile index. */
195167d92404d62044972599dcef3011d17fca46eed5Marek Olšák    tileb = MIN2(tile_split, nsamples * tileb_1x);
195267d92404d62044972599dcef3011d17fca46eed5Marek Olšák
195367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    for (macrotile_index = 0; tileb > 64; macrotile_index++) {
195467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        tileb >>= 1;
195567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
195667d92404d62044972599dcef3011d17fca46eed5Marek Olšák    gb_macrotile_mode = surf_man->hw_info.macrotile_mode_array[macrotile_index];
195767d92404d62044972599dcef3011d17fca46eed5Marek Olšák
195867d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (tile_split_ptr) {
195967d92404d62044972599dcef3011d17fca46eed5Marek Olšák        *tile_split_ptr = tile_split;
196067d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
196167d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (num_banks) {
196267d92404d62044972599dcef3011d17fca46eed5Marek Olšák        switch (CIK__GB_MACROTILE_MODE__NUM_BANKS(gb_macrotile_mode)) {
196367d92404d62044972599dcef3011d17fca46eed5Marek Olšák        default:
196467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__NUM_BANKS__2_BANK:
196567d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *num_banks = 2;
196667d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
196767d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__NUM_BANKS__4_BANK:
196867d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *num_banks = 4;
196967d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
197067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__NUM_BANKS__8_BANK:
197167d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *num_banks = 8;
197267d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
197367d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__NUM_BANKS__16_BANK:
197467d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *num_banks = 16;
197567d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
197667d92404d62044972599dcef3011d17fca46eed5Marek Olšák        }
197767d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
197867d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (macro_tile_aspect) {
197967d92404d62044972599dcef3011d17fca46eed5Marek Olšák        switch (CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(gb_macrotile_mode)) {
198067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        default:
198167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__MACRO_TILE_ASPECT__1:
198267d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *macro_tile_aspect = 1;
198367d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
198467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__MACRO_TILE_ASPECT__2:
198567d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *macro_tile_aspect = 2;
198667d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
198767d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__MACRO_TILE_ASPECT__4:
198867d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *macro_tile_aspect = 4;
198967d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
199067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__MACRO_TILE_ASPECT__8:
199167d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *macro_tile_aspect = 8;
199267d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
199367d92404d62044972599dcef3011d17fca46eed5Marek Olšák        }
199467d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
199567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (bank_w) {
199667d92404d62044972599dcef3011d17fca46eed5Marek Olšák        switch (CIK__GB_MACROTILE_MODE__BANK_WIDTH(gb_macrotile_mode)) {
199767d92404d62044972599dcef3011d17fca46eed5Marek Olšák        default:
199867d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__BANK_WIDTH__1:
199967d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *bank_w = 1;
200067d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
200167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__BANK_WIDTH__2:
200267d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *bank_w = 2;
200367d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
200467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__BANK_WIDTH__4:
200567d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *bank_w = 4;
200667d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
200767d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__BANK_WIDTH__8:
200867d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *bank_w = 8;
200967d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
201067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        }
201167d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
201267d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (bank_h) {
201367d92404d62044972599dcef3011d17fca46eed5Marek Olšák        switch (CIK__GB_MACROTILE_MODE__BANK_HEIGHT(gb_macrotile_mode)) {
201467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        default:
201567d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__BANK_HEIGHT__1:
201667d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *bank_h = 1;
201767d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
201867d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__BANK_HEIGHT__2:
201967d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *bank_h = 2;
202067d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
202167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__BANK_HEIGHT__4:
202267d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *bank_h = 4;
202367d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
202467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case CIK__BANK_HEIGHT__8:
202567d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *bank_h = 8;
202667d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
202767d92404d62044972599dcef3011d17fca46eed5Marek Olšák        }
202867d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
202967d92404d62044972599dcef3011d17fca46eed5Marek Olšák}
203067d92404d62044972599dcef3011d17fca46eed5Marek Olšák
203167d92404d62044972599dcef3011d17fca46eed5Marek Olšákstatic int cik_init_hw_info(struct radeon_surface_manager *surf_man)
203267d92404d62044972599dcef3011d17fca46eed5Marek Olšák{
203367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    uint32_t tiling_config;
203467d92404d62044972599dcef3011d17fca46eed5Marek Olšák    drmVersionPtr version;
203567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    int r;
203667d92404d62044972599dcef3011d17fca46eed5Marek Olšák
203767d92404d62044972599dcef3011d17fca46eed5Marek Olšák    r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
203867d92404d62044972599dcef3011d17fca46eed5Marek Olšák                         &tiling_config);
203967d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (r) {
204067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        return r;
204167d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
204267d92404d62044972599dcef3011d17fca46eed5Marek Olšák
204367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    surf_man->hw_info.allow_2d = 0;
204467d92404d62044972599dcef3011d17fca46eed5Marek Olšák    version = drmGetVersion(surf_man->fd);
204567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (version && version->version_minor >= 35) {
204667d92404d62044972599dcef3011d17fca46eed5Marek Olšák        if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array) &&
204767d92404d62044972599dcef3011d17fca46eed5Marek Olšák	    !radeon_get_value(surf_man->fd, RADEON_INFO_CIK_MACROTILE_MODE_ARRAY, surf_man->hw_info.macrotile_mode_array)) {
204867d92404d62044972599dcef3011d17fca46eed5Marek Olšák            surf_man->hw_info.allow_2d = 1;
204967d92404d62044972599dcef3011d17fca46eed5Marek Olšák        }
205067d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
205167d92404d62044972599dcef3011d17fca46eed5Marek Olšák    drmFreeVersion(version);
205267d92404d62044972599dcef3011d17fca46eed5Marek Olšák
205367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    switch (tiling_config & 0xf) {
205467d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case 0:
205567d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.num_pipes = 1;
205667d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
205767d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case 1:
205867d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.num_pipes = 2;
205967d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
206067d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case 2:
206167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.num_pipes = 4;
206267d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
206367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case 3:
206467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.num_pipes = 8;
206567d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
206667d92404d62044972599dcef3011d17fca46eed5Marek Olšák    default:
206767d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.num_pipes = 8;
206867d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.allow_2d = 0;
206967d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
207067d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
207167d92404d62044972599dcef3011d17fca46eed5Marek Olšák
207267d92404d62044972599dcef3011d17fca46eed5Marek Olšák    switch ((tiling_config & 0xf0) >> 4) {
207367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case 0:
207467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.num_banks = 4;
207567d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
207667d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case 1:
207767d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.num_banks = 8;
207867d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
207967d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case 2:
208067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.num_banks = 16;
208167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
208267d92404d62044972599dcef3011d17fca46eed5Marek Olšák    default:
208367d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.num_banks = 8;
208467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.allow_2d = 0;
208567d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
208667d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
208767d92404d62044972599dcef3011d17fca46eed5Marek Olšák
208867d92404d62044972599dcef3011d17fca46eed5Marek Olšák    switch ((tiling_config & 0xf00) >> 8) {
208967d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case 0:
209067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.group_bytes = 256;
209167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
209267d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case 1:
209367d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.group_bytes = 512;
209467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
209567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    default:
209667d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.group_bytes = 256;
209767d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.allow_2d = 0;
209867d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
209967d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
210067d92404d62044972599dcef3011d17fca46eed5Marek Olšák
210167d92404d62044972599dcef3011d17fca46eed5Marek Olšák    switch ((tiling_config & 0xf000) >> 12) {
210267d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case 0:
210367d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.row_size = 1024;
210467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
210567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case 1:
210667d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.row_size = 2048;
210767d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
210867d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case 2:
210967d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.row_size = 4096;
211067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
211167d92404d62044972599dcef3011d17fca46eed5Marek Olšák    default:
211267d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.row_size = 4096;
211367d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->hw_info.allow_2d = 0;
211467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
211567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
211667d92404d62044972599dcef3011d17fca46eed5Marek Olšák    return 0;
211767d92404d62044972599dcef3011d17fca46eed5Marek Olšák}
211867d92404d62044972599dcef3011d17fca46eed5Marek Olšák
211967d92404d62044972599dcef3011d17fca46eed5Marek Olšákstatic int cik_surface_sanity(struct radeon_surface_manager *surf_man,
212067d92404d62044972599dcef3011d17fca46eed5Marek Olšák                              struct radeon_surface *surf,
212167d92404d62044972599dcef3011d17fca46eed5Marek Olšák                              unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
212267d92404d62044972599dcef3011d17fca46eed5Marek Olšák{
212367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    /* check surface dimension */
212467d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
212567d92404d62044972599dcef3011d17fca46eed5Marek Olšák        return -EINVAL;
212667d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
212767d92404d62044972599dcef3011d17fca46eed5Marek Olšák
212867d92404d62044972599dcef3011d17fca46eed5Marek Olšák    /* check mipmap last_level */
212967d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (surf->last_level > 15) {
213067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        return -EINVAL;
213167d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
213267d92404d62044972599dcef3011d17fca46eed5Marek Olšák
213367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    /* force 1d on kernel that can't do 2d */
213467d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (mode > RADEON_SURF_MODE_1D &&
213567d92404d62044972599dcef3011d17fca46eed5Marek Olšák        (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
213667d92404d62044972599dcef3011d17fca46eed5Marek Olšák        if (surf->nsamples > 1) {
213767d92404d62044972599dcef3011d17fca46eed5Marek Olšák            fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
213867d92404d62044972599dcef3011d17fca46eed5Marek Olšák            return -EFAULT;
213967d92404d62044972599dcef3011d17fca46eed5Marek Olšák        }
214067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        mode = RADEON_SURF_MODE_1D;
214167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
214267d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf->flags |= RADEON_SURF_SET(mode, MODE);
214367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
214467d92404d62044972599dcef3011d17fca46eed5Marek Olšák
214567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
214667d92404d62044972599dcef3011d17fca46eed5Marek Olšák        return -EINVAL;
214767d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
214867d92404d62044972599dcef3011d17fca46eed5Marek Olšák
214967d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (!surf->tile_split) {
215067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        /* default value */
215167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf->mtilea = 1;
215267d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf->bankw = 1;
2153391bba9c4cd2825eadaa648df10e3d1c99c66e80Maks Naumov        surf->bankh = 1;
215467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf->tile_split = 64;
215567d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf->stencil_tile_split = 64;
215667d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
215767d92404d62044972599dcef3011d17fca46eed5Marek Olšák
215867d92404d62044972599dcef3011d17fca46eed5Marek Olšák    switch (mode) {
215967d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case RADEON_SURF_MODE_2D: {
216067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        if (surf->flags & RADEON_SURF_Z_OR_SBUFFER) {
216167d92404d62044972599dcef3011d17fca46eed5Marek Olšák            switch (surf->nsamples) {
216267d92404d62044972599dcef3011d17fca46eed5Marek Olšák            case 1:
216367d92404d62044972599dcef3011d17fca46eed5Marek Olšák                *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64;
216467d92404d62044972599dcef3011d17fca46eed5Marek Olšák                break;
216567d92404d62044972599dcef3011d17fca46eed5Marek Olšák            case 2:
216667d92404d62044972599dcef3011d17fca46eed5Marek Olšák            case 4:
216767d92404d62044972599dcef3011d17fca46eed5Marek Olšák                *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128;
216867d92404d62044972599dcef3011d17fca46eed5Marek Olšák                break;
216967d92404d62044972599dcef3011d17fca46eed5Marek Olšák            case 8:
217067d92404d62044972599dcef3011d17fca46eed5Marek Olšák                *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256;
217167d92404d62044972599dcef3011d17fca46eed5Marek Olšák                break;
217267d92404d62044972599dcef3011d17fca46eed5Marek Olšák            default:
217367d92404d62044972599dcef3011d17fca46eed5Marek Olšák                return -EINVAL;
217467d92404d62044972599dcef3011d17fca46eed5Marek Olšák            }
217567d92404d62044972599dcef3011d17fca46eed5Marek Olšák
217667d92404d62044972599dcef3011d17fca46eed5Marek Olšák            if (surf->flags & RADEON_SURF_SBUFFER) {
217767d92404d62044972599dcef3011d17fca46eed5Marek Olšák                *stencil_tile_mode = *tile_mode;
217867d92404d62044972599dcef3011d17fca46eed5Marek Olšák
217967d92404d62044972599dcef3011d17fca46eed5Marek Olšák                cik_get_2d_params(surf_man, 1, surf->nsamples, false,
218067d92404d62044972599dcef3011d17fca46eed5Marek Olšák                                  *stencil_tile_mode, NULL,
218167d92404d62044972599dcef3011d17fca46eed5Marek Olšák                                  &surf->stencil_tile_split,
218267d92404d62044972599dcef3011d17fca46eed5Marek Olšák                                  NULL, NULL, NULL, NULL);
218367d92404d62044972599dcef3011d17fca46eed5Marek Olšák            }
218467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        } else if (surf->flags & RADEON_SURF_SCANOUT) {
218567d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *tile_mode = CIK_TILE_MODE_COLOR_2D_SCANOUT;
218667d92404d62044972599dcef3011d17fca46eed5Marek Olšák        } else {
218767d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *tile_mode = CIK_TILE_MODE_COLOR_2D;
218867d92404d62044972599dcef3011d17fca46eed5Marek Olšák        }
218967d92404d62044972599dcef3011d17fca46eed5Marek Olšák
219067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        /* retrieve tiling mode values */
219167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
219267d92404d62044972599dcef3011d17fca46eed5Marek Olšák                          !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), *tile_mode,
219367d92404d62044972599dcef3011d17fca46eed5Marek Olšák                          NULL, &surf->tile_split, NULL, &surf->mtilea,
219467d92404d62044972599dcef3011d17fca46eed5Marek Olšák                          &surf->bankw, &surf->bankh);
219567d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
219667d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
219767d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case RADEON_SURF_MODE_1D:
219867d92404d62044972599dcef3011d17fca46eed5Marek Olšák        if (surf->flags & RADEON_SURF_SBUFFER) {
219967d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *stencil_tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
220067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        }
220167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        if (surf->flags & RADEON_SURF_ZBUFFER) {
220267d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
220367d92404d62044972599dcef3011d17fca46eed5Marek Olšák        } else if (surf->flags & RADEON_SURF_SCANOUT) {
220467d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
220567d92404d62044972599dcef3011d17fca46eed5Marek Olšák        } else {
220667d92404d62044972599dcef3011d17fca46eed5Marek Olšák            *tile_mode = SI_TILE_MODE_COLOR_1D;
220767d92404d62044972599dcef3011d17fca46eed5Marek Olšák        }
220867d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
220967d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case RADEON_SURF_MODE_LINEAR_ALIGNED:
221067d92404d62044972599dcef3011d17fca46eed5Marek Olšák    default:
221167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
221267d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
221367d92404d62044972599dcef3011d17fca46eed5Marek Olšák
221467d92404d62044972599dcef3011d17fca46eed5Marek Olšák    return 0;
221567d92404d62044972599dcef3011d17fca46eed5Marek Olšák}
221667d92404d62044972599dcef3011d17fca46eed5Marek Olšák
221767d92404d62044972599dcef3011d17fca46eed5Marek Olšákstatic int cik_surface_init_2d(struct radeon_surface_manager *surf_man,
221867d92404d62044972599dcef3011d17fca46eed5Marek Olšák                               struct radeon_surface *surf,
221967d92404d62044972599dcef3011d17fca46eed5Marek Olšák                               struct radeon_surface_level *level,
222067d92404d62044972599dcef3011d17fca46eed5Marek Olšák                               unsigned bpe, unsigned tile_mode,
222167d92404d62044972599dcef3011d17fca46eed5Marek Olšák                               unsigned tile_split,
222267d92404d62044972599dcef3011d17fca46eed5Marek Olšák                               unsigned num_pipes, unsigned num_banks,
222367d92404d62044972599dcef3011d17fca46eed5Marek Olšák                               uint64_t offset,
222467d92404d62044972599dcef3011d17fca46eed5Marek Olšák                               unsigned start_level)
222567d92404d62044972599dcef3011d17fca46eed5Marek Olšák{
222667d92404d62044972599dcef3011d17fca46eed5Marek Olšák    uint64_t aligned_offset = offset;
222767d92404d62044972599dcef3011d17fca46eed5Marek Olšák    unsigned tilew, tileh, tileb_1x, tileb;
222867d92404d62044972599dcef3011d17fca46eed5Marek Olšák    unsigned mtilew, mtileh, mtileb;
222967d92404d62044972599dcef3011d17fca46eed5Marek Olšák    unsigned slice_pt;
223067d92404d62044972599dcef3011d17fca46eed5Marek Olšák    unsigned i;
223167d92404d62044972599dcef3011d17fca46eed5Marek Olšák
223267d92404d62044972599dcef3011d17fca46eed5Marek Olšák    /* compute tile values */
223367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    tilew = 8;
223467d92404d62044972599dcef3011d17fca46eed5Marek Olšák    tileh = 8;
223567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    tileb_1x = tilew * tileh * bpe;
223667d92404d62044972599dcef3011d17fca46eed5Marek Olšák
223767d92404d62044972599dcef3011d17fca46eed5Marek Olšák    tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
223867d92404d62044972599dcef3011d17fca46eed5Marek Olšák
223967d92404d62044972599dcef3011d17fca46eed5Marek Olšák    tileb = surf->nsamples * tileb_1x;
224067d92404d62044972599dcef3011d17fca46eed5Marek Olšák
224167d92404d62044972599dcef3011d17fca46eed5Marek Olšák    /* slices per tile */
224267d92404d62044972599dcef3011d17fca46eed5Marek Olšák    slice_pt = 1;
22431543c96e154d6801cf725c3b511d61604a378e03Alex Deucher    if (tileb > tile_split && tile_split) {
224467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        slice_pt = tileb / tile_split;
224567d92404d62044972599dcef3011d17fca46eed5Marek Olšák        tileb = tileb / slice_pt;
224667d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
224767d92404d62044972599dcef3011d17fca46eed5Marek Olšák
224867d92404d62044972599dcef3011d17fca46eed5Marek Olšák    /* macro tile width & height */
224967d92404d62044972599dcef3011d17fca46eed5Marek Olšák    mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
225067d92404d62044972599dcef3011d17fca46eed5Marek Olšák    mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
225167d92404d62044972599dcef3011d17fca46eed5Marek Olšák
225267d92404d62044972599dcef3011d17fca46eed5Marek Olšák    /* macro tile bytes */
225367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
225467d92404d62044972599dcef3011d17fca46eed5Marek Olšák
225567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (start_level <= 1) {
225667d92404d62044972599dcef3011d17fca46eed5Marek Olšák        unsigned alignment = MAX2(256, mtileb);
225767d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
225867d92404d62044972599dcef3011d17fca46eed5Marek Olšák
225967d92404d62044972599dcef3011d17fca46eed5Marek Olšák        if (aligned_offset) {
226067d92404d62044972599dcef3011d17fca46eed5Marek Olšák            aligned_offset = ALIGN(aligned_offset, alignment);
226167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        }
226267d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
226367d92404d62044972599dcef3011d17fca46eed5Marek Olšák
226467d92404d62044972599dcef3011d17fca46eed5Marek Olšák    /* build mipmap tree */
226567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    for (i = start_level; i <= surf->last_level; i++) {
226667d92404d62044972599dcef3011d17fca46eed5Marek Olšák        level[i].mode = RADEON_SURF_MODE_2D;
226767d92404d62044972599dcef3011d17fca46eed5Marek Olšák        si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
226867d92404d62044972599dcef3011d17fca46eed5Marek Olšák        if (level[i].mode == RADEON_SURF_MODE_1D) {
226967d92404d62044972599dcef3011d17fca46eed5Marek Olšák            switch (tile_mode) {
227067d92404d62044972599dcef3011d17fca46eed5Marek Olšák            case CIK_TILE_MODE_COLOR_2D:
227167d92404d62044972599dcef3011d17fca46eed5Marek Olšák                tile_mode = SI_TILE_MODE_COLOR_1D;
227267d92404d62044972599dcef3011d17fca46eed5Marek Olšák                break;
227367d92404d62044972599dcef3011d17fca46eed5Marek Olšák            case CIK_TILE_MODE_COLOR_2D_SCANOUT:
227467d92404d62044972599dcef3011d17fca46eed5Marek Olšák                tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
227567d92404d62044972599dcef3011d17fca46eed5Marek Olšák                break;
227667d92404d62044972599dcef3011d17fca46eed5Marek Olšák            case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64:
227767d92404d62044972599dcef3011d17fca46eed5Marek Olšák            case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128:
227867d92404d62044972599dcef3011d17fca46eed5Marek Olšák            case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256:
227967d92404d62044972599dcef3011d17fca46eed5Marek Olšák            case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512:
228067d92404d62044972599dcef3011d17fca46eed5Marek Olšák            case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE:
228167d92404d62044972599dcef3011d17fca46eed5Marek Olšák                tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
228267d92404d62044972599dcef3011d17fca46eed5Marek Olšák                break;
228367d92404d62044972599dcef3011d17fca46eed5Marek Olšák            default:
228467d92404d62044972599dcef3011d17fca46eed5Marek Olšák                return -EINVAL;
228567d92404d62044972599dcef3011d17fca46eed5Marek Olšák            }
228667d92404d62044972599dcef3011d17fca46eed5Marek Olšák            return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
228767d92404d62044972599dcef3011d17fca46eed5Marek Olšák        }
228867d92404d62044972599dcef3011d17fca46eed5Marek Olšák        /* level0 and first mipmap need to have alignment */
228967d92404d62044972599dcef3011d17fca46eed5Marek Olšák        aligned_offset = offset = surf->bo_size;
229067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        if (i == 0) {
229167d92404d62044972599dcef3011d17fca46eed5Marek Olšák            aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
229267d92404d62044972599dcef3011d17fca46eed5Marek Olšák        }
229367d92404d62044972599dcef3011d17fca46eed5Marek Olšák        if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
229467d92404d62044972599dcef3011d17fca46eed5Marek Olšák            if (surf->level == level) {
229567d92404d62044972599dcef3011d17fca46eed5Marek Olšák                surf->tiling_index[i] = tile_mode;
229667d92404d62044972599dcef3011d17fca46eed5Marek Olšák                /* it's ok because stencil is done after */
229767d92404d62044972599dcef3011d17fca46eed5Marek Olšák                surf->stencil_tiling_index[i] = tile_mode;
229867d92404d62044972599dcef3011d17fca46eed5Marek Olšák            } else {
229967d92404d62044972599dcef3011d17fca46eed5Marek Olšák                surf->stencil_tiling_index[i] = tile_mode;
230067d92404d62044972599dcef3011d17fca46eed5Marek Olšák            }
230167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        }
230267d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
230367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    return 0;
230467d92404d62044972599dcef3011d17fca46eed5Marek Olšák}
230567d92404d62044972599dcef3011d17fca46eed5Marek Olšák
230667d92404d62044972599dcef3011d17fca46eed5Marek Olšákstatic int cik_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
230767d92404d62044972599dcef3011d17fca46eed5Marek Olšák                                        struct radeon_surface *surf,
230867d92404d62044972599dcef3011d17fca46eed5Marek Olšák                                        unsigned tile_mode, unsigned stencil_tile_mode)
230967d92404d62044972599dcef3011d17fca46eed5Marek Olšák{
231067d92404d62044972599dcef3011d17fca46eed5Marek Olšák    int r;
231167d92404d62044972599dcef3011d17fca46eed5Marek Olšák    uint32_t num_pipes, num_banks;
231267d92404d62044972599dcef3011d17fca46eed5Marek Olšák
231367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
231467d92404d62044972599dcef3011d17fca46eed5Marek Olšák                        !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), tile_mode,
231567d92404d62044972599dcef3011d17fca46eed5Marek Olšák                        &num_pipes, NULL, &num_banks, NULL, NULL, NULL);
231667d92404d62044972599dcef3011d17fca46eed5Marek Olšák
231767d92404d62044972599dcef3011d17fca46eed5Marek Olšák    r = cik_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode,
231867d92404d62044972599dcef3011d17fca46eed5Marek Olšák                            surf->tile_split, num_pipes, num_banks, 0, 0);
231967d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (r) {
232067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        return r;
232167d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
232267d92404d62044972599dcef3011d17fca46eed5Marek Olšák
232367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (surf->flags & RADEON_SURF_SBUFFER) {
232467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        r = cik_surface_init_2d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode,
232567d92404d62044972599dcef3011d17fca46eed5Marek Olšák                                surf->stencil_tile_split, num_pipes, num_banks,
232667d92404d62044972599dcef3011d17fca46eed5Marek Olšák                                surf->bo_size, 0);
232767d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf->stencil_offset = surf->stencil_level[0].offset;
232867d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
232967d92404d62044972599dcef3011d17fca46eed5Marek Olšák    return r;
233067d92404d62044972599dcef3011d17fca46eed5Marek Olšák}
233167d92404d62044972599dcef3011d17fca46eed5Marek Olšák
233267d92404d62044972599dcef3011d17fca46eed5Marek Olšákstatic int cik_surface_init(struct radeon_surface_manager *surf_man,
233367d92404d62044972599dcef3011d17fca46eed5Marek Olšák                            struct radeon_surface *surf)
233467d92404d62044972599dcef3011d17fca46eed5Marek Olšák{
233567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    unsigned mode, tile_mode, stencil_tile_mode;
233667d92404d62044972599dcef3011d17fca46eed5Marek Olšák    int r;
233767d92404d62044972599dcef3011d17fca46eed5Marek Olšák
233867d92404d62044972599dcef3011d17fca46eed5Marek Olšák    /* MSAA surfaces support the 2D mode only. */
233967d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (surf->nsamples > 1) {
234067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
234167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
234267d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
234367d92404d62044972599dcef3011d17fca46eed5Marek Olšák
234467d92404d62044972599dcef3011d17fca46eed5Marek Olšák    /* tiling mode */
234567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
234667d92404d62044972599dcef3011d17fca46eed5Marek Olšák
234767d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
234867d92404d62044972599dcef3011d17fca46eed5Marek Olšák        /* zbuffer only support 1D or 2D tiled surface */
234967d92404d62044972599dcef3011d17fca46eed5Marek Olšák        switch (mode) {
235067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case RADEON_SURF_MODE_1D:
235167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        case RADEON_SURF_MODE_2D:
235267d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
235367d92404d62044972599dcef3011d17fca46eed5Marek Olšák        default:
235467d92404d62044972599dcef3011d17fca46eed5Marek Olšák            mode = RADEON_SURF_MODE_1D;
235567d92404d62044972599dcef3011d17fca46eed5Marek Olšák            surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
235667d92404d62044972599dcef3011d17fca46eed5Marek Olšák            surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
235767d92404d62044972599dcef3011d17fca46eed5Marek Olšák            break;
235867d92404d62044972599dcef3011d17fca46eed5Marek Olšák        }
235967d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
236067d92404d62044972599dcef3011d17fca46eed5Marek Olšák
236167d92404d62044972599dcef3011d17fca46eed5Marek Olšák    r = cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
236267d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (r) {
236367d92404d62044972599dcef3011d17fca46eed5Marek Olšák        return r;
236467d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
236567d92404d62044972599dcef3011d17fca46eed5Marek Olšák
236667d92404d62044972599dcef3011d17fca46eed5Marek Olšák    surf->stencil_offset = 0;
236767d92404d62044972599dcef3011d17fca46eed5Marek Olšák    surf->bo_alignment = 0;
236867d92404d62044972599dcef3011d17fca46eed5Marek Olšák
236967d92404d62044972599dcef3011d17fca46eed5Marek Olšák    /* check tiling mode */
237067d92404d62044972599dcef3011d17fca46eed5Marek Olšák    switch (mode) {
237167d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case RADEON_SURF_MODE_LINEAR:
237267d92404d62044972599dcef3011d17fca46eed5Marek Olšák        r = r6_surface_init_linear(surf_man, surf, 0, 0);
237367d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
237467d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case RADEON_SURF_MODE_LINEAR_ALIGNED:
237567d92404d62044972599dcef3011d17fca46eed5Marek Olšák        r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
237667d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
237767d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case RADEON_SURF_MODE_1D:
237867d92404d62044972599dcef3011d17fca46eed5Marek Olšák        r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
237967d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
238067d92404d62044972599dcef3011d17fca46eed5Marek Olšák    case RADEON_SURF_MODE_2D:
238167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        r = cik_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
238267d92404d62044972599dcef3011d17fca46eed5Marek Olšák        break;
238367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    default:
238467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        return -EINVAL;
238567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
238667d92404d62044972599dcef3011d17fca46eed5Marek Olšák    return r;
238767d92404d62044972599dcef3011d17fca46eed5Marek Olšák}
238867d92404d62044972599dcef3011d17fca46eed5Marek Olšák
238967d92404d62044972599dcef3011d17fca46eed5Marek Olšák/*
239067d92404d62044972599dcef3011d17fca46eed5Marek Olšák * depending on surface
239167d92404d62044972599dcef3011d17fca46eed5Marek Olšák */
239267d92404d62044972599dcef3011d17fca46eed5Marek Olšákstatic int cik_surface_best(struct radeon_surface_manager *surf_man,
239367d92404d62044972599dcef3011d17fca46eed5Marek Olšák                            struct radeon_surface *surf)
239467d92404d62044972599dcef3011d17fca46eed5Marek Olšák{
239567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    unsigned mode, tile_mode, stencil_tile_mode;
239667d92404d62044972599dcef3011d17fca46eed5Marek Olšák
239767d92404d62044972599dcef3011d17fca46eed5Marek Olšák    /* tiling mode */
239867d92404d62044972599dcef3011d17fca46eed5Marek Olšák    mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
239967d92404d62044972599dcef3011d17fca46eed5Marek Olšák
240067d92404d62044972599dcef3011d17fca46eed5Marek Olšák    if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
240167d92404d62044972599dcef3011d17fca46eed5Marek Olšák        !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
240267d92404d62044972599dcef3011d17fca46eed5Marek Olšák        /* depth/stencil force 1d tiling for old mesa */
240367d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
240467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
240567d92404d62044972599dcef3011d17fca46eed5Marek Olšák    }
240667d92404d62044972599dcef3011d17fca46eed5Marek Olšák
240767d92404d62044972599dcef3011d17fca46eed5Marek Olšák    return cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
240867d92404d62044972599dcef3011d17fca46eed5Marek Olšák}
240967d92404d62044972599dcef3011d17fca46eed5Marek Olšák
241067d92404d62044972599dcef3011d17fca46eed5Marek Olšák
241167d92404d62044972599dcef3011d17fca46eed5Marek Olšák/* ===========================================================================
2412c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse * public API
2413c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse */
24140f8da82500ec542e269092c0718479e25eaff5f6Emil Velikovstruct radeon_surface_manager *
241558ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstradeon_surface_manager_new(int fd)
2416c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
2417c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    struct radeon_surface_manager *surf_man;
2418c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
2419c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    surf_man = calloc(1, sizeof(struct radeon_surface_manager));
2420c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (surf_man == NULL) {
2421c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return NULL;
2422c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
2423c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    surf_man->fd = fd;
2424c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (radeon_get_value(fd, RADEON_INFO_DEVICE_ID, &surf_man->device_id)) {
2425c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        goto out_err;
2426c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
2427c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (radeon_get_family(surf_man)) {
2428c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        goto out_err;
2429c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
2430c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
2431c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (surf_man->family <= CHIP_RV740) {
2432c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        if (r6_init_hw_info(surf_man)) {
2433c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            goto out_err;
2434c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
2435c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->surface_init = &r6_surface_init;
2436c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->surface_best = &r6_surface_best;
2437a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse    } else if (surf_man->family <= CHIP_ARUBA) {
2438c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        if (eg_init_hw_info(surf_man)) {
2439c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            goto out_err;
2440c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
2441a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->surface_init = &eg_surface_init;
2442c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        surf_man->surface_best = &eg_surface_best;
244367d92404d62044972599dcef3011d17fca46eed5Marek Olšák    } else if (surf_man->family < CHIP_BONAIRE) {
2444a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        if (si_init_hw_info(surf_man)) {
2445a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse            goto out_err;
2446a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        }
2447a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->surface_init = &si_surface_init;
2448a36cdb858e21f287d7b51ded2f211f1c84bda90bJerome Glisse        surf_man->surface_best = &si_surface_best;
244967d92404d62044972599dcef3011d17fca46eed5Marek Olšák    } else {
245067d92404d62044972599dcef3011d17fca46eed5Marek Olšák        if (cik_init_hw_info(surf_man)) {
245167d92404d62044972599dcef3011d17fca46eed5Marek Olšák            goto out_err;
245267d92404d62044972599dcef3011d17fca46eed5Marek Olšák        }
245367d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->surface_init = &cik_surface_init;
245467d92404d62044972599dcef3011d17fca46eed5Marek Olšák        surf_man->surface_best = &cik_surface_best;
2455c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
2456c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
2457c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return surf_man;
2458c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisseout_err:
2459c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    free(surf_man);
2460c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return NULL;
2461c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
2462c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
24630f8da82500ec542e269092c0718479e25eaff5f6Emil Velikovvoid
246458ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstradeon_surface_manager_free(struct radeon_surface_manager *surf_man)
2465c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
2466c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    free(surf_man);
2467c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
2468c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
2469c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glissestatic int radeon_surface_sanity(struct radeon_surface_manager *surf_man,
2470c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                                 struct radeon_surface *surf,
2471c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                                 unsigned type,
2472c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse                                 unsigned mode)
2473c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
2474c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (surf_man == NULL || surf_man->surface_init == NULL || surf == NULL) {
2475c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return -EINVAL;
2476c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
2477c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
2478c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* all dimension must be at least 1 ! */
2479c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (!surf->npix_x || !surf->npix_y || !surf->npix_z) {
2480c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return -EINVAL;
2481c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
248210c0837780b2d4a33568c16bb92527e196d6c05eJerome Glisse    if (!surf->blk_w || !surf->blk_h || !surf->blk_d) {
2483c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return -EINVAL;
2484c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
2485c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (!surf->array_size) {
2486c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return -EINVAL;
2487c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
2488c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* array size must be a power of 2 */
2489c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    surf->array_size = next_power_of_two(surf->array_size);
2490c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
2491c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    switch (surf->nsamples) {
2492c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 1:
2493c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 2:
2494c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 4:
2495c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case 8:
2496c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
2497c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    default:
2498c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return -EINVAL;
2499c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
2500c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    /* check type */
2501c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    switch (type) {
2502c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case RADEON_SURF_TYPE_1D:
2503c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        if (surf->npix_y > 1) {
2504c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            return -EINVAL;
2505c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
2506c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case RADEON_SURF_TYPE_2D:
2507c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        if (surf->npix_z > 1) {
2508c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            return -EINVAL;
2509c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
2510c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
2511c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case RADEON_SURF_TYPE_CUBEMAP:
2512c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        if (surf->npix_z > 1) {
2513c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            return -EINVAL;
2514c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
2515c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        /* deal with cubemap as they were texture array */
2516c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        if (surf_man->family >= CHIP_RV770) {
2517c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            surf->array_size = 8;
2518c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        } else {
2519c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            surf->array_size = 6;
2520c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
2521c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
2522c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case RADEON_SURF_TYPE_3D:
2523c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
2524c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case RADEON_SURF_TYPE_1D_ARRAY:
2525c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        if (surf->npix_y > 1) {
2526c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse            return -EINVAL;
2527c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        }
2528c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    case RADEON_SURF_TYPE_2D_ARRAY:
2529c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        break;
2530c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    default:
2531c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return -EINVAL;
2532c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
2533c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return 0;
2534c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
2535c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
25360f8da82500ec542e269092c0718479e25eaff5f6Emil Velikovint
253758ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstradeon_surface_init(struct radeon_surface_manager *surf_man,
253858ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorst                    struct radeon_surface *surf)
2539c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
2540c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned mode, type;
2541c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    int r;
2542c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
2543c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    type = RADEON_SURF_GET(surf->flags, TYPE);
2544c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    mode = RADEON_SURF_GET(surf->flags, MODE);
2545c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
2546c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    r = radeon_surface_sanity(surf_man, surf, type, mode);
2547c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (r) {
2548c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return r;
2549c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
2550c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return surf_man->surface_init(surf_man, surf);
2551c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
2552c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
25530f8da82500ec542e269092c0718479e25eaff5f6Emil Velikovint
255458ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorstradeon_surface_best(struct radeon_surface_manager *surf_man,
255558ce9d6292c7033ff76bb2ef35da0e4c36de2389Maarten Lankhorst                    struct radeon_surface *surf)
2556c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse{
2557c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    unsigned mode, type;
2558c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    int r;
2559c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
2560c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    type = RADEON_SURF_GET(surf->flags, TYPE);
2561c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    mode = RADEON_SURF_GET(surf->flags, MODE);
2562c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse
2563c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    r = radeon_surface_sanity(surf_man, surf, type, mode);
2564c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    if (r) {
2565c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse        return r;
2566c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    }
2567c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse    return surf_man->surface_best(surf_man, surf);
2568c51f7f0e460dcadb9f1a56ecf1615810877c33c8Jerome Glisse}
2569