From a99ff827140f82fb1742d79a8b14f62800d3a700 Mon Sep 17 00:00:00 2001 From: Chad Versace Date: Tue, 27 Sep 2016 23:33:45 -0700 Subject: i965/sync: Rename intel_syncobj.c -> brw_sync.c Reviewed-by: Iago Toral Quiroga Reviewed-by: Kenneth Graunke --- src/mesa/drivers/dri/i965/Makefile.sources | 2 +- src/mesa/drivers/dri/i965/brw_context.h | 2 +- src/mesa/drivers/dri/i965/brw_sync.c | 300 +++++++++++++++++++++++++++++ src/mesa/drivers/dri/i965/intel_syncobj.c | 300 ----------------------------- 4 files changed, 302 insertions(+), 302 deletions(-) create mode 100644 src/mesa/drivers/dri/i965/brw_sync.c delete mode 100644 src/mesa/drivers/dri/i965/intel_syncobj.c diff --git a/src/mesa/drivers/dri/i965/Makefile.sources b/src/mesa/drivers/dri/i965/Makefile.sources index df90cb49c4..4917358154 100644 --- a/src/mesa/drivers/dri/i965/Makefile.sources +++ b/src/mesa/drivers/dri/i965/Makefile.sources @@ -154,6 +154,7 @@ i965_FILES = \ brw_state_upload.c \ brw_structs.h \ brw_surface_formats.c \ + brw_sync.c \ brw_tcs.c \ brw_tcs_surface_state.c \ brw_tes.c \ @@ -239,7 +240,6 @@ i965_FILES = \ intel_screen.c \ intel_screen.h \ intel_state.c \ - intel_syncobj.c \ intel_tex.c \ intel_tex_copy.c \ intel_tex.h \ diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index a737c2da15..dcda574a70 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -1603,7 +1603,7 @@ extern int intel_translate_compare_func(GLenum func); extern int intel_translate_stencil_op(GLenum op); extern int intel_translate_logic_op(GLenum opcode); -/* intel_syncobj.c */ +/* brw_sync.c */ void brw_init_syncobj_functions(struct dd_function_table *functions); /* gen6_sol.c */ diff --git a/src/mesa/drivers/dri/i965/brw_sync.c b/src/mesa/drivers/dri/i965/brw_sync.c new file mode 100644 index 0000000000..cecf3c352d --- /dev/null +++ b/src/mesa/drivers/dri/i965/brw_sync.c @@ -0,0 +1,300 @@ +/* + * Copyright © 2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + * + */ + +/** + * \file + * \brief Support for GL_ARB_sync and EGL_KHR_fence_sync. + * + * GL_ARB_sync is implemented by flushing the current batchbuffer and keeping a + * reference on it. We can then check for completion or wait for completion + * using the normal buffer object mechanisms. This does mean that if an + * application is using many sync objects, it will emit small batchbuffers + * which may end up being a significant overhead. In other tests of removing + * gratuitous batchbuffer syncs in Mesa, it hasn't appeared to be a significant + * performance bottleneck, though. + */ + +#include "main/imports.h" + +#include "brw_context.h" +#include "intel_batchbuffer.h" + +struct brw_fence { + struct brw_context *brw; + /** The fence waits for completion of this batch. */ + drm_intel_bo *batch_bo; + + mtx_t mutex; + bool signalled; +}; + +struct brw_gl_sync { + struct gl_sync_object gl; + struct brw_fence fence; +}; + +static void +brw_fence_init(struct brw_context *brw, struct brw_fence *fence) +{ + fence->brw = brw; + fence->batch_bo = NULL; + mtx_init(&fence->mutex, mtx_plain); +} + +static void +brw_fence_finish(struct brw_fence *fence) +{ + if (fence->batch_bo) + drm_intel_bo_unreference(fence->batch_bo); + + mtx_destroy(&fence->mutex); +} + +static void +brw_fence_insert(struct brw_context *brw, struct brw_fence *fence) +{ + assert(!fence->batch_bo); + assert(!fence->signalled); + + brw_emit_mi_flush(brw); + fence->batch_bo = brw->batch.bo; + drm_intel_bo_reference(fence->batch_bo); + intel_batchbuffer_flush(brw); +} + +static bool +brw_fence_has_completed_locked(struct brw_fence *fence) +{ + if (fence->signalled) + return true; + + if (fence->batch_bo && !drm_intel_bo_busy(fence->batch_bo)) { + drm_intel_bo_unreference(fence->batch_bo); + fence->batch_bo = NULL; + fence->signalled = true; + return true; + } + + return false; +} + +static bool +brw_fence_has_completed(struct brw_fence *fence) +{ + bool ret; + + mtx_lock(&fence->mutex); + ret = brw_fence_has_completed_locked(fence); + mtx_unlock(&fence->mutex); + + return ret; +} + +static bool +brw_fence_client_wait_locked(struct brw_context *brw, struct brw_fence *fence, + uint64_t timeout) +{ + if (fence->signalled) + return true; + + assert(fence->batch_bo); + + /* DRM_IOCTL_I915_GEM_WAIT uses a signed 64 bit timeout and returns + * immediately for timeouts <= 0. The best we can do is to clamp the + * timeout to INT64_MAX. This limits the maximum timeout from 584 years to + * 292 years - likely not a big deal. + */ + if (timeout > INT64_MAX) + timeout = INT64_MAX; + + if (drm_intel_gem_bo_wait(fence->batch_bo, timeout) != 0) + return false; + + fence->signalled = true; + drm_intel_bo_unreference(fence->batch_bo); + fence->batch_bo = NULL; + + 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 +brw_fence_client_wait(struct brw_context *brw, struct brw_fence *fence, + uint64_t timeout) +{ + bool ret; + + mtx_lock(&fence->mutex); + ret = brw_fence_client_wait_locked(brw, fence, timeout); + mtx_unlock(&fence->mutex); + + return ret; +} + +static void +brw_fence_server_wait(struct brw_context *brw, struct brw_fence *fence) +{ + /* We have nothing to do for WaitSync. Our GL command stream is sequential, + * so given that the sync object has already flushed the batchbuffer, any + * batchbuffers coming after this waitsync will naturally not occur until + * the previous one is done. + */ +} + +static struct gl_sync_object * +brw_gl_new_sync(struct gl_context *ctx, GLuint id) +{ + struct brw_gl_sync *sync; + + sync = calloc(1, sizeof(*sync)); + if (!sync) + return NULL; + + return &sync->gl; +} + +static void +brw_gl_delete_sync(struct gl_context *ctx, struct gl_sync_object *_sync) +{ + struct brw_gl_sync *sync = (struct brw_gl_sync *) _sync; + + brw_fence_finish(&sync->fence); + free(sync); +} + +static void +brw_gl_fence_sync(struct gl_context *ctx, struct gl_sync_object *_sync, + GLenum condition, GLbitfield flags) +{ + struct brw_context *brw = brw_context(ctx); + struct brw_gl_sync *sync = (struct brw_gl_sync *) _sync; + + brw_fence_init(brw, &sync->fence); + brw_fence_insert(brw, &sync->fence); +} + +static void +brw_gl_client_wait_sync(struct gl_context *ctx, struct gl_sync_object *_sync, + GLbitfield flags, GLuint64 timeout) +{ + struct brw_context *brw = brw_context(ctx); + struct brw_gl_sync *sync = (struct brw_gl_sync *) _sync; + + if (brw_fence_client_wait(brw, &sync->fence, timeout)) + sync->gl.StatusFlag = 1; +} + +static void +brw_gl_server_wait_sync(struct gl_context *ctx, struct gl_sync_object *_sync, + GLbitfield flags, GLuint64 timeout) +{ + struct brw_context *brw = brw_context(ctx); + struct brw_gl_sync *sync = (struct brw_gl_sync *) _sync; + + brw_fence_server_wait(brw, &sync->fence); +} + +static void +brw_gl_check_sync(struct gl_context *ctx, struct gl_sync_object *_sync) +{ + struct brw_gl_sync *sync = (struct brw_gl_sync *) _sync; + + if (brw_fence_has_completed(&sync->fence)) + sync->gl.StatusFlag = 1; +} + +void +brw_init_syncobj_functions(struct dd_function_table *functions) +{ + functions->NewSyncObject = brw_gl_new_sync; + functions->DeleteSyncObject = brw_gl_delete_sync; + functions->FenceSync = brw_gl_fence_sync; + functions->CheckSync = brw_gl_check_sync; + functions->ClientWaitSync = brw_gl_client_wait_sync; + functions->ServerWaitSync = brw_gl_server_wait_sync; +} + +static void * +brw_dri_create_fence(__DRIcontext *ctx) +{ + struct brw_context *brw = ctx->driverPrivate; + struct brw_fence *fence; + + fence = calloc(1, sizeof(*fence)); + if (!fence) + return NULL; + + brw_fence_init(brw, fence); + brw_fence_insert(brw, fence); + + return fence; +} + +static void +brw_dri_destroy_fence(__DRIscreen *dri_screen, void *driver_fence) +{ + struct brw_fence *fence = driver_fence; + + brw_fence_finish(fence); + free(fence); +} + +static GLboolean +brw_dri_client_wait_sync(__DRIcontext *ctx, void *driver_fence, unsigned flags, + uint64_t timeout) +{ + struct brw_fence *fence = driver_fence; + + return brw_fence_client_wait(fence->brw, fence, timeout); +} + +static void +brw_dri_server_wait_sync(__DRIcontext *ctx, void *driver_fence, unsigned flags) +{ + struct brw_fence *fence = driver_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; + + brw_fence_server_wait(fence->brw, fence); +} + +const __DRI2fenceExtension intelFenceExtension = { + .base = { __DRI2_FENCE, 1 }, + + .create_fence = brw_dri_create_fence, + .destroy_fence = brw_dri_destroy_fence, + .client_wait_sync = brw_dri_client_wait_sync, + .server_wait_sync = brw_dri_server_wait_sync, + .get_fence_from_cl_event = NULL, +}; diff --git a/src/mesa/drivers/dri/i965/intel_syncobj.c b/src/mesa/drivers/dri/i965/intel_syncobj.c deleted file mode 100644 index cecf3c352d..0000000000 --- a/src/mesa/drivers/dri/i965/intel_syncobj.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eric Anholt - * - */ - -/** - * \file - * \brief Support for GL_ARB_sync and EGL_KHR_fence_sync. - * - * GL_ARB_sync is implemented by flushing the current batchbuffer and keeping a - * reference on it. We can then check for completion or wait for completion - * using the normal buffer object mechanisms. This does mean that if an - * application is using many sync objects, it will emit small batchbuffers - * which may end up being a significant overhead. In other tests of removing - * gratuitous batchbuffer syncs in Mesa, it hasn't appeared to be a significant - * performance bottleneck, though. - */ - -#include "main/imports.h" - -#include "brw_context.h" -#include "intel_batchbuffer.h" - -struct brw_fence { - struct brw_context *brw; - /** The fence waits for completion of this batch. */ - drm_intel_bo *batch_bo; - - mtx_t mutex; - bool signalled; -}; - -struct brw_gl_sync { - struct gl_sync_object gl; - struct brw_fence fence; -}; - -static void -brw_fence_init(struct brw_context *brw, struct brw_fence *fence) -{ - fence->brw = brw; - fence->batch_bo = NULL; - mtx_init(&fence->mutex, mtx_plain); -} - -static void -brw_fence_finish(struct brw_fence *fence) -{ - if (fence->batch_bo) - drm_intel_bo_unreference(fence->batch_bo); - - mtx_destroy(&fence->mutex); -} - -static void -brw_fence_insert(struct brw_context *brw, struct brw_fence *fence) -{ - assert(!fence->batch_bo); - assert(!fence->signalled); - - brw_emit_mi_flush(brw); - fence->batch_bo = brw->batch.bo; - drm_intel_bo_reference(fence->batch_bo); - intel_batchbuffer_flush(brw); -} - -static bool -brw_fence_has_completed_locked(struct brw_fence *fence) -{ - if (fence->signalled) - return true; - - if (fence->batch_bo && !drm_intel_bo_busy(fence->batch_bo)) { - drm_intel_bo_unreference(fence->batch_bo); - fence->batch_bo = NULL; - fence->signalled = true; - return true; - } - - return false; -} - -static bool -brw_fence_has_completed(struct brw_fence *fence) -{ - bool ret; - - mtx_lock(&fence->mutex); - ret = brw_fence_has_completed_locked(fence); - mtx_unlock(&fence->mutex); - - return ret; -} - -static bool -brw_fence_client_wait_locked(struct brw_context *brw, struct brw_fence *fence, - uint64_t timeout) -{ - if (fence->signalled) - return true; - - assert(fence->batch_bo); - - /* DRM_IOCTL_I915_GEM_WAIT uses a signed 64 bit timeout and returns - * immediately for timeouts <= 0. The best we can do is to clamp the - * timeout to INT64_MAX. This limits the maximum timeout from 584 years to - * 292 years - likely not a big deal. - */ - if (timeout > INT64_MAX) - timeout = INT64_MAX; - - if (drm_intel_gem_bo_wait(fence->batch_bo, timeout) != 0) - return false; - - fence->signalled = true; - drm_intel_bo_unreference(fence->batch_bo); - fence->batch_bo = NULL; - - 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 -brw_fence_client_wait(struct brw_context *brw, struct brw_fence *fence, - uint64_t timeout) -{ - bool ret; - - mtx_lock(&fence->mutex); - ret = brw_fence_client_wait_locked(brw, fence, timeout); - mtx_unlock(&fence->mutex); - - return ret; -} - -static void -brw_fence_server_wait(struct brw_context *brw, struct brw_fence *fence) -{ - /* We have nothing to do for WaitSync. Our GL command stream is sequential, - * so given that the sync object has already flushed the batchbuffer, any - * batchbuffers coming after this waitsync will naturally not occur until - * the previous one is done. - */ -} - -static struct gl_sync_object * -brw_gl_new_sync(struct gl_context *ctx, GLuint id) -{ - struct brw_gl_sync *sync; - - sync = calloc(1, sizeof(*sync)); - if (!sync) - return NULL; - - return &sync->gl; -} - -static void -brw_gl_delete_sync(struct gl_context *ctx, struct gl_sync_object *_sync) -{ - struct brw_gl_sync *sync = (struct brw_gl_sync *) _sync; - - brw_fence_finish(&sync->fence); - free(sync); -} - -static void -brw_gl_fence_sync(struct gl_context *ctx, struct gl_sync_object *_sync, - GLenum condition, GLbitfield flags) -{ - struct brw_context *brw = brw_context(ctx); - struct brw_gl_sync *sync = (struct brw_gl_sync *) _sync; - - brw_fence_init(brw, &sync->fence); - brw_fence_insert(brw, &sync->fence); -} - -static void -brw_gl_client_wait_sync(struct gl_context *ctx, struct gl_sync_object *_sync, - GLbitfield flags, GLuint64 timeout) -{ - struct brw_context *brw = brw_context(ctx); - struct brw_gl_sync *sync = (struct brw_gl_sync *) _sync; - - if (brw_fence_client_wait(brw, &sync->fence, timeout)) - sync->gl.StatusFlag = 1; -} - -static void -brw_gl_server_wait_sync(struct gl_context *ctx, struct gl_sync_object *_sync, - GLbitfield flags, GLuint64 timeout) -{ - struct brw_context *brw = brw_context(ctx); - struct brw_gl_sync *sync = (struct brw_gl_sync *) _sync; - - brw_fence_server_wait(brw, &sync->fence); -} - -static void -brw_gl_check_sync(struct gl_context *ctx, struct gl_sync_object *_sync) -{ - struct brw_gl_sync *sync = (struct brw_gl_sync *) _sync; - - if (brw_fence_has_completed(&sync->fence)) - sync->gl.StatusFlag = 1; -} - -void -brw_init_syncobj_functions(struct dd_function_table *functions) -{ - functions->NewSyncObject = brw_gl_new_sync; - functions->DeleteSyncObject = brw_gl_delete_sync; - functions->FenceSync = brw_gl_fence_sync; - functions->CheckSync = brw_gl_check_sync; - functions->ClientWaitSync = brw_gl_client_wait_sync; - functions->ServerWaitSync = brw_gl_server_wait_sync; -} - -static void * -brw_dri_create_fence(__DRIcontext *ctx) -{ - struct brw_context *brw = ctx->driverPrivate; - struct brw_fence *fence; - - fence = calloc(1, sizeof(*fence)); - if (!fence) - return NULL; - - brw_fence_init(brw, fence); - brw_fence_insert(brw, fence); - - return fence; -} - -static void -brw_dri_destroy_fence(__DRIscreen *dri_screen, void *driver_fence) -{ - struct brw_fence *fence = driver_fence; - - brw_fence_finish(fence); - free(fence); -} - -static GLboolean -brw_dri_client_wait_sync(__DRIcontext *ctx, void *driver_fence, unsigned flags, - uint64_t timeout) -{ - struct brw_fence *fence = driver_fence; - - return brw_fence_client_wait(fence->brw, fence, timeout); -} - -static void -brw_dri_server_wait_sync(__DRIcontext *ctx, void *driver_fence, unsigned flags) -{ - struct brw_fence *fence = driver_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; - - brw_fence_server_wait(fence->brw, fence); -} - -const __DRI2fenceExtension intelFenceExtension = { - .base = { __DRI2_FENCE, 1 }, - - .create_fence = brw_dri_create_fence, - .destroy_fence = brw_dri_destroy_fence, - .client_wait_sync = brw_dri_client_wait_sync, - .server_wait_sync = brw_dri_server_wait_sync, - .get_fence_from_cl_event = NULL, -}; -- cgit v1.2.3