radeon_sync.c revision 0d16fef4
1/*
2 * Copyright © 2013-2014 Intel Corporation
3 * Copyright © 2015 Advanced Micro Devices, Inc.
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that copyright
8 * notice and this permission notice appear in supporting documentation, and
9 * that the name of the copyright holders not be used in advertising or
10 * publicity pertaining to distribution of the software without specific,
11 * written prior permission.  The copyright holders make no representations
12 * about the suitability of this software for any purpose.  It is provided "as
13 * is" without express or implied warranty.
14 *
15 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21 * OF THIS SOFTWARE.
22 */
23
24#include "radeon.h"
25
26#ifdef HAVE_MISYNCSHM_H
27
28#include "misync.h"
29#include "misyncshm.h"
30#include "misyncstr.h"
31
32/*
33 * This whole file exists to wrap a sync fence trigger operation
34 * so that we can flush the batch buffer to provide serialization
35 * between the server and the shm fence client
36 */
37
38static DevPrivateKeyRec radeon_sync_fence_private_key;
39
40typedef struct _radeon_sync_fence_private {
41        SyncFenceSetTriggeredFunc set_triggered;
42} radeon_sync_fence_private;
43
44#define SYNC_FENCE_PRIV(pFence)                                         \
45        (radeon_sync_fence_private *) dixLookupPrivate(&pFence->devPrivates, &radeon_sync_fence_private_key)
46
47static void
48radeon_sync_fence_set_triggered (SyncFence *fence)
49{
50	ScreenPtr screen = fence->pScreen;
51	radeon_sync_fence_private *private = SYNC_FENCE_PRIV(fence);
52
53	/* Flush pending rendering operations */
54	radeon_cs_flush_indirect(xf86ScreenToScrn(screen));
55
56	fence->funcs.SetTriggered = private->set_triggered;
57	fence->funcs.SetTriggered(fence);
58	private->set_triggered = fence->funcs.SetTriggered;
59	fence->funcs.SetTriggered = radeon_sync_fence_set_triggered;
60}
61
62static void
63radeon_sync_create_fence(ScreenPtr screen,
64                        SyncFence *fence,
65                        Bool initially_triggered)
66{
67	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
68	RADEONInfoPtr info = RADEONPTR(scrn);
69	SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen);
70	radeon_sync_fence_private *private = SYNC_FENCE_PRIV(fence);
71
72	screen_funcs->CreateFence = info->CreateFence;
73	screen_funcs->CreateFence(screen, fence, initially_triggered);
74	info->CreateFence = screen_funcs->CreateFence;
75	screen_funcs->CreateFence = radeon_sync_create_fence;
76
77	private->set_triggered = fence->funcs.SetTriggered;
78	fence->funcs.SetTriggered = radeon_sync_fence_set_triggered;
79}
80
81Bool
82radeon_sync_init(ScreenPtr screen)
83{
84	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
85	RADEONInfoPtr info = RADEONPTR(scrn);
86	SyncScreenFuncsPtr screen_funcs;
87
88	if (!xf86LoaderCheckSymbol("miSyncShmScreenInit")) {
89		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
90			   "SYNC extension fences disabled because "
91			   "miSyncShmScreenInit symbol unresolved\n");
92		return FALSE;
93	}
94
95	if (!miSyncShmScreenInit(screen)) {
96		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
97			   "SYNC extension fences disabled because "
98			   "miSyncShmScreenInit failed\n");
99		return FALSE;
100	}
101
102	if (!dixPrivateKeyRegistered(&radeon_sync_fence_private_key)) {
103		if (!dixRegisterPrivateKey(&radeon_sync_fence_private_key,
104					   PRIVATE_SYNC_FENCE,
105					   sizeof (radeon_sync_fence_private))) {
106			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
107				   "SYNC extension fences disabled because "
108				   "dixRegisterPrivateKey failed\n");
109			return FALSE;
110		}
111	}
112
113	xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_INFO,
114		   "SYNC extension fences enabled\n");
115
116	screen_funcs = miSyncGetScreenFuncs(screen);
117	info->CreateFence = screen_funcs->CreateFence;
118	screen_funcs->CreateFence = radeon_sync_create_fence;
119	return TRUE;
120}
121
122void
123radeon_sync_close(ScreenPtr screen)
124{
125	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
126	RADEONInfoPtr info = RADEONPTR(scrn);
127	SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen);
128
129	if (screen_funcs && info->CreateFence)
130		screen_funcs->CreateFence = info->CreateFence;
131
132	info->CreateFence = NULL;
133}
134
135#else /* !HAVE_MISYNCSHM_H */
136
137Bool
138radeon_sync_init(ScreenPtr screen)
139{
140	xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_INFO,
141		   "SYNC extension fences disabled because misyncshm.h not "
142		   "available at build time\n");
143
144	return FALSE;
145}
146
147void
148radeon_sync_close(ScreenPtr screen)
149{
150}
151
152#endif
153