radeon_bo_helper.c revision 8bf5c682
1de2362d3Smrg/*
2de2362d3Smrg * Copyright 2012  Advanced Micro Devices, Inc.
3de2362d3Smrg *
4de2362d3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5de2362d3Smrg * copy of this software and associated documentation files (the "Software"),
6de2362d3Smrg * to deal in the Software without restriction, including without limitation
7de2362d3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8de2362d3Smrg * and/or sell copies of the Software, and to permit persons to whom the
9de2362d3Smrg * Software is furnished to do so, subject to the following conditions:
10de2362d3Smrg *
11de2362d3Smrg * The above copyright notice and this permission notice shall be included in
12de2362d3Smrg * all copies or substantial portions of the Software.
13de2362d3Smrg *
14de2362d3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15de2362d3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16de2362d3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17de2362d3Smrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18de2362d3Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19de2362d3Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20de2362d3Smrg * OTHER DEALINGS IN THE SOFTWARE.
21de2362d3Smrg */
22de2362d3Smrg
23de2362d3Smrg#ifdef HAVE_CONFIG_H
24de2362d3Smrg# include "config.h"
25de2362d3Smrg#endif
26de2362d3Smrg
27de2362d3Smrg#include "radeon.h"
280d16fef4Smrg#include "radeon_glamor.h"
29de2362d3Smrg#include "radeon_bo_gem.h"
30de2362d3Smrg
31de2362d3Smrgstatic const unsigned MicroBlockTable[5][3][2] = {
32de2362d3Smrg    /*linear  tiled   square-tiled */
33de2362d3Smrg    {{32, 1}, {8, 4}, {0, 0}}, /*   8 bits per pixel */
34de2362d3Smrg    {{16, 1}, {8, 2}, {4, 4}}, /*  16 bits per pixel */
35de2362d3Smrg    {{ 8, 1}, {4, 2}, {0, 0}}, /*  32 bits per pixel */
36de2362d3Smrg    {{ 4, 1}, {0, 0}, {2, 2}}, /*  64 bits per pixel */
37de2362d3Smrg    {{ 2, 1}, {0, 0}, {0, 0}}  /* 128 bits per pixel */
38de2362d3Smrg};
39de2362d3Smrg
40de2362d3Smrg/* Return true if macrotiling can be enabled */
41de2362d3Smrgstatic Bool RADEONMacroSwitch(int width, int height, int bpp,
42de2362d3Smrg                              uint32_t flags, Bool rv350_mode)
43de2362d3Smrg{
44de2362d3Smrg    unsigned tilew, tileh, microtiled, logbpp;
45de2362d3Smrg
46de2362d3Smrg    logbpp = RADEONLog2(bpp / 8);
47de2362d3Smrg    if (logbpp > 4)
48de2362d3Smrg        return 0;
49de2362d3Smrg
50de2362d3Smrg    microtiled = !!(flags & RADEON_TILING_MICRO);
51de2362d3Smrg    tilew = MicroBlockTable[logbpp][microtiled][0] * 8;
52de2362d3Smrg    tileh = MicroBlockTable[logbpp][microtiled][1] * 8;
53de2362d3Smrg
54de2362d3Smrg    /* See TX_FILTER1_n.MACRO_SWITCH. */
55de2362d3Smrg    if (rv350_mode) {
56de2362d3Smrg        return width >= tilew && height >= tileh;
57de2362d3Smrg    } else {
58de2362d3Smrg        return width > tilew && height > tileh;
59de2362d3Smrg    }
60de2362d3Smrg}
61de2362d3Smrg
62de2362d3Smrg/* Calculate appropriate tiling and pitch for a pixmap and allocate a BO that
63de2362d3Smrg * can hold it.
64de2362d3Smrg */
65de2362d3Smrgstruct radeon_bo*
66de2362d3Smrgradeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth,
67de2362d3Smrg		       int usage_hint, int bitsPerPixel, int *new_pitch,
68de2362d3Smrg		       struct radeon_surface *new_surface, uint32_t *new_tiling)
69de2362d3Smrg{
70de2362d3Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
71de2362d3Smrg    int pitch, base_align;
72de2362d3Smrg    uint32_t size, heighta;
73de2362d3Smrg    int cpp = bitsPerPixel / 8;
740d16fef4Smrg    uint32_t tiling = 0, flags = 0;
75de2362d3Smrg    struct radeon_surface surface;
76de2362d3Smrg    struct radeon_bo *bo;
77de2362d3Smrg    int domain = RADEON_GEM_DOMAIN_VRAM;
78de2362d3Smrg    if (usage_hint) {
79de2362d3Smrg	if (info->allowColorTiling) {
80de2362d3Smrg	    if (usage_hint & RADEON_CREATE_PIXMAP_TILING_MACRO)
81de2362d3Smrg		tiling |= RADEON_TILING_MACRO;
82de2362d3Smrg	    if (usage_hint & RADEON_CREATE_PIXMAP_TILING_MICRO)
83de2362d3Smrg                tiling |= RADEON_TILING_MICRO;
84de2362d3Smrg	}
85de2362d3Smrg	if (usage_hint & RADEON_CREATE_PIXMAP_DEPTH)
86de2362d3Smrg		tiling |= RADEON_TILING_MACRO | RADEON_TILING_MICRO;
87de2362d3Smrg
880d16fef4Smrg	if ((usage_hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP &&
898bf5c682Smrg	     info->shadow_primary) ||
908bf5c682Smrg	    (usage_hint & 0xffff) == CREATE_PIXMAP_USAGE_SHARED) {
91de2362d3Smrg		tiling = 0;
92de2362d3Smrg		domain = RADEON_GEM_DOMAIN_GTT;
93de2362d3Smrg	}
94de2362d3Smrg    }
95de2362d3Smrg
96de2362d3Smrg    /* Small pixmaps must not be macrotiled on R300, hw cannot sample them
97de2362d3Smrg     * correctly because samplers automatically switch to macrolinear. */
98de2362d3Smrg    if (info->ChipFamily >= CHIP_FAMILY_R300 &&
99de2362d3Smrg        info->ChipFamily <= CHIP_FAMILY_RS740 &&
100de2362d3Smrg        (tiling & RADEON_TILING_MACRO) &&
101de2362d3Smrg        !RADEONMacroSwitch(width, height, bitsPerPixel, tiling,
102de2362d3Smrg                           info->ChipFamily >= CHIP_FAMILY_RV350)) {
103de2362d3Smrg        tiling &= ~RADEON_TILING_MACRO;
104de2362d3Smrg    }
105de2362d3Smrg
106de2362d3Smrg    heighta = RADEON_ALIGN(height, drmmode_get_height_align(pScrn, tiling));
107de2362d3Smrg    pitch = RADEON_ALIGN(width, drmmode_get_pitch_align(pScrn, cpp, tiling)) * cpp;
108de2362d3Smrg    base_align = drmmode_get_base_align(pScrn, cpp, tiling);
109de2362d3Smrg    size = RADEON_ALIGN(heighta * pitch, RADEON_GPU_PAGE_SIZE);
110de2362d3Smrg    memset(&surface, 0, sizeof(struct radeon_surface));
111de2362d3Smrg
112de2362d3Smrg    if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) {
113de2362d3Smrg		if (width) {
114de2362d3Smrg			surface.npix_x = width;
115de2362d3Smrg			/* need to align height to 8 for old kernel */
116de2362d3Smrg			surface.npix_y = RADEON_ALIGN(height, 8);
117de2362d3Smrg			surface.npix_z = 1;
118de2362d3Smrg			surface.blk_w = 1;
119de2362d3Smrg			surface.blk_h = 1;
120de2362d3Smrg			surface.blk_d = 1;
121de2362d3Smrg			surface.array_size = 1;
122de2362d3Smrg			surface.last_level = 0;
123de2362d3Smrg			surface.bpe = cpp;
124de2362d3Smrg			surface.nsamples = 1;
125de2362d3Smrg			if (height < 128) {
126de2362d3Smrg				/* disable 2d tiling for small surface to work around
127de2362d3Smrg				 * the fact that ddx align height to 8 pixel for old
128de2362d3Smrg				 * obscure reason i can't remember
129de2362d3Smrg				 */
130de2362d3Smrg				tiling &= ~RADEON_TILING_MACRO;
131de2362d3Smrg			}
132de2362d3Smrg			surface.flags = RADEON_SURF_SCANOUT;
133de2362d3Smrg			/* we are requiring a recent enough libdrm version */
134de2362d3Smrg			surface.flags |= RADEON_SURF_HAS_TILE_MODE_INDEX;
135de2362d3Smrg			surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
136de2362d3Smrg			surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE);
137de2362d3Smrg			if ((tiling & RADEON_TILING_MICRO)) {
138de2362d3Smrg				surface.flags = RADEON_SURF_CLR(surface.flags, MODE);
139de2362d3Smrg				surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
140de2362d3Smrg			}
141de2362d3Smrg			if ((tiling & RADEON_TILING_MACRO)) {
142de2362d3Smrg				surface.flags = RADEON_SURF_CLR(surface.flags, MODE);
143de2362d3Smrg				surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
144de2362d3Smrg			}
145de2362d3Smrg			if (usage_hint & RADEON_CREATE_PIXMAP_SZBUFFER) {
146de2362d3Smrg				surface.flags |= RADEON_SURF_ZBUFFER;
147de2362d3Smrg				surface.flags |= RADEON_SURF_SBUFFER;
148de2362d3Smrg			}
149de2362d3Smrg			if (radeon_surface_best(info->surf_man, &surface)) {
150de2362d3Smrg				return NULL;
151de2362d3Smrg			}
152de2362d3Smrg			if (radeon_surface_init(info->surf_man, &surface)) {
153de2362d3Smrg				return NULL;
154de2362d3Smrg			}
155de2362d3Smrg			size = surface.bo_size;
156de2362d3Smrg			base_align = surface.bo_alignment;
157de2362d3Smrg			pitch = surface.level[0].pitch_bytes;
158de2362d3Smrg			tiling = 0;
159de2362d3Smrg			switch (surface.level[0].mode) {
160de2362d3Smrg			case RADEON_SURF_MODE_2D:
161de2362d3Smrg				tiling |= RADEON_TILING_MACRO;
162de2362d3Smrg				tiling |= surface.bankw << RADEON_TILING_EG_BANKW_SHIFT;
163de2362d3Smrg				tiling |= surface.bankh << RADEON_TILING_EG_BANKH_SHIFT;
164de2362d3Smrg				tiling |= surface.mtilea << RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT;
1650d16fef4Smrg				if (surface.tile_split)
1660d16fef4Smrg					tiling |= eg_tile_split(surface.tile_split) << RADEON_TILING_EG_TILE_SPLIT_SHIFT;
167de2362d3Smrg				tiling |= eg_tile_split(surface.stencil_tile_split) << RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT;
168de2362d3Smrg				break;
169de2362d3Smrg			case RADEON_SURF_MODE_1D:
170de2362d3Smrg				tiling |= RADEON_TILING_MICRO;
171de2362d3Smrg				break;
172de2362d3Smrg			default:
173de2362d3Smrg				break;
174de2362d3Smrg			}
175de2362d3Smrg		}
176de2362d3Smrg	}
177de2362d3Smrg
1780d16fef4Smrg    if (tiling)
1790d16fef4Smrg	flags |= RADEON_GEM_NO_CPU_ACCESS;
1800d16fef4Smrg
181de2362d3Smrg    bo = radeon_bo_open(info->bufmgr, 0, size, base_align,
1820d16fef4Smrg			domain, flags);
183de2362d3Smrg
184de2362d3Smrg    if (bo && tiling && radeon_bo_set_tiling(bo, tiling, pitch) == 0)
185de2362d3Smrg	*new_tiling = tiling;
186de2362d3Smrg
187de2362d3Smrg    *new_surface = surface;
188de2362d3Smrg    *new_pitch = pitch;
189de2362d3Smrg    return bo;
190de2362d3Smrg}
191de2362d3Smrg
1928bf5c682Smrg/* Clear the pixmap contents to black */
1938bf5c682Smrgvoid
1948bf5c682Smrgradeon_pixmap_clear(PixmapPtr pixmap)
1958bf5c682Smrg{
1968bf5c682Smrg    ScreenPtr screen = pixmap->drawable.pScreen;
1978bf5c682Smrg    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(screen));
1988bf5c682Smrg    GCPtr gc = GetScratchGC(pixmap->drawable.depth, screen);
1998bf5c682Smrg    Bool force = info->accel_state->force;
2008bf5c682Smrg    xRectangle rect;
2018bf5c682Smrg
2028bf5c682Smrg    info->accel_state->force = TRUE;
2038bf5c682Smrg    ValidateGC(&pixmap->drawable, gc);
2048bf5c682Smrg    rect.x = 0;
2058bf5c682Smrg    rect.y = 0;
2068bf5c682Smrg    rect.width = pixmap->drawable.width;
2078bf5c682Smrg    rect.height = pixmap->drawable.height;
2088bf5c682Smrg    gc->ops->PolyFillRect(&pixmap->drawable, gc, 1, &rect);
2098bf5c682Smrg    FreeScratchGC(gc);
2108bf5c682Smrg    info->accel_state->force = force;
2118bf5c682Smrg}
2128bf5c682Smrg
2130d16fef4Smrg/* Get GEM handle for the pixmap */
2140d16fef4SmrgBool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle)
2150d16fef4Smrg{
2160d16fef4Smrg    struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap);
2170d16fef4Smrg#ifdef USE_GLAMOR
2180d16fef4Smrg    ScreenPtr screen = pixmap->drawable.pScreen;
2198bf5c682Smrg    ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
2208bf5c682Smrg    RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
2218bf5c682Smrg    RADEONInfoPtr info = RADEONPTR(scrn);
2220d16fef4Smrg#endif
2230d16fef4Smrg
2240d16fef4Smrg    if (bo) {
2250d16fef4Smrg	*handle = bo->handle;
2260d16fef4Smrg	return TRUE;
2270d16fef4Smrg    }
2280d16fef4Smrg
2290d16fef4Smrg#ifdef USE_GLAMOR
2300d16fef4Smrg    if (info->use_glamor) {
2310d16fef4Smrg	struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
2320d16fef4Smrg	CARD16 stride;
2330d16fef4Smrg	CARD32 size;
2340d16fef4Smrg	int fd, r;
2350d16fef4Smrg
2360d16fef4Smrg	if (!priv) {
2370d16fef4Smrg	    priv = calloc(1, sizeof(*priv));
2380d16fef4Smrg	    radeon_set_pixmap_private(pixmap, priv);
2390d16fef4Smrg	}
2400d16fef4Smrg
2410d16fef4Smrg	if (priv->handle_valid) {
2420d16fef4Smrg	    *handle = priv->handle;
2430d16fef4Smrg	    return TRUE;
2440d16fef4Smrg	}
2450d16fef4Smrg
2460d16fef4Smrg	fd = glamor_fd_from_pixmap(screen, pixmap, &stride, &size);
2470d16fef4Smrg	if (fd < 0)
2480d16fef4Smrg	    return FALSE;
2490d16fef4Smrg
2508bf5c682Smrg	r = drmPrimeFDToHandle(pRADEONEnt->fd, fd, &priv->handle);
2510d16fef4Smrg	close(fd);
2520d16fef4Smrg	if (r == 0) {
2530d16fef4Smrg	    struct drm_radeon_gem_set_tiling args = { .handle = priv->handle };
2540d16fef4Smrg
2550d16fef4Smrg	    priv->handle_valid = TRUE;
2560d16fef4Smrg	    *handle = priv->handle;
2570d16fef4Smrg
2588bf5c682Smrg	    if (drmCommandWriteRead(pRADEONEnt->fd,
2590d16fef4Smrg				    DRM_RADEON_GEM_GET_TILING, &args,
2600d16fef4Smrg				    sizeof(args)) == 0)
2610d16fef4Smrg		priv->tiling_flags = args.tiling_flags;
2620d16fef4Smrg
2630d16fef4Smrg	    return TRUE;
2640d16fef4Smrg	}
2650d16fef4Smrg    }
2660d16fef4Smrg#endif
2670d16fef4Smrg
2680d16fef4Smrg    return FALSE;
2690d16fef4Smrg}
2700d16fef4Smrg
2710d16fef4Smrguint32_t radeon_get_pixmap_tiling_flags(PixmapPtr pPix)
2720d16fef4Smrg{
2730d16fef4Smrg#ifdef USE_GLAMOR
2740d16fef4Smrg    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
2750d16fef4Smrg
2760d16fef4Smrg    if (info->use_glamor) {
2770d16fef4Smrg	struct radeon_pixmap *priv = radeon_get_pixmap_private(pPix);
2780d16fef4Smrg
2790d16fef4Smrg	if (!priv || (!priv->bo && !priv->handle_valid)) {
2800d16fef4Smrg	    uint32_t handle;
2810d16fef4Smrg
2820d16fef4Smrg	    radeon_get_pixmap_handle(pPix, &handle);
2830d16fef4Smrg	    priv = radeon_get_pixmap_private(pPix);
2840d16fef4Smrg	}
2850d16fef4Smrg
2860d16fef4Smrg	return priv ? priv->tiling_flags : 0;
2870d16fef4Smrg    } else
2880d16fef4Smrg#endif
2890d16fef4Smrg    {
2900d16fef4Smrg	struct radeon_exa_pixmap_priv *driver_priv;
2910d16fef4Smrg	driver_priv = exaGetPixmapDriverPrivate(pPix);
2920d16fef4Smrg	return driver_priv ? driver_priv->tiling_flags : 0;
2930d16fef4Smrg    }
2940d16fef4Smrg}
2950d16fef4Smrg
296de2362d3Smrg
297de2362d3SmrgBool radeon_share_pixmap_backing(struct radeon_bo *bo, void **handle_p)
298de2362d3Smrg{
299de2362d3Smrg    int handle;
300de2362d3Smrg
301de2362d3Smrg    if (radeon_gem_prime_share_bo(bo, &handle) != 0)
302de2362d3Smrg	return FALSE;
303de2362d3Smrg
304de2362d3Smrg    *handle_p = (void *)(long)handle;
305de2362d3Smrg    return TRUE;
306de2362d3Smrg}
307de2362d3Smrg
3080d16fef4Smrgstatic unsigned eg_tile_split_opp(unsigned tile_split)
3090d16fef4Smrg{
3100d16fef4Smrg    switch (tile_split) {
3110d16fef4Smrg        case 0:     tile_split = 64;    break;
3120d16fef4Smrg        case 1:     tile_split = 128;   break;
3130d16fef4Smrg        case 2:     tile_split = 256;   break;
3140d16fef4Smrg        case 3:     tile_split = 512;   break;
3150d16fef4Smrg        default:
3160d16fef4Smrg        case 4:     tile_split = 1024;  break;
3170d16fef4Smrg        case 5:     tile_split = 2048;  break;
3180d16fef4Smrg        case 6:     tile_split = 4096;  break;
3190d16fef4Smrg    }
3200d16fef4Smrg    return tile_split;
3210d16fef4Smrg}
3220d16fef4Smrg
323de2362d3SmrgBool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle,
324de2362d3Smrg				      struct radeon_surface *surface)
325de2362d3Smrg{
326de2362d3Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen);
327de2362d3Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
328de2362d3Smrg    struct radeon_bo *bo;
329de2362d3Smrg    int ihandle = (int)(long)fd_handle;
330de2362d3Smrg    uint32_t size = ppix->devKind * ppix->drawable.height;
3317314432eSmrg    Bool ret = FALSE;
332de2362d3Smrg
333de2362d3Smrg    bo = radeon_gem_bo_open_prime(info->bufmgr, ihandle, size);
334de2362d3Smrg    if (!bo)
3357314432eSmrg        goto error;
336de2362d3Smrg
337de2362d3Smrg    memset(surface, 0, sizeof(struct radeon_surface));
338de2362d3Smrg
3397314432eSmrg    ret = radeon_set_pixmap_bo(ppix, bo);
3407314432eSmrg    if (!ret)
3417314432eSmrg	goto error;
3420d16fef4Smrg
343de2362d3Smrg    if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) {
3440d16fef4Smrg	uint32_t tiling_flags;
3450d16fef4Smrg
3460d16fef4Smrg#ifdef USE_GLAMOR
3470d16fef4Smrg	if (info->use_glamor) {
3480d16fef4Smrg	    tiling_flags = radeon_get_pixmap_private(ppix)->tiling_flags;
3490d16fef4Smrg	} else
3500d16fef4Smrg#endif
3510d16fef4Smrg	{
3520d16fef4Smrg	    struct radeon_exa_pixmap_priv *driver_priv;
3530d16fef4Smrg
3540d16fef4Smrg	    driver_priv = exaGetPixmapDriverPrivate(ppix);
3550d16fef4Smrg	    tiling_flags = driver_priv->tiling_flags;
3560d16fef4Smrg	}
357de2362d3Smrg
358de2362d3Smrg	surface->npix_x = ppix->drawable.width;
359de2362d3Smrg	surface->npix_y = ppix->drawable.height;
360de2362d3Smrg	surface->npix_z = 1;
361de2362d3Smrg	surface->blk_w = 1;
362de2362d3Smrg	surface->blk_h = 1;
363de2362d3Smrg	surface->blk_d = 1;
364de2362d3Smrg	surface->array_size = 1;
365de2362d3Smrg	surface->bpe = ppix->drawable.bitsPerPixel / 8;
366de2362d3Smrg	surface->nsamples = 1;
367de2362d3Smrg	/* we are requiring a recent enough libdrm version */
368de2362d3Smrg	surface->flags |= RADEON_SURF_HAS_TILE_MODE_INDEX;
369de2362d3Smrg	surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
3700d16fef4Smrg	if (tiling_flags & RADEON_TILING_MACRO)
3710d16fef4Smrg	    surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
3720d16fef4Smrg	else if (tiling_flags & RADEON_TILING_MICRO)
3730d16fef4Smrg	    surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
3740d16fef4Smrg	else
3750d16fef4Smrg	    surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
3760d16fef4Smrg	surface->bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK;
3770d16fef4Smrg	surface->bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK;
3780d16fef4Smrg	surface->tile_split = eg_tile_split_opp((tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK);
3790d16fef4Smrg	surface->stencil_tile_split = (tiling_flags >> RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK;
3800d16fef4Smrg	surface->mtilea = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK;
381de2362d3Smrg	if (radeon_surface_best(info->surf_man, surface)) {
3827314432eSmrg	    ret = FALSE;
3837314432eSmrg	    goto error;
384de2362d3Smrg	}
385de2362d3Smrg	if (radeon_surface_init(info->surf_man, surface)) {
3867314432eSmrg	    ret = FALSE;
3877314432eSmrg	    goto error;
388de2362d3Smrg	}
389de2362d3Smrg	/* we have to post hack the surface to reflect the actual size
390de2362d3Smrg	   of the shared pixmap */
391de2362d3Smrg	surface->level[0].pitch_bytes = ppix->devKind;
392de2362d3Smrg	surface->level[0].nblk_x = ppix->devKind / surface->bpe;
393de2362d3Smrg    }
394de2362d3Smrg
3957314432eSmrg error:
396de2362d3Smrg    close(ihandle);
397de2362d3Smrg    /* we have a reference from the alloc and one from set pixmap bo,
398de2362d3Smrg       drop one */
399de2362d3Smrg    radeon_bo_unref(bo);
4007314432eSmrg    return ret;
401de2362d3Smrg}
402