Mesa (master): ARB sync: Add support for GL_ARB_sync to swrast

Ian Romanick idr at kemper.freedesktop.org
Thu Sep 3 18:26:06 UTC 2009


Module: Mesa
Branch: master
Commit: f37070bab6af350caec905ea7658e9241042b6cc
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=f37070bab6af350caec905ea7658e9241042b6cc

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Fri Aug 28 20:10:05 2009 -0700

ARB sync: Add support for GL_ARB_sync to swrast

This isn't quite right yet.  The delete behavior and the context
clean-up needs some work.

---

 src/mesa/drivers/common/driverfuncs.c |    8 +
 src/mesa/drivers/dri/swrast/swrast.c  |    2 +
 src/mesa/main/api_exec.c              |   14 ++
 src/mesa/main/context.c               |   12 +
 src/mesa/main/dd.h                    |   16 ++
 src/mesa/main/extensions.c            |    4 +
 src/mesa/main/get.c                   |   19 ++
 src/mesa/main/get_gen.py              |    7 +
 src/mesa/main/mfeatures.h             |    1 +
 src/mesa/main/mtypes.h                |   21 ++
 src/mesa/main/syncobj.c               |  372 +++++++++++++++++++++++++++++++++
 src/mesa/main/syncobj.h               |   64 ++++++
 src/mesa/sources.mak                  |    1 +
 13 files changed, 541 insertions(+), 0 deletions(-)

diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c
index 3b397fe..a9f3c8e 100644
--- a/src/mesa/drivers/common/driverfuncs.c
+++ b/src/mesa/drivers/common/driverfuncs.c
@@ -45,6 +45,9 @@
 #include "main/fbobject.h"
 #include "main/texrender.h"
 #endif
+#if FEATURE_ARB_sync
+#include "main/syncobj.h"
+#endif
 
 #include "shader/program.h"
 #include "shader/prog_execute.h"
@@ -200,6 +203,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
    driver->GetDoublev = NULL;
    driver->GetFloatv = NULL;
    driver->GetIntegerv = NULL;
+   driver->GetInteger64v = NULL;
    driver->GetPointerv = NULL;
    
    /* buffer objects */
@@ -208,6 +212,10 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
    /* query objects */
    _mesa_init_query_object_functions(driver);
 
+#if FEATURE_ARB_sync
+   _mesa_init_sync_object_functions(driver);
+#endif
+
 #if FEATURE_EXT_framebuffer_object
    driver->NewFramebuffer = _mesa_new_framebuffer;
    driver->NewRenderbuffer = _mesa_new_soft_renderbuffer;
diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c
index 3aa7843..69b92e9 100644
--- a/src/mesa/drivers/dri/swrast/swrast.c
+++ b/src/mesa/drivers/dri/swrast/swrast.c
@@ -65,6 +65,7 @@
 #define need_GL_ARB_shader_objects
 #define need_GL_ARB_vertex_array_object
 #define need_GL_ARB_vertex_program
+#define need_GL_ARB_sync
 #define need_GL_APPLE_vertex_array_object
 #define need_GL_ATI_fragment_shader
 #define need_GL_ATI_separate_stencil
@@ -97,6 +98,7 @@ const struct dri_extension card_extensions[] =
     { "GL_ARB_shader_objects",		GL_ARB_shader_objects_functions },
     { "GL_ARB_vertex_array_object",	GL_ARB_vertex_array_object_functions },
     { "GL_ARB_vertex_program",		GL_ARB_vertex_program_functions },
+    { "GL_ARB_sync",			GL_ARB_sync },
     { "GL_APPLE_vertex_array_object",	GL_APPLE_vertex_array_object_functions },
     { "GL_ATI_fragment_shader",		GL_ATI_fragment_shader_functions },
     { "GL_ATI_separate_stencil",	GL_ATI_separate_stencil_functions },
