13192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/********************************************************** 2e2a1d21cb665b7e7bc2c9684cf533003cdc817b3Brian Paul * Copyright 2009-2015 VMware, Inc. All rights reserved. 33192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * 43192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Permission is hereby granted, free of charge, to any person 53192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * obtaining a copy of this software and associated documentation 63192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * files (the "Software"), to deal in the Software without 73192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * restriction, including without limitation the rights to use, copy, 83192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * modify, merge, publish, distribute, sublicense, and/or sell copies 93192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * of the Software, and to permit persons to whom the Software is 103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * furnished to do so, subject to the following conditions: 113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * 123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * The above copyright notice and this permission notice shall be 133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * included in all copies or substantial portions of the Software. 143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * 153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * SOFTWARE. 233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * 243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz **********************************************************/ 253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "util/u_memory.h" 26e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom#include "util/u_atomic.h" 277a30668ad665f3315106e1a959c6186dea79a24aJason Ekstrand#include "util/list.h" 28fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul#include "os/os_thread.h" 29e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "pipebuffer/pb_buffer_fenced.h" 313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "vmw_screen.h" 333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "vmw_fence.h" 343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct vmw_fence_ops 363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 37fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul /* 38fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * Immutable members. 39fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul */ 403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct pb_fence_ops base; 413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct vmw_winsys_screen *vws; 42fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 43fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul pipe_mutex mutex; 44fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 45fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul /* 46fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * Protected by mutex; 47fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul */ 48fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul struct list_head not_signaled; 49fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul uint32_t last_signaled; 50fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul uint32_t last_emitted; 513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}; 523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 53e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstromstruct vmw_fence 54e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom{ 55fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul struct list_head ops_list; 56e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom int32_t refcount; 57e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom uint32_t handle; 58e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom uint32_t mask; 59e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom int32_t signalled; 60fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul uint32_t seqno; 61e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom}; 623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 63e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom/** 64fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * vmw_fence_seq_is_signaled - Check whether a fence seqno is 65fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * signaled. 66fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * 67fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @ops: Pointer to a struct pb_fence_ops. 68fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * 69fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul */ 70a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline boolean 71fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulvmw_fence_seq_is_signaled(uint32_t seq, uint32_t last, uint32_t cur) 72fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul{ 73fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul return (cur - last <= cur - seq); 74fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul} 75fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 76fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 77fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul/** 78fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * vmw_fence_ops - Return the vmw_fence_ops structure backing a 79fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * struct pb_fence_ops pointer. 80fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * 81fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @ops: Pointer to a struct pb_fence_ops. 82fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * 83fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul */ 84a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline struct vmw_fence_ops * 85fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulvmw_fence_ops(struct pb_fence_ops *ops) 86fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul{ 87fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul assert(ops); 88fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul return (struct vmw_fence_ops *)ops; 89fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul} 90fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 91fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 92fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul/** 93fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * vmw_fences_release - Release all fences from the not_signaled 94fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * list. 95fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * 96fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @ops: Pointer to a struct vmw_fence_ops. 97fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * 98fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul */ 99fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulstatic void 100fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulvmw_fences_release(struct vmw_fence_ops *ops) 101fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul{ 102fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul struct vmw_fence *fence, *n; 103fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 104fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul pipe_mutex_lock(ops->mutex); 105fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul LIST_FOR_EACH_ENTRY_SAFE(fence, n, &ops->not_signaled, ops_list) 106fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul LIST_DELINIT(&fence->ops_list); 107fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul pipe_mutex_unlock(ops->mutex); 108fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul} 109fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 110fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul/** 111fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * vmw_fences_signal - Traverse the not_signaled list and try to 112fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * signal unsignaled fences. 113fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * 114fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @ops: Pointer to a struct pb_fence_ops. 115fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @signaled: Seqno that has signaled. 116fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @emitted: Last seqno emitted by the kernel. 117fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @has_emitted: Whether we provide the emitted value. 118fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * 119fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul */ 120fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulvoid 121fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulvmw_fences_signal(struct pb_fence_ops *fence_ops, 122fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul uint32_t signaled, 123fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul uint32_t emitted, 124fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul boolean has_emitted) 125fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul{ 126fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul struct vmw_fence_ops *ops = NULL; 127fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul struct vmw_fence *fence, *n; 128fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 129fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul if (fence_ops == NULL) 130fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul return; 131fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 132fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul ops = vmw_fence_ops(fence_ops); 133fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul pipe_mutex_lock(ops->mutex); 134fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 135fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul if (!has_emitted) { 136fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul emitted = ops->last_emitted; 137fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul if (emitted - signaled > (1 << 30)) 138fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul emitted = signaled; 139fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul } 140fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 141fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul if (signaled == ops->last_signaled && emitted == ops->last_emitted) 142fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul goto out_unlock; 143fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 144fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul LIST_FOR_EACH_ENTRY_SAFE(fence, n, &ops->not_signaled, ops_list) { 145fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul if (!vmw_fence_seq_is_signaled(fence->seqno, signaled, emitted)) 146fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul break; 147fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 148fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul p_atomic_set(&fence->signalled, 1); 149fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul LIST_DELINIT(&fence->ops_list); 150fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul } 151fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul ops->last_signaled = signaled; 152fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul ops->last_emitted = emitted; 153fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 154fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulout_unlock: 155fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul pipe_mutex_unlock(ops->mutex); 156fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul} 157fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 158fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 159fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul/** 160e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * vmw_fence - return the vmw_fence object identified by a 161e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * struct pipe_fence_handle * 162e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * 163e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * @fence: The opaque pipe fence handle. 164e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom */ 165a2a1a5805fd617e7f3cc8be44dd79b50da07ebb9Ilia Mirkinstatic inline struct vmw_fence * 166e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstromvmw_fence(struct pipe_fence_handle *fence) 167e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom{ 168e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom return (struct vmw_fence *) fence; 169e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom} 170e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 171fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 172e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom/** 173e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * vmw_fence_create - Create a user-space fence object. 174e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * 175fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * @fence_ops: The fence_ops manager to register with. 176e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * @handle: Handle identifying the kernel fence object. 177e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * @mask: Mask of flags that this fence object may signal. 178e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * 179e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * Returns NULL on failure. 180e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom */ 181e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstromstruct pipe_fence_handle * 182fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paulvmw_fence_create(struct pb_fence_ops *fence_ops, uint32_t handle, 183fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul uint32_t seqno, uint32_t mask) 184e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom{ 185e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom struct vmw_fence *fence = CALLOC_STRUCT(vmw_fence); 186fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul struct vmw_fence_ops *ops = vmw_fence_ops(fence_ops); 187e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 188e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom if (!fence) 189e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom return NULL; 190e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 191e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom p_atomic_set(&fence->refcount, 1); 192e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom fence->handle = handle; 193e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom fence->mask = mask; 194fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul fence->seqno = seqno; 195e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom p_atomic_set(&fence->signalled, 0); 196fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul pipe_mutex_lock(ops->mutex); 197fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 198fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul if (vmw_fence_seq_is_signaled(seqno, ops->last_signaled, seqno)) { 199fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul p_atomic_set(&fence->signalled, 1); 200fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul LIST_INITHEAD(&fence->ops_list); 201fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul } else { 202fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul p_atomic_set(&fence->signalled, 0); 203fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul LIST_ADDTAIL(&fence->ops_list, &ops->not_signaled); 204fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul } 205e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 206fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul pipe_mutex_unlock(ops->mutex); 207e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 208fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul return (struct pipe_fence_handle *) fence; 2093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 2103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 2113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 212e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom/** 213e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * vmw_fence_reference - Reference / unreference a vmw fence object. 214e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * 215e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * @vws: Pointer to the winsys screen. 216e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * @ptr: Pointer to reference transfer destination. 217e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * @fence: Pointer to object to reference. May be NULL. 218e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom */ 219e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstromvoid 220e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstromvmw_fence_reference(struct vmw_winsys_screen *vws, 221e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom struct pipe_fence_handle **ptr, 222e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom struct pipe_fence_handle *fence) 223e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom{ 224e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom if (*ptr) { 225e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom struct vmw_fence *vfence = vmw_fence(*ptr); 226e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 227e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom if (p_atomic_dec_zero(&vfence->refcount)) { 228fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul struct vmw_fence_ops *ops = vmw_fence_ops(vws->fence_ops); 229fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 230e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom vmw_ioctl_fence_unref(vws, vfence->handle); 231fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 232fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul pipe_mutex_lock(ops->mutex); 233fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul LIST_DELINIT(&vfence->ops_list); 234fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul pipe_mutex_unlock(ops->mutex); 235fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul 236e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom FREE(vfence); 237e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom } 238e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom } 239e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 240e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom if (fence) { 241e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom struct vmw_fence *vfence = vmw_fence(fence); 242e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 243e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom p_atomic_inc(&vfence->refcount); 244e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom } 245e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 246e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom *ptr = fence; 247e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom} 248e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 249e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 250e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom/** 251e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * vmw_fence_signalled - Check whether a fence object is signalled. 252e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * 253e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * @vws: Pointer to the winsys screen. 254e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * @fence: Handle to the fence object. 255e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * @flag: Fence flags to check. If the fence object can't signal 256e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * a flag, it is assumed to be already signaled. 257e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * 258e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * Returns 0 if the fence object was signaled, nonzero otherwise. 259e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom */ 260e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstromint 261e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstromvmw_fence_signalled(struct vmw_winsys_screen *vws, 262e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom struct pipe_fence_handle *fence, 263e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom unsigned flag) 264e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom{ 265e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom struct vmw_fence *vfence; 266e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom int32_t vflags = SVGA_FENCE_FLAG_EXEC; 267e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom int ret; 268e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom uint32_t old; 269e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 270e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom if (!fence) 271e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom return 0; 272e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 273e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom vfence = vmw_fence(fence); 274e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom old = p_atomic_read(&vfence->signalled); 275e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 276e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom vflags &= ~vfence->mask; 277e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 278e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom if ((old & vflags) == vflags) 279e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom return 0; 280e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 281fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul /* 282fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * Currently we update signaled fences on each execbuf call. 283fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * That should really be sufficient, and we can avoid 284fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul * a lot of kernel calls this way. 285fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul */ 286fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul#if 1 287e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom ret = vmw_ioctl_fence_signalled(vws, vfence->handle, vflags); 288e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 289fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul if (ret == 0) 290fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul p_atomic_set(&vfence->signalled, 1); 291e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom return ret; 292fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul#else 293fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul (void) ret; 294fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul return -1; 295fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul#endif 296e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom} 297e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 298e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom/** 299e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * vmw_fence_finish - Wait for a fence object to signal. 300e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * 301e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * @vws: Pointer to the winsys screen. 302e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * @fence: Handle to the fence object. 303e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * @flag: Fence flags to wait for. If the fence object can't signal 304e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * a flag, it is assumed to be already signaled. 305e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * 306e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * Returns 0 if the wait succeeded. Nonzero otherwise. 307e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom */ 308e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstromint 309e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstromvmw_fence_finish(struct vmw_winsys_screen *vws, 310e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom struct pipe_fence_handle *fence, 311e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom unsigned flag) 312e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom{ 313e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom struct vmw_fence *vfence; 314e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom int32_t vflags = SVGA_FENCE_FLAG_EXEC; 315e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom int ret; 316e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom uint32_t old; 317e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 318e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom if (!fence) 319e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom return 0; 320e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 321e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom vfence = vmw_fence(fence); 322e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom old = p_atomic_read(&vfence->signalled); 323e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom vflags &= ~vfence->mask; 324e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 325e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom if ((old & vflags) == vflags) 326e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom return 0; 327e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 328e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom ret = vmw_ioctl_fence_finish(vws, vfence->handle, vflags); 329e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 330e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom if (ret == 0) { 331e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom int32_t prev = old; 332e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 333e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom do { 334e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom old = prev; 335e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom prev = p_atomic_cmpxchg(&vfence->signalled, old, old | vflags); 336e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom } while (prev != old); 337e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom } 338e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 339e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom return ret; 340e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom} 341e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 342e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 343e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom/** 344e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * vmw_fence_ops_fence_reference - wrapper for the pb_fence_ops api. 345e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * 346e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * wrapper around vmw_fence_reference. 347e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom */ 3483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void 3493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_fence_ops_fence_reference(struct pb_fence_ops *ops, 3503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct pipe_fence_handle **ptr, 3513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct pipe_fence_handle *fence) 3523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 353e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom struct vmw_winsys_screen *vws = vmw_fence_ops(ops)->vws; 3543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 355e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom vmw_fence_reference(vws, ptr, fence); 356e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom} 3573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 358e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom/** 359e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * vmw_fence_ops_fence_signalled - wrapper for the pb_fence_ops api. 360e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * 361e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * wrapper around vmw_fence_signalled. 362e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom */ 3633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic int 3643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_fence_ops_fence_signalled(struct pb_fence_ops *ops, 3653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct pipe_fence_handle *fence, 3663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned flag) 3673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 3683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct vmw_winsys_screen *vws = vmw_fence_ops(ops)->vws; 369e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 370e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom return vmw_fence_signalled(vws, fence, flag); 3713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 3723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 374e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom/** 375e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * vmw_fence_ops_fence_finish - wrapper for the pb_fence_ops api. 376e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * 377e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * wrapper around vmw_fence_finish. 378e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom */ 3793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic int 3803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_fence_ops_fence_finish(struct pb_fence_ops *ops, 3813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct pipe_fence_handle *fence, 3823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz unsigned flag) 3833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 3843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct vmw_winsys_screen *vws = vmw_fence_ops(ops)->vws; 385e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom 386e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom return vmw_fence_finish(vws, fence, flag); 3873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 3883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 3893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 390e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom/** 391e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * vmw_fence_ops_destroy - Destroy a pb_fence_ops function table. 392e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * 393e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * @ops: The function table to destroy. 394e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * 395e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * Part of the pb_fence_ops api. 396e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom */ 3973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic void 3983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_fence_ops_destroy(struct pb_fence_ops *ops) 3993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 400fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul vmw_fences_release(vmw_fence_ops(ops)); 4013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz FREE(ops); 4023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 4033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 4043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 405e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom/** 406e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * vmw_fence_ops_create - Create a pb_fence_ops function table. 407e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * 408e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * @vws: Pointer to a struct vmw_winsys_screen. 409e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * 410e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * Returns a pointer to a pb_fence_ops function table to interface 411e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * with pipe_buffer. This function is typically called on driver setup. 412e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * 413e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom * Returns NULL on failure. 414e7843273fae516fa9922f12053bb6c063b39921cThomas Hellstrom */ 4153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct pb_fence_ops * 4163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzvmw_fence_ops_create(struct vmw_winsys_screen *vws) 4173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{ 4183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz struct vmw_fence_ops *ops; 4193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 4203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz ops = CALLOC_STRUCT(vmw_fence_ops); 4213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz if(!ops) 4223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return NULL; 4233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 424fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul pipe_mutex_init(ops->mutex); 425fe6a854477c2ed30c37c200668a4dc86512120f7Brian Paul LIST_INITHEAD(&ops->not_signaled); 4263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz ops->base.destroy = &vmw_fence_ops_destroy; 4273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz ops->base.fence_reference = &vmw_fence_ops_fence_reference; 4283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz ops->base.fence_signalled = &vmw_fence_ops_fence_signalled; 4293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz ops->base.fence_finish = &vmw_fence_ops_fence_finish; 4303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 4313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz ops->vws = vws; 4323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz 4333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz return &ops->base; 4343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz} 435