1de2362d3Smrg/*
2de2362d3Smrg * Copyright © 2011 Intel Corporation.
3de2362d3Smrg *             2012 Advanced Micro Devices, Inc.
4de2362d3Smrg *
5de2362d3Smrg * Permission is hereby granted, free of charge, to any person
6de2362d3Smrg * obtaining a copy of this software and associated documentation
7de2362d3Smrg * files (the "Software"), to deal in the Software without
8de2362d3Smrg * restriction, including without limitation the rights to use, copy,
9de2362d3Smrg * modify, merge, publish, distribute, sublicense, and/or sell copies
10de2362d3Smrg * of the Software, and to permit persons to whom the Software is
11de2362d3Smrg * furnished to do so, subject to the following conditions:
12de2362d3Smrg *
13de2362d3Smrg * The above copyright notice and this permission notice (including
14de2362d3Smrg * the next paragraph) shall be included in all copies or substantial
15de2362d3Smrg * portions of the Software.
16de2362d3Smrg *
17de2362d3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18de2362d3Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19de2362d3Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20de2362d3Smrg * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21de2362d3Smrg * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22de2362d3Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23de2362d3Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24de2362d3Smrg * DEALINGS IN THE SOFTWARE.
25de2362d3Smrg */
26de2362d3Smrg
27de2362d3Smrg#ifdef HAVE_CONFIG_H
28de2362d3Smrg#include "config.h"
29de2362d3Smrg#endif
30de2362d3Smrg
31de2362d3Smrg#include <xf86.h>
32de2362d3Smrg
33de2362d3Smrg#include "radeon.h"
34de2362d3Smrg#include "radeon_bo_helper.h"
350d16fef4Smrg#include "radeon_glamor.h"
36de2362d3Smrg
37de2362d3SmrgDevPrivateKeyRec glamor_pixmap_index;
38de2362d3Smrg
39de2362d3Smrgvoid
40de2362d3Smrgradeon_glamor_exchange_buffers(PixmapPtr src,
41de2362d3Smrg			       PixmapPtr dst)
42de2362d3Smrg{
43de2362d3Smrg	RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(dst->drawable.pScreen));
44de2362d3Smrg
45de2362d3Smrg	if (!info->use_glamor)
46de2362d3Smrg		return;
47de2362d3Smrg	glamor_egl_exchange_buffers(src, dst);
48de2362d3Smrg}
49de2362d3Smrg
50de2362d3SmrgBool
51de2362d3Smrgradeon_glamor_create_screen_resources(ScreenPtr screen)
52de2362d3Smrg{
5339413783Smrg	PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
54de2362d3Smrg	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
55de2362d3Smrg	RADEONInfoPtr info = RADEONPTR(scrn);
56de2362d3Smrg
57de2362d3Smrg	if (!info->use_glamor)
58de2362d3Smrg		return TRUE;
59de2362d3Smrg
600d16fef4Smrg#ifdef HAVE_GLAMOR_GLYPHS_INIT
61de2362d3Smrg	if (!glamor_glyphs_init(screen))
62de2362d3Smrg		return FALSE;
630d16fef4Smrg#endif
64de2362d3Smrg
6539413783Smrg	return radeon_glamor_create_textured_pixmap(screen_pixmap,
6639413783Smrg						    info->front_buffer);
67de2362d3Smrg}
68de2362d3Smrg
69de2362d3Smrg
70de2362d3SmrgBool
71de2362d3Smrgradeon_glamor_pre_init(ScrnInfoPtr scrn)
72de2362d3Smrg{
738bf5c682Smrg	RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
74de2362d3Smrg	RADEONInfoPtr info = RADEONPTR(scrn);
75de2362d3Smrg	pointer glamor_module;
76de2362d3Smrg	CARD32 version;
77de2362d3Smrg	const char *s;
78de2362d3Smrg
79de2362d3Smrg	if (!info->dri2.available)
80de2362d3Smrg		return FALSE;
81de2362d3Smrg
82de2362d3Smrg	s = xf86GetOptValString(info->Options, OPTION_ACCELMETHOD);
833ed65abbSmrg	if (!s) {
844090900bSmrg#ifdef __NetBSD__
854090900bSmrg		/*
864090900bSmrg		 * glamor isn't working yet for GL.  disable where not
874090900bSmrg		 * needed for anything at all.
884090900bSmrg		 */
894090900bSmrg		if (info->ChipFamily < CHIP_FAMILY_TAHITI)
904090900bSmrg			return FALSE;
914090900bSmrg#else
923ed65abbSmrg		if (xorgGetVersion() >= XORG_VERSION_NUMERIC(1,18,3,0,0)) {
933ed65abbSmrg			if (info->ChipFamily < CHIP_FAMILY_R600)
943ed65abbSmrg				return FALSE;
953ed65abbSmrg		} else {
963ed65abbSmrg			if (info->ChipFamily < CHIP_FAMILY_TAHITI)
973ed65abbSmrg				return FALSE;
983ed65abbSmrg		}
994090900bSmrg#endif
1003ed65abbSmrg	}
101de2362d3Smrg
102de2362d3Smrg	if (s && strcasecmp(s, "glamor") != 0) {
103de2362d3Smrg		if (info->ChipFamily >= CHIP_FAMILY_TAHITI)
104de2362d3Smrg			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
105de2362d3Smrg				   "EXA not supported, using glamor\n");
106de2362d3Smrg		else
107de2362d3Smrg			return FALSE;
108de2362d3Smrg	}
109de2362d3Smrg
110de2362d3Smrg	if (info->ChipFamily < CHIP_FAMILY_R300) {
111de2362d3Smrg		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
112de2362d3Smrg			   "glamor requires R300 or higher GPU, disabling.\n");
113de2362d3Smrg		return FALSE;
114de2362d3Smrg	}
115de2362d3Smrg
116de2362d3Smrg	if (info->ChipFamily < CHIP_FAMILY_RV515) {
117de2362d3Smrg		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
118de2362d3Smrg			   "glamor may not work (well) with GPUs < RV515.\n");
119de2362d3Smrg	}
120de2362d3Smrg
121446f62d6Smrg#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,20,99,0,0)
122de2362d3Smrg	if (scrn->depth < 24) {
123446f62d6Smrg#else
124446f62d6Smrg	if (scrn->depth < 15) {
125446f62d6Smrg#endif
126de2362d3Smrg		xf86DrvMsg(scrn->scrnIndex, s ? X_ERROR : X_WARNING,
127446f62d6Smrg			   "Depth %d not supported with glamor, disabling\n",
128446f62d6Smrg			   scrn->depth);
129de2362d3Smrg		return FALSE;
130de2362d3Smrg	}
131de2362d3Smrg
1328bf5c682Smrg	if (scrn->depth == 30 &&
1338bf5c682Smrg	    xorgGetVersion() < XORG_VERSION_NUMERIC(1,19,99,1,0)) {
1348bf5c682Smrg		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
1358bf5c682Smrg			   "Depth 30 is not supported by GLAMOR with Xorg < "
1368bf5c682Smrg			   "1.19.99.1\n");
1378bf5c682Smrg		return FALSE;
1388bf5c682Smrg	}
1398bf5c682Smrg
140de2362d3Smrg#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,15,0,0,0)
141de2362d3Smrg	if (!xf86LoaderCheckSymbol("glamor_egl_init")) {
142de2362d3Smrg		xf86DrvMsg(scrn->scrnIndex, s ? X_ERROR : X_WARNING,
143de2362d3Smrg			   "glamor requires Load \"glamoregl\" in "
144de2362d3Smrg			   "Section \"Module\", disabling.\n");
145de2362d3Smrg		return FALSE;
146de2362d3Smrg	}
147de2362d3Smrg#endif
148de2362d3Smrg
14939413783Smrg	info->gbm = gbm_create_device(pRADEONEnt->fd);
15039413783Smrg	if (!info->gbm) {
15139413783Smrg		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
15239413783Smrg			   "gbm_create_device returned NULL\n");
15339413783Smrg		return FALSE;
15439413783Smrg	}
15539413783Smrg
156de2362d3Smrg	/* Load glamor module */
157de2362d3Smrg	if ((glamor_module = xf86LoadSubModule(scrn, GLAMOR_EGL_MODULE_NAME))) {
158de2362d3Smrg		version = xf86GetModuleVersion(glamor_module);
159de2362d3Smrg		if (version < MODULE_VERSION_NUMERIC(0,3,1)) {
160de2362d3Smrg			xf86DrvMsg(scrn->scrnIndex, X_ERROR,
161de2362d3Smrg			"Incompatible glamor version, required >= 0.3.0.\n");
162de2362d3Smrg			return FALSE;
163de2362d3Smrg		} else {
1648bf5c682Smrg			if (glamor_egl_init(scrn, pRADEONEnt->fd)) {
165de2362d3Smrg				xf86DrvMsg(scrn->scrnIndex, X_INFO,
166de2362d3Smrg					   "glamor detected, initialising EGL layer.\n");
167de2362d3Smrg			} else {
168de2362d3Smrg				xf86DrvMsg(scrn->scrnIndex, X_ERROR,
169de2362d3Smrg					   "glamor detected, failed to initialize EGL.\n");
170de2362d3Smrg				return FALSE;
171de2362d3Smrg			}
172de2362d3Smrg		}
173de2362d3Smrg	} else {
174de2362d3Smrg		xf86DrvMsg(scrn->scrnIndex, X_ERROR, "glamor not available\n");
175de2362d3Smrg		return FALSE;
176de2362d3Smrg	}
177de2362d3Smrg
178de2362d3Smrg	info->use_glamor = TRUE;
179de2362d3Smrg
180de2362d3Smrg	return TRUE;
181de2362d3Smrg}
182de2362d3Smrg
183de2362d3SmrgBool
18439413783Smrgradeon_glamor_create_textured_pixmap(PixmapPtr pixmap, struct radeon_buffer *bo)
185de2362d3Smrg{
18639413783Smrg	ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
18739413783Smrg	RADEONInfoPtr info = RADEONPTR(scrn);
18839413783Smrg
18939413783Smrg	if (!info->use_glamor)
19039413783Smrg		return TRUE;
19139413783Smrg
19239413783Smrg	if (bo->flags & RADEON_BO_FLAGS_GBM) {
19339413783Smrg		return glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap,
19439413783Smrg								     bo->bo.gbm
19539413783Smrg#if XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(1,19,99,903,0)
19639413783Smrg								     , FALSE
19739413783Smrg#endif
19839413783Smrg								     );
19939413783Smrg	} else {
20039413783Smrg		return glamor_egl_create_textured_pixmap(pixmap,
20139413783Smrg							 bo->bo.radeon->handle,
20239413783Smrg							 pixmap->devKind);
20339413783Smrg	}
204de2362d3Smrg}
205de2362d3Smrg
2060d16fef4Smrgstatic Bool radeon_glamor_destroy_pixmap(PixmapPtr pixmap)
207de2362d3Smrg{
2080d16fef4Smrg#ifndef HAVE_GLAMOR_EGL_DESTROY_TEXTURED_PIXMAP
2090d16fef4Smrg	ScreenPtr screen = pixmap->drawable.pScreen;
2100d16fef4Smrg	RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(screen));
2110d16fef4Smrg	Bool ret;
2120d16fef4Smrg#endif
213de2362d3Smrg
2140d16fef4Smrg	if (pixmap->refcnt == 1) {
2150d16fef4Smrg#ifdef HAVE_GLAMOR_EGL_DESTROY_TEXTURED_PIXMAP
2160d16fef4Smrg		glamor_egl_destroy_textured_pixmap(pixmap);
217de2362d3Smrg#endif
2180d16fef4Smrg		radeon_set_pixmap_bo(pixmap, NULL);
2190d16fef4Smrg	}
2200d16fef4Smrg
2210d16fef4Smrg#ifdef HAVE_GLAMOR_EGL_DESTROY_TEXTURED_PIXMAP
2220d16fef4Smrg	fbDestroyPixmap(pixmap);
2230d16fef4Smrg	return TRUE;
2240d16fef4Smrg#else
2250d16fef4Smrg	screen->DestroyPixmap = info->glamor.SavedDestroyPixmap;
2260d16fef4Smrg	ret = screen->DestroyPixmap(pixmap);
2270d16fef4Smrg	info->glamor.SavedDestroyPixmap = screen->DestroyPixmap;
2280d16fef4Smrg	screen->DestroyPixmap = radeon_glamor_destroy_pixmap;
229de2362d3Smrg
2300d16fef4Smrg	return ret;
2310d16fef4Smrg#endif
2320d16fef4Smrg}
233de2362d3Smrg
234de2362d3Smrgstatic PixmapPtr
235de2362d3Smrgradeon_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
236de2362d3Smrg			unsigned usage)
237de2362d3Smrg{
238de2362d3Smrg	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
2390d16fef4Smrg	RADEONInfoPtr info = RADEONPTR(scrn);
240de2362d3Smrg	struct radeon_pixmap *priv;
241de2362d3Smrg	PixmapPtr pixmap, new_pixmap = NULL;
242de2362d3Smrg
24339413783Smrg	if (!xf86GetPixFormat(scrn, depth))
24439413783Smrg		return NULL;
24539413783Smrg
246de2362d3Smrg	if (!RADEON_CREATE_PIXMAP_SHARED(usage)) {
2470d16fef4Smrg		if (info->shadow_primary) {
2480d16fef4Smrg			if (usage != CREATE_PIXMAP_USAGE_BACKING_PIXMAP)
2490d16fef4Smrg				return fbCreatePixmap(screen, w, h, depth, usage);
2500d16fef4Smrg		} else {
2510d16fef4Smrg			pixmap = glamor_create_pixmap(screen, w, h, depth, usage);
2520d16fef4Smrg			if (pixmap)
2530d16fef4Smrg			    return pixmap;
2540d16fef4Smrg		}
255de2362d3Smrg	}
256de2362d3Smrg
257de2362d3Smrg	if (w > 32767 || h > 32767)
258de2362d3Smrg		return NullPixmap;
259de2362d3Smrg
260de2362d3Smrg	if (depth == 1)
261de2362d3Smrg		return fbCreatePixmap(screen, w, h, depth, usage);
262de2362d3Smrg
263de2362d3Smrg	if (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE && w <= 32 && h <= 32)
264de2362d3Smrg		return fbCreatePixmap(screen, w, h, depth, usage);
265de2362d3Smrg
266de2362d3Smrg	pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
267de2362d3Smrg	if (pixmap == NullPixmap)
268de2362d3Smrg		return pixmap;
269de2362d3Smrg
270de2362d3Smrg	if (w && h) {
2710d16fef4Smrg		int stride;
2720d16fef4Smrg
273de2362d3Smrg		priv = calloc(1, sizeof (struct radeon_pixmap));
27439413783Smrg		if (!priv)
275de2362d3Smrg			goto fallback_pixmap;
276de2362d3Smrg
277de2362d3Smrg		priv->bo = radeon_alloc_pixmap_bo(scrn, w, h, depth, usage,
278de2362d3Smrg						  pixmap->drawable.bitsPerPixel,
27939413783Smrg						  &stride, NULL,
280de2362d3Smrg						  &priv->tiling_flags);
281de2362d3Smrg		if (!priv->bo)
282de2362d3Smrg			goto fallback_priv;
283de2362d3Smrg
284de2362d3Smrg		radeon_set_pixmap_private(pixmap, priv);
285de2362d3Smrg
2860d16fef4Smrg		screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride, NULL);
287de2362d3Smrg
28839413783Smrg		if (!radeon_glamor_create_textured_pixmap(pixmap, priv->bo))
289de2362d3Smrg			goto fallback_glamor;
2900d16fef4Smrg
2910d16fef4Smrg		pixmap->devPrivate.ptr = NULL;
292de2362d3Smrg	}
293de2362d3Smrg
294de2362d3Smrg	return pixmap;
295de2362d3Smrg
296de2362d3Smrgfallback_glamor:
297de2362d3Smrg	if (RADEON_CREATE_PIXMAP_SHARED(usage)) {
298de2362d3Smrg	/* XXX need further work to handle the DRI2 failure case.
299de2362d3Smrg	 * Glamor don't know how to handle a BO only pixmap. Put
300de2362d3Smrg	 * a warning indicator here.
301de2362d3Smrg	 */
302de2362d3Smrg		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
303de2362d3Smrg			   "Failed to create textured DRI2/PRIME pixmap.");
3040d16fef4Smrg
3050d16fef4Smrg		radeon_glamor_destroy_pixmap(pixmap);
3060d16fef4Smrg		return NullPixmap;
307de2362d3Smrg	}
308de2362d3Smrg	/* Create textured pixmap failed means glamor failed to
309de2362d3Smrg	 * create a texture from current BO for some reasons. We turn
310de2362d3Smrg	 * to create a new glamor pixmap and clean up current one.
311de2362d3Smrg	 * One thing need to be noted, this new pixmap doesn't
312de2362d3Smrg	 * has a priv and bo attached to it. It's glamor's responsbility
313de2362d3Smrg	 * to take care of it. Glamor will mark this new pixmap as a
314de2362d3Smrg	 * texture only pixmap and will never fallback to DDX layer
315de2362d3Smrg	 * afterwards.
316de2362d3Smrg	 */
317de2362d3Smrg	new_pixmap = glamor_create_pixmap(screen, w, h,	depth, usage);
31839413783Smrg	radeon_buffer_unref(&priv->bo);
319de2362d3Smrgfallback_priv:
320de2362d3Smrg	free(priv);
321de2362d3Smrgfallback_pixmap:
322de2362d3Smrg	fbDestroyPixmap(pixmap);
323de2362d3Smrg	if (new_pixmap)
324de2362d3Smrg		return new_pixmap;
325de2362d3Smrg	else
326de2362d3Smrg		return fbCreatePixmap(screen, w, h, depth, usage);
327de2362d3Smrg}
328de2362d3Smrg
3297314432eSmrgPixmapPtr
3307314432eSmrgradeon_glamor_set_pixmap_bo(DrawablePtr drawable, PixmapPtr pixmap)
3317314432eSmrg{
3327314432eSmrg	PixmapPtr old = get_drawable_pixmap(drawable);
3337314432eSmrg	ScreenPtr screen = drawable->pScreen;
3347314432eSmrg	struct radeon_pixmap *priv = radeon_get_pixmap_private(pixmap);
3357314432eSmrg	GCPtr gc;
3367314432eSmrg
3377314432eSmrg	/* With a glamor pixmap, 2D pixmaps are created in texture
3387314432eSmrg	 * and without a static BO attached to it. To support DRI,
3397314432eSmrg	 * we need to create a new textured-drm pixmap and
3407314432eSmrg	 * need to copy the original content to this new textured-drm
3417314432eSmrg	 * pixmap, and then convert the old pixmap to a coherent
3427314432eSmrg	 * textured-drm pixmap which has a valid BO attached to it
3437314432eSmrg	 * and also has a valid texture, thus both glamor and DRI2
3447314432eSmrg	 * can access it.
3457314432eSmrg	 *
3467314432eSmrg	 */
3477314432eSmrg
3487314432eSmrg	/* Copy the current contents of the pixmap to the bo. */
3497314432eSmrg	gc = GetScratchGC(drawable->depth, screen);
3507314432eSmrg	if (gc) {
3517314432eSmrg		ValidateGC(&pixmap->drawable, gc);
3527314432eSmrg		gc->ops->CopyArea(&old->drawable, &pixmap->drawable,
3537314432eSmrg				  gc,
3547314432eSmrg				  0, 0,
3557314432eSmrg				  old->drawable.width,
3567314432eSmrg				  old->drawable.height, 0, 0);
3577314432eSmrg		FreeScratchGC(gc);
3587314432eSmrg	}
3597314432eSmrg
3607314432eSmrg	/* And redirect the pixmap to the new bo (for 3D). */
3617314432eSmrg	glamor_egl_exchange_buffers(old, pixmap);
3627314432eSmrg	radeon_set_pixmap_private(pixmap, radeon_get_pixmap_private(old));
3637314432eSmrg	radeon_set_pixmap_private(old, priv);
3647314432eSmrg
3657314432eSmrg	screen->ModifyPixmapHeader(old,
3667314432eSmrg				   old->drawable.width,
3677314432eSmrg				   old->drawable.height,
3687314432eSmrg				   0, 0, pixmap->devKind, NULL);
3697314432eSmrg	old->devPrivate.ptr = NULL;
3707314432eSmrg
3717314432eSmrg	screen->DestroyPixmap(pixmap);
3727314432eSmrg
3737314432eSmrg	return old;
3747314432eSmrg}
3757314432eSmrg
376de2362d3Smrg
377de2362d3Smrgstatic Bool
378cd2eb4f7Smrgradeon_glamor_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr secondary,
379de2362d3Smrg				   void **handle_p)
380de2362d3Smrg{
3817314432eSmrg	ScreenPtr screen = pixmap->drawable.pScreen;
3827314432eSmrg	CARD16 stride;
3837314432eSmrg	CARD32 size;
3847314432eSmrg	int fd;
3857314432eSmrg
3867314432eSmrg	if ((radeon_get_pixmap_tiling_flags(pixmap) &
3877314432eSmrg	     RADEON_TILING_MASK) != RADEON_TILING_LINEAR) {
3887314432eSmrg		PixmapPtr linear;
3897314432eSmrg
3907314432eSmrg		/* We don't want to re-allocate the screen pixmap as
3917314432eSmrg		 * linear, to avoid trouble with page flipping
3927314432eSmrg		 */
3937314432eSmrg		if (screen->GetScreenPixmap(screen) == pixmap)
3947314432eSmrg			return FALSE;
395de2362d3Smrg
3967314432eSmrg		linear = screen->CreatePixmap(screen, pixmap->drawable.width,
3977314432eSmrg					      pixmap->drawable.height,
3987314432eSmrg					      pixmap->drawable.depth,
3997314432eSmrg					      CREATE_PIXMAP_USAGE_SHARED);
4007314432eSmrg		if (!linear)
4017314432eSmrg			return FALSE;
4027314432eSmrg
4037314432eSmrg		radeon_glamor_set_pixmap_bo(&pixmap->drawable, linear);
4047314432eSmrg	}
4057314432eSmrg
4067314432eSmrg	fd = glamor_fd_from_pixmap(screen, pixmap, &stride, &size);
4077314432eSmrg	if (fd < 0)
408de2362d3Smrg		return FALSE;
409de2362d3Smrg
4107314432eSmrg	*handle_p = (void *)(long)fd;
4117314432eSmrg	return TRUE;
412de2362d3Smrg}
413de2362d3Smrg
414de2362d3Smrgstatic Bool
415de2362d3Smrgradeon_glamor_set_shared_pixmap_backing(PixmapPtr pixmap, void *handle)
416de2362d3Smrg{
417de2362d3Smrg	ScreenPtr screen = pixmap->drawable.pScreen;
418de2362d3Smrg	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
41939413783Smrg	int ihandle = (int)(long)handle;
420de2362d3Smrg
42139413783Smrg	if (!radeon_set_shared_pixmap_backing(pixmap, handle, NULL))
422de2362d3Smrg		return FALSE;
423de2362d3Smrg
42439413783Smrg	if (ihandle != -1 &&
42539413783Smrg	    !radeon_glamor_create_textured_pixmap(pixmap,
42639413783Smrg						  radeon_get_pixmap_bo(pixmap))) {
427de2362d3Smrg		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
428de2362d3Smrg			   "Failed to get PRIME drawable for glamor pixmap.\n");
429de2362d3Smrg		return FALSE;
430de2362d3Smrg	}
431de2362d3Smrg
432de2362d3Smrg	screen->ModifyPixmapHeader(pixmap,
433de2362d3Smrg				   pixmap->drawable.width,
434de2362d3Smrg				   pixmap->drawable.height,
4350d16fef4Smrg				   0, 0, 0, NULL);
436de2362d3Smrg
437de2362d3Smrg	return TRUE;
438de2362d3Smrg}
439de2362d3Smrg
440de2362d3Smrg
441de2362d3SmrgBool
442de2362d3Smrgradeon_glamor_init(ScreenPtr screen)
443de2362d3Smrg{
444de2362d3Smrg	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
4450d16fef4Smrg	RADEONInfoPtr info = RADEONPTR(scrn);
4460d16fef4Smrg#ifdef RENDER
4470d16fef4Smrg#ifdef HAVE_FBGLYPHS
4480d16fef4Smrg	UnrealizeGlyphProcPtr SavedUnrealizeGlyph = NULL;
4490d16fef4Smrg#endif
4500d16fef4Smrg	PictureScreenPtr ps = NULL;
4510d16fef4Smrg
4520d16fef4Smrg	if (info->shadow_primary) {
4530d16fef4Smrg		ps = GetPictureScreenIfSet(screen);
454de2362d3Smrg
4550d16fef4Smrg		if (ps) {
4560d16fef4Smrg#ifdef HAVE_FBGLYPHS
4570d16fef4Smrg			SavedUnrealizeGlyph = ps->UnrealizeGlyph;
458de2362d3Smrg#endif
4590d16fef4Smrg			info->glamor.SavedGlyphs = ps->Glyphs;
4600d16fef4Smrg			info->glamor.SavedTriangles = ps->Triangles;
4610d16fef4Smrg			info->glamor.SavedTrapezoids = ps->Trapezoids;
4620d16fef4Smrg		}
4630d16fef4Smrg	}
4640d16fef4Smrg#endif /* RENDER */
4650d16fef4Smrg
4660d16fef4Smrg	if (!glamor_init(screen, GLAMOR_USE_EGL_SCREEN | GLAMOR_USE_SCREEN |
4670d16fef4Smrg			 GLAMOR_USE_PICTURE_SCREEN | GLAMOR_INVERTED_Y_AXIS |
4680d16fef4Smrg			 GLAMOR_NO_DRI3)) {
469de2362d3Smrg		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
470de2362d3Smrg			   "Failed to initialize glamor.\n");
471de2362d3Smrg		return FALSE;
472de2362d3Smrg	}
473de2362d3Smrg
474de2362d3Smrg	if (!glamor_egl_init_textured_pixmap(screen)) {
475de2362d3Smrg		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
476de2362d3Smrg			   "Failed to initialize textured pixmap of screen for glamor.\n");
477de2362d3Smrg		return FALSE;
478de2362d3Smrg	}
479de2362d3Smrg
480de2362d3Smrg	if (!dixRegisterPrivateKey(&glamor_pixmap_index, PRIVATE_PIXMAP, 0))
481de2362d3Smrg		return FALSE;
482de2362d3Smrg
4830d16fef4Smrg	if (info->shadow_primary)
4840d16fef4Smrg		radeon_glamor_screen_init(screen);
4850d16fef4Smrg
4860d16fef4Smrg#if defined(RENDER) && defined(HAVE_FBGLYPHS)
4870d16fef4Smrg	/* For ShadowPrimary, we need fbUnrealizeGlyph instead of
4880d16fef4Smrg	 * glamor_unrealize_glyph
4890d16fef4Smrg	 */
4900d16fef4Smrg	if (ps)
4910d16fef4Smrg		ps->UnrealizeGlyph = SavedUnrealizeGlyph;
4920d16fef4Smrg#endif
4930d16fef4Smrg
4940d16fef4Smrg	info->glamor.SavedCreatePixmap = screen->CreatePixmap;
495de2362d3Smrg	screen->CreatePixmap = radeon_glamor_create_pixmap;
4960d16fef4Smrg	info->glamor.SavedDestroyPixmap = screen->DestroyPixmap;
497de2362d3Smrg	screen->DestroyPixmap = radeon_glamor_destroy_pixmap;
4980d16fef4Smrg	info->glamor.SavedSharePixmapBacking = screen->SharePixmapBacking;
499de2362d3Smrg	screen->SharePixmapBacking = radeon_glamor_share_pixmap_backing;
5000d16fef4Smrg	info->glamor.SavedSetSharedPixmapBacking = screen->SetSharedPixmapBacking;
501de2362d3Smrg	screen->SetSharedPixmapBacking = radeon_glamor_set_shared_pixmap_backing;
502de2362d3Smrg
503de2362d3Smrg	xf86DrvMsg(scrn->scrnIndex, X_INFO,
504de2362d3Smrg		   "Use GLAMOR acceleration.\n");
505de2362d3Smrg	return TRUE;
506de2362d3Smrg}
507de2362d3Smrg
508de2362d3Smrgvoid
5090d16fef4Smrgradeon_glamor_fini(ScreenPtr screen)
510de2362d3Smrg{
5110d16fef4Smrg	RADEONInfoPtr info = RADEONPTR(xf86ScreenToScrn(screen));
5120d16fef4Smrg
5130d16fef4Smrg	if (!info->use_glamor)
5140d16fef4Smrg		return;
515de2362d3Smrg
5160d16fef4Smrg	screen->CreatePixmap = info->glamor.SavedCreatePixmap;
5170d16fef4Smrg	screen->DestroyPixmap = info->glamor.SavedDestroyPixmap;
5180d16fef4Smrg	screen->SharePixmapBacking = info->glamor.SavedSharePixmapBacking;
5190d16fef4Smrg	screen->SetSharedPixmapBacking = info->glamor.SavedSetSharedPixmapBacking;
520de2362d3Smrg}
521de2362d3Smrg
522de2362d3SmrgXF86VideoAdaptorPtr radeon_glamor_xv_init(ScreenPtr pScreen, int num_adapt)
523de2362d3Smrg{
524de2362d3Smrg	return glamor_xv_init(pScreen, num_adapt);
525de2362d3Smrg}
526