radeon_bo_helper.c revision 7314432e
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
30de2362d3Smrg#ifdef RADEON_PIXMAP_SHARING
31de2362d3Smrg#include "radeon_bo_gem.h"
32de2362d3Smrg#endif
33de2362d3Smrg
34de2362d3Smrgstatic const unsigned MicroBlockTable[5][3][2] = {
35de2362d3Smrg    /*linear  tiled   square-tiled */
36de2362d3Smrg    {{32, 1}, {8, 4}, {0, 0}}, /*   8 bits per pixel */
37de2362d3Smrg    {{16, 1}, {8, 2}, {4, 4}}, /*  16 bits per pixel */
38de2362d3Smrg    {{ 8, 1}, {4, 2}, {0, 0}}, /*  32 bits per pixel */
39de2362d3Smrg    {{ 4, 1}, {0, 0}, {2, 2}}, /*  64 bits per pixel */
40de2362d3Smrg    {{ 2, 1}, {0, 0}, {0, 0}}  /* 128 bits per pixel */
41de2362d3Smrg};
42de2362d3Smrg
43de2362d3Smrg/* Return true if macrotiling can be enabled */
44de2362d3Smrgstatic Bool RADEONMacroSwitch(int width, int height, int bpp,
45de2362d3Smrg                              uint32_t flags, Bool rv350_mode)
46de2362d3Smrg{
47de2362d3Smrg    unsigned tilew, tileh, microtiled, logbpp;
48de2362d3Smrg
49de2362d3Smrg    logbpp = RADEONLog2(bpp / 8);
50de2362d3Smrg    if (logbpp > 4)
51de2362d3Smrg        return 0;
52de2362d3Smrg
53de2362d3Smrg    microtiled = !!(flags & RADEON_TILING_MICRO);
54de2362d3Smrg    tilew = MicroBlockTable[logbpp][microtiled][0] * 8;
55de2362d3Smrg    tileh = MicroBlockTable[logbpp][microtiled][1] * 8;
56de2362d3Smrg
57de2362d3Smrg    /* See TX_FILTER1_n.MACRO_SWITCH. */
58de2362d3Smrg    if (rv350_mode) {
59de2362d3Smrg        return width >= tilew && height >= tileh;
60de2362d3Smrg    } else {
61de2362d3Smrg        return width > tilew && height > tileh;
62de2362d3Smrg    }
63de2362d3Smrg}
64de2362d3Smrg
65de2362d3Smrg/* Calculate appropriate tiling and pitch for a pixmap and allocate a BO that
66de2362d3Smrg * can hold it.
67de2362d3Smrg */
68de2362d3Smrgstruct radeon_bo*
69de2362d3Smrgradeon_alloc_pixmap_bo(ScrnInfoPtr pScrn, int width, int height, int depth,
70de2362d3Smrg		       int usage_hint, int bitsPerPixel, int *new_pitch,
71de2362d3Smrg		       struct radeon_surface *new_surface, uint32_t *new_tiling)
72de2362d3Smrg{
73de2362d3Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
74de2362d3Smrg    int pitch, base_align;
75de2362d3Smrg    uint32_t size, heighta;
76de2362d3Smrg    int cpp = bitsPerPixel / 8;
770d16fef4Smrg    uint32_t tiling = 0, flags = 0;
78de2362d3Smrg    struct radeon_surface surface;
79de2362d3Smrg    struct radeon_bo *bo;
80de2362d3Smrg    int domain = RADEON_GEM_DOMAIN_VRAM;
81de2362d3Smrg    if (usage_hint) {
82de2362d3Smrg	if (info->allowColorTiling) {
83de2362d3Smrg	    if (usage_hint & RADEON_CREATE_PIXMAP_TILING_MACRO)
84de2362d3Smrg		tiling |= RADEON_TILING_MACRO;
85de2362d3Smrg	    if (usage_hint & RADEON_CREATE_PIXMAP_TILING_MICRO)
86de2362d3Smrg                tiling |= RADEON_TILING_MICRO;
87de2362d3Smrg	}
88de2362d3Smrg	if (usage_hint & RADEON_CREATE_PIXMAP_DEPTH)
89de2362d3Smrg		tiling |= RADEON_TILING_MACRO | RADEON_TILING_MICRO;
90de2362d3Smrg
910d16fef4Smrg	if ((usage_hint == CREATE_PIXMAP_USAGE_BACKING_PIXMAP &&
920d16fef4Smrg	     info->shadow_primary)
93de2362d3Smrg#ifdef CREATE_PIXMAP_USAGE_SHARED
940d16fef4Smrg	    || (usage_hint & 0xffff) == CREATE_PIXMAP_USAGE_SHARED
950d16fef4Smrg#endif
960d16fef4Smrg	    ) {
97de2362d3Smrg		tiling = 0;
98de2362d3Smrg		domain = RADEON_GEM_DOMAIN_GTT;
99de2362d3Smrg	}
100de2362d3Smrg    }
101de2362d3Smrg
102de2362d3Smrg    /* Small pixmaps must not be macrotiled on R300, hw cannot sample them
103de2362d3Smrg     * correctly because samplers automatically switch to macrolinear. */
104de2362d3Smrg    if (info->ChipFamily >= CHIP_FAMILY_R300 &&
105de2362d3Smrg        info->ChipFamily <= CHIP_FAMILY_RS740 &&
106de2362d3Smrg        (tiling & RADEON_TILING_MACRO) &&
107de2362d3Smrg        !RADEONMacroSwitch(width, height, bitsPerPixel, tiling,
108de2362d3Smrg                           info->ChipFamily >= CHIP_FAMILY_RV350)) {
109de2362d3Smrg        tiling &= ~RADEON_TILING_MACRO;
110de2362d3Smrg    }
111de2362d3Smrg
112de2362d3Smrg    heighta = RADEON_ALIGN(height, drmmode_get_height_align(pScrn, tiling));
113de2362d3Smrg    pitch = RADEON_ALIGN(width, drmmode_get_pitch_align(pScrn, cpp, tiling)) * cpp;
114de2362d3Smrg    base_align = drmmode_get_base_align(pScrn, cpp, tiling);
115de2362d3Smrg    size = RADEON_ALIGN(heighta * pitch, RADEON_GPU_PAGE_SIZE);
116de2362d3Smrg    memset(&surface, 0, sizeof(struct radeon_surface));
117de2362d3Smrg
118de2362d3Smrg    if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) {
119de2362d3Smrg		if (width) {
120de2362d3Smrg			surface.npix_x = width;
121de2362d3Smrg			/* need to align height to 8 for old kernel */
122de2362d3Smrg			surface.npix_y = RADEON_ALIGN(height, 8);
123de2362d3Smrg			surface.npix_z = 1;
124de2362d3Smrg			surface.blk_w = 1;
125de2362d3Smrg			surface.blk_h = 1;
126de2362d3Smrg			surface.blk_d = 1;
127de2362d3Smrg			surface.array_size = 1;
128de2362d3Smrg			surface.last_level = 0;
129de2362d3Smrg			surface.bpe = cpp;
130de2362d3Smrg			surface.nsamples = 1;
131de2362d3Smrg			if (height < 128) {
132de2362d3Smrg				/* disable 2d tiling for small surface to work around
133de2362d3Smrg				 * the fact that ddx align height to 8 pixel for old
134de2362d3Smrg				 * obscure reason i can't remember
135de2362d3Smrg				 */
136de2362d3Smrg				tiling &= ~RADEON_TILING_MACRO;
137de2362d3Smrg			}
138de2362d3Smrg			surface.flags = RADEON_SURF_SCANOUT;
139de2362d3Smrg			/* we are requiring a recent enough libdrm version */
140de2362d3Smrg			surface.flags |= RADEON_SURF_HAS_TILE_MODE_INDEX;
141de2362d3Smrg			surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
142de2362d3Smrg			surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE);
143de2362d3Smrg			if ((tiling & RADEON_TILING_MICRO)) {
144de2362d3Smrg				surface.flags = RADEON_SURF_CLR(surface.flags, MODE);
145de2362d3Smrg				surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
146de2362d3Smrg			}
147de2362d3Smrg			if ((tiling & RADEON_TILING_MACRO)) {
148de2362d3Smrg				surface.flags = RADEON_SURF_CLR(surface.flags, MODE);
149de2362d3Smrg				surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
150de2362d3Smrg			}
151de2362d3Smrg			if (usage_hint & RADEON_CREATE_PIXMAP_SZBUFFER) {
152de2362d3Smrg				surface.flags |= RADEON_SURF_ZBUFFER;
153de2362d3Smrg				surface.flags |= RADEON_SURF_SBUFFER;
154de2362d3Smrg			}
155de2362d3Smrg			if (radeon_surface_best(info->surf_man, &surface)) {
156de2362d3Smrg				return NULL;
157de2362d3Smrg			}
158de2362d3Smrg			if (radeon_surface_init(info->surf_man, &surface)) {
159de2362d3Smrg				return NULL;
160de2362d3Smrg			}
161de2362d3Smrg			size = surface.bo_size;
162de2362d3Smrg			base_align = surface.bo_alignment;
163de2362d3Smrg			pitch = surface.level[0].pitch_bytes;
164de2362d3Smrg			tiling = 0;
165de2362d3Smrg			switch (surface.level[0].mode) {
166de2362d3Smrg			case RADEON_SURF_MODE_2D:
167de2362d3Smrg				tiling |= RADEON_TILING_MACRO;
168de2362d3Smrg				tiling |= surface.bankw << RADEON_TILING_EG_BANKW_SHIFT;
169de2362d3Smrg				tiling |= surface.bankh << RADEON_TILING_EG_BANKH_SHIFT;
170de2362d3Smrg				tiling |= surface.mtilea << RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT;
1710d16fef4Smrg				if (surface.tile_split)
1720d16fef4Smrg					tiling |= eg_tile_split(surface.tile_split) << RADEON_TILING_EG_TILE_SPLIT_SHIFT;
173de2362d3Smrg				tiling |= eg_tile_split(surface.stencil_tile_split) << RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT;
174de2362d3Smrg				break;
175de2362d3Smrg			case RADEON_SURF_MODE_1D:
176de2362d3Smrg				tiling |= RADEON_TILING_MICRO;
177de2362d3Smrg				break;
178de2362d3Smrg			default:
179de2362d3Smrg				break;
180de2362d3Smrg			}
181de2362d3Smrg		}
182de2362d3Smrg	}
183de2362d3Smrg
1840d16fef4Smrg    if (tiling)
1850d16fef4Smrg	flags |= RADEON_GEM_NO_CPU_ACCESS;
1860d16fef4Smrg
187de2362d3Smrg    bo = radeon_bo_open(info->bufmgr, 0, size, base_align,
1880d16fef4Smrg			domain, flags);
189de2362d3Smrg
190de2362d3Smrg    if (bo && tiling && radeon_bo_set_tiling(bo, tiling, pitch) == 0)
191de2362d3Smrg	*new_tiling = tiling;
192de2362d3Smrg
193de2362d3Smrg    *new_surface = surface;
194de2362d3Smrg    *new_pitch = pitch;
195de2362d3Smrg    return bo;
196de2362d3Smrg}
197de2362d3Smrg
1980d16fef4Smrg/* Get GEM handle for the pixmap */
1990d16fef4SmrgBool radeon_get_pixmap_handle(PixmapPtr pixmap, uint32_t *handle)
2000d16fef4Smrg{
2010d16fef4Smrg    struct radeon_bo *bo = radeon_get_pixmap_bo(pixmap);
2020d16fef4Smrg#ifdef USE_GLAMOR
2030d16fef4Smrg    ScreenPtr screen = pixmap->drawable.pScreen;
2040d16fef4Smrg    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(screen));
2050d16fef4Smrg#endif
2060d16fef4Smrg
2070d16fef4Smrg    if (bo) {
2080d16fef4Smrg	*handle = bo->handle;
2090d16fef4Smrg	return TRUE;
2100d16fef4Smrg    }
2110d16fef4Smrg
2120d16fef4Smrg#ifdef USE_GLAMOR
2130d16fef4Smrg    if (info->use_glamor) {
2140d16fef4Smrg	struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
2150d16fef4Smrg	CARD16 stride;
2160d16fef4Smrg	CARD32 size;
2170d16fef4Smrg	int fd, r;
2180d16fef4Smrg
2190d16fef4Smrg	if (!priv) {
2200d16fef4Smrg	    priv = calloc(1, sizeof(*priv));
2210d16fef4Smrg	    radeon_set_pixmap_private(pixmap, priv);
2220d16fef4Smrg	}
2230d16fef4Smrg
2240d16fef4Smrg	if (priv->handle_valid) {
2250d16fef4Smrg	    *handle = priv->handle;
2260d16fef4Smrg	    return TRUE;
2270d16fef4Smrg	}
2280d16fef4Smrg
2290d16fef4Smrg	fd = glamor_fd_from_pixmap(screen, pixmap, &stride, &size);
2300d16fef4Smrg	if (fd < 0)
2310d16fef4Smrg	    return FALSE;
2320d16fef4Smrg
2330d16fef4Smrg	r = drmPrimeFDToHandle(info->dri2.drm_fd, fd, &priv->handle);
2340d16fef4Smrg	close(fd);
2350d16fef4Smrg	if (r == 0) {
2360d16fef4Smrg	    struct drm_radeon_gem_set_tiling args = { .handle = priv->handle };
2370d16fef4Smrg
2380d16fef4Smrg	    priv->handle_valid = TRUE;
2390d16fef4Smrg	    *handle = priv->handle;
2400d16fef4Smrg
2410d16fef4Smrg	    if (drmCommandWriteRead(info->dri2.drm_fd,
2420d16fef4Smrg				    DRM_RADEON_GEM_GET_TILING, &args,
2430d16fef4Smrg				    sizeof(args)) == 0)
2440d16fef4Smrg		priv->tiling_flags = args.tiling_flags;
2450d16fef4Smrg
2460d16fef4Smrg	    return TRUE;
2470d16fef4Smrg	}
2480d16fef4Smrg    }
2490d16fef4Smrg#endif
2500d16fef4Smrg
2510d16fef4Smrg    return FALSE;
2520d16fef4Smrg}
2530d16fef4Smrg
2540d16fef4Smrguint32_t radeon_get_pixmap_tiling_flags(PixmapPtr pPix)
2550d16fef4Smrg{
2560d16fef4Smrg#ifdef USE_GLAMOR
2570d16fef4Smrg    RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(pPix->drawable.pScreen));
2580d16fef4Smrg
2590d16fef4Smrg    if (info->use_glamor) {
2600d16fef4Smrg	struct radeon_pixmap *priv = radeon_get_pixmap_private(pPix);
2610d16fef4Smrg
2620d16fef4Smrg	if (!priv || (!priv->bo && !priv->handle_valid)) {
2630d16fef4Smrg	    uint32_t handle;
2640d16fef4Smrg
2650d16fef4Smrg	    radeon_get_pixmap_handle(pPix, &handle);
2660d16fef4Smrg	    priv = radeon_get_pixmap_private(pPix);
2670d16fef4Smrg	}
2680d16fef4Smrg
2690d16fef4Smrg	return priv ? priv->tiling_flags : 0;
2700d16fef4Smrg    } else
2710d16fef4Smrg#endif
2720d16fef4Smrg    {
2730d16fef4Smrg	struct radeon_exa_pixmap_priv *driver_priv;
2740d16fef4Smrg	driver_priv = exaGetPixmapDriverPrivate(pPix);
2750d16fef4Smrg	return driver_priv ? driver_priv->tiling_flags : 0;
2760d16fef4Smrg    }
2770d16fef4Smrg}
2780d16fef4Smrg
279de2362d3Smrg#ifdef RADEON_PIXMAP_SHARING
280de2362d3Smrg
281de2362d3SmrgBool radeon_share_pixmap_backing(struct radeon_bo *bo, void **handle_p)
282de2362d3Smrg{
283de2362d3Smrg    int handle;
284de2362d3Smrg
285de2362d3Smrg    if (radeon_gem_prime_share_bo(bo, &handle) != 0)
286de2362d3Smrg	return FALSE;
287de2362d3Smrg
288de2362d3Smrg    *handle_p = (void *)(long)handle;
289de2362d3Smrg    return TRUE;
290de2362d3Smrg}
291de2362d3Smrg
2920d16fef4Smrgstatic unsigned eg_tile_split_opp(unsigned tile_split)
2930d16fef4Smrg{
2940d16fef4Smrg    switch (tile_split) {
2950d16fef4Smrg        case 0:     tile_split = 64;    break;
2960d16fef4Smrg        case 1:     tile_split = 128;   break;
2970d16fef4Smrg        case 2:     tile_split = 256;   break;
2980d16fef4Smrg        case 3:     tile_split = 512;   break;
2990d16fef4Smrg        default:
3000d16fef4Smrg        case 4:     tile_split = 1024;  break;
3010d16fef4Smrg        case 5:     tile_split = 2048;  break;
3020d16fef4Smrg        case 6:     tile_split = 4096;  break;
3030d16fef4Smrg    }
3040d16fef4Smrg    return tile_split;
3050d16fef4Smrg}
3060d16fef4Smrg
307de2362d3SmrgBool radeon_set_shared_pixmap_backing(PixmapPtr ppix, void *fd_handle,
308de2362d3Smrg				      struct radeon_surface *surface)
309de2362d3Smrg{
310de2362d3Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(ppix->drawable.pScreen);
311de2362d3Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
312de2362d3Smrg    struct radeon_bo *bo;
313de2362d3Smrg    int ihandle = (int)(long)fd_handle;
314de2362d3Smrg    uint32_t size = ppix->devKind * ppix->drawable.height;
3157314432eSmrg    Bool ret = FALSE;
316de2362d3Smrg
317de2362d3Smrg    bo = radeon_gem_bo_open_prime(info->bufmgr, ihandle, size);
318de2362d3Smrg    if (!bo)
3197314432eSmrg        goto error;
320de2362d3Smrg
321de2362d3Smrg    memset(surface, 0, sizeof(struct radeon_surface));
322de2362d3Smrg
3237314432eSmrg    ret = radeon_set_pixmap_bo(ppix, bo);
3247314432eSmrg    if (!ret)
3257314432eSmrg	goto error;
3260d16fef4Smrg
327de2362d3Smrg    if (info->ChipFamily >= CHIP_FAMILY_R600 && info->surf_man) {
3280d16fef4Smrg	uint32_t tiling_flags;
3290d16fef4Smrg
3300d16fef4Smrg#ifdef USE_GLAMOR
3310d16fef4Smrg	if (info->use_glamor) {
3320d16fef4Smrg	    tiling_flags = radeon_get_pixmap_private(ppix)->tiling_flags;
3330d16fef4Smrg	} else
3340d16fef4Smrg#endif
3350d16fef4Smrg	{
3360d16fef4Smrg	    struct radeon_exa_pixmap_priv *driver_priv;
3370d16fef4Smrg
3380d16fef4Smrg	    driver_priv = exaGetPixmapDriverPrivate(ppix);
3390d16fef4Smrg	    tiling_flags = driver_priv->tiling_flags;
3400d16fef4Smrg	}
341de2362d3Smrg
342de2362d3Smrg	surface->npix_x = ppix->drawable.width;
343de2362d3Smrg	surface->npix_y = ppix->drawable.height;
344de2362d3Smrg	surface->npix_z = 1;
345de2362d3Smrg	surface->blk_w = 1;
346de2362d3Smrg	surface->blk_h = 1;
347de2362d3Smrg	surface->blk_d = 1;
348de2362d3Smrg	surface->array_size = 1;
349de2362d3Smrg	surface->bpe = ppix->drawable.bitsPerPixel / 8;
350de2362d3Smrg	surface->nsamples = 1;
351de2362d3Smrg	/* we are requiring a recent enough libdrm version */
352de2362d3Smrg	surface->flags |= RADEON_SURF_HAS_TILE_MODE_INDEX;
353de2362d3Smrg	surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
3540d16fef4Smrg	if (tiling_flags & RADEON_TILING_MACRO)
3550d16fef4Smrg	    surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
3560d16fef4Smrg	else if (tiling_flags & RADEON_TILING_MICRO)
3570d16fef4Smrg	    surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
3580d16fef4Smrg	else
3590d16fef4Smrg	    surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
3600d16fef4Smrg	surface->bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK;
3610d16fef4Smrg	surface->bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK;
3620d16fef4Smrg	surface->tile_split = eg_tile_split_opp((tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK);
3630d16fef4Smrg	surface->stencil_tile_split = (tiling_flags >> RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK;
3640d16fef4Smrg	surface->mtilea = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK;
365de2362d3Smrg	if (radeon_surface_best(info->surf_man, surface)) {
3667314432eSmrg	    ret = FALSE;
3677314432eSmrg	    goto error;
368de2362d3Smrg	}
369de2362d3Smrg	if (radeon_surface_init(info->surf_man, surface)) {
3707314432eSmrg	    ret = FALSE;
3717314432eSmrg	    goto error;
372de2362d3Smrg	}
373de2362d3Smrg	/* we have to post hack the surface to reflect the actual size
374de2362d3Smrg	   of the shared pixmap */
375de2362d3Smrg	surface->level[0].pitch_bytes = ppix->devKind;
376de2362d3Smrg	surface->level[0].nblk_x = ppix->devKind / surface->bpe;
377de2362d3Smrg    }
378de2362d3Smrg
3797314432eSmrg error:
380de2362d3Smrg    close(ihandle);
381de2362d3Smrg    /* we have a reference from the alloc and one from set pixmap bo,
382de2362d3Smrg       drop one */
383de2362d3Smrg    radeon_bo_unref(bo);
3847314432eSmrg    return ret;
385de2362d3Smrg}
386de2362d3Smrg
387de2362d3Smrg#endif /* RADEON_PIXMAP_SHARING */
388