10d16fef4Smrg/* 20d16fef4Smrg * Copyright © 2013-2014 Intel Corporation 30d16fef4Smrg * Copyright © 2015 Advanced Micro Devices, Inc. 40d16fef4Smrg * 50d16fef4Smrg * Permission to use, copy, modify, distribute, and sell this software and its 60d16fef4Smrg * documentation for any purpose is hereby granted without fee, provided that 70d16fef4Smrg * the above copyright notice appear in all copies and that both that copyright 80d16fef4Smrg * notice and this permission notice appear in supporting documentation, and 90d16fef4Smrg * that the name of the copyright holders not be used in advertising or 100d16fef4Smrg * publicity pertaining to distribution of the software without specific, 110d16fef4Smrg * written prior permission. The copyright holders make no representations 120d16fef4Smrg * about the suitability of this software for any purpose. It is provided "as 130d16fef4Smrg * is" without express or implied warranty. 140d16fef4Smrg * 150d16fef4Smrg * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 160d16fef4Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 170d16fef4Smrg * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 180d16fef4Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 190d16fef4Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 200d16fef4Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 210d16fef4Smrg * OF THIS SOFTWARE. 220d16fef4Smrg */ 230d16fef4Smrg 240d16fef4Smrg#include "radeon.h" 250d16fef4Smrg 260d16fef4Smrg#ifdef HAVE_MISYNCSHM_H 270d16fef4Smrg 280d16fef4Smrg#include "misync.h" 290d16fef4Smrg#include "misyncshm.h" 300d16fef4Smrg#include "misyncstr.h" 310d16fef4Smrg 320d16fef4Smrg/* 330d16fef4Smrg * This whole file exists to wrap a sync fence trigger operation 340d16fef4Smrg * so that we can flush the batch buffer to provide serialization 350d16fef4Smrg * between the server and the shm fence client 360d16fef4Smrg */ 370d16fef4Smrg 380d16fef4Smrgstatic DevPrivateKeyRec radeon_sync_fence_private_key; 390d16fef4Smrg 400d16fef4Smrgtypedef struct _radeon_sync_fence_private { 410d16fef4Smrg SyncFenceSetTriggeredFunc set_triggered; 420d16fef4Smrg} radeon_sync_fence_private; 430d16fef4Smrg 440d16fef4Smrg#define SYNC_FENCE_PRIV(pFence) \ 450d16fef4Smrg (radeon_sync_fence_private *) dixLookupPrivate(&pFence->devPrivates, &radeon_sync_fence_private_key) 460d16fef4Smrg 470d16fef4Smrgstatic void 480d16fef4Smrgradeon_sync_fence_set_triggered (SyncFence *fence) 490d16fef4Smrg{ 500d16fef4Smrg ScreenPtr screen = fence->pScreen; 510d16fef4Smrg radeon_sync_fence_private *private = SYNC_FENCE_PRIV(fence); 520d16fef4Smrg 530d16fef4Smrg /* Flush pending rendering operations */ 540d16fef4Smrg radeon_cs_flush_indirect(xf86ScreenToScrn(screen)); 550d16fef4Smrg 560d16fef4Smrg fence->funcs.SetTriggered = private->set_triggered; 570d16fef4Smrg fence->funcs.SetTriggered(fence); 580d16fef4Smrg private->set_triggered = fence->funcs.SetTriggered; 590d16fef4Smrg fence->funcs.SetTriggered = radeon_sync_fence_set_triggered; 600d16fef4Smrg} 610d16fef4Smrg 620d16fef4Smrgstatic void 630d16fef4Smrgradeon_sync_create_fence(ScreenPtr screen, 640d16fef4Smrg SyncFence *fence, 650d16fef4Smrg Bool initially_triggered) 660d16fef4Smrg{ 670d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 680d16fef4Smrg RADEONInfoPtr info = RADEONPTR(scrn); 690d16fef4Smrg SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen); 700d16fef4Smrg radeon_sync_fence_private *private = SYNC_FENCE_PRIV(fence); 710d16fef4Smrg 720d16fef4Smrg screen_funcs->CreateFence = info->CreateFence; 730d16fef4Smrg screen_funcs->CreateFence(screen, fence, initially_triggered); 740d16fef4Smrg info->CreateFence = screen_funcs->CreateFence; 750d16fef4Smrg screen_funcs->CreateFence = radeon_sync_create_fence; 760d16fef4Smrg 770d16fef4Smrg private->set_triggered = fence->funcs.SetTriggered; 780d16fef4Smrg fence->funcs.SetTriggered = radeon_sync_fence_set_triggered; 790d16fef4Smrg} 800d16fef4Smrg 810d16fef4SmrgBool 820d16fef4Smrgradeon_sync_init(ScreenPtr screen) 830d16fef4Smrg{ 840d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 850d16fef4Smrg RADEONInfoPtr info = RADEONPTR(scrn); 860d16fef4Smrg SyncScreenFuncsPtr screen_funcs; 870d16fef4Smrg 880d16fef4Smrg if (!xf86LoaderCheckSymbol("miSyncShmScreenInit")) { 890d16fef4Smrg xf86DrvMsg(scrn->scrnIndex, X_WARNING, 900d16fef4Smrg "SYNC extension fences disabled because " 910d16fef4Smrg "miSyncShmScreenInit symbol unresolved\n"); 920d16fef4Smrg return FALSE; 930d16fef4Smrg } 940d16fef4Smrg 950d16fef4Smrg if (!miSyncShmScreenInit(screen)) { 960d16fef4Smrg xf86DrvMsg(scrn->scrnIndex, X_WARNING, 970d16fef4Smrg "SYNC extension fences disabled because " 980d16fef4Smrg "miSyncShmScreenInit failed\n"); 990d16fef4Smrg return FALSE; 1000d16fef4Smrg } 1010d16fef4Smrg 1020d16fef4Smrg if (!dixPrivateKeyRegistered(&radeon_sync_fence_private_key)) { 1030d16fef4Smrg if (!dixRegisterPrivateKey(&radeon_sync_fence_private_key, 1040d16fef4Smrg PRIVATE_SYNC_FENCE, 1050d16fef4Smrg sizeof (radeon_sync_fence_private))) { 1060d16fef4Smrg xf86DrvMsg(scrn->scrnIndex, X_WARNING, 1070d16fef4Smrg "SYNC extension fences disabled because " 1080d16fef4Smrg "dixRegisterPrivateKey failed\n"); 1090d16fef4Smrg return FALSE; 1100d16fef4Smrg } 1110d16fef4Smrg } 1120d16fef4Smrg 1130d16fef4Smrg xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_INFO, 1140d16fef4Smrg "SYNC extension fences enabled\n"); 1150d16fef4Smrg 1160d16fef4Smrg screen_funcs = miSyncGetScreenFuncs(screen); 1170d16fef4Smrg info->CreateFence = screen_funcs->CreateFence; 1180d16fef4Smrg screen_funcs->CreateFence = radeon_sync_create_fence; 1190d16fef4Smrg return TRUE; 1200d16fef4Smrg} 1210d16fef4Smrg 1220d16fef4Smrgvoid 1230d16fef4Smrgradeon_sync_close(ScreenPtr screen) 1240d16fef4Smrg{ 1250d16fef4Smrg ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 1260d16fef4Smrg RADEONInfoPtr info = RADEONPTR(scrn); 1270d16fef4Smrg SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen); 1280d16fef4Smrg 1290d16fef4Smrg if (screen_funcs && info->CreateFence) 1300d16fef4Smrg screen_funcs->CreateFence = info->CreateFence; 1310d16fef4Smrg 1320d16fef4Smrg info->CreateFence = NULL; 1330d16fef4Smrg} 1340d16fef4Smrg 1350d16fef4Smrg#else /* !HAVE_MISYNCSHM_H */ 1360d16fef4Smrg 1370d16fef4SmrgBool 1380d16fef4Smrgradeon_sync_init(ScreenPtr screen) 1390d16fef4Smrg{ 1400d16fef4Smrg xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_INFO, 1410d16fef4Smrg "SYNC extension fences disabled because misyncshm.h not " 1420d16fef4Smrg "available at build time\n"); 1430d16fef4Smrg 1440d16fef4Smrg return FALSE; 1450d16fef4Smrg} 1460d16fef4Smrg 1470d16fef4Smrgvoid 1480d16fef4Smrgradeon_sync_close(ScreenPtr screen) 1490d16fef4Smrg{ 1500d16fef4Smrg} 1510d16fef4Smrg 1520d16fef4Smrg#endif 153