nouveau_sync.c revision fda9279d
1/*
2 * Copyright © 2013-2014 Intel Corporation
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission.  The copyright holders make no representations
11 * about the suitability of this software for any purpose.  It is provided "as
12 * is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 * OF THIS SOFTWARE.
21 */
22
23#include "nouveau_sync.h"
24#ifdef DRI3
25#include "nv_include.h"
26
27static DevPrivateKeyRec nouveau_syncobj_key;
28
29struct nouveau_syncobj {
30	SyncFenceSetTriggeredFunc SetTriggered;
31};
32
33#define nouveau_syncobj(fence)                                                 \
34	dixLookupPrivate(&(fence)->devPrivates, &nouveau_syncobj_key)
35
36struct nouveau_syncctx {
37	SyncScreenCreateFenceFunc CreateFence;
38};
39
40#define nouveau_syncctx(screen) ({                                             \
41	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);                           \
42	NVPtr pNv = NVPTR(scrn);                                               \
43	pNv->sync;                                                             \
44})
45
46static void
47nouveau_syncobj_flush(SyncFence *fence)
48{
49	struct nouveau_syncobj *pobj = nouveau_syncobj(fence);
50	ScrnInfoPtr scrn = xf86ScreenToScrn(fence->pScreen);
51	NVPtr pNv = NVPTR(scrn);
52	SyncFenceFuncsPtr func = &fence->funcs;
53
54	if (pNv->Flush)
55		pNv->Flush(scrn);
56
57	swap(pobj, func, SetTriggered);
58	func->SetTriggered(fence);
59	swap(pobj, func, SetTriggered);
60}
61
62static void
63nouveau_syncobj_new(ScreenPtr screen, SyncFence *fence, Bool triggered)
64{
65	struct nouveau_syncctx *priv = nouveau_syncctx(screen);
66	struct nouveau_syncobj *pobj = nouveau_syncobj(fence);
67	SyncScreenFuncsPtr sync = miSyncGetScreenFuncs(screen);
68	SyncFenceFuncsPtr func = &fence->funcs;
69
70	swap(priv, sync, CreateFence);
71	sync->CreateFence(screen, fence, triggered);
72	swap(priv, sync, CreateFence);
73
74	wrap(pobj, func, SetTriggered, nouveau_syncobj_flush);
75}
76
77void
78nouveau_sync_fini(ScreenPtr screen)
79{
80	struct nouveau_syncctx *priv = nouveau_syncctx(screen);
81	SyncScreenFuncsPtr sync = miSyncGetScreenFuncs(screen);
82	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
83	NVPtr pNv = NVPTR(scrn);
84
85	unwrap(priv, sync, CreateFence);
86
87	pNv->sync = NULL;
88	free(priv);
89}
90
91Bool
92nouveau_sync_init(ScreenPtr screen)
93{
94	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
95	NVPtr pNv = NVPTR(scrn);
96	struct nouveau_syncctx *priv;
97	SyncScreenFuncsPtr sync;
98
99	priv = pNv->sync = calloc(1, sizeof(*priv));
100	if (!priv)
101		return FALSE;
102
103	if (!miSyncShmScreenInit(screen))
104		return FALSE;
105
106	if (!dixPrivateKeyRegistered(&nouveau_syncobj_key)) {
107		if (!dixRegisterPrivateKey(&nouveau_syncobj_key,
108					    PRIVATE_SYNC_FENCE,
109					   sizeof(struct nouveau_syncobj)))
110			return FALSE;
111	}
112
113	sync = miSyncGetScreenFuncs(screen);
114	wrap(priv, sync, CreateFence, nouveau_syncobj_new);
115	return TRUE;
116}
117#endif
118