142542f5fSchristos/*
242542f5fSchristos * Copyright © 2013-2014 Intel Corporation
342542f5fSchristos *
442542f5fSchristos * Permission to use, copy, modify, distribute, and sell this software and its
542542f5fSchristos * documentation for any purpose is hereby granted without fee, provided that
642542f5fSchristos * the above copyright notice appear in all copies and that both that copyright
742542f5fSchristos * notice and this permission notice appear in supporting documentation, and
842542f5fSchristos * that the name of the copyright holders not be used in advertising or
942542f5fSchristos * publicity pertaining to distribution of the software without specific,
1042542f5fSchristos * written prior permission.  The copyright holders make no representations
1142542f5fSchristos * about the suitability of this software for any purpose.  It is provided "as
1242542f5fSchristos * is" without express or implied warranty.
1342542f5fSchristos *
1442542f5fSchristos * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1542542f5fSchristos * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
1642542f5fSchristos * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1742542f5fSchristos * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
1842542f5fSchristos * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
1942542f5fSchristos * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
2042542f5fSchristos * OF THIS SOFTWARE.
2142542f5fSchristos */
2242542f5fSchristos
2342542f5fSchristos#include "intel.h"
2442542f5fSchristos#include "misyncshm.h"
2542542f5fSchristos#include "misyncstr.h"
2642542f5fSchristos
2742542f5fSchristos/*
2842542f5fSchristos * This whole file exists to wrap a sync fence trigger operation
2942542f5fSchristos * so that we can flush the batch buffer to provide serialization
3042542f5fSchristos * between the server and the shm fence client
3142542f5fSchristos */
3242542f5fSchristos
3342542f5fSchristosstatic DevPrivateKeyRec intel_sync_fence_private_key;
3442542f5fSchristos
3542542f5fSchristostypedef struct _intel_sync_fence_private {
3642542f5fSchristos        SyncFenceSetTriggeredFunc set_triggered;
3742542f5fSchristos} intel_sync_fence_private;
3842542f5fSchristos
3942542f5fSchristos#define SYNC_FENCE_PRIV(pFence)                                         \
4042542f5fSchristos        (intel_sync_fence_private *) dixLookupPrivate(&pFence->devPrivates, &intel_sync_fence_private_key)
4142542f5fSchristos
4242542f5fSchristosstatic void
4342542f5fSchristosintel_sync_fence_set_triggered (SyncFence *fence)
4442542f5fSchristos{
4542542f5fSchristos	ScreenPtr screen = fence->pScreen;
4642542f5fSchristos	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
4742542f5fSchristos	intel_screen_private *intel = intel_get_screen_private(scrn);
4842542f5fSchristos	intel_sync_fence_private *private = SYNC_FENCE_PRIV(fence);
4942542f5fSchristos
5042542f5fSchristos	/* Flush pending rendering operations */
5142542f5fSchristos	if (intel->flush_rendering)
5242542f5fSchristos		intel->flush_rendering(intel);
5342542f5fSchristos
5442542f5fSchristos	fence->funcs.SetTriggered = private->set_triggered;
5542542f5fSchristos	fence->funcs.SetTriggered(fence);
5642542f5fSchristos	private->set_triggered = fence->funcs.SetTriggered;
5742542f5fSchristos	fence->funcs.SetTriggered = intel_sync_fence_set_triggered;
5842542f5fSchristos}
5942542f5fSchristos
6042542f5fSchristosstatic void
6142542f5fSchristosintel_sync_create_fence(ScreenPtr screen,
6242542f5fSchristos                        SyncFence *fence,
6342542f5fSchristos                        Bool initially_triggered)
6442542f5fSchristos{
6542542f5fSchristos	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
6642542f5fSchristos	intel_screen_private *intel = intel_get_screen_private(scrn);
6742542f5fSchristos	SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen);
6842542f5fSchristos	intel_sync_fence_private *private = SYNC_FENCE_PRIV(fence);
6942542f5fSchristos
7042542f5fSchristos	screen_funcs->CreateFence = intel->save_sync_screen_funcs.CreateFence;
7142542f5fSchristos	screen_funcs->CreateFence(screen, fence, initially_triggered);
7242542f5fSchristos	intel->save_sync_screen_funcs.CreateFence = screen_funcs->CreateFence;
7342542f5fSchristos	screen_funcs->CreateFence = intel_sync_create_fence;
7442542f5fSchristos
7542542f5fSchristos	private->set_triggered = fence->funcs.SetTriggered;
7642542f5fSchristos	fence->funcs.SetTriggered = intel_sync_fence_set_triggered;
7742542f5fSchristos}
7842542f5fSchristos
7942542f5fSchristosBool
8042542f5fSchristosintel_sync_init(ScreenPtr screen)
8142542f5fSchristos{
8242542f5fSchristos	ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
8342542f5fSchristos	intel_screen_private *intel = intel_get_screen_private(scrn);
8442542f5fSchristos	SyncScreenFuncsPtr screen_funcs;
8542542f5fSchristos
8642542f5fSchristos	if (!miSyncShmScreenInit(screen))
8742542f5fSchristos		return FALSE;
8842542f5fSchristos
8942542f5fSchristos	if (!dixPrivateKeyRegistered(&intel_sync_fence_private_key)) {
9042542f5fSchristos		if (!dixRegisterPrivateKey(&intel_sync_fence_private_key,
9142542f5fSchristos					   PRIVATE_SYNC_FENCE,
9242542f5fSchristos					   sizeof (intel_sync_fence_private)))
9342542f5fSchristos			return FALSE;
9442542f5fSchristos	}
9542542f5fSchristos
9642542f5fSchristos	screen_funcs = miSyncGetScreenFuncs(screen);
9742542f5fSchristos	intel->save_sync_screen_funcs.CreateFence = screen_funcs->CreateFence;
9842542f5fSchristos	screen_funcs->CreateFence = intel_sync_create_fence;
9942542f5fSchristos	return TRUE;
10042542f5fSchristos}
10142542f5fSchristos
10242542f5fSchristosvoid
10342542f5fSchristosintel_sync_close(ScreenPtr screen)
10442542f5fSchristos{
10542542f5fSchristos        ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
10642542f5fSchristos        intel_screen_private *intel = intel_get_screen_private(scrn);
10742542f5fSchristos        SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen);
10842542f5fSchristos
10942542f5fSchristos        if (screen_funcs)
11042542f5fSchristos                screen_funcs->CreateFence = intel->save_sync_screen_funcs.CreateFence;
11142542f5fSchristos}
112