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