Merge branch 'mesa_7_6_branch'
[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 static void
86 xorg_exa_init_state(struct exa_context *exa)
87 {
88 struct pipe_depth_stencil_alpha_state dsa;
89
90 /* set common initial clip state */
91 memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
92 cso_set_depth_stencil_alpha(exa->cso, &dsa);
93 }
94
95 static void
96 xorg_exa_common_done(struct exa_context *exa)
97 {
98 exa->copy.src = NULL;
99 exa->copy.dst = NULL;
100 exa->has_solid_color = FALSE;
101 exa->num_bound_samplers = 0;
102 }
103
104 /*
105 * Static exported EXA functions
106 */
107
108 static void
109 ExaWaitMarker(ScreenPtr pScreen, int marker)
110 {
111 }
112
113 static int
114 ExaMarkSync(ScreenPtr pScreen)
115 {
116 return 1;
117 }
118
119 static Bool
120 ExaDownloadFromScreen(PixmapPtr pPix, int x, int y, int w, int h, char *dst,
121 int dst_pitch)
122 {
123 ScreenPtr pScreen = pPix->drawable.pScreen;
124 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
125 modesettingPtr ms = modesettingPTR(pScrn);
126 struct exa_context *exa = ms->exa;
127 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix);
128 struct pipe_transfer *transfer;
129
130 if (!priv || !priv->tex)
131 return FALSE;
132
133 if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) &
134 PIPE_REFERENCED_FOR_WRITE)
135 exa->pipe->flush(exa->pipe, 0, NULL);
136
137 transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
138 PIPE_TRANSFER_READ, x, y, w, h);
139 if (!transfer)
140 return FALSE;
141
142 util_copy_rect((unsigned char*)dst, &priv->tex->block, dst_pitch, 0, 0,
143 w, h, exa->scrn->transfer_map(exa->scrn, transfer),
144 transfer->stride, 0, 0);
145
146 exa->scrn->transfer_unmap(exa->scrn, transfer);
147 exa->scrn->tex_transfer_destroy(transfer);
148
149 return TRUE;
150 }
151
152 static Bool
153 ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
154 int src_pitch)
155 {
156 ScreenPtr pScreen = pPix->drawable.pScreen;
157 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
158 modesettingPtr ms = modesettingPTR(pScrn);
159 struct exa_context *exa = ms->exa;
160 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix);
161 struct pipe_transfer *transfer;
162
163 if (!priv || !priv->tex)
164 return FALSE;
165
166 transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
167 PIPE_TRANSFER_WRITE, x, y, w, h);
168 if (!transfer)
169 return FALSE;
170
171 util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
172 &priv->tex->block, transfer->stride, 0, 0, w, h,
173 (unsigned char*)src, src_pitch, 0, 0);
174
175 exa->scrn->transfer_unmap(exa->scrn, transfer);
176 exa->scrn->tex_transfer_destroy(transfer);
177
178 return TRUE;
179 }
180
181 static Bool
182 ExaPrepareAccess(PixmapPtr pPix, int index)
183 {
184 ScreenPtr pScreen = pPix->drawable.pScreen;
185 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
186 modesettingPtr ms = modesettingPTR(pScrn);
187 struct exa_context *exa = ms->exa;
188 struct exa_pixmap_priv *priv;
189
190 priv = exaGetPixmapDriverPrivate(pPix);
191
192 if (!priv)
193 return FALSE;
194
195 if (!priv->tex)
196 return FALSE;
197
198 if (priv->map_count++ == 0)
199 {
200 if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) &
201 PIPE_REFERENCED_FOR_WRITE)
202 exa->pipe->flush(exa->pipe, 0, NULL);
203
204 priv->map_transfer =
205 exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
206 PIPE_TRANSFER_READ_WRITE,
207 0, 0, priv->tex->width[0], priv->tex->height[0]);
208
209 pPix->devPrivate.ptr =
210 exa->scrn->transfer_map(exa->scrn, priv->map_transfer);
211 pPix->devKind = priv->map_transfer->stride;
212 }
213
214 return TRUE;
215 }
216
217 static void
218 ExaFinishAccess(PixmapPtr pPix, int index)
219 {
220 ScreenPtr pScreen = pPix->drawable.pScreen;
221 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
222 modesettingPtr ms = modesettingPTR(pScrn);
223 struct exa_context *exa = ms->exa;
224 struct exa_pixmap_priv *priv;
225 priv = exaGetPixmapDriverPrivate(pPix);
226
227 if (!priv)
228 return;
229
230 if (!priv->map_transfer)
231 return;
232
233 if (--priv->map_count == 0) {
234 assert(priv->map_transfer);
235 exa->scrn->transfer_unmap(exa->scrn, priv->map_transfer);
236 exa->scrn->tex_transfer_destroy(priv->map_transfer);
237 priv->map_transfer = NULL;
238 pPix->devPrivate.ptr = NULL;
239 }
240 }
241
242 static void
243 ExaDone(PixmapPtr pPixmap)
244 {
245 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
246 modesettingPtr ms = modesettingPTR(pScrn);
247 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
248 struct exa_context *exa = ms->exa;
249
250 if (!priv)
251 return;
252
253 #if 1
254 xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL);
255 #else
256 xorg_finish(exa);
257 #endif
258 xorg_exa_common_done(exa);
259 }
260
261 static void
262 ExaDoneComposite(PixmapPtr pPixmap)
263 {
264 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
265 modesettingPtr ms = modesettingPTR(pScrn);
266 struct exa_context *exa = ms->exa;
267
268 xorg_exa_common_done(exa);
269 }
270
271 static Bool
272 ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
273 {
274 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
275 modesettingPtr ms = modesettingPTR(pScrn);
276 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
277 struct exa_context *exa = ms->exa;
278
279 debug_printf("ExaPrepareSolid - test\n");
280 if (pPixmap->drawable.depth < 15)
281 return FALSE;
282
283 if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask))
284 return FALSE;
285
286 if (!priv || !priv->tex)
287 return FALSE;
288
289 if (alu != GXcopy)
290 return FALSE;
291
292 if (!exa->pipe)
293 return FALSE;
294
295 debug_printf(" ExaPrepareSolid(0x%x)\n", fg);
296 return xorg_solid_bind_state(exa, priv, fg);
297 }
298
299 static void
300 ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1)
301 {
302 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
303 modesettingPtr ms = modesettingPTR(pScrn);
304 struct exa_context *exa = ms->exa;
305 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
306
307 debug_printf("\tExaSolid(%d, %d, %d, %d)\n", x0, y0, x1, y1);
308
309 #if 0
310 if (x0 == 0 && y0 == 0 &&
311 x1 == priv->tex->width[0] &&
312 y1 == priv->tex->height[0]) {
313 exa->ctx->clear(exa->ctx, PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL,
314 exa->solid_color, 1., 0);
315 } else
316 #endif
317 xorg_solid(exa, priv, x0, y0, x1, y1) ;
318 }
319
320 static Bool
321 ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
322 int ydir, int alu, Pixel planeMask)
323 {
324 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
325 modesettingPtr ms = modesettingPTR(pScrn);
326 struct exa_context *exa = ms->exa;
327 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
328 struct exa_pixmap_priv *src_priv = exaGetPixmapDriverPrivate(pSrcPixmap);
329
330 debug_printf("ExaPrepareCopy\n");
331
332 if (alu != GXcopy)
333 return FALSE;
334
335 if (pSrcPixmap->drawable.depth < 15 || pDstPixmap->drawable.depth < 15)
336 return FALSE;
337
338 if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planeMask))
339 return FALSE;
340
341 if (!priv || !src_priv)
342 return FALSE;
343
344 if (!priv->tex || !src_priv->tex)
345 return FALSE;
346
347 if (!exa->pipe)
348 return FALSE;
349
350 exa->copy.src = src_priv;
351 exa->copy.dst = priv;
352
353 /*XXX disabled until some issues with syncing are fixed */
354 return FALSE;
355 }
356
357 static void
358 ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
359 int width, int height)
360 {
361 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
362 modesettingPtr ms = modesettingPTR(pScrn);
363 struct exa_context *exa = ms->exa;
364 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
365
366 debug_printf("\tExaCopy(srcx=%d, srcy=%d, dstX=%d, dstY=%d, w=%d, h=%d)\n",
367 srcX, srcY, dstX, dstY, width, height);
368
369 debug_assert(priv == exa->copy.dst);
370
371 xorg_copy_pixmap(exa, exa->copy.dst, dstX, dstY,
372 exa->copy.src, srcX, srcY,
373 width, height);
374 }
375
376 static Bool
377 ExaPrepareComposite(int op, PicturePtr pSrcPicture,
378 PicturePtr pMaskPicture, PicturePtr pDstPicture,
379 PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
380 {
381 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
382 modesettingPtr ms = modesettingPTR(pScrn);
383 struct exa_context *exa = ms->exa;
384
385 debug_printf("ExaPrepareComposite\n");
386
387 return xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture,
388 pDstPicture,
389 exaGetPixmapDriverPrivate(pSrc),
390 exaGetPixmapDriverPrivate(pMask),
391 exaGetPixmapDriverPrivate(pDst));
392 }
393
394 static void
395 ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
396 int dstX, int dstY, int width, int height)
397 {
398 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
399 modesettingPtr ms = modesettingPTR(pScrn);
400 struct exa_context *exa = ms->exa;
401 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDst);
402
403 debug_printf("\tExaComposite\n");
404
405 xorg_composite(exa, priv, srcX, srcY, maskX, maskY,
406 dstX, dstY, width, height);
407 }
408
409 static Bool
410 ExaCheckComposite(int op,
411 PicturePtr pSrcPicture, PicturePtr pMaskPicture,
412 PicturePtr pDstPicture)
413 {
414 return xorg_composite_accelerated(op,
415 pSrcPicture,
416 pMaskPicture,
417 pDstPicture);
418 }
419
420 static void *
421 ExaCreatePixmap(ScreenPtr pScreen, int size, int align)
422 {
423 struct exa_pixmap_priv *priv;
424
425 priv = xcalloc(1, sizeof(struct exa_pixmap_priv));
426 if (!priv)
427 return NULL;
428
429 return priv;
430 }
431
432 static void
433 ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv)
434 {
435 struct exa_pixmap_priv *priv = (struct exa_pixmap_priv *)dPriv;
436 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
437 modesettingPtr ms = modesettingPTR(pScrn);
438
439 if (!priv)
440 return;
441
442 if (priv->tex)
443 ms->screen->texture_destroy(priv->tex);
444
445 xfree(priv);
446 }
447
448 static Bool
449 ExaPixmapIsOffscreen(PixmapPtr pPixmap)
450 {
451 struct exa_pixmap_priv *priv;
452
453 priv = exaGetPixmapDriverPrivate(pPixmap);
454
455 if (!priv)
456 return FALSE;
457
458 if (priv->tex)
459 return TRUE;
460
461 return FALSE;
462 }
463
464 int
465 xorg_exa_set_displayed_usage(PixmapPtr pPixmap)
466 {
467 struct exa_pixmap_priv *priv;
468 priv = exaGetPixmapDriverPrivate(pPixmap);
469
470 if (!priv) {
471 FatalError("NO PIXMAP PRIVATE\n");
472 return 0;
473 }
474
475 priv->flags |= PIPE_TEXTURE_USAGE_PRIMARY;
476
477 return 0;
478 }
479
480 int
481 xorg_exa_set_shared_usage(PixmapPtr pPixmap)
482 {
483 struct exa_pixmap_priv *priv;
484 priv = exaGetPixmapDriverPrivate(pPixmap);
485
486 if (!priv) {
487 FatalError("NO PIXMAP PRIVATE\n");
488 return 0;
489 }
490
491 priv->flags |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
492
493 return 0;
494 }
495
496 unsigned
497 xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out)
498 {
499 ScreenPtr pScreen = pPixmap->drawable.pScreen;
500 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
501 modesettingPtr ms = modesettingPTR(pScrn);
502 struct exa_pixmap_priv *priv;
503 unsigned handle;
504 unsigned stride;
505
506 if (!ms->exa) {
507 FatalError("NO MS->EXA\n");
508 return 0;
509 }
510
511 priv = exaGetPixmapDriverPrivate(pPixmap);
512
513 if (!priv) {
514 FatalError("NO PIXMAP PRIVATE\n");
515 return 0;
516 }
517
518 ms->api->local_handle_from_texture(ms->api, ms->screen, priv->tex, &stride, &handle);
519 if (stride_out)
520 *stride_out = stride;
521
522 return handle;
523 }
524
525 static Bool
526 ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
527 int depth, int bitsPerPixel, int devKind,
528 pointer pPixData)
529 {
530 ScreenPtr pScreen = pPixmap->drawable.pScreen;
531 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
532 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
533 modesettingPtr ms = modesettingPTR(pScrn);
534 struct exa_context *exa = ms->exa;
535
536 if (!priv || pPixData)
537 return FALSE;
538
539 if (depth <= 0)
540 depth = pPixmap->drawable.depth;
541
542 if (bitsPerPixel <= 0)
543 bitsPerPixel = pPixmap->drawable.bitsPerPixel;
544
545 if (width <= 0)
546 width = pPixmap->drawable.width;
547
548 if (height <= 0)
549 height = pPixmap->drawable.height;
550
551 if (width <= 0 || height <= 0 || depth <= 0)
552 return FALSE;
553
554 miModifyPixmapHeader(pPixmap, width, height, depth,
555 bitsPerPixel, devKind, NULL);
556
557 /* Deal with screen resize */
558 if (!priv->tex ||
559 (priv->tex->width[0] != width ||
560 priv->tex->height[0] != height ||
561 priv->tex_flags != priv->flags)) {
562 struct pipe_texture *texture = NULL;
563
564 #ifdef DRM_MODE_FEATURE_DIRTYFB
565 if (priv->flags)
566 #endif
567 {
568 struct pipe_texture template;
569
570 memset(&template, 0, sizeof(template));
571 template.target = PIPE_TEXTURE_2D;
572 exa_get_pipe_format(depth, &template.format, &bitsPerPixel);
573 pf_get_block(template.format, &template.block);
574 template.width[0] = width;
575 template.height[0] = height;
576 template.depth[0] = 1;
577 template.last_level = 0;
578 template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags;
579 priv->tex_flags = priv->flags;
580 texture = exa->scrn->texture_create(exa->scrn, &template);
581
582 if (priv->tex) {
583 struct pipe_surface *dst_surf;
584 struct pipe_surface *src_surf;
585
586 dst_surf = exa->scrn->get_tex_surface(exa->scrn, texture, 0, 0, 0,
587 PIPE_BUFFER_USAGE_GPU_WRITE);
588 src_surf = exa_gpu_surface(exa, priv);
589 exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf,
590 0, 0, min(width, texture->width[0]),
591 min(height, texture->height[0]));
592 exa->scrn->tex_surface_destroy(dst_surf);
593 exa->scrn->tex_surface_destroy(src_surf);
594 } else if (pPixmap->devPrivate.ptr) {
595 struct pipe_transfer *transfer;
596
597 if (priv->map_count != 0)
598 FatalError("doing ExaModifyPixmapHeader on mapped buffer\n");
599
600 transfer =
601 exa->scrn->get_tex_transfer(exa->scrn, texture, 0, 0, 0,
602 PIPE_TRANSFER_WRITE,
603 0, 0, width, height);
604 util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
605 &texture->block, transfer->stride, 0, 0,
606 width, height, pPixmap->devPrivate.ptr,
607 pPixmap->devKind, 0, 0);
608 exa->scrn->transfer_unmap(exa->scrn, transfer);
609 exa->scrn->tex_transfer_destroy(transfer);
610
611 xfree(pPixmap->devPrivate.ptr);
612 pPixmap->devPrivate.ptr = NULL;
613 }
614 }
615 #ifdef DRM_MODE_FEATURE_DIRTYFB
616 else {
617 xfree(pPixmap->devPrivate.ptr);
618 pPixmap->devPrivate.ptr = xalloc(pPixmap->drawable.height *
619 pPixmap->devKind);
620 }
621 #endif
622
623 pipe_texture_reference(&priv->tex, texture);
624 }
625
626 return TRUE;
627 }
628
629 struct pipe_texture *
630 xorg_exa_get_texture(PixmapPtr pPixmap)
631 {
632 struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
633 struct pipe_texture *tex = NULL;
634 pipe_texture_reference(&tex, priv->tex);
635 return tex;
636 }
637
638 void
639 xorg_exa_close(ScrnInfoPtr pScrn)
640 {
641 modesettingPtr ms = modesettingPTR(pScrn);
642 struct exa_context *exa = ms->exa;
643 struct pipe_constant_buffer *vsbuf = &exa->vs_const_buffer;
644 struct pipe_constant_buffer *fsbuf = &exa->fs_const_buffer;
645
646 if (exa->shaders) {
647 xorg_shaders_destroy(exa->shaders);
648 }
649
650 if (vsbuf && vsbuf->buffer)
651 pipe_buffer_reference(&vsbuf->buffer, NULL);
652
653 if (fsbuf && fsbuf->buffer)
654 pipe_buffer_reference(&fsbuf->buffer, NULL);
655
656 if (exa->cso) {
657 cso_release_all(exa->cso);
658 cso_destroy_context(exa->cso);
659 }
660
661 if (exa->pipe)
662 exa->pipe->destroy(exa->pipe);
663
664 exaDriverFini(pScrn->pScreen);
665 xfree(exa);
666 ms->exa = NULL;
667 }
668
669 void *
670 xorg_exa_init(ScrnInfoPtr pScrn)
671 {
672 modesettingPtr ms = modesettingPTR(pScrn);
673 struct exa_context *exa;
674 ExaDriverPtr pExa;
675
676 exa = xcalloc(1, sizeof(struct exa_context));
677 if (!exa)
678 return NULL;
679
680 pExa = exaDriverAlloc();
681 if (!pExa) {
682 goto out_err;
683 }
684
685 memset(pExa, 0, sizeof(*pExa));
686
687 pExa->exa_major = 2;
688 pExa->exa_minor = 2;
689 pExa->memoryBase = 0;
690 pExa->memorySize = 0;
691 pExa->offScreenBase = 0;
692 pExa->pixmapOffsetAlign = 0;
693 pExa->pixmapPitchAlign = 1;
694 pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
695 #ifdef EXA_SUPPORTS_PREPARE_AUX
696 pExa->flags |= EXA_SUPPORTS_PREPARE_AUX;
697 #endif
698 #ifdef EXA_MIXED_PIXMAPS
699 pExa->flags |= EXA_MIXED_PIXMAPS;
700 #endif
701 pExa->maxX = 8191; /* FIXME */
702 pExa->maxY = 8191; /* FIXME */
703
704 pExa->WaitMarker = ExaWaitMarker;
705 pExa->MarkSync = ExaMarkSync;
706 pExa->PrepareSolid = ExaPrepareSolid;
707 pExa->Solid = ExaSolid;
708 pExa->DoneSolid = ExaDone;
709 pExa->PrepareCopy = ExaPrepareCopy;
710 pExa->Copy = ExaCopy;
711 pExa->DoneCopy = ExaDone;
712 pExa->CheckComposite = ExaCheckComposite;
713 pExa->PrepareComposite = ExaPrepareComposite;
714 pExa->Composite = ExaComposite;
715 pExa->DoneComposite = ExaDoneComposite;
716 pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen;
717 pExa->DownloadFromScreen = ExaDownloadFromScreen;
718 pExa->UploadToScreen = ExaUploadToScreen;
719 pExa->PrepareAccess = ExaPrepareAccess;
720 pExa->FinishAccess = ExaFinishAccess;
721 pExa->CreatePixmap = ExaCreatePixmap;
722 pExa->DestroyPixmap = ExaDestroyPixmap;
723 pExa->ModifyPixmapHeader = ExaModifyPixmapHeader;
724
725 if (!exaDriverInit(pScrn->pScreen, pExa)) {
726 goto out_err;
727 }
728
729 exa->scrn = ms->screen;
730 exa->pipe = ms->api->create_context(ms->api, exa->scrn);
731 /* Share context with DRI */
732 ms->ctx = exa->pipe;
733
734 exa->cso = cso_create_context(exa->pipe);
735 exa->shaders = xorg_shaders_create(exa);
736
737 xorg_exa_init_state(exa);
738
739 return (void *)exa;
740
741 out_err:
742 xorg_exa_close(pScrn);
743
744 return NULL;
745 }
746
747 struct pipe_surface *
748 exa_gpu_surface(struct exa_context *exa, struct exa_pixmap_priv *priv)
749 {
750 return exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
751 PIPE_BUFFER_USAGE_GPU_READ |
752 PIPE_BUFFER_USAGE_GPU_WRITE);
753
754 }
755
756 void xorg_exa_flush(struct exa_context *exa, uint pipeFlushFlags,
757 struct pipe_fence_handle **fence)
758 {
759 exa->pipe->flush(exa->pipe, pipeFlushFlags, fence);
760 }
761
762 void xorg_exa_finish(struct exa_context *exa)
763 {
764 struct pipe_fence_handle *fence = NULL;
765
766 xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, &fence);
767
768 exa->pipe->screen->fence_finish(exa->pipe->screen, fence, 0);
769 exa->pipe->screen->fence_reference(exa->pipe->screen, &fence, NULL);
770 }
771