diff --git a/src/mesa/main/api_exec.c b/src/mesa/main/api_exec.c
index cbf4861..02550ae 100644
--- a/src/mesa/main/api_exec.c
+++ b/src/mesa/main/api_exec.c
@@ -129,6 +129,9 @@
 #if FEATURE_ARB_shader_objects
 #include "shaders.h"
 #endif
+#if FEATURE_ARB_sync
+#include "syncobj.h"
+#endif
 #include "debug.h"
 #include "glapi/dispatch.h"
 
@@ -823,6 +826,17 @@ _mesa_init_exec_table(struct _glapi_table *exec)
    SET_GetAttribLocationARB(exec, _mesa_GetAttribLocationARB);
 #endif    /* FEATURE_ARB_vertex_shader */
 
+   /* GL_ARB_sync */
+#if FEATURE_ARB_sync
+   SET_IsSync(exec, _mesa_IsSync);
+   SET_DeleteSync(exec, _mesa_DeleteSync);
+   SET_FenceSync(exec, _mesa_FenceSync);
+   SET_ClientWaitSync(exec, _mesa_ClientWaitSync);
+   SET_WaitSync(exec, _mesa_WaitSync);
+   SET_GetInteger64v(exec, _mesa_GetInteger64v);
+   SET_GetSynciv(exec, _mesa_GetSynciv);
+#endif
+
   /* GL_ATI_fragment_shader */
 #if FEATURE_ATI_fragment_shader
    SET_GenFragmentShadersATI(exec, _mesa_GenFragmentShadersATI);
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 4651760..f6d4ac4 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -129,6 +129,9 @@
 #if FEATURE_ARB_occlusion_query
 #include "queryobj.h"
 #endif
+#if FEATURE_ARB_sync
+#include "syncobj.h"
+#endif
 #if FEATURE_drawpix
 #include "rastpos.h"
 #endif
@@ -592,6 +595,9 @@ _mesa_init_constants(GLcontext *ctx)
    /* GL_ARB_framebuffer_object */
    ctx->Const.MaxSamples = 0;
 
+   /* GL_ARB_sync */
+   ctx->Const.MaxServerWaitTimeout = (GLuint64) ~0;
+
    /* GL_ATI_envmap_bumpmap */
    ctx->Const.SupportedBumpUnits = SUPPORTED_ATI_BUMP_UNITS;
 
@@ -715,6 +721,9 @@ init_attrib_groups(GLcontext *ctx)
 #if FEATURE_ARB_occlusion_query
    _mesa_init_query( ctx );
 #endif
+#if FEATURE_ARB_sync
+   _mesa_init_sync( ctx );
+#endif
 #if FEATURE_drawpix
    _mesa_init_rastpos( ctx );
 #endif
@@ -1014,6 +1023,9 @@ _mesa_free_context_data( GLcontext *ctx )
 #if FEATURE_ARB_occlusion_query
    _mesa_free_query_data(ctx);
 #endif
