diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/mesa/drivers/common/driverfuncs.c | 8 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/swrast/swrast.c | 2 | ||||
| -rw-r--r-- | src/mesa/main/api_exec.c | 14 | ||||
| -rw-r--r-- | src/mesa/main/context.c | 12 | ||||
| -rw-r--r-- | src/mesa/main/dd.h | 16 | ||||
| -rw-r--r-- | src/mesa/main/extensions.c | 4 | ||||
| -rw-r--r-- | src/mesa/main/get.c | 19 | ||||
| -rw-r--r-- | src/mesa/main/get_gen.py | 7 | ||||
| -rw-r--r-- | src/mesa/main/mfeatures.h | 1 | ||||
| -rw-r--r-- | src/mesa/main/mtypes.h | 21 | ||||
| -rw-r--r-- | src/mesa/main/syncobj.c | 372 | ||||
| -rw-r--r-- | src/mesa/main/syncobj.h | 64 | ||||
| -rw-r--r-- | 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 3b397fef7d..a9f3c8e727 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 3aa7843b1b..69b92e9e44 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 cbf48615bf..02550ae108 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 4651760d78..f6d4ac4595 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 3a59872b5a..4a700b5cb4 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 195fdde346..e3070b1547 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 fc742c4a90..477ed01030 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 4f0feaad3c..2878c1b552 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 ef973314e3..e23cdb1f42 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 53dc6360ea..58da5d15eb 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 0000000000..eeeeb49175 --- /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@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 0000000000..d2b4d051c9 --- /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@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 9a9c988ed9..fa2a6307a4 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 \ | 
