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 "amdgpu_drv.h" 25 26#ifdef HAVE_MISYNCSHM_H 27 28#include "misync.h" 29#include "misyncshm.h" 30#include "misyncstr.h" 31 32#include "amdgpu_glamor.h" 33 34/* 35 * This whole file exists to wrap a sync fence trigger operation 36 * so that we can flush the batch buffer to provide serialization 37 * between the server and the shm fence client 38 */ 39 40static DevPrivateKeyRec amdgpu_sync_fence_private_key; 41 42typedef struct _amdgpu_sync_fence_private { 43 SyncFenceSetTriggeredFunc set_triggered; 44} amdgpu_sync_fence_private; 45 46#define SYNC_FENCE_PRIV(pFence) \ 47 (amdgpu_sync_fence_private *) dixLookupPrivate(&pFence->devPrivates, &amdgpu_sync_fence_private_key) 48 49static void 50amdgpu_sync_fence_set_triggered (SyncFence *fence) 51{ 52 ScreenPtr screen = fence->pScreen; 53 amdgpu_sync_fence_private *private = SYNC_FENCE_PRIV(fence); 54 55 /* Flush pending rendering operations */ 56 amdgpu_glamor_flush(xf86ScreenToScrn(screen)); 57 58 fence->funcs.SetTriggered = private->set_triggered; 59 fence->funcs.SetTriggered(fence); 60 private->set_triggered = fence->funcs.SetTriggered; 61 fence->funcs.SetTriggered = amdgpu_sync_fence_set_triggered; 62} 63 64static void 65amdgpu_sync_create_fence(ScreenPtr screen, 66 SyncFence *fence, 67 Bool initially_triggered) 68{ 69 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 70 AMDGPUInfoPtr info = AMDGPUPTR(scrn); 71 SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen); 72 amdgpu_sync_fence_private *private = SYNC_FENCE_PRIV(fence); 73 74 screen_funcs->CreateFence = info->CreateFence; 75 screen_funcs->CreateFence(screen, fence, initially_triggered); 76 info->CreateFence = screen_funcs->CreateFence; 77 screen_funcs->CreateFence = amdgpu_sync_create_fence; 78 79 private->set_triggered = fence->funcs.SetTriggered; 80 fence->funcs.SetTriggered = amdgpu_sync_fence_set_triggered; 81} 82 83Bool 84amdgpu_sync_init(ScreenPtr screen) 85{ 86 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 87 AMDGPUInfoPtr info = AMDGPUPTR(scrn); 88 SyncScreenFuncsPtr screen_funcs; 89 90 if (!xf86LoaderCheckSymbol("miSyncShmScreenInit")) { 91 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 92 "SYNC extension fences disabled because " 93 "miSyncShmScreenInit symbol unresolved\n"); 94 return FALSE; 95 } 96 97 if (!miSyncShmScreenInit(screen)) { 98 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 99 "SYNC extension fences disabled because " 100 "miSyncShmScreenInit failed\n"); 101 return FALSE; 102 } 103 104 if (!dixPrivateKeyRegistered(&amdgpu_sync_fence_private_key)) { 105 if (!dixRegisterPrivateKey(&amdgpu_sync_fence_private_key, 106 PRIVATE_SYNC_FENCE, 107 sizeof (amdgpu_sync_fence_private))) { 108 xf86DrvMsg(scrn->scrnIndex, X_WARNING, 109 "SYNC extension fences disabled because " 110 "dixRegisterPrivateKey failed\n"); 111 return FALSE; 112 } 113 } 114 115 xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_INFO, 116 "SYNC extension fences enabled\n"); 117 118 screen_funcs = miSyncGetScreenFuncs(screen); 119 info->CreateFence = screen_funcs->CreateFence; 120 screen_funcs->CreateFence = amdgpu_sync_create_fence; 121 return TRUE; 122} 123 124void 125amdgpu_sync_close(ScreenPtr screen) 126{ 127 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 128 AMDGPUInfoPtr info = AMDGPUPTR(scrn); 129 SyncScreenFuncsPtr screen_funcs = miSyncGetScreenFuncs(screen); 130 131 if (screen_funcs && info->CreateFence) 132 screen_funcs->CreateFence = info->CreateFence; 133 134 info->CreateFence = NULL; 135} 136 137#else /* !HAVE_MISYNCSHM_H */ 138 139Bool 140amdgpu_sync_init(ScreenPtr screen) 141{ 142 xf86DrvMsg(xf86ScreenToScrn(screen)->scrnIndex, X_INFO, 143 "SYNC extension fences disabled because misyncshm.h not " 144 "available at build time\n"); 145 146 return FALSE; 147} 148 149void 150amdgpu_sync_close(ScreenPtr screen) 151{ 152} 153 154#endif 155