+#if FEATURE_ARB_sync
+   _mesa_free_sync_data(ctx);
+#endif
    _mesa_free_varray_data(ctx);
 
    _mesa_delete_array_object(ctx, ctx->Array.DefaultArrayObj);
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 3a59872..4a700b5 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -1044,6 +1044,22 @@ struct dd_function_table {
     */
    void (*EndCallList)( GLcontext *ctx );
 
+
+#if FEATURE_ARB_sync
+   /**
+    * \name GL_ARB_sync interfaces
+    */
+   /*@{*/
+   struct gl_sync_object * (*NewSyncObject)(GLcontext *, GLenum);
+   void (*FenceSync)(GLcontext *, struct gl_sync_object *, GLenum, GLbitfield);
+   void (*DeleteSyncObject)(GLcontext *, struct gl_sync_object *);
+   void (*CheckSync)(GLcontext *, struct gl_sync_object *);
+   void (*ClientWaitSync)(GLcontext *, struct gl_sync_object *,
+			  GLbitfield, GLuint64);
+   void (*ServerWaitSync)(GLcontext *, struct gl_sync_object *,
+			  GLbitfield, GLuint64);
+   /*@}*/
+#endif
 };
 
 
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index 195fdde..e3070b1 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -67,6 +67,7 @@ static const struct {
    { OFF, "GL_ARB_shading_language_120",       F(ARB_shading_language_120) },
    { OFF, "GL_ARB_shadow",                     F(ARB_shadow) },
    { OFF, "GL_ARB_shadow_ambient",             F(ARB_shadow_ambient) },
+   { OFF, "GL_ARB_sync",                       F(ARB_sync) },
    { OFF, "GL_ARB_texture_border_clamp",       F(ARB_texture_border_clamp) },
    { ON,  "GL_ARB_texture_compression",        F(ARB_texture_compression) },
    { OFF, "GL_ARB_texture_cube_map",           F(ARB_texture_cube_map) },
@@ -240,6 +241,9 @@ _mesa_enable_sw_extensions(GLcontext *ctx)
 #if FEATURE_ARB_vertex_buffer_object
    /*ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;*/
 #endif
+#if FEATURE_ARB_sync
+   ctx->Extensions.ARB_sync = GL_TRUE;
+#endif
    ctx->Extensions.APPLE_vertex_array_object = GL_TRUE;
    ctx->Extensions.ATI_envmap_bumpmap = GL_TRUE;
 #if FEATURE_ATI_fragment_shader
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index fc742c4..477ed01 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -19,6 +19,9 @@
 
 #define INT_TO_BOOLEAN(I)     ( (I) ? GL_TRUE : GL_FALSE )
 
+#define INT64_TO_BOOLEAN(I)   ( (I) ? GL_TRUE : GL_FALSE )
+#define INT64_TO_INT(I)       ( (GLint)((I > INT_MAX) ? INT_MAX : ((I < INT_MIN) ? INT_MIN : (I))) )
+
 #define BOOLEAN_TO_INT(B)     ( (GLint) (B) )
 #define BOOLEAN_TO_INT64(B)   ( (GLint64) (B) )
 #define BOOLEAN_TO_FLOAT(B)   ( (B) ? 1.0F : 0.0F )
@@ -1887,6 +1890,10 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
          CHECK_EXT1(ARB_seamless_cube_map, "GetBooleanv");
          params[0] = ctx->Texture.CubeMapSeamless;
          break;
+      case GL_MAX_SERVER_WAIT_TIMEOUT:
+         CHECK_EXT1(ARB_sync, "GetBooleanv");
+         params[0] = INT64_TO_BOOLEAN(ctx->Const.MaxServerWaitTimeout);
+         break;
       default:
          _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv(pname=0x%x)", pname);
    }
@@ -3714,6 +3721,10 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
          CHECK_EXT1(ARB_seamless_cube_map, "GetFloatv");
          params[0] = BOOLEAN_TO_FLOAT(ctx->Texture.CubeMapSeamless);
          break;
+      case GL_MAX_SERVER_WAIT_TIMEOUT:
+         CHECK_EXT1(ARB_sync, "GetFloatv");
+         params[0] = (GLfloat)(ctx->Const.MaxServerWaitTimeout);
+         break;
       default:
          _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv(pname=0x%x)", pname);
    }
@@ -5541,6 +5552,10 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
          CHECK_EXT1(ARB_seamless_cube_map, "GetIntegerv");
          params[0] = BOOLEAN_TO_INT(ctx->Texture.CubeMapSeamless);
          break;
+      case GL_MAX_SERVER_WAIT_TIMEOUT:
+         CHECK_EXT1(ARB_sync, "GetIntegerv");
+         params[0] = INT64_TO_INT(ctx->Const.MaxServerWaitTimeout);
+         break;
       default:
          _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv(pname=0x%x)", pname);
    }
