1f37070bab6af350caec905ea7658e9241042b6ccIan Romanick/*
2f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * Copyright © 2009 Intel Corporation
3f37070bab6af350caec905ea7658e9241042b6ccIan Romanick *
4f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * Permission is hereby granted, free of charge, to any person obtaining a
5f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * copy of this software and associated documentation files (the "Software"),
6f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * to deal in the Software without restriction, including without limitation
7f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * and/or sell copies of the Software, and to permit persons to whom the
9f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * Software is furnished to do so, subject to the following conditions:
10f37070bab6af350caec905ea7658e9241042b6ccIan Romanick *
11f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * The above copyright notice and this permission notice (including the next
12f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * paragraph) shall be included in all copies or substantial portions of the
13f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * Software.
14f37070bab6af350caec905ea7658e9241042b6ccIan Romanick *
15f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * DEALINGS IN THE SOFTWARE.
22f37070bab6af350caec905ea7658e9241042b6ccIan Romanick */
23f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
24f37070bab6af350caec905ea7658e9241042b6ccIan Romanick/**
25f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * \file syncobj.c
26f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * Sync object management.
27f37070bab6af350caec905ea7658e9241042b6ccIan Romanick *
2816b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick * Unlike textures and other objects that are shared between contexts, sync
2916b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick * objects are not bound to the context.  As a result, the reference counting
3016b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick * and delete behavior of sync objects is slightly different.  References to
3116b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick * sync objects are added:
3216b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick *
3316b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick *    - By \c glFencSynce.  This sets the initial reference count to 1.
3416b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick *    - At the start of \c glClientWaitSync.  The reference is held for the
3516b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick *      duration of the wait call.
3616b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick *
3716b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick * References are removed:
3816b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick *
3916b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick *    - By \c glDeleteSync.
4016b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick *    - At the end of \c glClientWaitSync.
4116b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick *
4216b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick * Additionally, drivers may call \c _mesa_ref_sync_object and
4316b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick * \c _mesa_unref_sync_object as needed to implement \c ServerWaitSync.
4416b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick *
4516b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick * As with shader objects, sync object names become invalid as soon as
4616b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick * \c glDeleteSync is called.  For this reason \c glDeleteSync sets the
4716b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick * \c DeletePending flag.  All functions validate object handles by testing
4816b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick * this flag.
4916b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick *
5016b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick * \note
5116b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick * Only \c GL_ARB_sync objects are shared between contexts.  If support is ever
5216b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick * added for either \c GL_NV_fence or \c GL_APPLE_fence different semantics
5316b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick * will need to be implemented.
5416b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick *
55f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * \author Ian Romanick <ian.d.romanick@intel.com>
56f37070bab6af350caec905ea7658e9241042b6ccIan Romanick */
57f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
58f37070bab6af350caec905ea7658e9241042b6ccIan Romanick#include "glheader.h"
59f37070bab6af350caec905ea7658e9241042b6ccIan Romanick#include "imports.h"
60f37070bab6af350caec905ea7658e9241042b6ccIan Romanick#include "context.h"
610f8fdd81989de5026c8e415f1525931b74dd8647Ian Romanick#include "macros.h"
62db61b9ce39bccc43140357652ceb78baaf2aea44Vinson Lee#include "mfeatures.h"
6310ff2646a443ca3c54d66443b346eb7063973b5eChia-I Wu#include "get.h"
6410ff2646a443ca3c54d66443b346eb7063973b5eChia-I Wu#include "dispatch.h"
650117da40cd7edd3d165bb28569c289b37eca12b9Vinson Lee#include "mtypes.h"
66f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
67f37070bab6af350caec905ea7658e9241042b6ccIan Romanick#if FEATURE_ARB_sync
68f37070bab6af350caec905ea7658e9241042b6ccIan Romanick#include "syncobj.h"
69f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
70f37070bab6af350caec905ea7658e9241042b6ccIan Romanickstatic struct gl_sync_object *
71f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_new_sync_object(struct gl_context *ctx, GLenum type)
72f37070bab6af350caec905ea7658e9241042b6ccIan Romanick{
73f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   struct gl_sync_object *s = MALLOC_STRUCT(gl_sync_object);
74f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   (void) ctx;
75f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   (void) type;
76f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
77f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   return s;
78f37070bab6af350caec905ea7658e9241042b6ccIan Romanick}
79f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
80f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
81f37070bab6af350caec905ea7658e9241042b6ccIan Romanickstatic void
82f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_delete_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj)
83f37070bab6af350caec905ea7658e9241042b6ccIan Romanick{
84f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   (void) ctx;
8532f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg   free(syncObj);
86f37070bab6af350caec905ea7658e9241042b6ccIan Romanick}
87f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
88f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
89f37070bab6af350caec905ea7658e9241042b6ccIan Romanickstatic void
90f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_fence_sync(struct gl_context *ctx, struct gl_sync_object *syncObj,
91f37070bab6af350caec905ea7658e9241042b6ccIan Romanick		 GLenum condition, GLbitfield flags)
92f37070bab6af350caec905ea7658e9241042b6ccIan Romanick{
93f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   (void) ctx;
94f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   (void) condition;
95f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   (void) flags;
96f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
97e059885ce357dee8b847f10e8e8c515a4a20042eBrian Paul   syncObj->StatusFlag = 1;
98f37070bab6af350caec905ea7658e9241042b6ccIan Romanick}
99f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
100f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
101f37070bab6af350caec905ea7658e9241042b6ccIan Romanickstatic void
102f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_check_sync(struct gl_context *ctx, struct gl_sync_object *syncObj)
103f37070bab6af350caec905ea7658e9241042b6ccIan Romanick{
104f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   (void) ctx;
105f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   (void) syncObj;
106f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
107f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   /* No-op for software rendering.  Hardware drivers will need to determine
108f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    * whether the state of the sync object has changed.
109f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    */
110f37070bab6af350caec905ea7658e9241042b6ccIan Romanick}
111f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
112f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
113f37070bab6af350caec905ea7658e9241042b6ccIan Romanickstatic void
114f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_wait_sync(struct gl_context *ctx, struct gl_sync_object *syncObj,
115f37070bab6af350caec905ea7658e9241042b6ccIan Romanick		GLbitfield flags, GLuint64 timeout)
116f37070bab6af350caec905ea7658e9241042b6ccIan Romanick{
117f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   (void) ctx;
118f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   (void) syncObj;
119f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   (void) flags;
120f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   (void) timeout;
121f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
122f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   /* No-op for software rendering.  Hardware drivers will need to wait until
123f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    * the state of the sync object changes or the timeout expires.
124f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    */
125f37070bab6af350caec905ea7658e9241042b6ccIan Romanick}
126f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
127f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
128f37070bab6af350caec905ea7658e9241042b6ccIan Romanickvoid
129f37070bab6af350caec905ea7658e9241042b6ccIan Romanick_mesa_init_sync_object_functions(struct dd_function_table *driver)
130f37070bab6af350caec905ea7658e9241042b6ccIan Romanick{
131f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   driver->NewSyncObject = _mesa_new_sync_object;
132f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   driver->FenceSync = _mesa_fence_sync;
133f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   driver->DeleteSyncObject = _mesa_delete_sync_object;
134f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   driver->CheckSync = _mesa_check_sync;
135f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
136f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   /* Use the same no-op wait function for both.
137f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    */
138f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   driver->ClientWaitSync = _mesa_wait_sync;
139f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   driver->ServerWaitSync = _mesa_wait_sync;
140f37070bab6af350caec905ea7658e9241042b6ccIan Romanick}
141f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
142f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
14310ff2646a443ca3c54d66443b346eb7063973b5eChia-I Wuvoid
14410ff2646a443ca3c54d66443b346eb7063973b5eChia-I Wu_mesa_init_sync_dispatch(struct _glapi_table *disp)
14510ff2646a443ca3c54d66443b346eb7063973b5eChia-I Wu{
14610ff2646a443ca3c54d66443b346eb7063973b5eChia-I Wu   SET_IsSync(disp, _mesa_IsSync);
14710ff2646a443ca3c54d66443b346eb7063973b5eChia-I Wu   SET_DeleteSync(disp, _mesa_DeleteSync);
14810ff2646a443ca3c54d66443b346eb7063973b5eChia-I Wu   SET_FenceSync(disp, _mesa_FenceSync);
14910ff2646a443ca3c54d66443b346eb7063973b5eChia-I Wu   SET_ClientWaitSync(disp, _mesa_ClientWaitSync);
15010ff2646a443ca3c54d66443b346eb7063973b5eChia-I Wu   SET_WaitSync(disp, _mesa_WaitSync);
15110ff2646a443ca3c54d66443b346eb7063973b5eChia-I Wu   SET_GetInteger64v(disp, _mesa_GetInteger64v);
15210ff2646a443ca3c54d66443b346eb7063973b5eChia-I Wu   SET_GetSynciv(disp, _mesa_GetSynciv);
15310ff2646a443ca3c54d66443b346eb7063973b5eChia-I Wu}
15410ff2646a443ca3c54d66443b346eb7063973b5eChia-I Wu
15510ff2646a443ca3c54d66443b346eb7063973b5eChia-I Wu
156f37070bab6af350caec905ea7658e9241042b6ccIan Romanick/**
157f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * Allocate/init the context state related to sync objects.
158f37070bab6af350caec905ea7658e9241042b6ccIan Romanick */
159f37070bab6af350caec905ea7658e9241042b6ccIan Romanickvoid
160f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_init_sync(struct gl_context *ctx)
161f37070bab6af350caec905ea7658e9241042b6ccIan Romanick{
162f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   (void) ctx;
163f37070bab6af350caec905ea7658e9241042b6ccIan Romanick}
164f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
165f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
166f37070bab6af350caec905ea7658e9241042b6ccIan Romanick/**
167f37070bab6af350caec905ea7658e9241042b6ccIan Romanick * Free the context state related to sync objects.
168f37070bab6af350caec905ea7658e9241042b6ccIan Romanick */
169f37070bab6af350caec905ea7658e9241042b6ccIan Romanickvoid
170f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_free_sync_data(struct gl_context *ctx)
171f37070bab6af350caec905ea7658e9241042b6ccIan Romanick{
172f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   (void) ctx;
173f37070bab6af350caec905ea7658e9241042b6ccIan Romanick}
174f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
175f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
17616b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanickstatic int
17716b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick_mesa_validate_sync(struct gl_sync_object *syncObj)
178f37070bab6af350caec905ea7658e9241042b6ccIan Romanick{
17916b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick   return (syncObj != NULL)
18016b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick      && (syncObj->Type == GL_SYNC_FENCE)
18116b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick      && !syncObj->DeletePending;
18216b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick}
183f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
184f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
18516b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanickvoid
186f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_ref_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj)
18716b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick{
18816b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
18916b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick   syncObj->RefCount++;
19016b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
191f37070bab6af350caec905ea7658e9241042b6ccIan Romanick}
192f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
193f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
19416b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanickvoid
195f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_unref_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj)
196f37070bab6af350caec905ea7658e9241042b6ccIan Romanick{
19716b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
198f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   syncObj->RefCount--;
199f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   if (syncObj->RefCount == 0) {
20016b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick      remove_from_list(& syncObj->link);
20116b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick      _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
20216b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick
2030342dce226fe79d7a6c0e7cd735c596fad3e8aacIan Romanick      ctx->Driver.DeleteSyncObject(ctx, syncObj);
204f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   } else {
20516b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick      _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
206f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   }
207f37070bab6af350caec905ea7658e9241042b6ccIan Romanick}
208f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
209f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
210826d441cdfa16a16d165297beb3013f4ff8b4816Michal KrolGLboolean GLAPIENTRY
21116b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick_mesa_IsSync(GLsync sync)
21216b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick{
21316b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick   GET_CURRENT_CONTEXT(ctx);
21416b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick   struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync;
21516b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
21616b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick
21716b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick   return _mesa_validate_sync(syncObj) ? GL_TRUE : GL_FALSE;
21816b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick}
21916b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick
22016b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick
221826d441cdfa16a16d165297beb3013f4ff8b4816Michal Krolvoid GLAPIENTRY
222f37070bab6af350caec905ea7658e9241042b6ccIan Romanick_mesa_DeleteSync(GLsync sync)
223f37070bab6af350caec905ea7658e9241042b6ccIan Romanick{
224f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   GET_CURRENT_CONTEXT(ctx);
225f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync;
226f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   ASSERT_OUTSIDE_BEGIN_END(ctx);
227f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
228f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   /* From the GL_ARB_sync spec:
229f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    *
230f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    *    DeleteSync will silently ignore a <sync> value of zero. An
231f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    *    INVALID_VALUE error is generated if <sync> is neither zero nor the
232f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    *    name of a sync object.
233f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    */
234f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   if (sync == 0) {
235f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      return;
236f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   }
237f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
23816b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick   if (!_mesa_validate_sync(syncObj)) {
239f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteSync");
240f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      return;
241f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   }
242f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
243f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   /* If there are no client-waits or server-waits pending on this sync, delete
244f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    * the underlying object.
245f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    */
24616b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick   syncObj->DeletePending = GL_TRUE;
247f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   _mesa_unref_sync_object(ctx, syncObj);
248f37070bab6af350caec905ea7658e9241042b6ccIan Romanick}
249f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
250f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
251826d441cdfa16a16d165297beb3013f4ff8b4816Michal KrolGLsync GLAPIENTRY
252f37070bab6af350caec905ea7658e9241042b6ccIan Romanick_mesa_FenceSync(GLenum condition, GLbitfield flags)
253f37070bab6af350caec905ea7658e9241042b6ccIan Romanick{
254f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   GET_CURRENT_CONTEXT(ctx);
255f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   struct gl_sync_object *syncObj;
256f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
257f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
258f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE) {
259f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      _mesa_error(ctx, GL_INVALID_ENUM, "glFenceSync(condition=0x%x)",
260f37070bab6af350caec905ea7658e9241042b6ccIan Romanick		  condition);
261f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      return 0;
262f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   }
263f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
264f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   if (flags != 0) {
265f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      _mesa_error(ctx, GL_INVALID_VALUE, "glFenceSync(flags=0x%x)",
266f37070bab6af350caec905ea7658e9241042b6ccIan Romanick		  condition);
267f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      return 0;
268f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   }
269f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
2700342dce226fe79d7a6c0e7cd735c596fad3e8aacIan Romanick   syncObj = ctx->Driver.NewSyncObject(ctx, GL_SYNC_FENCE);
271f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   if (syncObj != NULL) {
272f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      syncObj->Type = GL_SYNC_FENCE;
273f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      /* The name is not currently used, and it is never visible to
274f37070bab6af350caec905ea7658e9241042b6ccIan Romanick       * applications.  If sync support is extended to provide support for
275f37070bab6af350caec905ea7658e9241042b6ccIan Romanick       * NV_fence, this field will be used.  We'll also need to add an object
276f37070bab6af350caec905ea7658e9241042b6ccIan Romanick       * ID hashtable.
277f37070bab6af350caec905ea7658e9241042b6ccIan Romanick       */
278f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      syncObj->Name = 1;
279f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      syncObj->RefCount = 1;
280f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      syncObj->DeletePending = GL_FALSE;
281f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      syncObj->SyncCondition = condition;
282f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      syncObj->Flags = flags;
283e059885ce357dee8b847f10e8e8c515a4a20042eBrian Paul      syncObj->StatusFlag = 0;
284f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
2850342dce226fe79d7a6c0e7cd735c596fad3e8aacIan Romanick      ctx->Driver.FenceSync(ctx, syncObj, condition, flags);
286f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
28716b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick      _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
28816b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick      insert_at_tail(& ctx->Shared->SyncObjects, & syncObj->link);
28916b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick      _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
29016b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick
291f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      return (GLsync) syncObj;
292f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   }
293f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
294f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   return NULL;
295f37070bab6af350caec905ea7658e9241042b6ccIan Romanick}
296f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
297f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
298826d441cdfa16a16d165297beb3013f4ff8b4816Michal KrolGLenum GLAPIENTRY
299f37070bab6af350caec905ea7658e9241042b6ccIan Romanick_mesa_ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
300f37070bab6af350caec905ea7658e9241042b6ccIan Romanick{
301f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   GET_CURRENT_CONTEXT(ctx);
302f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync;
303f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   GLenum ret;
304f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_WAIT_FAILED);
305f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
30616b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick   if (!_mesa_validate_sync(syncObj)) {
307f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      _mesa_error(ctx, GL_INVALID_OPERATION, "glClientWaitSync");
308f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      return GL_WAIT_FAILED;
309f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   }
310f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
311f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   if ((flags & ~GL_SYNC_FLUSH_COMMANDS_BIT) != 0) {
312f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      _mesa_error(ctx, GL_INVALID_ENUM, "glClientWaitSync(flags=0x%x)", flags);
313f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      return GL_WAIT_FAILED;
314f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   }
315f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
31616b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick   _mesa_ref_sync_object(ctx, syncObj);
31716b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick
318f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   /* From the GL_ARB_sync spec:
319f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    *
320f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    *    ClientWaitSync returns one of four status values. A return value of
321f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    *    ALREADY_SIGNALED indicates that <sync> was signaled at the time
322f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    *    ClientWaitSync was called. ALREADY_SIGNALED will always be returned
323f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    *    if <sync> was signaled, even if the value of <timeout> is zero.
324f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    */
3250342dce226fe79d7a6c0e7cd735c596fad3e8aacIan Romanick   ctx->Driver.CheckSync(ctx, syncObj);
326e059885ce357dee8b847f10e8e8c515a4a20042eBrian Paul   if (syncObj->StatusFlag) {
32716b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick      ret = GL_ALREADY_SIGNALED;
32816b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick   } else {
329405d47bbe78106f44e4283925e58a1d1ebc88455Vadim Girlin      if (timeout == 0) {
330405d47bbe78106f44e4283925e58a1d1ebc88455Vadim Girlin         ret = GL_TIMEOUT_EXPIRED;
331405d47bbe78106f44e4283925e58a1d1ebc88455Vadim Girlin      } else {
332405d47bbe78106f44e4283925e58a1d1ebc88455Vadim Girlin         ctx->Driver.ClientWaitSync(ctx, syncObj, flags, timeout);
333f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
334405d47bbe78106f44e4283925e58a1d1ebc88455Vadim Girlin         ret = syncObj->StatusFlag ? GL_CONDITION_SATISFIED : GL_TIMEOUT_EXPIRED;
335405d47bbe78106f44e4283925e58a1d1ebc88455Vadim Girlin      }
336f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   }
337f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
33816b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick   _mesa_unref_sync_object(ctx, syncObj);
339f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   return ret;
340f37070bab6af350caec905ea7658e9241042b6ccIan Romanick}
341f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
342f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
343826d441cdfa16a16d165297beb3013f4ff8b4816Michal Krolvoid GLAPIENTRY
344f37070bab6af350caec905ea7658e9241042b6ccIan Romanick_mesa_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
345f37070bab6af350caec905ea7658e9241042b6ccIan Romanick{
346f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   GET_CURRENT_CONTEXT(ctx);
347f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync;
348f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   ASSERT_OUTSIDE_BEGIN_END(ctx);
349f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
35016b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick   if (!_mesa_validate_sync(syncObj)) {
351f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      _mesa_error(ctx, GL_INVALID_OPERATION, "glWaitSync");
352f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      return;
353f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   }
354f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
355f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   if (flags != 0) {
356f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      _mesa_error(ctx, GL_INVALID_ENUM, "glWaitSync(flags=0x%x)", flags);
357f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      return;
358f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   }
359f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
360f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   /* From the GL_ARB_sync spec:
361f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    *
362f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    *     If the value of <timeout> is zero, then WaitSync does nothing.
363f37070bab6af350caec905ea7658e9241042b6ccIan Romanick    */
364f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   if (timeout == 0) {
365f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      return;
366f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   }
367f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
3680342dce226fe79d7a6c0e7cd735c596fad3e8aacIan Romanick   ctx->Driver.ServerWaitSync(ctx, syncObj, flags, timeout);
369f37070bab6af350caec905ea7658e9241042b6ccIan Romanick}
370f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
371f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
372826d441cdfa16a16d165297beb3013f4ff8b4816Michal Krolvoid GLAPIENTRY
373f37070bab6af350caec905ea7658e9241042b6ccIan Romanick_mesa_GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length,
374f37070bab6af350caec905ea7658e9241042b6ccIan Romanick		GLint *values)
375f37070bab6af350caec905ea7658e9241042b6ccIan Romanick{
376f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   GET_CURRENT_CONTEXT(ctx);
377f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync;
378f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   GLsizei size = 0;
379f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   GLint v[1];
380f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   ASSERT_OUTSIDE_BEGIN_END(ctx);
381f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
38216b393d05990b6e917e144f9de87d0103b4c3e6dIan Romanick   if (!_mesa_validate_sync(syncObj)) {
383f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetSynciv");
384f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      return;
385f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   }
386f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
387f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   switch (pname) {
388f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   case GL_OBJECT_TYPE:
389f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      v[0] = syncObj->Type;
390f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      size = 1;
391f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      break;
392f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
393f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   case GL_SYNC_CONDITION:
394f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      v[0] = syncObj->SyncCondition;
395f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      size = 1;
396f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      break;
397f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
398f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   case GL_SYNC_STATUS:
399f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      /* Update the state of the sync by dipping into the driver.  Note that
400f37070bab6af350caec905ea7658e9241042b6ccIan Romanick       * this call won't block.  It just updates state in the common object
401f37070bab6af350caec905ea7658e9241042b6ccIan Romanick       * data from the current driver state.
402f37070bab6af350caec905ea7658e9241042b6ccIan Romanick       */
4030342dce226fe79d7a6c0e7cd735c596fad3e8aacIan Romanick      ctx->Driver.CheckSync(ctx, syncObj);
404f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
405e059885ce357dee8b847f10e8e8c515a4a20042eBrian Paul      v[0] = (syncObj->StatusFlag) ? GL_SIGNALED : GL_UNSIGNALED;
406f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      size = 1;
407f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      break;
408f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
409f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   case GL_SYNC_FLAGS:
410f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      v[0] = syncObj->Flags;
411f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      size = 1;
412f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      break;
413f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
414f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   default:
415f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      _mesa_error(ctx, GL_INVALID_ENUM, "glGetSynciv(pname=0x%x)\n", pname);
416f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      return;
417f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   }
418f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
419f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   if (size > 0) {
4200f8fdd81989de5026c8e415f1525931b74dd8647Ian Romanick      const GLsizei copy_count = MIN2(size, bufSize);
421f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
422c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke      memcpy(values, v, sizeof(GLint) * copy_count);
423f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   }
424f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
425f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   if (length != NULL) {
426f37070bab6af350caec905ea7658e9241042b6ccIan Romanick      *length = size;
427f37070bab6af350caec905ea7658e9241042b6ccIan Romanick   }
428f37070bab6af350caec905ea7658e9241042b6ccIan Romanick}
429f37070bab6af350caec905ea7658e9241042b6ccIan Romanick
430f37070bab6af350caec905ea7658e9241042b6ccIan Romanick#endif /* FEATURE_ARB_sync */
431