xorg_exa.c revision 16886c8be34fd17ed34c83ed2e83af2c825c989d
1/*
2 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 *
26 * Author: Alan Hourihane <alanh@tungstengraphics.com>
27 * Author: Jakob Bornecrantz <wallbraker@gmail.com>
28 *
29 */
30
31#include "xorg_exa.h"
32#include "xorg_tracker.h"
33#include "xorg_composite.h"
34#include "xorg_exa_tgsi.h"
35
36#include <xorg-server.h>
37#include <xf86.h>
38#include <picturestr.h>
39#include <picture.h>
40
41#include "pipe/p_format.h"
42#include "pipe/p_context.h"
43#include "pipe/p_state.h"
44#include "pipe/p_inlines.h"
45
46#include "cso_cache/cso_context.h"
47
48#include "util/u_rect.h"
49
50/*
51 * Helper functions
52 */
53
54static void
55exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp)
56{
57    switch (depth) {
58    case 32:
59	*format = PIPE_FORMAT_A8R8G8B8_UNORM;
60	assert(*bbp == 32);
61	break;
62    case 24:
63	*format = PIPE_FORMAT_X8R8G8B8_UNORM;
64	assert(*bbp == 32);
65	break;
66    case 16:
67	*format = PIPE_FORMAT_R5G6B5_UNORM;
68	assert(*bbp == 16);
69	break;
70    case 15:
71	*format = PIPE_FORMAT_A1R5G5B5_UNORM;
72	assert(*bbp == 16);
73	break;
74    case 8:
75    case 4:
76    case 1:
77	*format = PIPE_FORMAT_A8R8G8B8_UNORM; /* bad bad bad */
78	break;
79    default:
80	assert(0);
81	break;
82    }
83}
84
85/*
86 * Static exported EXA functions
87 */
88
89static void
90ExaWaitMarker(ScreenPtr pScreen, int marker)
91{
92}
93
94static int
95ExaMarkSync(ScreenPtr pScreen)
96{
97    return 1;
98}
99
100static Bool
101ExaDownloadFromScreen(PixmapPtr pPix, int x,  int y, int w,  int h, char *dst,
102		      int dst_pitch)
103{
104    ScreenPtr pScreen = pPix->drawable.pScreen;
105    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
106    modesettingPtr ms = modesettingPTR(pScrn);
107    struct exa_context *exa = ms->exa;
108    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix);
109    struct pipe_transfer *transfer;
110
111    if (!priv || !priv->tex)
112	return FALSE;
113
114    if (exa->ctx->is_texture_referenced(exa->ctx, priv->tex, 0, 0) &
115	PIPE_REFERENCED_FOR_WRITE)
116	exa->ctx->flush(exa->ctx, 0, NULL);
117
118    transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
119					   PIPE_TRANSFER_READ, x, y, w, h);
120    if (!transfer)
121	return FALSE;
122
123    util_copy_rect((unsigned char*)dst, &priv->tex->block, dst_pitch, 0, 0,
124		   w, h, exa->scrn->transfer_map(exa->scrn, transfer),
125		   transfer->stride, 0, 0);
126
127    exa->scrn->transfer_unmap(exa->scrn, transfer);
128    exa->scrn->tex_transfer_destroy(transfer);
129
130    return TRUE;
131}
132
133static Bool
134ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
135		  int src_pitch)
136{
137    ScreenPtr pScreen = pPix->drawable.pScreen;
138    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
139    modesettingPtr ms = modesettingPTR(pScrn);
140    struct exa_context *exa = ms->exa;
141    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix);
142    struct pipe_transfer *transfer;
143
144    if (!priv || !priv->tex)
145	return FALSE;
146
147    transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
148					   PIPE_TRANSFER_WRITE, x, y, w, h);
149    if (!transfer)
150	return FALSE;
151
152    util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
153		   &priv->tex->block, transfer->stride, 0, 0, w, h,
154		   (unsigned char*)src, src_pitch, 0, 0);
155
156    exa->scrn->transfer_unmap(exa->scrn, transfer);
157    exa->scrn->tex_transfer_destroy(transfer);
158
159    return TRUE;
160}
161
162static Bool
163ExaPrepareAccess(PixmapPtr pPix, int index)
164{
165    ScreenPtr pScreen = pPix->drawable.pScreen;
166    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
167    modesettingPtr ms = modesettingPTR(pScrn);
168    struct exa_context *exa = ms->exa;
169    struct exa_pixmap_priv *priv;
170
171    priv = exaGetPixmapDriverPrivate(pPix);
172
173    if (!priv)
174	return FALSE;
175
176    if (!priv->tex)
177	return FALSE;
178
179    if (priv->map_count++ == 0)
180    {
181	if (exa->ctx->is_texture_referenced(exa->ctx, priv->tex, 0, 0) &
182	    PIPE_REFERENCED_FOR_WRITE)
183	    exa->ctx->flush(exa->ctx, 0, NULL);
184
185	priv->map_transfer =
186	    exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
187					PIPE_TRANSFER_READ_WRITE,
188					0, 0, priv->tex->width[0], priv->tex->height[0]);
189
190	pPix->devPrivate.ptr =
191	    exa->scrn->transfer_map(exa->scrn, priv->map_transfer);
192	pPix->devKind = priv->map_transfer->stride;
193    }
194
195    return TRUE;
196}
197
198static void
199ExaFinishAccess(PixmapPtr pPix, int index)
200{
201    ScreenPtr pScreen = pPix->drawable.pScreen;
202    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
203    modesettingPtr ms = modesettingPTR(pScrn);
204    struct exa_context *exa = ms->exa;
205    struct exa_pixmap_priv *priv;
206    priv = exaGetPixmapDriverPrivate(pPix);
207
208    if (!priv)
209	return;
210
211    if (!priv->map_transfer)
212	return;
213
214    if (--priv->map_count == 0) {
215	assert(priv->map_transfer);
216	exa->scrn->transfer_unmap(exa->scrn, priv->map_transfer);
217	exa->scrn->tex_transfer_destroy(priv->map_transfer);
218	priv->map_transfer = NULL;
219	pPix->devPrivate.ptr = NULL;
220    }
221}
222
223static void
224ExaDone(PixmapPtr pPixmap)
225{
226    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
227    modesettingPtr ms = modesettingPTR(pScrn);
228    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
229    struct exa_context *exa = ms->exa;
230    struct pipe_fence_handle *fence = NULL;
231
232    if (!priv)
233	return;
234
235    exa->ctx->flush(exa->ctx, PIPE_FLUSH_RENDER_CACHE, &fence);
236#if 0
237    exa->ctx->screen->fence_finish(exa->ctx->screen, fence, 0);
238    exa->ctx->screen->fence_reference(exa->ctx->screen, &fence, NULL);
239#endif
240
241    if (priv->src_surf)
242	exa->scrn->tex_surface_destroy(priv->src_surf);
243    priv->src_surf = NULL;
244}
245
246static void
247ExaDoneComposite(PixmapPtr pPixmap)
248{
249
250}
251
252static Bool
253ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
254{
255    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
256    modesettingPtr ms = modesettingPTR(pScrn);
257    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
258    struct exa_context *exa = ms->exa;
259
260    debug_printf("ExaPrepareSolid - test\n");
261    if (pPixmap->drawable.depth < 15)
262	return FALSE;
263
264    if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask))
265	return FALSE;
266
267    if (!priv || !priv->tex)
268	return FALSE;
269
270    if (alu != GXcopy)
271	return FALSE;
272
273    if (!exa->ctx)
274	return FALSE;
275
276    debug_printf("  ExaPrepareSolid(0x%x)\n", fg);
277    return xorg_solid_bind_state(exa, priv, fg);
278}
279
280static void
281ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1)
282{
283    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
284    modesettingPtr ms = modesettingPTR(pScrn);
285    struct exa_context *exa = ms->exa;
286    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
287
288    debug_printf("\tExaSolid(%d, %d, %d, %d)\n", x0, y0, x1, y1);
289
290#if 0
291    if (x0 == 0 && y0 == 0 &&
292        x1 == priv->tex->width[0] &&
293        y1 == priv->tex->height[0]) {
294       exa->ctx->clear(exa->ctx, PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL,
295                       exa->solid_color, 1., 0);
296    } else
297#endif
298       xorg_solid(exa, priv, x0, y0, x1, y1) ;
299}
300
301static Bool
302ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
303	       int ydir, int alu, Pixel planeMask)
304{
305    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
306    modesettingPtr ms = modesettingPTR(pScrn);
307    struct exa_context *exa = ms->exa;
308    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
309    struct exa_pixmap_priv *src_priv = exaGetPixmapDriverPrivate(pSrcPixmap);
310
311    debug_printf("ExaPrepareCopy\n");
312
313    if (alu != GXcopy)
314	return FALSE;
315
316    if (pSrcPixmap->drawable.depth < 15 || pDstPixmap->drawable.depth < 15)
317	return FALSE;
318
319    if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planeMask))
320	return FALSE;
321
322    if (!priv || !src_priv)
323	return FALSE;
324
325    if (!priv->tex || !src_priv->tex)
326	return FALSE;
327
328    if (!exa->ctx || !exa->ctx->surface_copy)
329	return FALSE;
330
331    priv->src_surf = exa_gpu_surface(exa, src_priv);
332
333    return TRUE;
334}
335
336static void
337ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
338	int width, int height)
339{
340    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
341    modesettingPtr ms = modesettingPTR(pScrn);
342    struct exa_context *exa = ms->exa;
343    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
344    struct pipe_surface *surf = exa_gpu_surface(exa, priv);
345
346    debug_printf("\tExaCopy\n");
347
348    exa->ctx->surface_copy(exa->ctx, surf, dstX, dstY, priv->src_surf,
349			   srcX, srcY, width, height);
350    exa->scrn->tex_surface_destroy(surf);
351}
352
353static Bool
354ExaPrepareComposite(int op, PicturePtr pSrcPicture,
355		    PicturePtr pMaskPicture, PicturePtr pDstPicture,
356		    PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
357{
358   ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
359   modesettingPtr ms = modesettingPTR(pScrn);
360   struct exa_context *exa = ms->exa;
361
362   debug_printf("ExaPrepareComposite\n");
363
364   return xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture,
365                                    pDstPicture,
366                                    exaGetPixmapDriverPrivate(pSrc),
367                                    exaGetPixmapDriverPrivate(pMask),
368                                    exaGetPixmapDriverPrivate(pDst));
369}
370
371static void
372ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
373	     int dstX, int dstY, int width, int height)
374{
375   ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
376   modesettingPtr ms = modesettingPTR(pScrn);
377   struct exa_context *exa = ms->exa;
378   struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDst);
379
380   debug_printf("\tExaComposite\n");
381
382   xorg_composite(exa, priv, srcX, srcY, maskX, maskY,
383                  dstX, dstY, width, height);
384}
385
386static Bool
387ExaCheckComposite(int op,
388		  PicturePtr pSrcPicture, PicturePtr pMaskPicture,
389		  PicturePtr pDstPicture)
390{
391   return xorg_composite_accelerated(op,
392                                     pSrcPicture,
393                                     pMaskPicture,
394                                     pDstPicture);
395}
396
397static void *
398ExaCreatePixmap(ScreenPtr pScreen, int size, int align)
399{
400    struct exa_pixmap_priv *priv;
401
402    priv = xcalloc(1, sizeof(struct exa_pixmap_priv));
403    if (!priv)
404	return NULL;
405
406    return priv;
407}
408
409static void
410ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv)
411{
412    struct exa_pixmap_priv *priv = (struct exa_pixmap_priv *)dPriv;
413    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
414    modesettingPtr ms = modesettingPTR(pScrn);
415
416    if (!priv)
417	return;
418
419    if (priv->tex)
420	ms->screen->texture_destroy(priv->tex);
421
422    xfree(priv);
423}
424
425static Bool
426ExaPixmapIsOffscreen(PixmapPtr pPixmap)
427{
428    struct exa_pixmap_priv *priv;
429
430    priv = exaGetPixmapDriverPrivate(pPixmap);
431
432    if (!priv)
433	return FALSE;
434
435    if (priv->tex)
436	return TRUE;
437
438    return FALSE;
439}
440
441int
442xorg_exa_set_displayed_usage(PixmapPtr pPixmap)
443{
444    struct exa_pixmap_priv *priv;
445    priv = exaGetPixmapDriverPrivate(pPixmap);
446
447    if (!priv) {
448	FatalError("NO PIXMAP PRIVATE\n");
449	return 0;
450    }
451
452    priv->flags |= PIPE_TEXTURE_USAGE_PRIMARY;
453
454    return 0;
455}
456
457int
458xorg_exa_set_shared_usage(PixmapPtr pPixmap)
459{
460    struct exa_pixmap_priv *priv;
461    priv = exaGetPixmapDriverPrivate(pPixmap);
462
463    if (!priv) {
464	FatalError("NO PIXMAP PRIVATE\n");
465	return 0;
466    }
467
468    priv->flags |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
469
470    return 0;
471}
472
473unsigned
474xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out)
475{
476    ScreenPtr pScreen = pPixmap->drawable.pScreen;
477    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
478    modesettingPtr ms = modesettingPTR(pScrn);
479    struct exa_pixmap_priv *priv;
480    unsigned handle;
481    unsigned stride;
482
483    if (!ms->exa) {
484	FatalError("NO MS->EXA\n");
485	return 0;
486    }
487
488    priv = exaGetPixmapDriverPrivate(pPixmap);
489
490    if (!priv) {
491	FatalError("NO PIXMAP PRIVATE\n");
492	return 0;
493    }
494
495    ms->api->local_handle_from_texture(ms->api, ms->screen, priv->tex, &stride, &handle);
496    if (stride_out)
497	*stride_out = stride;
498
499    return handle;
500}
501
502static Bool
503ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
504		      int depth, int bitsPerPixel, int devKind,
505		      pointer pPixData)
506{
507    ScreenPtr pScreen = pPixmap->drawable.pScreen;
508    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
509    struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
510    modesettingPtr ms = modesettingPTR(pScrn);
511    struct exa_context *exa = ms->exa;
512
513    if (!priv || pPixData)
514	return FALSE;
515
516    if (depth <= 0)
517	depth = pPixmap->drawable.depth;
518
519    if (bitsPerPixel <= 0)
520	bitsPerPixel = pPixmap->drawable.bitsPerPixel;
521
522    if (width <= 0)
523	width = pPixmap->drawable.width;
524
525    if (height <= 0)
526	height = pPixmap->drawable.height;
527
528    if (width <= 0 || height <= 0 || depth <= 0)
529	return FALSE;
530
531    miModifyPixmapHeader(pPixmap, width, height, depth,
532			     bitsPerPixel, devKind, NULL);
533
534    /* Deal with screen resize */
535    if (!priv->tex ||
536        (priv->tex->width[0] != width ||
537         priv->tex->height[0] != height ||
538         priv->tex_flags != priv->flags)) {
539	struct pipe_texture *texture = NULL;
540
541#ifdef DRM_MODE_FEATURE_DIRTYFB
542	if (priv->flags)
543#endif
544	{
545	    struct pipe_texture template;
546
547	    memset(&template, 0, sizeof(template));
548	    template.target = PIPE_TEXTURE_2D;
549	    exa_get_pipe_format(depth, &template.format, &bitsPerPixel);
550	    pf_get_block(template.format, &template.block);
551	    template.width[0] = width;
552	    template.height[0] = height;
553	    template.depth[0] = 1;
554	    template.last_level = 0;
555	    template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags;
556	    priv->tex_flags = priv->flags;
557	    texture = exa->scrn->texture_create(exa->scrn, &template);
558
559	    if (priv->tex) {
560		struct pipe_surface *dst_surf;
561
562		dst_surf = exa->scrn->get_tex_surface(exa->scrn, texture, 0, 0, 0,
563						      PIPE_BUFFER_USAGE_GPU_WRITE);
564		priv->src_surf = exa_gpu_surface(exa, priv);
565		exa->ctx->surface_copy(exa->ctx, dst_surf, 0, 0, priv->src_surf,
566				       0, 0, min(width, texture->width[0]),
567				       min(height, texture->height[0]));
568		exa->scrn->tex_surface_destroy(dst_surf);
569		exa->scrn->tex_surface_destroy(priv->src_surf);
570		priv->src_surf = NULL;
571	    } else if (pPixmap->devPrivate.ptr) {
572		struct pipe_transfer *transfer;
573
574		if (priv->map_count != 0)
575		     FatalError("doing ExaModifyPixmapHeader on mapped buffer\n");
576
577		transfer =
578		    exa->scrn->get_tex_transfer(exa->scrn, texture, 0, 0, 0,
579						PIPE_TRANSFER_WRITE,
580						0, 0, width, height);
581		util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
582			       &texture->block, transfer->stride, 0, 0,
583			       width, height, pPixmap->devPrivate.ptr,
584			       pPixmap->devKind, 0, 0);
585		exa->scrn->transfer_unmap(exa->scrn, transfer);
586		exa->scrn->tex_transfer_destroy(transfer);
587
588		xfree(pPixmap->devPrivate.ptr);
589		pPixmap->devPrivate.ptr = NULL;
590	    }
591	}
592#ifdef DRM_MODE_FEATURE_DIRTYFB
593	else {
594	    xfree(pPixmap->devPrivate.ptr);
595	    pPixmap->devPrivate.ptr = xalloc(pPixmap->drawable.height *
596					     pPixmap->devKind);
597	}
598#endif
599
600	pipe_texture_reference(&priv->tex, texture);
601    }
602
603    return TRUE;
604}
605
606struct pipe_texture *
607xorg_exa_get_texture(PixmapPtr pPixmap)
608{
609   struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
610   struct pipe_texture *tex = NULL;
611   pipe_texture_reference(&tex, priv->tex);
612   return tex;
613}
614
615void
616xorg_exa_close(ScrnInfoPtr pScrn)
617{
618   modesettingPtr ms = modesettingPTR(pScrn);
619   struct exa_context *exa = ms->exa;
620   struct pipe_constant_buffer *vsbuf = &exa->vs_const_buffer;
621   struct pipe_constant_buffer *fsbuf = &exa->fs_const_buffer;
622
623   if (exa->shaders) {
624      xorg_shaders_destroy(exa->shaders);
625   }
626
627   if (vsbuf && vsbuf->buffer)
628      pipe_buffer_reference(&vsbuf->buffer, NULL);
629
630   if (fsbuf && fsbuf->buffer)
631      pipe_buffer_reference(&fsbuf->buffer, NULL);
632
633   if (exa->cso) {
634      cso_release_all(exa->cso);
635      cso_destroy_context(exa->cso);
636   }
637
638   if (exa->ctx)
639      exa->ctx->destroy(exa->ctx);
640
641   exaDriverFini(pScrn->pScreen);
642   xfree(exa);
643   ms->exa = NULL;
644}
645
646void *
647xorg_exa_init(ScrnInfoPtr pScrn)
648{
649   modesettingPtr ms = modesettingPTR(pScrn);
650   struct exa_context *exa;
651   ExaDriverPtr pExa;
652
653   exa = xcalloc(1, sizeof(struct exa_context));
654   if (!exa)
655      return NULL;
656
657   pExa = exaDriverAlloc();
658   if (!pExa) {
659      goto out_err;
660   }
661
662   memset(pExa, 0, sizeof(*pExa));
663
664   pExa->exa_major         = 2;
665   pExa->exa_minor         = 2;
666   pExa->memoryBase        = 0;
667   pExa->memorySize        = 0;
668   pExa->offScreenBase     = 0;
669   pExa->pixmapOffsetAlign = 0;
670   pExa->pixmapPitchAlign  = 1;
671   pExa->flags             = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
672#ifdef EXA_SUPPORTS_PREPARE_AUX
673   pExa->flags            |= EXA_SUPPORTS_PREPARE_AUX;
674#endif
675#ifdef EXA_MIXED_PIXMAPS
676   pExa->flags            |= EXA_MIXED_PIXMAPS;
677#endif
678   pExa->maxX              = 8191; /* FIXME */
679   pExa->maxY              = 8191; /* FIXME */
680
681   pExa->WaitMarker         = ExaWaitMarker;
682   pExa->MarkSync           = ExaMarkSync;
683   pExa->PrepareSolid       = ExaPrepareSolid;
684   pExa->Solid              = ExaSolid;
685   pExa->DoneSolid          = ExaDone;
686   pExa->PrepareCopy        = ExaPrepareCopy;
687   pExa->Copy               = ExaCopy;
688   pExa->DoneCopy           = ExaDone;
689   pExa->CheckComposite     = ExaCheckComposite;
690   pExa->PrepareComposite   = ExaPrepareComposite;
691   pExa->Composite          = ExaComposite;
692   pExa->DoneComposite      = ExaDoneComposite;
693   pExa->PixmapIsOffscreen  = ExaPixmapIsOffscreen;
694   pExa->DownloadFromScreen = ExaDownloadFromScreen;
695   pExa->UploadToScreen     = ExaUploadToScreen;
696   pExa->PrepareAccess      = ExaPrepareAccess;
697   pExa->FinishAccess       = ExaFinishAccess;
698   pExa->CreatePixmap       = ExaCreatePixmap;
699   pExa->DestroyPixmap      = ExaDestroyPixmap;
700   pExa->ModifyPixmapHeader = ExaModifyPixmapHeader;
701
702   if (!exaDriverInit(pScrn->pScreen, pExa)) {
703      goto out_err;
704   }
705
706   exa->scrn = ms->screen;
707   exa->ctx = ms->api->create_context(ms->api, exa->scrn);
708   /* Share context with DRI */
709   ms->ctx = exa->ctx;
710
711   exa->cso = cso_create_context(exa->ctx);
712   exa->shaders = xorg_shaders_create(exa);
713
714   return (void *)exa;
715
716out_err:
717   xorg_exa_close(pScrn);
718
719   return NULL;
720}
721
722struct pipe_surface *
723exa_gpu_surface(struct exa_context *exa, struct exa_pixmap_priv *priv)
724{
725   return exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
726                                     PIPE_BUFFER_USAGE_GPU_READ |
727                                     PIPE_BUFFER_USAGE_GPU_WRITE);
728
729}
730
731