@@ -7369,6 +7384,10 @@ _mesa_GetInteger64v( GLenum pname, GLint64 *params )
          CHECK_EXT1(ARB_seamless_cube_map, "GetInteger64v");
          params[0] = BOOLEAN_TO_INT64(ctx->Texture.CubeMapSeamless);
          break;
+      case GL_MAX_SERVER_WAIT_TIMEOUT:
+         CHECK_EXT1(ARB_sync, "GetInteger64v");
+         params[0] = ctx->Const.MaxServerWaitTimeout;
+         break;
       default:
          _mesa_error(ctx, GL_INVALID_ENUM, "glGetInteger64v(pname=0x%x)", pname);
    }
diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py
index 4f0feaa..2878c1b 100644
--- a/src/mesa/main/get_gen.py
+++ b/src/mesa/main/get_gen.py
@@ -1022,6 +1022,10 @@ StateVars = [
 	# GL_ARB_seamless_cube_map
 	( "GL_TEXTURE_CUBE_MAP_SEAMLESS", GLboolean, ["ctx->Texture.CubeMapSeamless"], "",
 	  ["ARB_seamless_cube_map"] ),
+
+	# GL_ARB_sync
+	( "GL_MAX_SERVER_WAIT_TIMEOUT", GLint64, ["ctx->Const.MaxServerWaitTimeout"], "",
+	  ["ARB_sync"] ),
 ]
 
 
@@ -1157,6 +1161,9 @@ def EmitHeader():
 
 #define INT_TO_BOOLEAN(I)     ( (I) ? GL_TRUE : GL_FALSE )
 
+#define INT64_TO_BOOLEAN(I)   ( (I) ? GL_TRUE : GL_FALSE )
+#define INT64_TO_INT(I)       ( (GLint)((I > INT_MAX) ? INT_MAX : ((I < INT_MIN) ? INT_MIN : (I))) )
+
 #define BOOLEAN_TO_INT(B)     ( (GLint) (B) )
 #define BOOLEAN_TO_INT64(B)   ( (GLint64) (B) )
 #define BOOLEAN_TO_FLOAT(B)   ( (B) ? 1.0F : 0.0F )
diff --git a/src/mesa/main/mfeatures.h b/src/mesa/main/mfeatures.h
index ef97331..e23cdb1 100644
--- a/src/mesa/main/mfeatures.h
+++ b/src/mesa/main/mfeatures.h
@@ -70,6 +70,7 @@
 #define FEATURE_ARB_shader_objects (FEATURE_ARB_vertex_shader || FEATURE_ARB_fragment_shader)
 #define FEATURE_ARB_shading_language_100 FEATURE_ARB_shader_objects
 #define FEATURE_ARB_shading_language_120 FEATURE_ARB_shader_objects
+#define FEATURE_ARB_sync _HAVE_FULL_GL
 
 #define FEATURE_EXT_framebuffer_blit _HAVE_FULL_GL
 #define FEATURE_EXT_framebuffer_object _HAVE_FULL_GL
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 53dc636..58da5d1 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1986,6 +1986,20 @@ struct gl_query_state
 };
 
 
+/** Sync object state */
+struct gl_sync_object {
+   GLenum Type;               /**< GL_SYNC_FENCE */
+   GLuint Name;               /**< Fence name */
+   GLint RefCount;            /**< Reference count */
+   GLboolean DeletePending;   /**< Object was deleted while there were still
+			       * live references (e.g., sync not yet finished)
+			       */
+   GLenum SyncCondition;
+   GLbitfield Flags;          /**< Flags passed to glFenceSync */
+   GLuint Status:1;           /**< Has the sync object been signaled? */
+};
+
+
 /** Set by #pragma directives */
 struct gl_sl_pragmas
 {
@@ -2435,6 +2449,12 @@ struct gl_constants
 
    GLbitfield SupportedBumpUnits; /**> units supporting GL_ATI_envmap_bumpmap as targets */
 
+   /**
+    * Maximum amount of time, measured in nanseconds, that the server can wait.
+    */
+   GLuint64 MaxServerWaitTimeout;
+
+
    /**< GL_EXT_provoking_vertex */
    GLboolean QuadsFollowProvokingVertexConvention;
 };
