st/xorg: Add EXA UploadToScreen and DownloadFromScreen hooks.
[mesa.git] / src / gallium / state_trackers / xorg / xorg_exa.c
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
54 static void
55 exa_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
89 static void
90 ExaWaitMarker(ScreenPtr pScreen, int marker)
91 {
92 }
93
94 static int
95 ExaMarkSync(ScreenPtr pScreen)
96 {
97 return 1;
98 }
99
100 static Bool
101 ExaDownloadFromScreen(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
133 static Bool
134 ExaUploadToScreen(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
162 static Bool
163 ExaPrepareAccess(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
198 static void
199 ExaFinishAccess(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
223 static void
224 ExaDone(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
231 if (!priv)
232 return;
233
234 if (priv->src_surf)
235 exa->scrn->tex_surface_destroy(priv->src_surf);
236 priv->src_surf = NULL;
237 }
238
239 static void
240 ExaDoneComposite(PixmapPtr pPixmap)
241 {
242
243 }
244
245 static Bool
246 ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
247 {
248 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
249 modesettingPtr ms = modesettingPTR(pScrn);
250 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
251 struct exa_context *exa = ms->exa;
252
253 if (pPixmap->drawable.depth < 15)
254 return FALSE;
255
256 if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask))
257 return FALSE;
258
259 if (!priv || !priv->tex)
260 return FALSE;
261
262 if (alu != GXcopy)
263 return FALSE;
264
265 if (!exa->ctx || !exa->ctx->surface_fill)
266 return FALSE;
267
268 priv->color = fg;
269
270 return TRUE;
271 }
272
273 static void
274 ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1)
275 {
276 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
277 modesettingPtr ms = modesettingPTR(pScrn);
278 struct exa_context *exa = ms->exa;
279 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
280 struct pipe_surface *surf = exa_gpu_surface(exa, priv);
281
282 exa->ctx->surface_fill(exa->ctx, surf, x0, y0, x1 - x0, y1 - y0,
283 priv->color);
284
285 exa->scrn->tex_surface_destroy(surf);
286 }
287
288 static Bool
289 ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
290 int ydir, int alu, Pixel planeMask)
291 {
292 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
293 modesettingPtr ms = modesettingPTR(pScrn);
294 struct exa_context *exa = ms->exa;
295 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
296 struct exa_pixmap_priv *src_priv = exaGetPixmapDriverPrivate(pSrcPixmap);
297
298 if (alu != GXcopy)
299 return FALSE;
300
301 if (pSrcPixmap->drawable.depth < 15 || pDstPixmap->drawable.depth < 15)
302 return FALSE;
303
304 if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planeMask))
305 return FALSE;
306
307 if (!priv || !src_priv)
308 return FALSE;
309
310 if (!priv->tex || !src_priv->tex)
311 return FALSE;
312
313 if (!exa->ctx || !exa->ctx->surface_copy)
314 return FALSE;
315
316 priv->src_surf = exa_gpu_surface(exa, src_priv);
317
318 return TRUE;
319 }
320
321 static void
322 ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
323 int width, int height)
324 {
325 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
326 modesettingPtr ms = modesettingPTR(pScrn);
327 struct exa_context *exa = ms->exa;
328 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
329 struct pipe_surface *surf = exa_gpu_surface(exa, priv);
330
331 exa->ctx->surface_copy(exa->ctx, surf, dstX, dstY, priv->src_surf,
332 srcX, srcY, width, height);
333 exa->scrn->tex_surface_destroy(surf);
334 }
335
336 static Bool
337 ExaPrepareComposite(int op, PicturePtr pSrcPicture,
338 PicturePtr pMaskPicture, PicturePtr pDstPicture,
339 PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
340 {
341 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
342 modesettingPtr ms = modesettingPTR(pScrn);
343 struct exa_context *exa = ms->exa;
344
345 return xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture,
346 pDstPicture,
347 exaGetPixmapDriverPrivate(pSrc),
348 exaGetPixmapDriverPrivate(pMask),
349 exaGetPixmapDriverPrivate(pDst));
350 }
351
352 static void
353 ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
354 int dstX, int dstY, int width, int height)
355 {
356 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
357 modesettingPtr ms = modesettingPTR(pScrn);
358 struct exa_context *exa = ms->exa;
359 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDst);
360
361 xorg_composite(exa, priv, srcX, srcY, maskX, maskY,
362 dstX, dstY, width, height);
363 }
364
365 static Bool
366 ExaCheckComposite(int op,
367 PicturePtr pSrcPicture, PicturePtr pMaskPicture,
368 PicturePtr pDstPicture)
369 {
370 return xorg_composite_accelerated(op,
371 pSrcPicture,
372 pMaskPicture,
373 pDstPicture);
374 }
375
376 static void *
377 ExaCreatePixmap(ScreenPtr pScreen, int size, int align)
378 {
379 struct exa_pixmap_priv *priv;
380
381 priv = xcalloc(1, sizeof(struct exa_pixmap_priv));
382 if (!priv)
383 return NULL;
384
385 return priv;
386 }
387
388 static void
389 ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv)
390 {
391 struct exa_pixmap_priv *priv = (struct exa_pixmap_priv *)dPriv;
392 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
393 modesettingPtr ms = modesettingPTR(pScrn);
394
395 if (!priv)
396 return;
397
398 if (priv->tex)
399 ms->screen->texture_destroy(priv->tex);
400
401 xfree(priv);
402 }
403
404 static Bool
405 ExaPixmapIsOffscreen(PixmapPtr pPixmap)
406 {
407 struct exa_pixmap_priv *priv;
408
409 priv = exaGetPixmapDriverPrivate(pPixmap);
410
411 if (!priv)
412 return FALSE;
413
414 if (priv->tex)
415 return TRUE;
416
417 return FALSE;
418 }
419
420 int
421 xorg_exa_set_displayed_usage(PixmapPtr pPixmap)
422 {
423 struct exa_pixmap_priv *priv;
424 priv = exaGetPixmapDriverPrivate(pPixmap);
425
426 if (!priv) {
427 FatalError("NO PIXMAP PRIVATE\n");
428 return 0;
429 }
430
431 priv->flags |= PIPE_TEXTURE_USAGE_PRIMARY;
432
433 return 0;
434 }
435
436 int
437 xorg_exa_set_shared_usage(PixmapPtr pPixmap)
438 {
439 struct exa_pixmap_priv *priv;
440 priv = exaGetPixmapDriverPrivate(pPixmap);
441
442 if (!priv) {
443 FatalError("NO PIXMAP PRIVATE\n");
444 return 0;
445 }
446
447 priv->flags |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
448
449 return 0;
450 }
451
452 unsigned
453 xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out)
454 {
455 ScreenPtr pScreen = pPixmap->drawable.pScreen;
456 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
457 modesettingPtr ms = modesettingPTR(pScrn);
458 struct exa_pixmap_priv *priv;
459 unsigned handle;
460 unsigned stride;
461
462 if (!ms->exa) {
463 FatalError("NO MS->EXA\n");
464 return 0;
465 }
466
467 priv = exaGetPixmapDriverPrivate(pPixmap);
468
469 if (!priv) {
470 FatalError("NO PIXMAP PRIVATE\n");
471 return 0;
472 }
473
474 ms->api->local_handle_from_texture(ms->api, ms->screen, priv->tex, &stride, &handle);
475 if (stride_out)
476 *stride_out = stride;
477
478 return handle;
479 }
480
481 static Bool
482 ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
483 int depth, int bitsPerPixel, int devKind,
484 pointer pPixData)
485 {
486 ScreenPtr pScreen = pPixmap->drawable.pScreen;
487 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
488 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
489 modesettingPtr ms = modesettingPTR(pScrn);
490 struct exa_context *exa = ms->exa;
491
492 if (!priv || pPixData)
493 return FALSE;
494
495 if (depth <= 0)
496 depth = pPixmap->drawable.depth;
497
498 if (bitsPerPixel <= 0)
499 bitsPerPixel = pPixmap->drawable.bitsPerPixel;
500
501 if (width <= 0)
502 width = pPixmap->drawable.width;
503
504 if (height <= 0)
505 height = pPixmap->drawable.height;
506
507 if (width <= 0 || height <= 0 || depth <= 0)
508 return FALSE;
509
510 miModifyPixmapHeader(pPixmap, width, height, depth,
511 bitsPerPixel, devKind, NULL);
512
513 /* Deal with screen resize */
514 if (!priv->tex ||
515 (priv->tex->width[0] != width ||
516 priv->tex->height[0] != height ||
517 priv->tex_flags != priv->flags)) {
518 struct pipe_texture *texture = NULL;
519
520 #ifdef DRM_MODE_FEATURE_DIRTYFB
521 if (priv->flags)
522 #endif
523 {
524 struct pipe_texture template;
525
526 memset(&template, 0, sizeof(template));
527 template.target = PIPE_TEXTURE_2D;
528 exa_get_pipe_format(depth, &template.format, &bitsPerPixel);
529 pf_get_block(template.format, &template.block);
530 template.width[0] = width;
531 template.height[0] = height;
532 template.depth[0] = 1;
533 template.last_level = 0;
534 template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags;
535 priv->tex_flags = priv->flags;
536 texture = exa->scrn->texture_create(exa->scrn, &template);
537
538 if (priv->tex) {
539 struct pipe_surface *dst_surf;
540
541 dst_surf = exa->scrn->get_tex_surface(exa->scrn, texture, 0, 0, 0,
542 PIPE_BUFFER_USAGE_GPU_WRITE);
543 priv->src_surf = exa_gpu_surface(exa, priv);
544 exa->ctx->surface_copy(exa->ctx, dst_surf, 0, 0, priv->src_surf,
545 0, 0, min(width, texture->width[0]),
546 min(height, texture->height[0]));
547 exa->scrn->tex_surface_destroy(dst_surf);
548 exa->scrn->tex_surface_destroy(priv->src_surf);
549 priv->src_surf = NULL;
550 } else if (pPixmap->devPrivate.ptr) {
551 struct pipe_transfer *transfer;
552
553 if (priv->map_count != 0)
554 FatalError("doing ExaModifyPixmapHeader on mapped buffer\n");
555
556 transfer =
557 exa->scrn->get_tex_transfer(exa->scrn, texture, 0, 0, 0,
558 PIPE_TRANSFER_WRITE,
559 0, 0, width, height);
560 util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
561 &texture->block, transfer->stride, 0, 0,
562 width, height, pPixmap->devPrivate.ptr,
563 pPixmap->devKind, 0, 0);
564 exa->scrn->transfer_unmap(exa->scrn, transfer);
565 exa->scrn->tex_transfer_destroy(transfer);
566 }
567 }
568 #ifdef DRM_MODE_FEATURE_DIRTYFB
569 else {
570 xfree(pPixmap->devPrivate.ptr);
571 pPixmap->devPrivate.ptr = xalloc(pPixmap->drawable.height *
572 pPixmap->devKind);
573 }
574 #endif
575
576 pipe_texture_reference(&priv->tex, texture);
577 }
578
579 return TRUE;
580 }
581
582 struct pipe_texture *
583 xorg_exa_get_texture(PixmapPtr pPixmap)
584 {
585 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
586 struct pipe_texture *tex = NULL;
587 pipe_texture_reference(&tex, priv->tex);
588 return tex;
589 }
590
591 void
592 xorg_exa_close(ScrnInfoPtr pScrn)
593 {
594 modesettingPtr ms = modesettingPTR(pScrn);
595 struct exa_context *exa = ms->exa;
596 struct pipe_constant_buffer *vsbuf = &exa->vs_const_buffer;
597 struct pipe_constant_buffer *fsbuf = &exa->fs_const_buffer;
598
599 if (exa->shaders) {
600 xorg_shaders_destroy(exa->shaders);
601 }
602
603 if (vsbuf && vsbuf->buffer)
604 pipe_buffer_reference(&vsbuf->buffer, NULL);
605
606 if (fsbuf && fsbuf->buffer)
607 pipe_buffer_reference(&fsbuf->buffer, NULL);
608
609 if (exa->cso) {
610 cso_release_all(exa->cso);
611 cso_destroy_context(exa->cso);
612 }
613
614 if (exa->ctx)
615 exa->ctx->destroy(exa->ctx);
616
617 exaDriverFini(pScrn->pScreen);
618 xfree(exa);
619 ms->exa = NULL;
620 }
621
622 void *
623 xorg_exa_init(ScrnInfoPtr pScrn)
624 {
625 modesettingPtr ms = modesettingPTR(pScrn);
626 struct exa_context *exa;
627 ExaDriverPtr pExa;
628
629 exa = xcalloc(1, sizeof(struct exa_context));
630 if (!exa)
631 return NULL;
632
633 pExa = exaDriverAlloc();
634 if (!pExa) {
635 goto out_err;
636 }
637
638 memset(pExa, 0, sizeof(*pExa));
639
640 pExa->exa_major = 2;
641 pExa->exa_minor = 2;
642 pExa->memoryBase = 0;
643 pExa->memorySize = 0;
644 pExa->offScreenBase = 0;
645 pExa->pixmapOffsetAlign = 0;
646 pExa->pixmapPitchAlign = 1;
647 pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
648 pExa->maxX = 8191; /* FIXME */
649 pExa->maxY = 8191; /* FIXME */
650
651 pExa->WaitMarker = ExaWaitMarker;
652 pExa->MarkSync = ExaMarkSync;
653 pExa->PrepareSolid = ExaPrepareSolid;
654 pExa->Solid = ExaSolid;
655 pExa->DoneSolid = ExaDone;
656 pExa->PrepareCopy = ExaPrepareCopy;
657 pExa->Copy = ExaCopy;
658 pExa->DoneCopy = ExaDone;
659 pExa->CheckComposite = ExaCheckComposite;
660 pExa->PrepareComposite = ExaPrepareComposite;
661 pExa->Composite = ExaComposite;
662 pExa->DoneComposite = ExaDoneComposite;
663 pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen;
664 pExa->DownloadFromScreen = ExaDownloadFromScreen;
665 pExa->UploadToScreen = ExaUploadToScreen;
666 pExa->PrepareAccess = ExaPrepareAccess;
667 pExa->FinishAccess = ExaFinishAccess;
668 pExa->CreatePixmap = ExaCreatePixmap;
669 pExa->DestroyPixmap = ExaDestroyPixmap;
670 pExa->ModifyPixmapHeader = ExaModifyPixmapHeader;
671
672 if (!exaDriverInit(pScrn->pScreen, pExa)) {
673 goto out_err;
674 }
675
676 exa->scrn = ms->screen;
677 exa->ctx = ms->api->create_context(ms->api, exa->scrn);
678 /* Share context with DRI */
679 ms->ctx = exa->ctx;
680
681 exa->cso = cso_create_context(exa->ctx);
682 exa->shaders = xorg_shaders_create(exa);
683
684 return (void *)exa;
685
686 out_err:
687 xorg_exa_close(pScrn);
688
689 return NULL;
690 }
691
692 struct pipe_surface *
693 exa_gpu_surface(struct exa_context *exa, struct exa_pixmap_priv *priv)
694 {
695 return exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
696 PIPE_BUFFER_USAGE_GPU_READ |
697 PIPE_BUFFER_USAGE_GPU_WRITE);
698
699 }
700