diff options
-rw-r--r-- | src/mesa/drivers/dri/i915/intel_syncobj.c | 55 |
1 files changed, 44 insertions, 11 deletions
diff --git a/src/mesa/drivers/dri/i915/intel_syncobj.c b/src/mesa/drivers/dri/i915/intel_syncobj.c index ae3ad821692..d0a99aa2e6d 100644 --- a/src/mesa/drivers/dri/i915/intel_syncobj.c +++ b/src/mesa/drivers/dri/i915/intel_syncobj.c @@ -46,9 +46,11 @@ #include "intel_reg.h" struct intel_fence { + struct intel_context *intel; /** The fence waits for completion of this batch. */ drm_intel_bo *batch_bo; + mtx_t mutex; bool signalled; }; @@ -77,7 +79,7 @@ intel_fence_insert(struct intel_context *intel, struct intel_fence *fence) } static bool -intel_fence_has_completed(struct intel_fence *fence) +intel_fence_has_completed_locked(struct intel_fence *fence) { if (fence->signalled) return true; @@ -92,13 +94,21 @@ intel_fence_has_completed(struct intel_fence *fence) return false; } -/** - * Return true if the function successfully signals or has already signalled. - * (This matches the behavior expected from __DRI2fence::client_wait_sync). - */ static bool -intel_fence_client_wait(struct intel_context *intel, struct intel_fence *fence, - uint64_t timeout) +intel_fence_has_completed(struct intel_fence *fence) +{ + bool ret; + + mtx_lock(&fence->mutex); + ret = intel_fence_has_completed_locked(fence); + mtx_unlock(&fence->mutex); + + return ret; +} + +static bool +intel_fence_client_wait_locked(struct intel_context *intel, struct intel_fence *fence, + uint64_t timeout) { if (fence->signalled) return true; @@ -123,6 +133,23 @@ intel_fence_client_wait(struct intel_context *intel, struct intel_fence *fence, return true; } +/** + * Return true if the function successfully signals or has already signalled. + * (This matches the behavior expected from __DRI2fence::client_wait_sync). + */ +static bool +intel_fence_client_wait(struct intel_context *intel, struct intel_fence *fence, + uint64_t timeout) +{ + bool ret; + + mtx_lock(&fence->mutex); + ret = intel_fence_client_wait_locked(intel, fence, timeout); + mtx_unlock(&fence->mutex); + + return ret; +} + static void intel_fence_server_wait(struct intel_context *intel, struct intel_fence *fence) { @@ -215,6 +242,8 @@ intel_dri_create_fence(__DRIcontext *ctx) if (!fence) return NULL; + mtx_init(&fence->mutex, mtx_plain); + fence->intel = intel; intel_fence_insert(intel, fence); return fence; @@ -233,19 +262,23 @@ static GLboolean intel_dri_client_wait_sync(__DRIcontext *ctx, void *driver_fence, unsigned flags, uint64_t timeout) { - struct intel_context *intel = ctx->driverPrivate; struct intel_fence *fence = driver_fence; - return intel_fence_client_wait(intel, fence, timeout); + return intel_fence_client_wait(fence->intel, fence, timeout); } static void intel_dri_server_wait_sync(__DRIcontext *ctx, void *driver_fence, unsigned flags) { - struct intel_context *intel = ctx->driverPrivate; struct intel_fence *fence = driver_fence; - intel_fence_server_wait(intel, fence); + /* We might be called here with a NULL fence as a result of WaitSyncKHR + * on a EGL_KHR_reusable_sync fence. Nothing to do here in such case. + */ + if (!fence) + return; + + intel_fence_server_wait(fence->intel, fence); } const __DRI2fenceExtension intelFenceExtension = { |