summaryrefslogtreecommitdiff
path: root/src/gallium/state_trackers
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r--src/gallium/state_trackers/dri/common/dri_drawable.c57
-rw-r--r--src/gallium/state_trackers/dri/common/dri_drawable.h4
-rw-r--r--src/gallium/state_trackers/dri/drm/dri2.c86
-rw-r--r--src/gallium/state_trackers/dri/sw/drisw.c4
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.c3
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.h20
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_api.c8
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_sync.c284
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_sync.h53
9 files changed, 428 insertions, 91 deletions
diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.c b/src/gallium/state_trackers/dri/common/dri_drawable.c
index c67ca2224d..1bdfdccf43 100644
--- a/src/gallium/state_trackers/dri/common/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.c
@@ -30,6 +30,7 @@
*/
#include "dri_screen.h"
+#include "dri_context.h"
#include "dri_drawable.h"
#include "pipe/p_screen.h"
@@ -157,9 +158,9 @@ dri_destroy_buffer(__DRIdrawable * dPriv)
/**
* Validate the texture at an attachment. Allocate the texture if it does not
- * exist.
+ * exist. Used by the TFP extension.
*/
-void
+static void
dri_drawable_validate_att(struct dri_drawable *drawable,
enum st_attachment_type statt)
{
@@ -180,11 +181,61 @@ dri_drawable_validate_att(struct dri_drawable *drawable,
drawable->texture_stamp = drawable->dPriv->lastStamp - 1;
- /* this calles into the manager */
drawable->base.validate(&drawable->base, statts, count, NULL);
}
/**
+ * These are used for GLX_EXT_texture_from_pixmap
+ */
+static void
+dri_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
+ GLint format, __DRIdrawable *dPriv)
+{
+ struct dri_context *ctx = dri_context(pDRICtx);
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct pipe_resource *pt;
+
+ dri_drawable_validate_att(drawable, ST_ATTACHMENT_FRONT_LEFT);
+
+ pt = drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
+
+ if (pt) {
+ enum pipe_format internal_format = pt->format;
+
+ if (format == __DRI_TEXTURE_FORMAT_RGB) {
+ /* only need to cover the formats recognized by dri_fill_st_visual */
+ switch (internal_format) {
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ internal_format = PIPE_FORMAT_B8G8R8X8_UNORM;
+ break;
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ internal_format = PIPE_FORMAT_X8R8G8B8_UNORM;
+ break;
+ default:
+ break;
+ }
+ }
+
+ ctx->st->teximage(ctx->st,
+ (target == GL_TEXTURE_2D) ? ST_TEXTURE_2D : ST_TEXTURE_RECT,
+ 0, internal_format, pt, FALSE);
+ }
+}
+
+static void
+dri_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
+ __DRIdrawable *dPriv)
+{
+ dri_set_tex_buffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
+}
+
+const __DRItexBufferExtension driTexBufferExtension = {
+ { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+ dri_set_tex_buffer,
+ dri_set_tex_buffer2,
+};
+
+/**
* Get the format and binding of an attachment.
*/
void
diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.h b/src/gallium/state_trackers/dri/common/dri_drawable.h
index 3f2e24fc15..74e662d36c 100644
--- a/src/gallium/state_trackers/dri/common/dri_drawable.h
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.h
@@ -89,9 +89,7 @@ dri_drawable_get_format(struct dri_drawable *drawable,
enum pipe_format *format,
unsigned *bind);
-void
-dri_drawable_validate_att(struct dri_drawable *drawable,
- enum st_attachment_type statt);
+extern const __DRItexBufferExtension driTexBufferExtension;
#endif
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
index 1fb8996337..47005c17e2 100644
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -67,86 +67,6 @@ static const __DRI2flushExtension dri2FlushExtension = {
};
/**
- * These are used for GLX_EXT_texture_from_pixmap
- */
-static void
-dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
- GLint format, __DRIdrawable *dPriv)
-{
- struct dri_context *ctx = dri_context(pDRICtx);
- struct dri_drawable *drawable = dri_drawable(dPriv);
- struct pipe_resource *pt;
-
- dri_drawable_validate_att(drawable, ST_ATTACHMENT_FRONT_LEFT);
-
- pt = drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
-
- if (pt) {
- enum pipe_format internal_format = pt->format;
-
- if (format == __DRI_TEXTURE_FORMAT_RGB) {
- /* only need to cover the formats recognized by dri_fill_st_visual */
- switch (internal_format) {
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- internal_format = PIPE_FORMAT_B8G8R8X8_UNORM;
- break;
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- internal_format = PIPE_FORMAT_X8R8G8B8_UNORM;
- break;
- default:
- break;
- }
- }
-
- ctx->st->teximage(ctx->st,
- (target == GL_TEXTURE_2D) ? ST_TEXTURE_2D : ST_TEXTURE_RECT,
- 0, internal_format, pt, FALSE);
- }
-}
-
-static void
-dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
- __DRIdrawable *dPriv)
-{
- dri2_set_tex_buffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
-}
-
-static const __DRItexBufferExtension dri2TexBufferExtension = {
- { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
- dri2_set_tex_buffer,
- dri2_set_tex_buffer2,
-};
-
-/**
- * Get the format and binding of an attachment.
- */
-static INLINE void
-dri2_drawable_get_format(struct dri_drawable *drawable,
- enum st_attachment_type statt,
- enum pipe_format *format,
- unsigned *bind)
-{
- switch (statt) {
- case ST_ATTACHMENT_FRONT_LEFT:
- case ST_ATTACHMENT_BACK_LEFT:
- case ST_ATTACHMENT_FRONT_RIGHT:
- case ST_ATTACHMENT_BACK_RIGHT:
- *format = drawable->stvis.color_format;
- *bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
- break;
- case ST_ATTACHMENT_DEPTH_STENCIL:
- *format = drawable->stvis.depth_stencil_format;
- *bind = PIPE_BIND_DEPTH_STENCIL; /* XXX sampler? */
- break;
- default:
- *format = PIPE_FORMAT_NONE;
- *bind = 0;
- break;
- }
-}
-
-
-/**
* Retrieve __DRIbuffer from the DRI loader.
*/
static __DRIbuffer *
@@ -176,7 +96,7 @@ dri2_drawable_get_buffers(struct dri_drawable *drawable,
unsigned bind;
int att, bpp;
- dri2_drawable_get_format(drawable, statts[i], &format, &bind);
+ dri_drawable_get_format(drawable, statts[i], &format, &bind);
if (format == PIPE_FORMAT_NONE)
continue;
@@ -318,7 +238,7 @@ dri2_drawable_process_buffers(struct dri_drawable *drawable,
break;
}
- dri2_drawable_get_format(drawable, statt, &format, &bind);
+ dri_drawable_get_format(drawable, statt, &format, &bind);
if (statt == ST_ATTACHMENT_INVALID || format == PIPE_FORMAT_NONE)
continue;
@@ -483,7 +403,7 @@ static const __DRIextension *dri_screen_extensions[] = {
&driCopySubBufferExtension.base,
&driSwapControlExtension.base,
&driMediaStreamCounterExtension.base,
- &dri2TexBufferExtension.base,
+ &driTexBufferExtension.base,
&dri2FlushExtension.base,
&dri2ImageExtension.base,
&dri2ConfigQueryExtension.base,
diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c
index ae96f1b20e..249ccd7fcf 100644
--- a/src/gallium/state_trackers/dri/sw/drisw.c
+++ b/src/gallium/state_trackers/dri/sw/drisw.c
@@ -201,7 +201,7 @@ drisw_allocate_textures(struct dri_drawable *drawable,
struct pipe_resource templ;
unsigned width, height;
boolean resized;
- int i;
+ unsigned i;
width = drawable->dPriv->w;
height = drawable->dPriv->h;
@@ -222,7 +222,7 @@ drisw_allocate_textures(struct dri_drawable *drawable,
templ.depth0 = 1;
templ.last_level = 0;
- for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+ for (i = 0; i < count; i++) {
enum pipe_format format;
unsigned bind;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 56d575ffe0..02b9f6aec4 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -530,6 +530,9 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_USE_NATIVE_BUFFER))
dpy->Extensions.KHR_image_pixmap = EGL_TRUE;
+ dpy->Extensions.KHR_reusable_sync = EGL_TRUE;
+ dpy->Extensions.KHR_fence_sync = EGL_TRUE;
+
if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
_eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)");
goto fail;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h
index f33dc91cf9..be450bbede 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.h
@@ -30,12 +30,14 @@
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "pipe/p_format.h"
+#include "os/os_thread.h"
#include "egldriver.h"
#include "egldisplay.h"
#include "eglcontext.h"
#include "eglsurface.h"
#include "eglconfig.h"
#include "eglimage.h"
+#include "eglsync.h"
#include "eglscreen.h"
#include "eglmode.h"
@@ -99,6 +101,24 @@ struct egl_g3d_image {
_EGL_DRIVER_STANDARD_TYPECASTS(egl_g3d)
_EGL_DRIVER_TYPECAST(egl_g3d_image, _EGLImage, obj)
+#ifdef EGL_KHR_reusable_sync
+
+struct egl_g3d_sync {
+ _EGLSync base;
+
+ int refs;
+
+ /* the mutex protects only the condvar, not the struct */
+ pipe_mutex mutex;
+ pipe_condvar condvar;
+
+ /* for fence sync */
+ struct pipe_fence_handle *fence;
+};
+_EGL_DRIVER_TYPECAST(egl_g3d_sync, _EGLSync, obj)
+
+#endif /* EGL_KHR_reusable_sync */
+
#ifdef EGL_MESA_screen_surface
struct egl_g3d_screen {
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
index edac72a822..1120945edc 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
@@ -34,6 +34,7 @@
#include "egl_g3d.h"
#include "egl_g3d_api.h"
#include "egl_g3d_image.h"
+#include "egl_g3d_sync.h"
#include "egl_g3d_st.h"
#include "egl_g3d_loader.h"
#include "native.h"
@@ -806,6 +807,13 @@ egl_g3d_init_driver_api(_EGLDriver *drv)
drv->API.CreateImageKHR = egl_g3d_create_image;
drv->API.DestroyImageKHR = egl_g3d_destroy_image;
+#ifdef EGL_KHR_reusable_sync
+ drv->API.CreateSyncKHR = egl_g3d_create_sync;
+ drv->API.DestroySyncKHR = egl_g3d_destroy_sync;
+ drv->API.ClientWaitSyncKHR = egl_g3d_client_wait_sync;
+ drv->API.SignalSyncKHR = egl_g3d_signal_sync;
+#endif
+
#ifdef EGL_MESA_screen_surface
drv->API.CreateScreenSurfaceMESA = egl_g3d_create_screen_surface;
drv->API.ShowScreenSurfaceMESA = egl_g3d_show_screen_surface;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_sync.c b/src/gallium/state_trackers/egl/common/egl_g3d_sync.c
new file mode 100644
index 0000000000..ec74e9eb94
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_sync.c
@@ -0,0 +1,284 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * 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 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:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "util/u_memory.h"
+#include "util/u_atomic.h"
+#include "os/os_thread.h"
+#include "eglsync.h"
+#include "eglcurrent.h"
+
+#include "egl_g3d.h"
+#include "egl_g3d_sync.h"
+
+#ifdef EGL_KHR_reusable_sync
+
+/**
+ * Wait for the conditional variable.
+ */
+static EGLint
+egl_g3d_wait_sync_condvar(struct egl_g3d_sync *gsync, EGLTimeKHR timeout)
+{
+ _EGLDisplay *dpy = gsync->base.Resource.Display;
+
+ pipe_mutex_lock(gsync->mutex);
+
+ /* unlock display lock just before waiting */
+ _eglUnlockMutex(&dpy->Mutex);
+
+ /* No timed wait. Always treat timeout as EGL_FOREVER_KHR */
+ pipe_condvar_wait(gsync->condvar, gsync->mutex);
+
+ _eglLockMutex(&dpy->Mutex);
+
+ pipe_mutex_unlock(gsync->mutex);
+
+ return EGL_CONDITION_SATISFIED_KHR;
+}
+
+/**
+ * Signal the conditional variable.
+ */
+static void
+egl_g3d_signal_sync_condvar(struct egl_g3d_sync *gsync)
+{
+ pipe_mutex_lock(gsync->mutex);
+ pipe_condvar_broadcast(gsync->condvar);
+ pipe_mutex_unlock(gsync->mutex);
+}
+
+/**
+ * Insert a fence command to the command stream of the current context.
+ */
+static EGLint
+egl_g3d_insert_fence_sync(struct egl_g3d_sync *gsync)
+{
+ _EGLContext *ctx = _eglGetCurrentContext();
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+
+ /* already checked in egl_g3d_create_sync */
+ assert(gctx);
+
+ /* insert the fence command */
+ gctx->stctxi->flush(gctx->stctxi, 0x0, &gsync->fence);
+ if (!gsync->fence)
+ gsync->base.SyncStatus = EGL_SIGNALED_KHR;
+
+ return EGL_SUCCESS;
+}
+
+/**
+ * Wait for the fence sync to be signaled.
+ */
+static EGLint
+egl_g3d_wait_fence_sync(struct egl_g3d_sync *gsync, EGLTimeKHR timeout)
+{
+ EGLint ret;
+
+ if (gsync->fence) {
+ _EGLDisplay *dpy = gsync->base.Resource.Display;
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct pipe_screen *screen = gdpy->native->screen;
+ struct pipe_fence_handle *fence = gsync->fence;
+
+ gsync->fence = NULL;
+
+ _eglUnlockMutex(&dpy->Mutex);
+ /* no timed finish? */
+ screen->fence_finish(screen, fence, 0x0);
+ ret = EGL_CONDITION_SATISFIED_KHR;
+ _eglLockMutex(&dpy->Mutex);
+
+ gsync->base.SyncStatus = EGL_SIGNALED_KHR;
+
+ screen->fence_reference(screen, &fence, NULL);
+ egl_g3d_signal_sync_condvar(gsync);
+ }
+ else {
+ ret = egl_g3d_wait_sync_condvar(gsync, timeout);
+ }
+
+ return ret;
+}
+
+static INLINE void
+egl_g3d_ref_sync(struct egl_g3d_sync *gsync)
+{
+ p_atomic_inc(&gsync->refs);
+}
+
+static INLINE void
+egl_g3d_unref_sync(struct egl_g3d_sync *gsync)
+{
+ if (p_atomic_dec_zero(&gsync->refs)) {
+ pipe_condvar_destroy(gsync->condvar);
+ pipe_mutex_destroy(gsync->mutex);
+
+ if (gsync->fence) {
+ struct egl_g3d_display *gdpy =
+ egl_g3d_display(gsync->base.Resource.Display);
+ struct pipe_screen *screen = gdpy->native->screen;
+
+ screen->fence_reference(screen, &gsync->fence, NULL);
+ }
+
+ FREE(gsync);
+ }
+}
+
+_EGLSync *
+egl_g3d_create_sync(_EGLDriver *drv, _EGLDisplay *dpy,
+ EGLenum type, const EGLint *attrib_list)
+{
+ _EGLContext *ctx = _eglGetCurrentContext();
+ struct egl_g3d_sync *gsync;
+ EGLint err;
+
+ if (!ctx || ctx->Resource.Display != dpy) {
+ _eglError(EGL_BAD_MATCH, "eglCreateSyncKHR");
+ return NULL;
+ }
+
+ gsync = CALLOC_STRUCT(egl_g3d_sync);
+ if (!gsync) {
+ _eglError(EGL_BAD_ALLOC, "eglCreateSyncKHR");
+ return NULL;
+ }
+
+ if (!_eglInitSync(&gsync->base, dpy, type, attrib_list)) {
+ FREE(gsync);
+ return NULL;
+ }
+
+ switch (type) {
+ case EGL_SYNC_REUSABLE_KHR:
+ err = EGL_SUCCESS;
+ break;
+ case EGL_SYNC_FENCE_KHR:
+ err = egl_g3d_insert_fence_sync(gsync);
+ break;
+ default:
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+
+ if (err != EGL_SUCCESS) {
+ _eglError(err, "eglCreateSyncKHR");
+ FREE(gsync);
+ return NULL;
+ }
+
+ pipe_mutex_init(gsync->mutex);
+ pipe_condvar_init(gsync->condvar);
+ p_atomic_set(&gsync->refs, 1);
+
+ return &gsync->base;
+}
+
+EGLBoolean
+egl_g3d_destroy_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync)
+{
+ struct egl_g3d_sync *gsync = egl_g3d_sync(sync);
+
+ switch (gsync->base.Type) {
+ case EGL_SYNC_REUSABLE_KHR:
+ /* signal the waiters */
+ if (gsync->base.SyncStatus != EGL_SIGNALED_KHR) {
+ gsync->base.SyncStatus = EGL_SIGNALED_KHR;
+ egl_g3d_signal_sync_condvar(gsync);
+ }
+ break;
+ default:
+ break;
+ }
+
+ egl_g3d_unref_sync(gsync);
+
+ return EGL_TRUE;
+}
+
+EGLint
+egl_g3d_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+ EGLint flags, EGLTimeKHR timeout)
+{
+ struct egl_g3d_sync *gsync = egl_g3d_sync(sync);
+ EGLint ret = EGL_CONDITION_SATISFIED_KHR;
+
+ if (gsync->base.SyncStatus != EGL_SIGNALED_KHR) {
+ /* flush if there is a current context */
+ if (flags & EGL_SYNC_FLUSH_COMMANDS_BIT_KHR) {
+ _EGLContext *ctx = _eglGetCurrentContext();
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+
+ if (gctx)
+ gctx->stctxi->flush(gctx->stctxi, PIPE_FLUSH_RENDER_CACHE , NULL);
+ }
+
+ if (timeout) {
+ /* reference the sync object in case it is destroyed while waiting */
+ egl_g3d_ref_sync(gsync);
+
+ switch (gsync->base.Type) {
+ case EGL_SYNC_REUSABLE_KHR:
+ ret = egl_g3d_wait_sync_condvar(gsync, timeout);
+ break;
+ case EGL_SYNC_FENCE_KHR:
+ ret = egl_g3d_wait_fence_sync(gsync, timeout);
+ default:
+ break;
+ }
+
+ egl_g3d_unref_sync(gsync);
+ }
+ else {
+ ret = EGL_TIMEOUT_EXPIRED_KHR;
+ }
+ }
+
+ return ret;
+}
+
+EGLBoolean
+egl_g3d_signal_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+ EGLenum mode)
+{
+ struct egl_g3d_sync *gsync = egl_g3d_sync(sync);
+
+ /* only for reusable sync */
+ if (sync->Type != EGL_SYNC_REUSABLE_KHR)
+ return _eglError(EGL_BAD_MATCH, "eglSignalSyncKHR");
+
+ if (gsync->base.SyncStatus != mode) {
+ gsync->base.SyncStatus = mode;
+ if (mode == EGL_SIGNALED_KHR)
+ egl_g3d_signal_sync_condvar(gsync);
+ }
+
+ return EGL_TRUE;
+}
+
+#endif /* EGL_KHR_reusable_sync */
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_sync.h b/src/gallium/state_trackers/egl/common/egl_g3d_sync.h
new file mode 100644
index 0000000000..3179ca04e1
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_sync.h
@@ -0,0 +1,53 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * 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 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:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef _EGL_G3D_SYNC_H_
+#define _EGL_G3D_SYNC_H_
+
+#include "egl_g3d.h"
+
+#ifdef EGL_KHR_reusable_sync
+
+_EGLSync *
+egl_g3d_create_sync(_EGLDriver *drv, _EGLDisplay *dpy,
+ EGLenum type, const EGLint *attrib_list);
+
+EGLBoolean
+egl_g3d_destroy_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync);
+
+EGLint
+egl_g3d_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+ EGLint flags, EGLTimeKHR timeout);
+
+EGLBoolean
+egl_g3d_signal_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+ EGLenum mode);
+
+#endif /* EGL_KHR_reusable_sync */
+
+#endif /* _EGL_G3D_SYNC_H_ */