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