@@ -2467,6 +2487,7 @@ struct gl_extensions
    GLboolean ARB_shading_language_120;
    GLboolean ARB_shadow;
    GLboolean ARB_shadow_ambient; /* or GL_ARB_shadow_ambient */
+   GLboolean ARB_sync;
    GLboolean ARB_texture_border_clamp;
    GLboolean ARB_texture_compression;
    GLboolean ARB_texture_cube_map;
diff --git a/src/mesa/main/syncobj.c b/src/mesa/main/syncobj.c
new file mode 100644
index 0000000..eeeeb49
--- /dev/null
+++ b/src/mesa/main/syncobj.c
@@ -0,0 +1,372 @@
+/*
+ * Copyright © 2009 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.
+ */
+
+/**
+ * \file syncobj.c
+ * Sync object management.
+ *
+ * \author Ian Romanick <ian.d.romanick at intel.com>
+ */
+
+#include "glheader.h"
+#include "hash.h"
+#include "imports.h"
+#include "context.h"
+
+#if FEATURE_ARB_sync
+#include "syncobj.h"
+
+static struct gl_sync_object *
+_mesa_new_sync_object(GLcontext *ctx, GLenum type)
+{
+   struct gl_sync_object *s = MALLOC_STRUCT(gl_sync_object);
+   (void) ctx;
+   (void) type;
+
+   return s;
+}
+
+
+static void
+_mesa_delete_sync_object(GLcontext *ctx, struct gl_sync_object *syncObj)
+{
+   (void) ctx;
+   _mesa_free(syncObj);
+}
+
+
+static void
+_mesa_fence_sync(GLcontext *ctx, struct gl_sync_object *syncObj,
+		 GLenum condition, GLbitfield flags)
+{
+   (void) ctx;
+   (void) condition;
+   (void) flags;
+
+   syncObj->Status = 1;
+}
+
+
+static void
+_mesa_check_sync(GLcontext *ctx, struct gl_sync_object *syncObj)
+{
+   (void) ctx;
+   (void) syncObj;
+
+   /* No-op for software rendering.  Hardware drivers will need to determine
+    * whether the state of the sync object has changed.
+    */
+}
+
+
+static void
+_mesa_wait_sync(GLcontext *ctx, struct gl_sync_object *syncObj,
+		GLbitfield flags, GLuint64 timeout)
+{
+   (void) ctx;
+   (void) syncObj;
+   (void) flags;
+   (void) timeout;
+
+
+   /* No-op for software rendering.  Hardware drivers will need to wait until
+    * the state of the sync object changes or the timeout expires.
+    */
+}
+
+
+void
+_mesa_init_sync_object_functions(struct dd_function_table *driver)
+{
+   driver->NewSyncObject = _mesa_new_sync_object;
+   driver->FenceSync = _mesa_fence_sync;
+   driver->DeleteSyncObject = _mesa_delete_sync_object;
+   driver->CheckSync = _mesa_check_sync;
+
+   /* Use the same no-op wait function for both.
+    */
+   driver->ClientWaitSync = _mesa_wait_sync;
+   driver->ServerWaitSync = _mesa_wait_sync;
+}
+
+
+/**
+ * Allocate/init the context state related to sync objects.
+ */
+void
+_mesa_init_sync(GLcontext *ctx)
+{
+   (void) ctx;
+}
+
+
+/**
+ * Free the context state related to sync objects.
+ */
+void
+_mesa_free_sync_data(GLcontext *ctx)
+{
+   (void) ctx;
+}
+
+
+GLboolean
+_mesa_IsSync(GLsync sync)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync;
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+
+
+   return ((syncObj != NULL) && (syncObj->Type == GL_SYNC_FENCE))
+      ? GL_TRUE : GL_FALSE;
+}
+
+
+static void
+_mesa_unref_sync_object(GLcontext *ctx, struct gl_sync_object *syncObj)
+{
+   syncObj->RefCount--;
+   if (syncObj->RefCount == 0) {
+      (*ctx->Driver.DeleteSyncObject)(ctx, syncObj);
+   } else {
+      syncObj->DeletePending = 1;
+   }
+}
+
+
+void
+_mesa_DeleteSync(GLsync sync)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync;
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+
+   /* From the GL_ARB_sync spec:
+    *
+    *    DeleteSync will silently ignore a <sync> value of zero. An
+    *    INVALID_VALUE error is generated if <sync> is neither zero nor the
+    *    name of a sync object.
+    */
+   if (sync == 0) {
+      return;
+   }
+
+   if (syncObj->Type != GL_SYNC_FENCE) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteSync");
+      return;
+   }
+
+
+   /* If there are no client-waits or server-waits pending on this sync, delete
+    * the underlying object.
+    */
+   _mesa_unref_sync_object(ctx, syncObj);
+}
+
+
+
+GLsync
+_mesa_FenceSync(GLenum condition, GLbitfield flags)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_sync_object *syncObj;
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
+
+
+   if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glFenceSync(condition=0x%x)",
+		  condition);
+      return 0;
+   }
+
+   if (flags != 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glFenceSync(flags=0x%x)",
+		  condition);
+      return 0;
+   }
+
+   syncObj = (*ctx->Driver.NewSyncObject)(ctx, GL_SYNC_FENCE);
+   if (syncObj != NULL) {
+      syncObj->Type = GL_SYNC_FENCE;
+      /* The name is not currently used, and it is never visible to
+       * applications.  If sync support is extended to provide support for
+       * NV_fence, this field will be used.  We'll also need to add an object
+       * ID hashtable.
+       */
+      syncObj->Name = 1;
+      syncObj->RefCount = 1;
+      syncObj->DeletePending = GL_FALSE;
+      syncObj->SyncCondition = condition;
+      syncObj->Flags = flags;
+      syncObj->Status = 0;
+
+      (*ctx->Driver.FenceSync)(ctx, syncObj, condition, flags);
+
+      return (GLsync) syncObj;
+   }
+
+   return NULL;
+}
+
+
+GLenum
+_mesa_ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync;
+   GLenum ret;
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_WAIT_FAILED);
+
+
+   if ((syncObj == NULL) || (syncObj->Type != GL_SYNC_FENCE)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glClientWaitSync");
+      return GL_WAIT_FAILED;
+   }
+
+   if ((flags & ~GL_SYNC_FLUSH_COMMANDS_BIT) != 0) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glClientWaitSync(flags=0x%x)", flags);
+      return GL_WAIT_FAILED;
+   }
+
+
+   /* From the GL_ARB_sync spec:
+    *
+    *    ClientWaitSync returns one of four status values. A return value of
+    *    ALREADY_SIGNALED indicates that <sync> was signaled at the time
+    *    ClientWaitSync was called. ALREADY_SIGNALED will always be returned
+    *    if <sync> was signaled, even if the value of <timeout> is zero.
+    */
+   (*ctx->Driver.CheckSync)(ctx, syncObj);
+
+   if (syncObj->Status) {
+      return GL_ALREADY_SIGNALED;
+   }
+
+
+   (*ctx->Driver.ClientWaitSync)(ctx, syncObj, flags, timeout);
+
+   ret = syncObj->Status ? GL_CONDITION_SATISFIED : GL_TIMEOUT_EXPIRED;
+
+   if (syncObj->DeletePending && syncObj->Status) {
+      _mesa_unref_sync_object(ctx, syncObj);
+   }
+
+   return ret;
+}
+
+
+void
+_mesa_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync;
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+
+   if ((syncObj == NULL) || (syncObj->Type != GL_SYNC_FENCE)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glWaitSync");
+      return;
+   }
+
+   if (flags != 0) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glWaitSync(flags=0x%x)", flags);
+      return;
+   }
+
+   /* From the GL_ARB_sync spec:
+    *
+    *     If the value of <timeout> is zero, then WaitSync does nothing.
+    */
+   if (timeout == 0) {
+      return;
+   }
+
+   (*ctx->Driver.ServerWaitSync)(ctx, syncObj, flags, timeout);
+}
+
+
+void
+_mesa_GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length,
+		GLint *values)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync;
+   GLsizei size = 0;
+   GLint v[1];
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+
+   if ((syncObj == NULL) || (syncObj->Type != GL_SYNC_FENCE)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetSynciv");
+      return;
+   }
+
+
+   switch (pname) {
+   case GL_OBJECT_TYPE:
+      v[0] = syncObj->Type;
+      size = 1;
+      break;
+
+   case GL_SYNC_CONDITION:
+      v[0] = syncObj->SyncCondition;
+      size = 1;
+      break;
+
+   case GL_SYNC_STATUS:
+      /* Update the state of the sync by dipping into the driver.  Note that
+       * this call won't block.  It just updates state in the common object
+       * data from the current driver state.
+       */
+      (*ctx->Driver.CheckSync)(ctx, syncObj);
+
+      v[0] = (syncObj->Status) ? GL_SIGNALED : GL_UNSIGNALED;
+      size = 1;
+      break;
+
+   case GL_SYNC_FLAGS:
+      v[0] = syncObj->Flags;
+      size = 1;
+      break;
+
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetSynciv(pname=0x%x)\n", pname);
+      return;
+   }
+
+
+   if (size > 0) {
+      const GLsizei copy_count = (size > bufSize) ? bufSize : size;
+
+      _mesa_memcpy(values, v, sizeof(GLint) * copy_count);
+   }
+
+
+   if (length != NULL) {
+      *length = size;
+   }
+}
+
+#endif /* FEATURE_ARB_sync */
diff --git a/src/mesa/main/syncobj.h b/src/mesa/main/syncobj.h
new file mode 100644
index 0000000..d2b4d05
--- /dev/null
+++ b/src/mesa/main/syncobj.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2009 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.
+ */
+
+/**
+ * \file syncobj.h
+ * Sync object management.
+ *
+ * \author Ian Romanick <ian.d.romanick at intel.com>
+ */
+
+#ifndef SYNCOBJ_H
+#define SYNCOBJ_H
+
+#include "context.h"
+
+extern void
+_mesa_init_sync_object_functions(struct dd_function_table *driver);
+
+extern void
+_mesa_init_sync(GLcontext *);
+
+extern void
+_mesa_free_sync_data(GLcontext *);
+
+extern GLboolean
+_mesa_IsSync(GLsync sync);
+
+extern void
+_mesa_DeleteSync(GLsync sync);
+
+extern GLsync
+_mesa_FenceSync(GLenum condition, GLbitfield flags);
+
+extern GLenum
+_mesa_ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
+
+extern void
+_mesa_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
+
+extern void
+_mesa_GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length,
+		GLint *values);
+
+#endif /* SYNCOBJ_H */
diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak
index 9a9c988..fa2a630 100644
--- a/src/mesa/sources.mak
+++ b/src/mesa/sources.mak
@@ -61,6 +61,7 @@ MAIN_SOURCES = \
 	main/shared.c \
 	main/state.c \
 	main/stencil.c \
+	main/syncobj.c \
 	main/texcompress.c \
 	main/texcompress_s3tc.c \
 	main/texcompress_fxt1.c \




More information about the mesa-commit mailing list