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