From afd6141934a0fb52fc1739a2a9992db3ac34682b Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 1 Sep 2009 12:20:10 -0700 Subject: intel: Add support for ARB_sync. We currently weasel out of supporting the timeout parameter, but otherwise this extension looks ready, and should make the common case happy. --- src/mesa/drivers/dri/intel/intel_syncobj.c | 132 +++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 src/mesa/drivers/dri/intel/intel_syncobj.c (limited to 'src/mesa/drivers/dri/intel/intel_syncobj.c') diff --git a/src/mesa/drivers/dri/intel/intel_syncobj.c b/src/mesa/drivers/dri/intel/intel_syncobj.c new file mode 100644 index 0000000000..d447b6a0fa --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_syncobj.c @@ -0,0 +1,132 @@ +/* + * 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 intel_syncobj.c + * + * Support for ARB_sync + * + * ARB_sync is implemented by flushing the current batchbuffer and keeping a + * reference on it. We can then check for completion or wait for compeltion + * 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/simple_list.h" +#include "main/imports.h" + +#include "intel_context.h" +#include "intel_batchbuffer.h" +#include "intel_reg.h" + +static struct gl_sync_object * +intel_new_sync_object(GLcontext *ctx, GLuint id) +{ + struct intel_sync_object *sync; + + sync = _mesa_calloc(sizeof(struct intel_sync_object)); + + return &sync->Base; +} + +static void +intel_delete_sync_object(GLcontext *ctx, struct gl_sync_object *s) +{ + struct intel_sync_object *sync = (struct intel_sync_object *)s; + + drm_intel_bo_unreference(sync->bo); + _mesa_free(sync); +} + +static void +intel_fence_sync(GLcontext *ctx, struct gl_sync_object *s, + GLenum condition, GLbitfield flags) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_sync_object *sync = (struct intel_sync_object *)s; + + assert(condition == GL_SYNC_GPU_COMMANDS_COMPLETE); + intel_batchbuffer_emit_mi_flush(intel->batch); + + sync->bo = intel->batch->buf; + drm_intel_bo_reference(sync->bo); + + intelFlush(ctx); +} + +/* We ignore the user-supplied timeout. This is weaselly -- we're allowed to + * round to an implementation-dependent accuracy, and right now our + * implementation "rounds" to the wait-forever value. + * + * The fix would be a new kernel function to do the GTT transition with a + * timeout. + */ +static void intel_client_wait_sync(GLcontext *ctx, struct gl_sync_object *s, + GLbitfield flags, GLuint64 timeout) +{ + struct intel_sync_object *sync = (struct intel_sync_object *)s; + + if (sync->bo) { + drm_intel_bo_wait_rendering(sync->bo); + s->Status = 1; + drm_intel_bo_unreference(sync->bo); + sync->bo = NULL; + } +} + +/* 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 void intel_server_wait_sync(GLcontext *ctx, struct gl_sync_object *s, + GLbitfield flags, GLuint64 timeout) +{ +} + +static void intel_check_sync(GLcontext *ctx, struct gl_sync_object *s) +{ + struct intel_sync_object *sync = (struct intel_sync_object *)s; + + if (sync->bo && drm_intel_bo_busy(sync->bo)) { + drm_intel_bo_unreference(sync->bo); + sync->bo = NULL; + s->Status = 1; + } +} + +void intel_init_syncobj_functions(struct dd_function_table *functions) +{ + functions->NewSyncObject = intel_new_sync_object; + functions->DeleteSyncObject = intel_delete_sync_object; + functions->FenceSync = intel_fence_sync; + functions->CheckSync = intel_check_sync; + functions->ClientWaitSync = intel_client_wait_sync; + functions->ServerWaitSync = intel_server_wait_sync; +} -- cgit v1.2.3 From e059885ce357dee8b847f10e8e8c515a4a20042e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Sep 2009 12:47:25 -0600 Subject: mesa: rename gl_sync_object::Status to StatusFlag There's a symbol collision with X11/Xlib.h #define Status int in the Mesa xlib code. This seems the simpliest way to work around this. --- src/mesa/drivers/dri/intel/intel_syncobj.c | 4 ++-- src/mesa/main/mtypes.h | 2 +- src/mesa/main/syncobj.c | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/mesa/drivers/dri/intel/intel_syncobj.c') diff --git a/src/mesa/drivers/dri/intel/intel_syncobj.c b/src/mesa/drivers/dri/intel/intel_syncobj.c index d447b6a0fa..1286fe929b 100644 --- a/src/mesa/drivers/dri/intel/intel_syncobj.c +++ b/src/mesa/drivers/dri/intel/intel_syncobj.c @@ -94,7 +94,7 @@ static void intel_client_wait_sync(GLcontext *ctx, struct gl_sync_object *s, if (sync->bo) { drm_intel_bo_wait_rendering(sync->bo); - s->Status = 1; + s->StatusFlag = 1; drm_intel_bo_unreference(sync->bo); sync->bo = NULL; } @@ -117,7 +117,7 @@ static void intel_check_sync(GLcontext *ctx, struct gl_sync_object *s) if (sync->bo && drm_intel_bo_busy(sync->bo)) { drm_intel_bo_unreference(sync->bo); sync->bo = NULL; - s->Status = 1; + s->StatusFlag = 1; } } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index bd3bf28328..6b64bf8139 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1998,7 +1998,7 @@ struct gl_sync_object { */ GLenum SyncCondition; GLbitfield Flags; /**< Flags passed to glFenceSync */ - GLuint Status:1; /**< Has the sync object been signaled? */ + GLuint StatusFlag:1; /**< Has the sync object been signaled? */ }; diff --git a/src/mesa/main/syncobj.c b/src/mesa/main/syncobj.c index 075931c7ce..64f923ff91 100644 --- a/src/mesa/main/syncobj.c +++ b/src/mesa/main/syncobj.c @@ -90,7 +90,7 @@ _mesa_fence_sync(GLcontext *ctx, struct gl_sync_object *syncObj, (void) condition; (void) flags; - syncObj->Status = 1; + syncObj->StatusFlag = 1; } @@ -263,7 +263,7 @@ _mesa_FenceSync(GLenum condition, GLbitfield flags) syncObj->DeletePending = GL_FALSE; syncObj->SyncCondition = condition; syncObj->Flags = flags; - syncObj->Status = 0; + syncObj->StatusFlag = 0; ctx->Driver.FenceSync(ctx, syncObj, condition, flags); @@ -306,12 +306,12 @@ _mesa_ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) * if was signaled, even if the value of is zero. */ ctx->Driver.CheckSync(ctx, syncObj); - if (syncObj->Status) { + if (syncObj->StatusFlag) { ret = GL_ALREADY_SIGNALED; } else { ctx->Driver.ClientWaitSync(ctx, syncObj, flags, timeout); - ret = syncObj->Status ? GL_CONDITION_SATISFIED : GL_TIMEOUT_EXPIRED; + ret = syncObj->StatusFlag ? GL_CONDITION_SATISFIED : GL_TIMEOUT_EXPIRED; } _mesa_unref_sync_object(ctx, syncObj); @@ -381,7 +381,7 @@ _mesa_GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, */ ctx->Driver.CheckSync(ctx, syncObj); - v[0] = (syncObj->Status) ? GL_SIGNALED : GL_UNSIGNALED; + v[0] = (syncObj->StatusFlag) ? GL_SIGNALED : GL_UNSIGNALED; size = 1; break; -- cgit v1.2.3