st/drm: s/hocks/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 /* FIXME ! */
32 #define DRI_DRIVER_PATH "/ISO/X.Org/modular/i386/lib/dri"
33
34 #include "xf86.h"
35 //#include "xf86_OSproc.h"
36 #include "xorg_tracker.h"
37
38 //#include "pipe/p_winsys.h"
39 #include "pipe/p_format.h"
40 #include "pipe/p_context.h"
41 #include "pipe/p_state.h"
42 #include "pipe/p_inlines.h"
43
44 struct exa_entity
45 {
46 ExaDriverPtr pExa;
47 struct pipe_context *ctx;
48 struct pipe_screen *scrn;
49 };
50
51 struct PixmapPriv
52 {
53 int flags;
54 struct pipe_texture *tex;
55 unsigned int color;
56 struct pipe_surface *src_surf; /* for copies */
57 struct pipe_transfer *map_transfer;
58 };
59
60 /*
61 * Helper functions
62 */
63
64 static enum pipe_format
65 exa_get_pipe_format(int depth)
66 {
67 switch (depth) {
68 case 32:
69 return PIPE_FORMAT_A8R8G8B8_UNORM;
70 case 24:
71 return PIPE_FORMAT_X8R8G8B8_UNORM;
72 case 16:
73 return PIPE_FORMAT_R5G6B5_UNORM;
74 case 15:
75 return PIPE_FORMAT_A1R5G5B5_UNORM;
76 case 8:
77 case 4:
78 case 1:
79 return PIPE_FORMAT_A8R8G8B8_UNORM; /* bad bad bad */
80 default:
81 assert(0);
82 return 0;
83 }
84 }
85
86 /*
87 * Static exported EXA functions
88 */
89
90 static void
91 ExaWaitMarker(ScreenPtr pScreen, int marker)
92 {
93 }
94
95 static int
96 ExaMarkSync(ScreenPtr pScreen)
97 {
98 return 1;
99 }
100
101 static Bool
102 ExaPrepareAccess(PixmapPtr pPix, int index)
103 {
104 ScreenPtr pScreen = pPix->drawable.pScreen;
105 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
106 modesettingPtr ms = modesettingPTR(pScrn);
107 //PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
108 struct exa_entity *exa = ms->exa;
109 struct PixmapPriv *priv;
110 //int ret;
111
112 priv = exaGetPixmapDriverPrivate(pPix);
113
114 if (!priv)
115 return FALSE;
116
117 if (!priv->tex)
118 return FALSE;
119 {
120 priv->map_transfer =
121 exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
122 PIPE_TRANSFER_READ_WRITE,
123 0, 0, priv->tex->width[0], priv->tex->height[0]);
124
125 pPix->devPrivate.ptr =
126 exa->scrn->transfer_map(exa->scrn, priv->map_transfer);
127 pPix->devKind = priv->map_transfer->stride;
128 }
129
130 return TRUE;
131 }
132
133 static void
134 ExaFinishAccess(PixmapPtr pPix, int index)
135 {
136 ScreenPtr pScreen = pPix->drawable.pScreen;
137 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
138 modesettingPtr ms = modesettingPTR(pScrn);
139 struct exa_entity *exa = ms->exa;
140 struct PixmapPriv *priv;
141 priv = exaGetPixmapDriverPrivate(pPix);
142
143 if (!priv)
144 return;
145
146 if (!priv->map_transfer)
147 return;
148
149 exa->scrn->transfer_unmap(exa->scrn, priv->map_transfer);
150 pipe_transfer_reference(&priv->map_transfer, NULL);
151
152 }
153
154 static void
155 ExaDone(PixmapPtr pPixmap)
156 {
157 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
158 modesettingPtr ms = modesettingPTR(pScrn);
159 struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
160 struct exa_entity *exa = ms->exa;
161
162 if (!priv)
163 return;
164
165 if (priv->src_surf)
166 exa->scrn->tex_surface_release(exa->scrn, &priv->src_surf);
167 priv->src_surf = NULL;
168 }
169
170 static void
171 ExaDoneComposite(PixmapPtr pPixmap)
172 {
173
174 }
175
176 static Bool
177 ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
178 {
179 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
180 modesettingPtr ms = modesettingPTR(pScrn);
181 struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
182 struct exa_entity *exa = ms->exa;
183
184 if (1)
185 return FALSE;
186
187 if (pPixmap->drawable.depth < 15)
188 return FALSE;
189
190 if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask))
191 return FALSE;
192
193 if (!priv || !priv->tex)
194 return FALSE;
195
196 if (alu != GXcopy)
197 return FALSE;
198
199 if (!exa->ctx || !exa->ctx->surface_fill)
200 return FALSE;
201
202 priv->color = fg;
203
204 return TRUE;
205 }
206
207 static void
208 ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1)
209 {
210 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
211 modesettingPtr ms = modesettingPTR(pScrn);
212 struct exa_entity *exa = ms->exa;
213 struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
214 struct pipe_surface *surf =
215 exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
216 PIPE_BUFFER_USAGE_GPU_READ |
217 PIPE_BUFFER_USAGE_GPU_WRITE);
218
219 exa->ctx->surface_fill(exa->ctx, surf, x0, y0, x1 - x0, y1 - y0,
220 priv->color);
221
222 exa->scrn->tex_surface_release(exa->scrn, &surf);
223 }
224
225 static Bool
226 ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
227 int ydir, int alu, Pixel planeMask)
228 {
229 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
230 modesettingPtr ms = modesettingPTR(pScrn);
231 struct exa_entity *exa = ms->exa;
232 struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
233 struct PixmapPriv *src_priv = exaGetPixmapDriverPrivate(pSrcPixmap);
234
235 if (1)
236 return FALSE;
237
238 if (alu != GXcopy)
239 return FALSE;
240
241 if (pSrcPixmap->drawable.depth < 15 || pDstPixmap->drawable.depth < 15)
242 return FALSE;
243
244 if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planeMask))
245 return FALSE;
246
247 if (!priv || !src_priv)
248 return FALSE;
249
250 if (!priv->tex || !src_priv->tex)
251 return FALSE;
252
253 if (!exa->ctx || !exa->ctx->surface_copy)
254 return FALSE;
255
256 priv->src_surf =
257 exa->scrn->get_tex_surface(exa->scrn, src_priv->tex, 0, 0, 0,
258 PIPE_BUFFER_USAGE_GPU_READ |
259 PIPE_BUFFER_USAGE_GPU_WRITE);
260
261 return FALSE;
262 }
263
264 static void
265 ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
266 int width, int height)
267 {
268 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
269 modesettingPtr ms = modesettingPTR(pScrn);
270 struct exa_entity *exa = ms->exa;
271 struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
272 struct pipe_surface *surf =
273 exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
274 PIPE_BUFFER_USAGE_GPU_READ |
275 PIPE_BUFFER_USAGE_GPU_WRITE);
276
277 exa->ctx->surface_copy(exa->ctx, 0, surf, dstX, dstY, priv->src_surf,
278 srcX, srcY, width, height);
279 exa->scrn->tex_surface_release(exa->scrn, &surf);
280 }
281
282 static Bool
283 ExaPrepareComposite(int op, PicturePtr pSrcPicture,
284 PicturePtr pMaskPicture, PicturePtr pDstPicture,
285 PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
286 {
287 return FALSE;
288 }
289
290 #if 0
291 static Bool
292 ExaUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
293 int src_pitch)
294 {
295 ErrorF("UPLOAD\n");
296
297 return FALSE;
298 }
299 #endif
300
301 static void
302 ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
303 int dstX, int dstY, int width, int height)
304 {
305 }
306
307 static Bool
308 ExaCheckComposite(int op,
309 PicturePtr pSrcPicture, PicturePtr pMaskPicture,
310 PicturePtr pDstPicture)
311 {
312 return FALSE;
313 }
314
315 static void *
316 ExaCreatePixmap(ScreenPtr pScreen, int size, int align)
317 {
318 struct PixmapPriv *priv;
319
320 priv = xcalloc(1, sizeof(struct PixmapPriv));
321 if (!priv)
322 return NULL;
323
324 return priv;
325 }
326
327 static void
328 ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv)
329 {
330 struct PixmapPriv *priv = (struct PixmapPriv *)dPriv;
331 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
332 modesettingPtr ms = modesettingPTR(pScrn);
333 struct exa_entity *exa = ms->exa;
334
335 if (!priv)
336 return;
337
338 if (priv->tex)
339 ms->screen->texture_release(exa->scrn, &priv->tex);
340
341 xfree(priv);
342 }
343
344 static Bool
345 ExaPixmapIsOffscreen(PixmapPtr pPixmap)
346 {
347 struct PixmapPriv *priv;
348
349 priv = exaGetPixmapDriverPrivate(pPixmap);
350
351 if (!priv)
352 return FALSE;
353
354 if (priv->tex)
355 return TRUE;
356
357 return FALSE;
358 }
359
360 unsigned
361 xorg_exa_get_pixmap_handle(PixmapPtr pPixmap)
362 {
363 ScreenPtr pScreen = pPixmap->drawable.pScreen;
364 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
365 modesettingPtr ms = modesettingPTR(pScrn);
366 struct PixmapPriv *priv;
367 struct pipe_buffer *buffer = NULL;
368 unsigned handle;
369 unsigned stride;
370
371 if (!ms->exa) {
372 FatalError("NO MS->EXA\n");
373 return 0;
374 }
375
376 priv = exaGetPixmapDriverPrivate(pPixmap);
377
378 if (!priv) {
379 FatalError("NO PIXMAP PRIVATE\n");
380 return 0;
381 }
382
383 drm_api_hooks.buffer_from_texture(priv->tex, &buffer, &stride);
384 drm_api_hooks.handle_from_buffer(ms->screen, buffer, &handle);
385 pipe_buffer_reference(ms->screen, &buffer, NULL);
386 return handle;
387 }
388
389 static Bool
390 ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
391 int depth, int bitsPerPixel, int devKind,
392 pointer pPixData)
393 {
394 ScreenPtr pScreen = pPixmap->drawable.pScreen;
395 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
396 struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
397 modesettingPtr ms = modesettingPTR(pScrn);
398 //PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
399 struct exa_entity *exa = ms->exa;
400
401 if (!priv)
402 return FALSE;
403
404 if (depth <= 0)
405 depth = pPixmap->drawable.depth;
406
407 if (bitsPerPixel <= 0)
408 bitsPerPixel = pPixmap->drawable.bitsPerPixel;
409
410 if (width <= 0)
411 width = pPixmap->drawable.width;
412
413 if (height <= 0)
414 height = pPixmap->drawable.height;
415
416 if (width <= 0 || height <= 0 || depth <= 0)
417 return FALSE;
418
419 miModifyPixmapHeader(pPixmap, width, height, depth,
420 bitsPerPixel, devKind, NULL);
421
422 /* Deal with screen resize */
423 if (priv->tex && (priv->tex->width[0] != width || priv->tex->height[0] != height)) {
424 pipe_texture_reference(&priv->tex, NULL);
425 }
426
427 if (!priv->tex) {
428 struct pipe_texture template;
429
430 memset(&template, 0, sizeof(template));
431 template.target = PIPE_TEXTURE_2D;
432 template.compressed = 0;
433 template.format = exa_get_pipe_format(depth);
434 pf_get_block(template.format, &template.block);
435 template.width[0] = width;
436 template.height[0] = height;
437 template.depth[0] = 1;
438 template.last_level = 0;
439 template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
440 priv->tex = exa->scrn->texture_create(exa->scrn, &template);
441 }
442
443 return TRUE;
444 }
445
446 struct pipe_texture *
447 xorg_exa_get_texture(PixmapPtr pPixmap)
448 {
449 struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap);
450 struct pipe_texture *tex = NULL;
451 pipe_texture_reference(&tex, priv->tex);
452 return tex;
453 }
454
455 void
456 xorg_exa_close(ScrnInfoPtr pScrn)
457 {
458 modesettingPtr ms = modesettingPTR(pScrn);
459 struct exa_entity *exa = ms->exa;
460
461 if (exa->ctx)
462 exa->ctx->destroy(exa->ctx);
463
464 exaDriverFini(pScrn->pScreen);
465 xfree(exa);
466 ms->exa = NULL;
467 }
468
469 void *
470 xorg_exa_init(ScrnInfoPtr pScrn)
471 {
472 modesettingPtr ms = modesettingPTR(pScrn);
473 struct exa_entity *exa;
474 ExaDriverPtr pExa;
475
476 exa = xcalloc(1, sizeof(struct exa_entity));
477 if (!exa)
478 return NULL;
479
480 pExa = exaDriverAlloc();
481 if (!pExa) {
482 goto out_err;
483 }
484
485 memset(pExa, 0, sizeof(*pExa));
486 pExa->exa_major = 2;
487 pExa->exa_minor = 2;
488 pExa->memoryBase = 0;
489 pExa->memorySize = 0;
490 pExa->offScreenBase = 0;
491 pExa->pixmapOffsetAlign = 0;
492 pExa->pixmapPitchAlign = 1;
493 pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
494 pExa->maxX = 8191; /* FIXME */
495 pExa->maxY = 8191; /* FIXME */
496 pExa->WaitMarker = ExaWaitMarker;
497 pExa->MarkSync = ExaMarkSync;
498 pExa->PrepareSolid = ExaPrepareSolid;
499 pExa->Solid = ExaSolid;
500 pExa->DoneSolid = ExaDone;
501 pExa->PrepareCopy = ExaPrepareCopy;
502 pExa->Copy = ExaCopy;
503 pExa->DoneCopy = ExaDone;
504 pExa->CheckComposite = ExaCheckComposite;
505 pExa->PrepareComposite = ExaPrepareComposite;
506 pExa->Composite = ExaComposite;
507 pExa->DoneComposite = ExaDoneComposite;
508 pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen;
509 pExa->PrepareAccess = ExaPrepareAccess;
510 pExa->FinishAccess = ExaFinishAccess;
511 //pExa->UploadToScreen = ExaUploadToScreen;
512 pExa->UploadToScreen = NULL;
513 pExa->CreatePixmap = ExaCreatePixmap;
514 pExa->DestroyPixmap = ExaDestroyPixmap;
515 pExa->ModifyPixmapHeader = ExaModifyPixmapHeader;
516
517 if (!exaDriverInit(pScrn->pScreen, pExa)) {
518 goto out_err;
519 }
520
521 exa->scrn = ms->screen;
522 exa->ctx = drm_api_hooks.create_context(exa->scrn);
523 /* Share context with DRI */
524 ms->ctx = exa->ctx;
525
526 return (void *)exa;
527
528 out_err:
529 xorg_exa_close(pScrn);
530
531 return NULL;
532 }
533
534 /* vim: set sw=4 ts=8 sts=4: */